Skip to content

Commit

Permalink
Merge pull request #6081 from mermaid-js/6080-fix
Browse files Browse the repository at this point in the history
fix: Elk rendering of Diamond shape intersections
  • Loading branch information
ashishjain0512 authored Nov 26, 2024
2 parents dfaaf36 + 3753831 commit cc29437
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .changeset/nervous-beans-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@mermaid-js/layout-elk': patch
---

fix: Elk rendering of Diamond shape intersections
43 changes: 43 additions & 0 deletions cypress/integration/rendering/flowchart-elk.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,49 @@ flowchart LR
D --> E
A["A"]
`,
{ flowchart: { titleTopMargin: 0 } }
);
});
it('6080: should handle diamond shape intersections', () => {
imgSnapshotTest(
`---
config:
layout: elk
---
flowchart LR
subgraph s1["Untitled subgraph"]
n1["Evaluate"]
n2["Option 1"]
n3["Option 2"]
n4["fa:fa-car Option 3"]
end
subgraph s2["Untitled subgraph"]
n5["Evaluate"]
n6["Option 1"]
n7["Option 2"]
n8["fa:fa-car Option 3"]
end
A["Start"] -- Some text --> B("Continue")
B --> C{"Evaluate"}
C -- One --> D["Option 1"]
C -- Two --> E["Option 2"]
C -- Three --> F["fa:fa-car Option 3"]
n1 -- One --> n2
n1 -- Two --> n3
n1 -- Three --> n4
n5 -- One --> n6
n5 -- Two --> n7
n5 -- Three --> n8
n1@{ shape: diam}
n2@{ shape: rect}
n3@{ shape: rect}
n4@{ shape: rect}
n5@{ shape: diam}
n6@{ shape: rect}
n7@{ shape: rect}
n8@{ shape: rect}
`,
{ flowchart: { titleTopMargin: 0 } }
);
Expand Down
142 changes: 118 additions & 24 deletions cypress/platform/knsv2.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,40 +88,134 @@
</head>

<body>
<pre id="diagram4" class="mermaid">
<pre id="diagram4" class="mermaid2">
---
config:
look: handDrawn
theme: default
layout: elk
---
flowchart LR
n00@{ shape: triangle, label: 'This is a label for triangle shape' }
n11@{ shape: sloped-rectangle, label: 'This is a label for sloped-rectangle shape' }
n22@{ shape: horizontal-cylinder, label: 'This is a label for horizontal-cylinder shape' }
n33@{ shape: flipped-triangle, label: 'This is a label for flipped-triangle shape' }
n44@{ shape: hourglass, label: 'This is a label for hourglass shape' }
n00 --> n11
n00 --> n22
n00 --> n33
n00 --> n44
n11 --> n22
n11 --> n33
n11 --> n44
n22 --> n33
n22 --> n44
n33 --> n44
subgraph s1["Untitled subgraph"]
n1["Evaluate"]
n2["Option 1"]
n3["Option 2"]
n4["fa:fa-car Option 3"]
end
n1 -- One --> n2
n1 -- Two --> n3
n1 -- Three --> n4
n5
n1@{ shape: diam}
n2@{ shape: rect}
n3@{ shape: rect}
n4@{ shape: rect}
A["Start"] -- Some text --> B("Continue")
B --> C{"Evaluate"}
C -- One --> D["Option 1"]
C -- Two --> E["Option 2"]
C -- Three --> F["fa:fa-car Option 3"]


</pre>
<pre id="diagram4" class="mermaid">
---
config:
look: handDrawn
theme: default
layout: elk
---
flowchart LR
subgraph s1["Untitled subgraph"]
n1["Evaluate"]
n2["Option 1"]
n3["Option 2"]
n4["fa:fa-car Option 3"]
end
subgraph s2["Untitled subgraph"]
n5["Evaluate"]
n6["Option 1"]
n7["Option 2"]
n8["fa:fa-car Option 3"]
end
A["Start"] -- Some text --> B("Continue")
B --> C{"Evaluate"}
C -- One --> D["Option 1"]
C -- Two --> E["Option 2"]
C -- Three --> F["fa:fa-car Option 3"]
n1 -- One --> n2
n1 -- Two --> n3
n1 -- Three --> n4
n5 -- One --> n6
n5 -- Two --> n7
n5 -- Three --> n8
n1@{ shape: diam}
n2@{ shape: rect}
n3@{ shape: rect}
n4@{ shape: rect}
n5@{ shape: diam}
n6@{ shape: rect}
n7@{ shape: rect}
n8@{ shape: rect}

</pre>
<pre id="diagram4" class="mermaid2">
---
config:
layout: elk
---
flowchart LR
subgraph s1["Untitled subgraph"]
n1["Evaluate"]
n2["Option 1"]
end
n1 -- One --> n2




</pre>
<pre id="diagram4" class="mermaid2">
---
config:
layout: elk
---
flowchart LR
n22@{ shape: h-cyl }
n00 --> n11
n00 --> n22
n11 --> n22
A{A} --> B & C
</pre
>
<pre id="diagram4" class="mermaid2">
---
config:
layout: elk
---
flowchart LR
n2@{ shape: rect}
n3@{ shape: rect}
n4@{ shape: rect}
A["Start"] -- Some text --> B("Continue")
B --> C{"Evaluate"}
C -- One --> D["Option 1"]
C -- Two --> E["Option 2"]
C -- Three --> F["fa:fa-car Option 3"]
%% C@{ shape: hexagon}


</pre>
<pre id="diagram4" class="mermaid2">
---
config:
kanban:
ticketBaseUrl: 'https://github.com/your-repo/issues/#TICKET#'
---
kanban
Backlog
task1[📝 Define project requirements]@{ ticket: a101 }
To Do
task2[🔍 Research technologies]@{ ticket: a102 }
Review
task4[🔍 Code review for login feature]@{ ticket: a104 }
Done
task5[✅ Deploy initial version]@{ ticket: a105 }
In Progress
task3[💻 Develop login feature]@{ ticket: 103 }

</pre>
<pre id="diagram4" class="mermaid2">
flowchart LR
Expand Down
29 changes: 15 additions & 14 deletions packages/mermaid-layout-elk/src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,8 @@ export const render = async (
const r3 = a1 * q1.x + b1 * q1.y + c1;
const r4 = a1 * q2.x + b1 * q2.y + c1;

const epsilon = 1e-6;

// Check signs of r3 and r4. If both point 3 and point 4 lie on
// same side of line 1, the line segments do not intersect.
if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) {
Expand All @@ -502,7 +504,7 @@ export const render = async (
// Check signs of r1 and r2. If both point 1 and point 2 lie
// on same side of second line segment, the line segments do
// not intersect.
if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) {
if (Math.abs(r1) < epsilon && Math.abs(r2) < epsilon && sameSign(r1, r2)) {
return /*DON'T_INTERSECT*/;
}

Expand Down Expand Up @@ -547,11 +549,11 @@ export const render = async (
{ x: x1 - w / 2, y: y1 },
];
log.debug(
`UIO diamondIntersection calc abc89:
`APA16 diamondIntersection calc abc89:
outsidePoint: ${JSON.stringify(outsidePoint)}
insidePoint : ${JSON.stringify(insidePoint)}
node : x:${bounds.x} y:${bounds.y} w:${bounds.width} h:${bounds.height}`,
polyPoints
node-bounds : x:${bounds.x} y:${bounds.y} w:${bounds.width} h:${bounds.height}`,
JSON.stringify(polyPoints)
);

const intersections = [];
Expand All @@ -564,17 +566,17 @@ export const render = async (
minY = Math.min(minY, entry.y);
});

// const left = x1 - w / 2;
// const top = y1 + h / 2;
const left = x1 - w / 2 - minX;
const top = y1 - h / 2 - minY;

for (let i = 0; i < polyPoints.length; i++) {
const p1 = polyPoints[i];
const p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0];
const intersect = intersectLine(
bounds,
outsidePoint,
{ x: p1.x, y: p1.y },
{ x: p2.x, y: p2.y }
{ x: left + p1.x, y: top + p1.y },
{ x: left + p2.x, y: top + p2.y }
);

if (intersect) {
Expand Down Expand Up @@ -753,7 +755,6 @@ export const render = async (
}
}
});
log.debug('returning points', points);
return points;
};

Expand Down Expand Up @@ -968,17 +969,17 @@ export const render = async (
startNode.innerHTML
);
}
if (startNode.shape === 'diamond') {
if (startNode.shape === 'diamond' || startNode.shape === 'diam') {
edge.points.unshift({
x: startNode.x + startNode.width / 2 + offset.x,
y: startNode.y + startNode.height / 2 + offset.y,
});
}
if (endNode.shape === 'diamond') {
if (endNode.shape === 'diamond' || endNode.shape === 'diam') {
const x = endNode.x + endNode.width / 2 + offset.x;
// Add a point at the center of the diamond
if (
Math.abs(edge.points[edge.points.length - 1].y - endNode.y - offset.y) > 0.001 ||
Math.abs(edge.points[edge.points.length - 1].y - endNode.y - offset.y) > 0.01 ||
Math.abs(edge.points[edge.points.length - 1].x - x) > 0.001
) {
edge.points.push({
Expand All @@ -997,7 +998,7 @@ export const render = async (
height: startNode.height,
padding: startNode.padding,
},
startNode.shape === 'diamond'
startNode.shape === 'diamond' || startNode.shape === 'diam'
).reverse();

edge.points = cutPathAtIntersect(
Expand All @@ -1009,7 +1010,7 @@ export const render = async (
height: endNode.height,
padding: endNode.padding,
},
endNode.shape === 'diamond'
endNode.shape === 'diamond' || endNode.shape === 'diam'
);

const paths = insertEdge(
Expand Down

0 comments on commit cc29437

Please sign in to comment.