diff --git a/.changeset/hungry-guests-drive.md b/.changeset/hungry-guests-drive.md new file mode 100644 index 0000000000..7a09fa1cc3 --- /dev/null +++ b/.changeset/hungry-guests-drive.md @@ -0,0 +1,5 @@ +--- +'@mermaid-js/layout-elk': patch +--- + +fix: Updated offset calculations for diamond shape when handling intersections diff --git a/cypress/integration/rendering/flowchart-elk.spec.js b/cypress/integration/rendering/flowchart-elk.spec.js index c3aba53ea4..38bfe6440e 100644 --- a/cypress/integration/rendering/flowchart-elk.spec.js +++ b/cypress/integration/rendering/flowchart-elk.spec.js @@ -900,6 +900,153 @@ flowchart LR n7@{ shape: rect} n8@{ shape: rect} +`, + { flowchart: { titleTopMargin: 0 } } + ); + }); + + it('6088-1: should handle diamond shape intersections', () => { + imgSnapshotTest( + `--- +config: + layout: elk +--- + flowchart LR + subgraph S2 + subgraph s1["APA"] + D{"Use the editor"} + end + + + D -- Mermaid js --> I{"fa:fa-code Text"} + D --> I + D --> I + + end +`, + { flowchart: { titleTopMargin: 0 } } + ); + }); + + it('6088-2: should handle diamond shape intersections', () => { + imgSnapshotTest( + `--- +config: + layout: elk +--- + flowchart LR + a + subgraph s0["APA"] + subgraph s8["APA"] + subgraph s1["APA"] + D{"X"} + E[Q] + end + subgraph s3["BAPA"] + F[Q] + I + end + D --> I + D --> I + D --> I + + I{"X"} + end + end + +`, + { flowchart: { titleTopMargin: 0 } } + ); + }); + + it('6088-3: should handle diamond shape intersections', () => { + imgSnapshotTest( + `--- +config: + layout: elk +--- + flowchart LR + a + D{"Use the editor"} + + D -- Mermaid js --> I{"fa:fa-code Text"} + D-->I + D-->I + +`, + { flowchart: { titleTopMargin: 0 } } + ); + }); + + it('6088-4: 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 } } + ); + }); + + it('6088-5: should handle diamond shape intersections', () => { + imgSnapshotTest( + `--- +config: + layout: elk +--- +flowchart LR + A{A} --> B & C + +`, + { flowchart: { titleTopMargin: 0 } } + ); + }); + it('6088-6: should handle diamond shape intersections', () => { + imgSnapshotTest( + `--- +config: + layout: elk +--- +flowchart LR + A{A} --> B & C + subgraph "subbe" + A + end + `, { flowchart: { titleTopMargin: 0 } } ); diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 7ec666c1a9..1c7bda8e7d 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -88,33 +88,61 @@
-+--- config: layout: elk --- -flowchart LR - 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"] + flowchart LR + subgraph S2 + subgraph s1["APA"] + D{"Use the editor"} + end + + D -- Mermaid js --> I{"fa:fa-code Text"} + D --> I + D --> I + end +++--- +config: + layout: elk +--- + flowchart LR + a + subgraph s0["APA"] + subgraph s8["APA"] + subgraph s1["APA"] + D{"X"} + E[Q] + end + subgraph s3["BAPA"] + F[Q] + I + end + D --> I + D --> I + D --> I + + I{"X"} + end + end +++--- +config: + layout: elk +--- + flowchart LR + a + D{"Use the editor"} + + D -- Mermaid js --> I{"fa:fa-code Text"} + D-->I + D-->I--- @@ -155,7 +183,7 @@ n8@{ shape: rect}-+--- config: layout: elk @@ -171,7 +199,7 @@-+--- config: layout: elk @@ -180,7 +208,19 @@ A{A} --> B & C-++--- +config: + layout: elk +--- +flowchart LR + A{A} --> B & C + subgraph "subbe" + A + end ++--- config: layout: elk diff --git a/packages/mermaid-layout-elk/src/render.ts b/packages/mermaid-layout-elk/src/render.ts index 1216b5dc82..59b97c557f 100644 --- a/packages/mermaid-layout-elk/src/render.ts +++ b/packages/mermaid-layout-elk/src/render.ts @@ -705,14 +705,11 @@ export const render = async ( bounds: { x: any; y: any; width: any; height: any; padding: any }, isDiamond: boolean ) => { - log.debug('UIO cutPathAtIntersect Points:', _points, 'node:', bounds, 'isDiamond', isDiamond); + log.debug('APA18 cutPathAtIntersect Points:', _points, 'node:', bounds, 'isDiamond', isDiamond); const points: any[] = []; let lastPointOutside = _points[0]; let isInside = false; _points.forEach((point: any) => { - // const node = clusterDb[edge.toCluster].node; - log.debug(' checking point', point, bounds); - // check if point is inside the boundary rect if (!outsideNode(bounds, point) && !isInside) { // First point inside the rect found @@ -906,7 +903,7 @@ export const render = async ( const offset = calcOffset(sourceId, targetId, parentLookupDb); log.debug( - 'offset', + 'APA18 offset', offset, sourceId, ' ==> ', @@ -971,29 +968,22 @@ export const render = async ( } 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, + x: startNode.offset.posX + startNode.width / 2, + y: startNode.offset.posY + startNode.height / 2, }); } 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.01 || - Math.abs(edge.points[edge.points.length - 1].x - x) > 0.001 - ) { - edge.points.push({ - x: endNode.x + endNode.width / 2 + offset.x, - y: endNode.y + endNode.height / 2 + offset.y, - }); - } + edge.points.push({ + x: endNode.offset.posX + endNode.width / 2, + y: endNode.offset.posY + endNode.height / 2, + }); } edge.points = cutPathAtIntersect( edge.points.reverse(), { - x: startNode.x + startNode.width / 2 + offset.x, - y: startNode.y + startNode.height / 2 + offset.y, + x: startNode.offset.posX + startNode.width / 2, + y: startNode.offset.posY + startNode.height / 2, width: sw, height: startNode.height, padding: startNode.padding, @@ -1004,8 +994,8 @@ export const render = async ( edge.points = cutPathAtIntersect( edge.points, { - x: endNode.x + ew / 2 + endNode.offset.x, - y: endNode.y + endNode.height / 2 + endNode.offset.y, + x: endNode.offset.posX + endNode.width / 2, + y: endNode.offset.posY + endNode.height / 2, width: ew, height: endNode.height, padding: endNode.padding,