From c063b92cc9120895cbd36f5884e7c91cfcba1535 Mon Sep 17 00:00:00 2001 From: Ashish Jain Date: Wed, 22 Jan 2025 02:03:29 +0100 Subject: [PATCH] Handle more edge cases, and lint fixes --- .../mermaid/src/diagrams/flowchart/flowDb.ts | 16 ++++--- .../flowchart/parser/flow-node-data.spec.js | 45 ++++++++++++++++--- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts index 83c55fc9b..053e6f73c 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts +++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts @@ -232,17 +232,16 @@ export const addSingleLink = function (_start: string, _end: string, type: any, edge.stroke = type.stroke; edge.length = type.length > 10 ? 10 : type.length; } - if (id) { + + if (id && !edges.some((e) => e.id === id)) { edge.id = id; edge.isUserDefinedId = true; } else { const existingLinks = edges.filter((e) => e.start === edge.start && e.end === edge.end); if (existingLinks.length === 0) { edge.id = getEdgeId(edge.start, edge.end, { counter: 0, prefix: 'L' }); - //edge.id = `${edge.start}-${edge.end}-${edge.length}`; } else { edge.id = getEdgeId(edge.start, edge.end, { counter: existingLinks.length + 1, prefix: 'L' }); - //edge.id = `${edge.start}-${edge.end}-${existingLinks.length + 1}`; } } @@ -280,11 +279,16 @@ export const addLink = function (_start: string[], _end: string[], linkData: unk // for a group syntax like A e1@--> B & C, only the first edge should have an the userDefined id // the rest of the edges should have auto generated ids - let isEdgeConsumed = false; for (const start of _start) { for (const end of _end) { - addSingleLink(start, end, linkData, !isEdgeConsumed ? id : undefined); - isEdgeConsumed = true; + //use the id only for last node in _start and and first node in _end + const isLastStart = start === _start[_start.length - 1]; + const isFirstEnd = end === _end[0]; + if (isLastStart && isFirstEnd) { + addSingleLink(start, end, linkData, id); + } else { + addSingleLink(start, end, linkData, undefined); + } } } }; diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js index 0125572ae..2a987753c 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-node-data.spec.js @@ -251,7 +251,7 @@ describe('when parsing directions', function () { expect(data4Layout.nodes[0].shape).toEqual('squareRect'); expect(data4Layout.nodes[0].label).toEqual('This is a
multiline string'); }); - it(' should be possible to use } in strings', function () { + it('should be possible to use } in strings', function () { const res = flow.parser.parse(`flowchart TB A@{ label: "This is a string with }" @@ -264,7 +264,7 @@ describe('when parsing directions', function () { expect(data4Layout.nodes[0].shape).toEqual('squareRect'); expect(data4Layout.nodes[0].label).toEqual('This is a string with }'); }); - it(' should be possible to use @ in strings', function () { + it('should be possible to use @ in strings', function () { const res = flow.parser.parse(`flowchart TB A@{ label: "This is a string with @" @@ -277,7 +277,7 @@ describe('when parsing directions', function () { expect(data4Layout.nodes[0].shape).toEqual('squareRect'); expect(data4Layout.nodes[0].label).toEqual('This is a string with @'); }); - it(' should be possible to use @ in strings', function () { + it('should be possible to use @ in strings', function () { const res = flow.parser.parse(`flowchart TB A@{ label: "This is a string with}" @@ -291,7 +291,7 @@ describe('when parsing directions', function () { expect(data4Layout.nodes[0].label).toEqual('This is a string with}'); }); - it(' should be possible to use @ syntax to add labels on multi nodes', function () { + it('should be possible to use @ syntax to add labels on multi nodes', function () { const res = flow.parser.parse(`flowchart TB n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"} `); @@ -343,7 +343,42 @@ describe('when parsing directions', function () { expect(data4Layout.nodes[9].label).toEqual('@for@ AS@'); expect(data4Layout.nodes[10].label).toEqual('@for@ AS@'); }); - it.skip(' should be possible to use @ syntax to add labels with trail spaces', function () { + + it('should handle unique edge creation with using @ and &', function () { + const res = flow.parser.parse(`flowchart TD + A & B e1@--> C & D + A1 e2@--> C1 & D1 + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(7); + expect(data4Layout.edges.length).toBe(6); + expect(data4Layout.edges[0].id).toEqual('L_A_C_0'); + expect(data4Layout.edges[1].id).toEqual('L_A_D_0'); + expect(data4Layout.edges[2].id).toEqual('e1'); + expect(data4Layout.edges[3].id).toEqual('L_B_D_0'); + expect(data4Layout.edges[4].id).toEqual('e2'); + expect(data4Layout.edges[5].id).toEqual('L_A1_D1_0'); + }); + + it('should handle redefine same edge ids again', function () { + const res = flow.parser.parse(`flowchart TD + A & B e1@--> C & D + A1 e1@--> C1 & D1 + `); + + const data4Layout = flow.parser.yy.getData(); + expect(data4Layout.nodes.length).toBe(7); + expect(data4Layout.edges.length).toBe(6); + expect(data4Layout.edges[0].id).toEqual('L_A_C_0'); + expect(data4Layout.edges[1].id).toEqual('L_A_D_0'); + expect(data4Layout.edges[2].id).toEqual('e1'); + expect(data4Layout.edges[3].id).toEqual('L_B_D_0'); + expect(data4Layout.edges[4].id).toEqual('L_A1_C1_0'); + expect(data4Layout.edges[5].id).toEqual('L_A1_D1_0'); + }); + + it.skip('should be possible to use @ syntax to add labels with trail spaces', function () { const res = flow.parser.parse( `flowchart TB n2["label for n2"] & n4@{ label: "labe for n4"} & n5@{ label: "labe for n5"} `