Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Elk rendering of Diamond shape intersections #6081

Merged
merged 4 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -36,8 +36,8 @@
}: InternalHelpers,
{ algorithm }: RenderOptions
) => {
const nodeDb: Record<string, any> = {};

Check warning on line 39 in packages/mermaid-layout-elk/src/render.ts

View workflow job for this annotation

GitHub Actions / autofix

Unexpected any. Specify a different type
const clusterDb: Record<string, any> = {};

Check warning on line 40 in packages/mermaid-layout-elk/src/render.ts

View workflow job for this annotation

GitHub Actions / autofix

Unexpected any. Specify a different type

const addVertex = async (
nodeEl: SVGGroup,
Expand Down Expand Up @@ -112,21 +112,21 @@
const drawNodes = async (
relX: number,
relY: number,
nodeArray: any[],

Check warning on line 115 in packages/mermaid-layout-elk/src/render.ts

View workflow job for this annotation

GitHub Actions / autofix

Unexpected any. Specify a different type
svg: any,

Check warning on line 116 in packages/mermaid-layout-elk/src/render.ts

View workflow job for this annotation

GitHub Actions / autofix

Unexpected any. Specify a different type
subgraphsEl: SVGGroup,
depth: number
) => {
await Promise.all(
nodeArray.map(async function (node: {
id: string | number;
x: any;

Check warning on line 123 in packages/mermaid-layout-elk/src/render.ts

View workflow job for this annotation

GitHub Actions / autofix

Unexpected any. Specify a different type
y: any;

Check warning on line 124 in packages/mermaid-layout-elk/src/render.ts

View workflow job for this annotation

GitHub Actions / autofix

Unexpected any. Specify a different type
width: number;
labels: { width: any }[];

Check warning on line 126 in packages/mermaid-layout-elk/src/render.ts

View workflow job for this annotation

GitHub Actions / autofix

Unexpected any. Specify a different type
height: number;
isGroup: any;

Check warning on line 128 in packages/mermaid-layout-elk/src/render.ts

View workflow job for this annotation

GitHub Actions / autofix

Unexpected any. Specify a different type
labelData: any;

Check warning on line 129 in packages/mermaid-layout-elk/src/render.ts

View workflow job for this annotation

GitHub Actions / autofix

Unexpected any. Specify a different type
offset: { posX: number; posY: number };
shape: any;
domId: { node: () => any; attr: (arg0: string, arg1: string) => void };
Expand Down Expand Up @@ -484,6 +484,8 @@
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 @@
// 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 @@
{ 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 @@
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 @@
}
}
});
log.debug('returning points', points);
return points;
};

Expand Down Expand Up @@ -968,17 +969,17 @@
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 @@
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 @@
height: endNode.height,
padding: endNode.padding,
},
endNode.shape === 'diamond'
endNode.shape === 'diamond' || endNode.shape === 'diam'
);

const paths = insertEdge(
Expand Down
Loading