diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 885868c167..c27b9decd6 120000 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1 +1 @@ -./packages/mermaid/src/docs/community/contributing.md \ No newline at end of file +./packages/mermaid/src/docs/community/contributing.md diff --git a/cypress/integration/rendering/marker_unique_id_c4.spec.js b/cypress/integration/rendering/marker_unique_id_c4.spec.js new file mode 100644 index 0000000000..65254f29da --- /dev/null +++ b/cypress/integration/rendering/marker_unique_id_c4.spec.js @@ -0,0 +1,10 @@ +import { urlSnapshotTest } from '../../helpers/util.ts'; + +describe('Marker Unique IDs Per Diagram', () => { + it('Should show an arrow on each and of the link', () => { + urlSnapshotTest('http://localhost:9000/marker_unique_id_c4.html', { + logLevel: 1, + flowchart: { htmlLabels: false }, + }); + }); +}); diff --git a/cypress/integration/rendering/marker_unique_id_er.spec.js b/cypress/integration/rendering/marker_unique_id_er.spec.js new file mode 100644 index 0000000000..60895d42e8 --- /dev/null +++ b/cypress/integration/rendering/marker_unique_id_er.spec.js @@ -0,0 +1,10 @@ +import { urlSnapshotTest } from '../../helpers/util.ts'; + +describe('Marker Unique IDs Per Diagram', () => { + it('Should show a marker on each end of each link', () => { + urlSnapshotTest('http://localhost:9000/marker_unique_id_er.html', { + logLevel: 1, + flowchart: { htmlLabels: false }, + }); + }); +}); diff --git a/cypress/integration/rendering/marker_unique_id_journey.spec.js b/cypress/integration/rendering/marker_unique_id_journey.spec.js new file mode 100644 index 0000000000..f66578332e --- /dev/null +++ b/cypress/integration/rendering/marker_unique_id_journey.spec.js @@ -0,0 +1,10 @@ +import { urlSnapshotTest } from '../../helpers/util.ts'; + +describe('Marker Unique IDs Per Diagram', () => { + it('Should show the arrow pointer (pointing right)', () => { + urlSnapshotTest('http://localhost:9000/marker_unique_id_journey.html', { + logLevel: 1, + flowchart: { htmlLabels: false }, + }); + }); +}); diff --git a/cypress/integration/rendering/marker_unique_id_requirement.spec.js b/cypress/integration/rendering/marker_unique_id_requirement.spec.js new file mode 100644 index 0000000000..7fa986a282 --- /dev/null +++ b/cypress/integration/rendering/marker_unique_id_requirement.spec.js @@ -0,0 +1,10 @@ +import { urlSnapshotTest } from '../../helpers/util.ts'; + +describe('Marker Unique IDs Per Diagram', () => { + it('Should show an arrow and a cross markers on the links', () => { + urlSnapshotTest('http://localhost:9000/marker_unique_id_requirement.html', { + logLevel: 1, + flowchart: { htmlLabels: false }, + }); + }); +}); diff --git a/cypress/integration/rendering/marker_unique_id_sequence.spec.js b/cypress/integration/rendering/marker_unique_id_sequence.spec.js new file mode 100644 index 0000000000..444d28347e --- /dev/null +++ b/cypress/integration/rendering/marker_unique_id_sequence.spec.js @@ -0,0 +1,10 @@ +import { urlSnapshotTest } from '../../helpers/util.ts'; + +describe('Marker Unique IDs Per Diagram', () => { + it('Should show circles behind the sequence numbers, and three types of pointers (▶, ≻, ×)', () => { + urlSnapshotTest('http://localhost:9000/marker_unique_id_sequence.html', { + logLevel: 1, + flowchart: { htmlLabels: false }, + }); + }); +}); diff --git a/cypress/integration/rendering/marker_unique_id_timeline.spec.js b/cypress/integration/rendering/marker_unique_id_timeline.spec.js new file mode 100644 index 0000000000..bb11e86638 --- /dev/null +++ b/cypress/integration/rendering/marker_unique_id_timeline.spec.js @@ -0,0 +1,10 @@ +import { urlSnapshotTest } from '../../helpers/util.ts'; + +describe('Marker Unique IDs Per Diagram', () => { + it('Should show the arrow pointers (pointing right and down)', () => { + urlSnapshotTest('http://localhost:9000/marker_unique_id_timeline.html', { + logLevel: 1, + flowchart: { htmlLabels: false }, + }); + }); +}); diff --git a/cypress/platform/marker_unique_id_c4.html b/cypress/platform/marker_unique_id_c4.html new file mode 100644 index 0000000000..a29a26fe3f --- /dev/null +++ b/cypress/platform/marker_unique_id_c4.html @@ -0,0 +1,27 @@ + +
+ + ++ C4Context + Person(A, "A") + System(B, "B") + BiRel(A, B, "") ++ + + diff --git a/cypress/platform/marker_unique_id_er.html b/cypress/platform/marker_unique_id_er.html new file mode 100644 index 0000000000..68ada55217 --- /dev/null +++ b/cypress/platform/marker_unique_id_er.html @@ -0,0 +1,29 @@ + + + + +
+ erDiagram + START_OO ||--|| END_OO : ONLY_ONE + START_ZOO |o--o| END_ZOO : ZERO_OR_ONE + START_ZOM }o--o{ END_ZOM : ZERO_OR_MORE + START_OOM }|--|{ END_OOM : ONE_OR_MORE ++ + + diff --git a/cypress/platform/marker_unique_id_journey.html b/cypress/platform/marker_unique_id_journey.html new file mode 100644 index 0000000000..f0cf4291ca --- /dev/null +++ b/cypress/platform/marker_unique_id_journey.html @@ -0,0 +1,27 @@ + + + + +
+ journey + title My working day + section Go to work + Make tea: 5: Me ++ + + diff --git a/cypress/platform/marker_unique_id_requirement.html b/cypress/platform/marker_unique_id_requirement.html new file mode 100644 index 0000000000..83a0c07280 --- /dev/null +++ b/cypress/platform/marker_unique_id_requirement.html @@ -0,0 +1,37 @@ + + + + +
+ requirementDiagram + element test_entity { + } + requirement test_req { + } + performanceRequirement test_req_perf { + } + test_entity - satisfies -> test_req + test_req - contains -> test_req_perf ++ + + diff --git a/cypress/platform/marker_unique_id_sequence.html b/cypress/platform/marker_unique_id_sequence.html new file mode 100644 index 0000000000..4eba30bb7f --- /dev/null +++ b/cypress/platform/marker_unique_id_sequence.html @@ -0,0 +1,29 @@ + + + + +
+ sequenceDiagram + autonumber + A ->> B: arrowhead + A -) B: filled-head + A -x B: crosshead ++ + + diff --git a/cypress/platform/marker_unique_id_timeline.html b/cypress/platform/marker_unique_id_timeline.html new file mode 100644 index 0000000000..1700ba947d --- /dev/null +++ b/cypress/platform/marker_unique_id_timeline.html @@ -0,0 +1,23 @@ + + + + +
+ timeline + 2000 : Event ++ + + diff --git a/packages/mermaid/src/diagrams/c4/c4Renderer.js b/packages/mermaid/src/diagrams/c4/c4Renderer.js index 58dd808fda..9d332dca4c 100644 --- a/packages/mermaid/src/diagrams/c4/c4Renderer.js +++ b/packages/mermaid/src/diagrams/c4/c4Renderer.js @@ -406,7 +406,7 @@ let getIntersectPoints = function (fromNode, endNode) { return { startPoint: startPoint, endPoint: endPoint }; }; -export const drawRels = function (diagram, rels, getC4ShapeObj, diagObj) { +export const drawRels = function (diagram, id, rels, getC4ShapeObj, diagObj) { let i = 0; for (let rel of rels) { i = i + 1; @@ -435,7 +435,7 @@ export const drawRels = function (diagram, rels, getC4ShapeObj, diagObj) { rel.startPoint = points.startPoint; rel.endPoint = points.endPoint; } - svgDraw.drawRels(diagram, rels, conf); + svgDraw.drawRels(diagram, id, rels, conf); }; /** @@ -604,9 +604,9 @@ export const draw = function (_text, id, _version, diagObj) { const diagram = securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : select(`[id="${id}"]`); - svgDraw.insertComputerIcon(diagram); - svgDraw.insertDatabaseIcon(diagram); - svgDraw.insertClockIcon(diagram); + svgDraw.insertComputerIcon(diagram, id); + svgDraw.insertDatabaseIcon(diagram, id); + svgDraw.insertClockIcon(diagram, id); let screenBounds = new Bounds(diagObj); @@ -630,12 +630,12 @@ export const draw = function (_text, id, _version, diagObj) { // } // The arrow head definition is attached to the svg once - svgDraw.insertArrowHead(diagram); - svgDraw.insertArrowEnd(diagram); - svgDraw.insertArrowCrossHead(diagram); - svgDraw.insertArrowFilledHead(diagram); + svgDraw.insertArrowHead(diagram, id); + svgDraw.insertArrowEnd(diagram, id); + svgDraw.insertArrowCrossHead(diagram, id); + svgDraw.insertArrowFilledHead(diagram, id); - drawRels(diagram, diagObj.db.getRels(), diagObj.db.getC4Shape, diagObj); + drawRels(diagram, id, diagObj.db.getRels(), diagObj.db.getC4Shape, diagObj); screenBounds.data.stopx = globalBoundaryMaxX; screenBounds.data.stopy = globalBoundaryMaxY; diff --git a/packages/mermaid/src/diagrams/c4/svgDraw.js b/packages/mermaid/src/diagrams/c4/svgDraw.js index 6bff267f6f..22619e7320 100644 --- a/packages/mermaid/src/diagrams/c4/svgDraw.js +++ b/packages/mermaid/src/diagrams/c4/svgDraw.js @@ -16,7 +16,7 @@ export const drawImage = function (elem, width, height, x, y, link) { imageElem.attr('xlink:href', sanitizedLink); }; -export const drawRels = (elem, rels, conf) => { +export const drawRels = (elem, id, rels, conf) => { const relsElem = elem.append('g'); let i = 0; for (let rel of rels) { @@ -25,7 +25,6 @@ export const drawRels = (elem, rels, conf) => { let offsetX = rel.offsetX ? parseInt(rel.offsetX) : 0; let offsetY = rel.offsetY ? parseInt(rel.offsetY) : 0; - let url = ''; if (i === 0) { let line = relsElem.append('line'); line.attr('x1', rel.startPoint.x); @@ -37,10 +36,10 @@ export const drawRels = (elem, rels, conf) => { line.attr('stroke', strokeColor); line.style('fill', 'none'); if (rel.type !== 'rel_b') { - line.attr('marker-end', 'url(' + url + '#arrowhead)'); + line.attr('marker-end', 'url(#' + id + '-arrowhead)'); } if (rel.type === 'birel' || rel.type === 'rel_b') { - line.attr('marker-start', 'url(' + url + '#arrowend)'); + line.attr('marker-start', 'url(#' + id + '-arrowend)'); } i = -1; } else { @@ -65,10 +64,10 @@ export const drawRels = (elem, rels, conf) => { .replaceAll('stopy', rel.endPoint.y) ); if (rel.type !== 'rel_b') { - line.attr('marker-end', 'url(' + url + '#arrowhead)'); + line.attr('marker-end', 'url(#' + id + '-arrowhead)'); } if (rel.type === 'birel' || rel.type === 'rel_b') { - line.attr('marker-start', 'url(' + url + '#arrowend)'); + line.attr('marker-start', 'url(#' + id + '-arrowend)'); } } @@ -397,11 +396,12 @@ export const drawC4Shape = function (elem, c4Shape, conf) { return c4Shape.height; }; -export const insertDatabaseIcon = function (elem) { +export const insertDatabaseIcon = function (elem, id) { elem .append('defs') .append('symbol') - .attr('id', 'database') + .attr('id', id + '-database') + .attr('class', 'mermaid-marker-c4-database') .attr('fill-rule', 'evenodd') .attr('clip-rule', 'evenodd') .append('path') @@ -412,11 +412,12 @@ export const insertDatabaseIcon = function (elem) { ); }; -export const insertComputerIcon = function (elem) { +export const insertComputerIcon = function (elem, id) { elem .append('defs') .append('symbol') - .attr('id', 'computer') + .attr('id', id + '-computer') + .attr('class', 'mermaid-marker-c4-computer') .attr('width', '24') .attr('height', '24') .append('path') @@ -427,11 +428,12 @@ export const insertComputerIcon = function (elem) { ); }; -export const insertClockIcon = function (elem) { +export const insertClockIcon = function (elem, id) { elem .append('defs') .append('symbol') - .attr('id', 'clock') + .attr('id', id + '-clock') + .attr('class', 'mermaid-marker-c4-clock') .attr('width', '24') .attr('height', '24') .append('path') @@ -447,11 +449,12 @@ export const insertClockIcon = function (elem) { * * @param elem */ -export const insertArrowHead = function (elem) { +export const insertArrowHead = function (elem, id) { elem .append('defs') .append('marker') - .attr('id', 'arrowhead') + .attr('id', id + '-arrowhead') + .attr('class', 'mermaid-marker-c4-arrowhead') .attr('refX', 9) .attr('refY', 5) .attr('markerUnits', 'userSpaceOnUse') @@ -462,11 +465,12 @@ export const insertArrowHead = function (elem) { .attr('d', 'M 0 0 L 10 5 L 0 10 z'); // this is actual shape for arrowhead }; -export const insertArrowEnd = function (elem) { +export const insertArrowEnd = function (elem, id) { elem .append('defs') .append('marker') - .attr('id', 'arrowend') + .attr('id', id + '-arrowend') + .attr('class', 'mermaid-marker-c4-arrowend') .attr('refX', 1) .attr('refY', 5) .attr('markerUnits', 'userSpaceOnUse') @@ -482,11 +486,12 @@ export const insertArrowEnd = function (elem) { * * @param {any} elem */ -export const insertArrowFilledHead = function (elem) { +export const insertArrowFilledHead = function (elem, id) { elem .append('defs') .append('marker') - .attr('id', 'filled-head') + .attr('id', id + '-filled-head') + .attr('class', 'mermaid-marker-c4-filled-head') .attr('refX', 18) .attr('refY', 7) .attr('markerWidth', 20) @@ -501,11 +506,12 @@ export const insertArrowFilledHead = function (elem) { * * @param {any} elem */ -export const insertDynamicNumber = function (elem) { +export const insertDynamicNumber = function (elem, id) { elem .append('defs') .append('marker') - .attr('id', 'sequencenumber') + .attr('id', id + '-sequencenumber') + .attr('class', 'mermaid-marker-c4-sequencenumber') .attr('refX', 15) .attr('refY', 15) .attr('markerWidth', 60) @@ -522,12 +528,14 @@ export const insertDynamicNumber = function (elem) { * Setup arrow head and define the marker. The result is appended to the svg. * * @param {any} elem + * @param {any} id */ -export const insertArrowCrossHead = function (elem) { +export const insertArrowCrossHead = function (elem, id) { const defs = elem.append('defs'); const marker = defs .append('marker') - .attr('id', 'crosshead') + .attr('id', id + '-crosshead') + .attr('class', 'mermaid-marker-c4-crosshead') .attr('markerWidth', 15) .attr('markerHeight', 8) .attr('orient', 'auto') diff --git a/packages/mermaid/src/diagrams/er/erMarkers.js b/packages/mermaid/src/diagrams/er/erMarkers.js index 48cafae657..407512f935 100644 --- a/packages/mermaid/src/diagrams/er/erMarkers.js +++ b/packages/mermaid/src/diagrams/er/erMarkers.js @@ -16,14 +16,16 @@ const ERMarkers = { * * @param elem * @param conf + * @param id */ -const insertMarkers = function (elem, conf) { +const insertMarkers = function (elem, conf, id) { let marker; elem .append('defs') .append('marker') - .attr('id', ERMarkers.MD_PARENT_START) + .attr('id', id + '-' + ERMarkers.MD_PARENT_START) + .attr('class', 'mermaid-marker-er-MD_PARENT_START') .attr('refX', 0) .attr('refY', 7) .attr('markerWidth', 190) @@ -35,7 +37,8 @@ const insertMarkers = function (elem, conf) { elem .append('defs') .append('marker') - .attr('id', ERMarkers.MD_PARENT_END) + .attr('id', id + '-' + ERMarkers.MD_PARENT_END) + .attr('class', 'mermaid-marker-er-MD_PARENT_END') .attr('refX', 19) .attr('refY', 7) .attr('markerWidth', 20) @@ -47,7 +50,8 @@ const insertMarkers = function (elem, conf) { elem .append('defs') .append('marker') - .attr('id', ERMarkers.ONLY_ONE_START) + .attr('id', id + '-' + ERMarkers.ONLY_ONE_START) + .attr('class', 'mermaid-marker-er-ONLY_ONE_START') .attr('refX', 0) .attr('refY', 9) .attr('markerWidth', 18) @@ -61,7 +65,8 @@ const insertMarkers = function (elem, conf) { elem .append('defs') .append('marker') - .attr('id', ERMarkers.ONLY_ONE_END) + .attr('id', id + '-' + ERMarkers.ONLY_ONE_END) + .attr('class', 'mermaid-marker-er-ONLY_ONE_END') .attr('refX', 18) .attr('refY', 9) .attr('markerWidth', 18) @@ -75,7 +80,8 @@ const insertMarkers = function (elem, conf) { marker = elem .append('defs') .append('marker') - .attr('id', ERMarkers.ZERO_OR_ONE_START) + .attr('id', id + '-' + ERMarkers.ZERO_OR_ONE_START) + .attr('class', 'mermaid-marker-er-ZERO_OR_ONE_START') .attr('refX', 0) .attr('refY', 9) .attr('markerWidth', 30) @@ -93,7 +99,8 @@ const insertMarkers = function (elem, conf) { marker = elem .append('defs') .append('marker') - .attr('id', ERMarkers.ZERO_OR_ONE_END) + .attr('id', id + '-' + ERMarkers.ZERO_OR_ONE_END) + .attr('class', 'mermaid-marker-er-ZERO_OR_ONE_END') .attr('refX', 30) .attr('refY', 9) .attr('markerWidth', 30) @@ -111,7 +118,8 @@ const insertMarkers = function (elem, conf) { elem .append('defs') .append('marker') - .attr('id', ERMarkers.ONE_OR_MORE_START) + .attr('id', id + '-' + ERMarkers.ONE_OR_MORE_START) + .attr('class', 'mermaid-marker-er-ONE_OR_MORE_START') .attr('refX', 18) .attr('refY', 18) .attr('markerWidth', 45) @@ -125,7 +133,8 @@ const insertMarkers = function (elem, conf) { elem .append('defs') .append('marker') - .attr('id', ERMarkers.ONE_OR_MORE_END) + .attr('id', id + '-' + ERMarkers.ONE_OR_MORE_END) + .attr('class', 'mermaid-marker-er-ONE_OR_MORE_END') .attr('refX', 27) .attr('refY', 18) .attr('markerWidth', 45) @@ -139,7 +148,8 @@ const insertMarkers = function (elem, conf) { marker = elem .append('defs') .append('marker') - .attr('id', ERMarkers.ZERO_OR_MORE_START) + .attr('id', id + '-' + ERMarkers.ZERO_OR_MORE_START) + .attr('class', 'mermaid-marker-er-ZERO_OR_MORE_START') .attr('refX', 18) .attr('refY', 18) .attr('markerWidth', 57) @@ -161,7 +171,8 @@ const insertMarkers = function (elem, conf) { marker = elem .append('defs') .append('marker') - .attr('id', ERMarkers.ZERO_OR_MORE_END) + .attr('id', id + '-' + ERMarkers.ZERO_OR_MORE_END) + .attr('class', 'mermaid-marker-er-ZERO_OR_MORE_END') .attr('refX', 39) .attr('refY', 18) .attr('markerWidth', 57) diff --git a/packages/mermaid/src/diagrams/er/erRenderer.js b/packages/mermaid/src/diagrams/er/erRenderer.js index 0327bfc9d5..95d1020e1f 100644 --- a/packages/mermaid/src/diagrams/er/erRenderer.js +++ b/packages/mermaid/src/diagrams/er/erRenderer.js @@ -415,7 +415,7 @@ let relCnt = 0; * sit 'behind' opaque entity boxes) * @param diagObj */ -const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) { +const drawRelationshipFromLayout = function (svg, id, rel, g, insert, diagObj) { relCnt++; // Find the edge relating to this relationship @@ -467,19 +467,34 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) { // Note that the 'A' entity's marker is at the end of the relationship and the 'B' entity's marker is at the start switch (rel.relSpec.cardA) { case diagObj.db.Cardinality.ZERO_OR_ONE: - svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_END + ')'); + svgPath.attr( + 'marker-end', + 'url(' + url + '#' + id + '-' + erMarkers.ERMarkers.ZERO_OR_ONE_END + ')' + ); break; case diagObj.db.Cardinality.ZERO_OR_MORE: - svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_END + ')'); + svgPath.attr( + 'marker-end', + 'url(' + url + '#' + id + '-' + erMarkers.ERMarkers.ZERO_OR_MORE_END + ')' + ); break; case diagObj.db.Cardinality.ONE_OR_MORE: - svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_END + ')'); + svgPath.attr( + 'marker-end', + 'url(' + url + '#' + id + '-' + erMarkers.ERMarkers.ONE_OR_MORE_END + ')' + ); break; case diagObj.db.Cardinality.ONLY_ONE: - svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_END + ')'); + svgPath.attr( + 'marker-end', + 'url(' + url + '#' + id + '-' + erMarkers.ERMarkers.ONLY_ONE_END + ')' + ); break; case diagObj.db.Cardinality.MD_PARENT: - svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.MD_PARENT_END + ')'); + svgPath.attr( + 'marker-end', + 'url(' + url + '#' + id + '-' + erMarkers.ERMarkers.MD_PARENT_END + ')' + ); break; } @@ -487,26 +502,32 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) { case diagObj.db.Cardinality.ZERO_OR_ONE: svgPath.attr( 'marker-start', - 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_START + ')' + 'url(' + url + '#' + id + '-' + erMarkers.ERMarkers.ZERO_OR_ONE_START + ')' ); break; case diagObj.db.Cardinality.ZERO_OR_MORE: svgPath.attr( 'marker-start', - 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_START + ')' + 'url(' + url + '#' + id + '-' + erMarkers.ERMarkers.ZERO_OR_MORE_START + ')' ); break; case diagObj.db.Cardinality.ONE_OR_MORE: svgPath.attr( 'marker-start', - 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_START + ')' + 'url(' + url + '#' + id + '-' + erMarkers.ERMarkers.ONE_OR_MORE_START + ')' ); break; case diagObj.db.Cardinality.ONLY_ONE: - svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_START + ')'); + svgPath.attr( + 'marker-start', + 'url(' + url + '#' + id + '-' + erMarkers.ERMarkers.ONLY_ONE_START + ')' + ); break; case diagObj.db.Cardinality.MD_PARENT: - svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.MD_PARENT_START + ')'); + svgPath.attr( + 'marker-start', + 'url(' + url + '#' + id + '-' + erMarkers.ERMarkers.MD_PARENT_START + ')' + ); break; } @@ -585,7 +606,7 @@ export const draw = function (text, id, _version, diagObj) { const svg = root.select(`[id='${id}']`); // Add cardinality marker definitions to the svg - erMarkers.insertMarkers(svg, conf); + erMarkers.insertMarkers(svg, conf, id); // Now we have to construct the diagram in a specific way: // --- @@ -642,7 +663,7 @@ export const draw = function (text, id, _version, diagObj) { // Draw the relationships relationships.forEach(function (rel) { - drawRelationshipFromLayout(svg, rel, g, firstEntity, diagObj); + drawRelationshipFromLayout(svg, id, rel, g, firstEntity, diagObj); }); const padding = conf.diagramPadding; diff --git a/packages/mermaid/src/diagrams/er/styles.js b/packages/mermaid/src/diagrams/er/styles.js index 08ea2e8510..697294750e 100644 --- a/packages/mermaid/src/diagrams/er/styles.js +++ b/packages/mermaid/src/diagrams/er/styles.js @@ -33,12 +33,12 @@ const getStyles = (options) => font-size: 18px; fill: ${options.textColor}; } - #MD_PARENT_START { + .mermaid-marker-er-MD_PARENT_START { fill: #f5f5f5 !important; stroke: ${options.lineColor} !important; stroke-width: 1; } - #MD_PARENT_END { + .mermaid-marker-er-MD_PARENT_END { fill: #f5f5f5 !important; stroke: ${options.lineColor} !important; stroke-width: 1; diff --git a/packages/mermaid/src/diagrams/requirement/requirementMarkers.js b/packages/mermaid/src/diagrams/requirement/requirementMarkers.js index 96e42d78da..42daadbd40 100644 --- a/packages/mermaid/src/diagrams/requirement/requirementMarkers.js +++ b/packages/mermaid/src/diagrams/requirement/requirementMarkers.js @@ -3,11 +3,12 @@ const ReqMarkers = { ARROW: 'arrow', }; -const insertLineEndings = (parentNode, conf) => { +const insertLineEndings = (parentNode, id, conf) => { let containsNode = parentNode .append('defs') .append('marker') - .attr('id', ReqMarkers.CONTAINS + '_line_ending') + .attr('id', id + '-' + ReqMarkers.CONTAINS + '_line_ending') + .attr('class', 'mermaid-marker-req-' + ReqMarkers.CONTAINS + '_line_ending') .attr('refX', 0) .attr('refY', conf.line_height / 2) .attr('markerWidth', conf.line_height) @@ -45,7 +46,8 @@ const insertLineEndings = (parentNode, conf) => { parentNode .append('defs') .append('marker') - .attr('id', ReqMarkers.ARROW + '_line_ending') + .attr('id', id + '-' + ReqMarkers.ARROW + '_line_ending') + .attr('class', 'mermaid-marker-req-' + ReqMarkers.ARROW + '_line_ending') .attr('refX', conf.line_height) .attr('refY', 0.5 * conf.line_height) .attr('markerWidth', conf.line_height) diff --git a/packages/mermaid/src/diagrams/requirement/requirementRenderer.js b/packages/mermaid/src/diagrams/requirement/requirementRenderer.js index 778dc36b1c..9f4dfd291c 100644 --- a/packages/mermaid/src/diagrams/requirement/requirementRenderer.js +++ b/packages/mermaid/src/diagrams/requirement/requirementRenderer.js @@ -148,7 +148,7 @@ const addEdgeLabel = (parentNode, svgPath, conf, txt) => { .attr('fill-opacity', '85%'); }; -const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) { +const drawRelationshipFromLayout = function (svg, id, rel, g, insert, diagObj) { // Find the edge relating to this relationship const edge = g.edge(elementString(rel.src), elementString(rel.dst)); @@ -171,7 +171,14 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) { if (rel.type == diagObj.db.Relationships.CONTAINS) { svgPath.attr( 'marker-start', - 'url(' + common.getUrl(conf.arrowMarkerAbsolute) + '#' + rel.type + '_line_ending' + ')' + 'url(' + + common.getUrl(conf.arrowMarkerAbsolute) + + '#' + + id + + '-' + + rel.type + + '_line_ending' + + ')' ); } else { svgPath.attr('stroke-dasharray', '10,7'); @@ -180,6 +187,8 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) { 'url(' + common.getUrl(conf.arrowMarkerAbsolute) + '#' + + id + + '-' + markers.ReqMarkers.ARROW + '_line_ending' + ')' @@ -327,7 +336,7 @@ export const draw = (text, id, _version, diagObj) => { : select('body'); const svg = root.select(`[id='${id}']`); - markers.insertLineEndings(svg, conf); + markers.insertLineEndings(svg, id, conf); const g = new graphlib.Graph({ multigraph: false, @@ -357,7 +366,7 @@ export const draw = (text, id, _version, diagObj) => { adjustEntities(svg, g); relationships.forEach(function (rel) { - drawRelationshipFromLayout(svg, rel, g, id, diagObj); + drawRelationshipFromLayout(svg, id, rel, g, id, diagObj); }); const padding = conf.rect_padding; diff --git a/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts b/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts index 951d84b862..c358ee1410 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts +++ b/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts @@ -361,11 +361,12 @@ async function boundMessage(_diagram, msgModel): Promise