Skip to content

Commit d539f70

Browse files
authored
Merge pull request #4825 from chadfawcett/bug/1871_fix_duplicate_marker_ids
Give markers unique id's per graph
2 parents ce78ff1 + 983cf45 commit d539f70

5 files changed

Lines changed: 152 additions & 48 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { urlSnapshotTest } from '../../helpers/util.ts';
2+
3+
describe('Marker Unique IDs Per Diagram', () => {
4+
it('should render a blue arrow tip in second digram', () => {
5+
urlSnapshotTest('http://localhost:9000/marker_unique_id.html', {
6+
logLevel: 1,
7+
flowchart: { htmlLabels: false },
8+
});
9+
});
10+
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<html>
2+
<head> </head>
3+
<body>
4+
<h1>Example</h1>
5+
<pre class="mermaid">
6+
%%{init:{"theme":"base", "themeVariables": {"lineColor":"red"}}}%%
7+
flowchart LR
8+
subgraph red
9+
A --> B
10+
end
11+
</pre>
12+
<pre class="mermaid">
13+
%%{init:{"theme":"base", "themeVariables": {"lineColor":"blue"}}}%%
14+
flowchart LR
15+
subgraph black
16+
A --> B
17+
end
18+
</pre>
19+
<pre class="mermaid">
20+
---
21+
config:
22+
theme: base
23+
themeVariables:
24+
lineColor: yellow
25+
---
26+
flowchart LR
27+
subgraph red
28+
A --> B
29+
end
30+
</pre>
31+
<pre class="mermaid">
32+
---
33+
config:
34+
theme: base
35+
themeVariables:
36+
lineColor: green
37+
---
38+
flowchart LR
39+
subgraph black
40+
A --> B
41+
end
42+
</pre>
43+
<script type="module">
44+
import mermaid from './mermaid.esm.mjs';
45+
mermaid.initialize({ startOnLoad: true, logLevel: 0 });
46+
47+
if (window.Cypress) {
48+
window.rendered = true;
49+
}
50+
</script>
51+
</body>
52+
</html>

packages/mermaid/src/dagre-wrapper/edges.js

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ const cutPathAtIntersect = (_points, boundryNode) => {
369369
return points;
370370
};
371371

372-
export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph) {
372+
export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph, id) {
373373
let points = edge.points;
374374
let pointsHasChanged = false;
375375
const tail = graph.node(e.v);
@@ -508,61 +508,103 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph
508508

509509
switch (edge.arrowTypeStart) {
510510
case 'arrow_cross':
511-
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-crossStart' + ')');
511+
svgPath.attr(
512+
'marker-start',
513+
'url(' + url + '#' + id + '_' + diagramType + '-crossStart' + ')'
514+
);
512515
break;
513516
case 'arrow_point':
514-
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-pointStart' + ')');
517+
svgPath.attr(
518+
'marker-start',
519+
'url(' + url + '#' + id + '_' + diagramType + '-pointStart' + ')'
520+
);
515521
break;
516522
case 'arrow_barb':
517-
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-barbStart' + ')');
523+
svgPath.attr(
524+
'marker-start',
525+
'url(' + url + '#' + id + '_' + diagramType + '-barbStart' + ')'
526+
);
518527
break;
519528
case 'arrow_circle':
520-
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-circleStart' + ')');
529+
svgPath.attr(
530+
'marker-start',
531+
'url(' + url + '#' + id + '_' + diagramType + '-circleStart' + ')'
532+
);
521533
break;
522534
case 'aggregation':
523-
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-aggregationStart' + ')');
535+
svgPath.attr(
536+
'marker-start',
537+
'url(' + url + '#' + id + '_' + diagramType + '-aggregationStart' + ')'
538+
);
524539
break;
525540
case 'extension':
526-
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-extensionStart' + ')');
541+
svgPath.attr(
542+
'marker-start',
543+
'url(' + url + '#' + id + '_' + diagramType + '-extensionStart' + ')'
544+
);
527545
break;
528546
case 'composition':
529-
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-compositionStart' + ')');
547+
svgPath.attr(
548+
'marker-start',
549+
'url(' + url + '#' + id + '_' + diagramType + '-compositionStart' + ')'
550+
);
530551
break;
531552
case 'dependency':
532-
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-dependencyStart' + ')');
553+
svgPath.attr(
554+
'marker-start',
555+
'url(' + url + '#' + id + '_' + diagramType + '-dependencyStart' + ')'
556+
);
533557
break;
534558
case 'lollipop':
535-
svgPath.attr('marker-start', 'url(' + url + '#' + diagramType + '-lollipopStart' + ')');
559+
svgPath.attr(
560+
'marker-start',
561+
'url(' + url + '#' + id + '_' + diagramType + '-lollipopStart' + ')'
562+
);
536563
break;
537564
default:
538565
}
539566
switch (edge.arrowTypeEnd) {
540567
case 'arrow_cross':
541-
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-crossEnd' + ')');
568+
svgPath.attr('marker-end', 'url(' + url + '#' + id + '_' + diagramType + '-crossEnd' + ')');
542569
break;
543570
case 'arrow_point':
544-
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-pointEnd' + ')');
571+
svgPath.attr('marker-end', 'url(' + url + '#' + id + '_' + diagramType + '-pointEnd' + ')');
545572
break;
546573
case 'arrow_barb':
547-
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-barbEnd' + ')');
574+
svgPath.attr('marker-end', 'url(' + url + '#' + id + '_' + diagramType + '-barbEnd' + ')');
548575
break;
549576
case 'arrow_circle':
550-
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-circleEnd' + ')');
577+
svgPath.attr('marker-end', 'url(' + url + '#' + id + '_' + diagramType + '-circleEnd' + ')');
551578
break;
552579
case 'aggregation':
553-
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-aggregationEnd' + ')');
580+
svgPath.attr(
581+
'marker-end',
582+
'url(' + url + '#' + id + '_' + diagramType + '-aggregationEnd' + ')'
583+
);
554584
break;
555585
case 'extension':
556-
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-extensionEnd' + ')');
586+
svgPath.attr(
587+
'marker-end',
588+
'url(' + url + '#' + id + '_' + diagramType + '-extensionEnd' + ')'
589+
);
557590
break;
558591
case 'composition':
559-
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-compositionEnd' + ')');
592+
svgPath.attr(
593+
'marker-end',
594+
'url(' + url + '#' + id + '_' + diagramType + '-compositionEnd' + ')'
595+
);
560596
break;
561597
case 'dependency':
562-
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-dependencyEnd' + ')');
598+
svgPath.attr(
599+
'marker-end',
600+
'url(' + url + '#' + id + '_' + diagramType + '-dependencyEnd' + ')'
601+
);
563602
break;
564603
case 'lollipop':
565-
svgPath.attr('marker-end', 'url(' + url + '#' + diagramType + '-lollipopEnd' + ')');
604+
svgPath.attr(
605+
'marker-end',
606+
'url(' + url + '#' + id + '_' + diagramType + '-lollipopEnd' + ')'
607+
);
566608
break;
567609
default:
568610
}

