mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-30 13:46:43 +02:00
feat(flowchart): implement double circle node
The implementation uses two circles, inside each other. A double circle node is opend with `()(` and closed with `)()`.
This commit is contained in:
@@ -368,6 +368,7 @@ flowchart TD
|
|||||||
I{{red text}} -->|default style| J[/blue text/]
|
I{{red text}} -->|default style| J[/blue text/]
|
||||||
K[\\ red text\\] -->|default style| L[/blue text\\]
|
K[\\ red text\\] -->|default style| L[/blue text\\]
|
||||||
M[\\ red text/] -->|default style| N[blue text];
|
M[\\ red text/] -->|default style| N[blue text];
|
||||||
|
O()(red text)() -->|default style| P()(blue text)();
|
||||||
linkStyle default color:Sienna;
|
linkStyle default color:Sienna;
|
||||||
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||||
style B stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
style B stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
@@ -383,6 +384,8 @@ flowchart TD
|
|||||||
style L stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
style L stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||||
style N stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
style N stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
|
style O stroke:#ff0000,fill:#ffcccc,color:#ff0000;
|
||||||
|
style P stroke:#0000ff,fill:#ccccff,color:#0000ff;
|
||||||
`,
|
`,
|
||||||
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', logLevel: 2 }
|
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', logLevel: 2 }
|
||||||
);
|
);
|
||||||
|
@@ -1047,6 +1047,7 @@
|
|||||||
L1[/red text\] <-->|default style| L2[/blue text\]
|
L1[/red text\] <-->|default style| L2[/blue text\]
|
||||||
M1[\red text/] <-->|default style| M2[\blue text/]
|
M1[\red text/] <-->|default style| M2[\blue text/]
|
||||||
N1[red text] <-->|default style| N2[blue text]
|
N1[red text] <-->|default style| N2[blue text]
|
||||||
|
O1()(red text)() <-->|default style| O2()(blue text)()
|
||||||
linkStyle default color:Sienna;
|
linkStyle default color:Sienna;
|
||||||
style A1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
style A1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
style B1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
style B1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
@@ -1062,6 +1063,7 @@
|
|||||||
style L1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
style L1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
style M1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
style M1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
style N1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
style N1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
|
style O1 stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||||
style A2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
style A2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
style B2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
style B2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
style C2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
style C2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
@@ -1076,6 +1078,7 @@
|
|||||||
style L2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
style L2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
style M2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
style M2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
style N2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
style N2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
|
style O2 stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
@@ -552,6 +552,42 @@ const circle = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const doublecircle = (parent, node) => {
|
||||||
|
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, undefined, true);
|
||||||
|
const gap = 5;
|
||||||
|
const circleGroup = shapeSvg.insert('g', ':first-child');
|
||||||
|
const outerCircle = circleGroup.insert('circle');
|
||||||
|
const innerCircle = circleGroup.insert('circle');
|
||||||
|
|
||||||
|
// center the circle around its coordinate
|
||||||
|
outerCircle
|
||||||
|
.attr('style', node.style)
|
||||||
|
.attr('rx', node.rx)
|
||||||
|
.attr('ry', node.ry)
|
||||||
|
.attr('r', bbox.width / 2 + halfPadding + gap)
|
||||||
|
.attr('width', bbox.width + node.padding + gap * 2)
|
||||||
|
.attr('height', bbox.height + node.padding + gap * 2);
|
||||||
|
|
||||||
|
innerCircle
|
||||||
|
.attr('style', node.style)
|
||||||
|
.attr('rx', node.rx)
|
||||||
|
.attr('ry', node.ry)
|
||||||
|
.attr('r', bbox.width / 2 + halfPadding)
|
||||||
|
.attr('width', bbox.width + node.padding)
|
||||||
|
.attr('height', bbox.height + node.padding);
|
||||||
|
|
||||||
|
log.info('DoubleCircle main');
|
||||||
|
|
||||||
|
updateNodeBounds(node, outerCircle);
|
||||||
|
|
||||||
|
node.intersect = function (point) {
|
||||||
|
log.info('DoubleCircle intersect', node, bbox.width / 2 + halfPadding + gap, point);
|
||||||
|
return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point);
|
||||||
|
};
|
||||||
|
|
||||||
|
return shapeSvg;
|
||||||
|
};
|
||||||
|
|
||||||
const subroutine = (parent, node) => {
|
const subroutine = (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
@@ -941,6 +977,7 @@ const shapes = {
|
|||||||
rectWithTitle,
|
rectWithTitle,
|
||||||
choice,
|
choice,
|
||||||
circle,
|
circle,
|
||||||
|
doublecircle,
|
||||||
stadium,
|
stadium,
|
||||||
hexagon,
|
hexagon,
|
||||||
rect_left_inv_arrow,
|
rect_left_inv_arrow,
|
||||||
@@ -965,6 +1002,8 @@ export const insertNode = (elem, node, dir) => {
|
|||||||
let newEl;
|
let newEl;
|
||||||
let el;
|
let el;
|
||||||
|
|
||||||
|
console.log(shapes);
|
||||||
|
|
||||||
// Add link when appropriate
|
// Add link when appropriate
|
||||||
if (node.link) {
|
if (node.link) {
|
||||||
newEl = elem
|
newEl = elem
|
||||||
|
@@ -131,6 +131,9 @@ export const addVertices = function (vert, g, svgId) {
|
|||||||
case 'group':
|
case 'group':
|
||||||
_shape = 'rect';
|
_shape = 'rect';
|
||||||
break;
|
break;
|
||||||
|
case 'doublecircle':
|
||||||
|
_shape = 'doublecircle';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_shape = 'rect';
|
_shape = 'rect';
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ describe('the flowchart renderer', function () {
|
|||||||
['subroutine', 'subroutine'],
|
['subroutine', 'subroutine'],
|
||||||
['cylinder', 'cylinder'],
|
['cylinder', 'cylinder'],
|
||||||
['group', 'rect'],
|
['group', 'rect'],
|
||||||
|
['doublecircle', 'doublecircle'],
|
||||||
].forEach(function ([type, expectedShape, expectedRadios = 0]) {
|
].forEach(function ([type, expectedShape, expectedRadios = 0]) {
|
||||||
it(`should add the correct shaped node to the graph for vertex type ${type}`, function () {
|
it(`should add the correct shaped node to the graph for vertex type ${type}`, function () {
|
||||||
const addedNodes = [];
|
const addedNodes = [];
|
||||||
|
@@ -159,6 +159,40 @@ describe('[Singlenodes] when parsing', () => {
|
|||||||
expect(vert['a'].text).toBe('A <br> end');
|
expect(vert['a'].text).toBe('A <br> end');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle a single double circle node', function () {
|
||||||
|
// Silly but syntactically correct
|
||||||
|
const res = flow.parser.parse('graph TD;a()(A)();');
|
||||||
|
|
||||||
|
const vert = flow.parser.yy.getVertices();
|
||||||
|
const edges = flow.parser.yy.getEdges();
|
||||||
|
|
||||||
|
expect(edges.length).toBe(0);
|
||||||
|
expect(vert['a'].type).toBe('doublecircle');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle a single double circle node with whitespace after it', function () {
|
||||||
|
// Silly but syntactically correct
|
||||||
|
const res = flow.parser.parse('graph TD;a()(A)() ;');
|
||||||
|
|
||||||
|
const vert = flow.parser.yy.getVertices();
|
||||||
|
const edges = flow.parser.yy.getEdges();
|
||||||
|
|
||||||
|
expect(edges.length).toBe(0);
|
||||||
|
expect(vert['a'].type).toBe('doublecircle');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle a single double circle node with html in it (SN3)', function () {
|
||||||
|
// Silly but syntactically correct
|
||||||
|
const res = flow.parser.parse('graph TD;a()(A <br> end)();');
|
||||||
|
|
||||||
|
const vert = flow.parser.yy.getVertices();
|
||||||
|
const edges = flow.parser.yy.getEdges();
|
||||||
|
|
||||||
|
expect(edges.length).toBe(0);
|
||||||
|
expect(vert['a'].type).toBe('doublecircle');
|
||||||
|
expect(vert['a'].text).toBe('A <br> end');
|
||||||
|
});
|
||||||
|
|
||||||
it('should handle a single node with alphanumerics starting on a char', function () {
|
it('should handle a single node with alphanumerics starting on a char', function () {
|
||||||
// Silly but syntactically correct
|
// Silly but syntactically correct
|
||||||
const res = flow.parser.parse('graph TD;id1;');
|
const res = flow.parser.parse('graph TD;id1;');
|
||||||
|
@@ -121,6 +121,8 @@ that id.
|
|||||||
"[|" return 'VERTEX_WITH_PROPS_START';
|
"[|" return 'VERTEX_WITH_PROPS_START';
|
||||||
"[(" return 'CYLINDERSTART';
|
"[(" return 'CYLINDERSTART';
|
||||||
")]" return 'CYLINDEREND';
|
")]" return 'CYLINDEREND';
|
||||||
|
"()(" return 'DOUBLECIRCLESTART';
|
||||||
|
")()" return 'DOUBLECIRCLEEND';
|
||||||
\- return 'MINUS';
|
\- return 'MINUS';
|
||||||
"." return 'DOT';
|
"." return 'DOT';
|
||||||
[\_] return 'UNDERSCORE';
|
[\_] return 'UNDERSCORE';
|
||||||
@@ -373,6 +375,8 @@ node: vertex
|
|||||||
|
|
||||||
vertex: idString SQS text SQE
|
vertex: idString SQS text SQE
|
||||||
{$$ = $1;yy.addVertex($1,$3,'square');}
|
{$$ = $1;yy.addVertex($1,$3,'square');}
|
||||||
|
| idString DOUBLECIRCLESTART text DOUBLECIRCLEEND
|
||||||
|
{$$ = $1;yy.addVertex($1,$3,'doublecircle');}
|
||||||
| idString PS PS text PE PE
|
| idString PS PS text PE PE
|
||||||
{$$ = $1;yy.addVertex($1,$4,'circle');}
|
{$$ = $1;yy.addVertex($1,$4,'circle');}
|
||||||
| idString '(-' text '-)'
|
| idString '(-' text '-)'
|
||||||
|
Reference in New Issue
Block a user