packages/mermaid/src/dagre-wrapper/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { insertCluster, clear as clearClusters } from './clusters.js';
1414
import { insertEdgeLabel, positionEdgeLabel, insertEdge, clear as clearEdges } from './edges.js';
1515
import { log } from '../logger.js';
1616

17-
const recursiveRender = async (_elem, graph, diagramtype, parentCluster) => {
17+
const recursiveRender = async (_elem, graph, diagramtype, id, parentCluster) => {
1818
log.info('Graph in recursive render: XXX', graphlibJson.write(graph), parentCluster);
1919
const dir = graph.graph().rankdir;
2020
log.trace('Dir in recursive render - dir:', dir);
@@ -52,7 +52,7 @@ const recursiveRender = async (_elem, graph, diagramtype, parentCluster) => {
5252
if (node && node.clusterNode) {
5353
// const children = graph.children(v);
5454
log.info('Cluster identified', v, node.width, graph.node(v));
55-
const o = await recursiveRender(nodes, node.graph, diagramtype, graph.node(v));
55+
const o = await recursiveRender(nodes, node.graph, diagramtype, id, graph.node(v));
5656
const newEl = o.elem;
5757
updateNodeBounds(node, newEl);
5858
node.diff = o.diff || 0;
@@ -134,7 +134,7 @@ const recursiveRender = async (_elem, graph, diagramtype, parentCluster) => {
134134
const edge = graph.edge(e);
135135
log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge);
136136

137-
const paths = insertEdge(edgePaths, e, edge, clusterDb, diagramtype, graph);
137+
const paths = insertEdge(edgePaths, e, edge, clusterDb, diagramtype, graph, id);
138138
positionEdgeLabel(edge, paths);
139139
});
140140

@@ -159,7 +159,7 @@ export const render = async (elem, graph, markers, diagramtype, id) => {
159159
adjustClustersAndEdges(graph);
160160
log.warn('Graph after:', JSON.stringify(graphlibJson.write(graph)));
161161
// log.warn('Graph ever after:', graphlibJson.write(graph.node('A').graph));
162-
await recursiveRender(elem, graph, diagramtype);
162+
await recursiveRender(elem, graph, diagramtype, id);
163163
};
164164

165165
// const shapeDefinitions = {};

0 commit comments

Comments
 (0)