From 7f67435cb944a03204e8914118081cd70b0d5ad1 Mon Sep 17 00:00:00 2001 From: Marc Faber Date: Fri, 10 Apr 2020 00:14:41 +0200 Subject: [PATCH 1/2] #1343 Add flowchart subroutine node shape --- .../integration/rendering/flowchart.spec.js | 19 +++++++++++++++ dist/index.html | 14 +++++++++++ docs/flowchart.md | 11 +++++++++ src/diagrams/flowchart/flowChartShapes.js | 24 +++++++++++++++++++ .../flowchart/flowChartShapes.spec.js | 3 ++- src/diagrams/flowchart/flowRenderer-v2.js | 3 +++ src/diagrams/flowchart/flowRenderer.js | 3 +++ src/diagrams/flowchart/flowRenderer.spec.js | 1 + src/diagrams/flowchart/parser/flow.jison | 6 ++++- 9 files changed, 82 insertions(+), 2 deletions(-) diff --git a/cypress/integration/rendering/flowchart.spec.js b/cypress/integration/rendering/flowchart.spec.js index 1a7c41163..4acccfc37 100644 --- a/cypress/integration/rendering/flowchart.spec.js +++ b/cypress/integration/rendering/flowchart.spec.js @@ -652,4 +652,23 @@ describe('Flowchart', () => { { flowchart: { htmlLabels: false } } ); }); + + it('32: Render Subroutine shape', () => { + imgSnapshotTest( + `graph LR + A[[subroutine shape test]] + A -->|Get money| B[[Go shopping]] + B --> C[[Let me think...
Do I want something for work,
something to spend every free second with,
or something to get around?]] + C -->|One| D[[Laptop]] + C -->|Two| E[[iPhone]] + C -->|Three| F[[Car
wroom wroom]] + click A "index.html#link-clicked" "link test" + click B testClick "click test" + classDef someclass fill:#f96; + class A someclass; + class C someclass; + `, + { flowchart: { htmlLabels: false } } + ); + }); }); diff --git a/dist/index.html b/dist/index.html index 46af0d709..7a3d213a6 100644 --- a/dist/index.html +++ b/dist/index.html @@ -315,6 +315,20 @@ graph TB class A someclass; class C someclass; +
+ graph LR + A[[subroutine shape test]] + A -->|Get money| B[[Go shopping]] + B --> C[[Let me think...
Do I want something for work,
something to spend every free second with,
or something to get around?]] + C -->|One| D[[Laptop]] + C -->|Two| E[[iPhone]] + C -->|Three| F[[Car
wroom wroom]] + click A "index.html#link-clicked" "link test" + click B testClick "click test" + classDef someclass fill:#f96; + class A someclass; + class C someclass; +
graph LR A[(cylindrical
shape
test)] diff --git a/docs/flowchart.md b/docs/flowchart.md index 0d964bdcc..1e3d00510 100644 --- a/docs/flowchart.md +++ b/docs/flowchart.md @@ -89,6 +89,17 @@ graph LR id1([This is the text in the box]) ``` +### A node in a subroutine shape + +``` +graph LR + id1[[This is the text in the box]] +``` +```mermaid +graph LR + id1[[This is the text in the box]] +``` + ### A node in a cylindrical shape ``` diff --git a/src/diagrams/flowchart/flowChartShapes.js b/src/diagrams/flowchart/flowChartShapes.js index 8bd4f0b7a..66a7b79d2 100644 --- a/src/diagrams/flowchart/flowChartShapes.js +++ b/src/diagrams/flowchart/flowChartShapes.js @@ -154,6 +154,28 @@ function stadium(parent, bbox, node) { return shapeSvg; } +function subroutine(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return dagreD3.intersect.polygon(node, points, point); + }; + return shapeSvg; +} + function cylinder(parent, bbox, node) { const w = bbox.width; const rx = w / 2; @@ -221,6 +243,7 @@ export function addToRender(render) { render.shapes().question = question; render.shapes().hexagon = hexagon; render.shapes().stadium = stadium; + render.shapes().subroutine = subroutine; render.shapes().cylinder = cylinder; // Add custom shape for box with inverted arrow on left side @@ -246,6 +269,7 @@ export function addToRenderV2(addShape) { addShape({ question }); addShape({ hexagon }); addShape({ stadium }); + addShape({ subroutine }); addShape({ cylinder }); // Add custom shape for box with inverted arrow on left side diff --git a/src/diagrams/flowchart/flowChartShapes.spec.js b/src/diagrams/flowchart/flowChartShapes.spec.js index 61e876d4b..d6446f66e 100644 --- a/src/diagrams/flowchart/flowChartShapes.spec.js +++ b/src/diagrams/flowchart/flowChartShapes.spec.js @@ -65,7 +65,8 @@ describe('flowchart shapes', function() { ['lean_right', 4, useWidth, useHeight], ['lean_left', 4, useWidth, useHeight], ['trapezoid', 4, useWidth, useHeight], - ['inv_trapezoid', 4, useWidth, useHeight] + ['inv_trapezoid', 4, useWidth, useHeight], + ['subroutine', 10, useWidth, useHeight], ].forEach(function([shapeType, expectedPointCount, getW, getH]) { it(`should add a ${shapeType} shape that renders a properly translated polygon element`, function() { const mockRender = MockRender(); diff --git a/src/diagrams/flowchart/flowRenderer-v2.js b/src/diagrams/flowchart/flowRenderer-v2.js index e8915fc08..c635c0606 100644 --- a/src/diagrams/flowchart/flowRenderer-v2.js +++ b/src/diagrams/flowchart/flowRenderer-v2.js @@ -119,6 +119,9 @@ export const addVertices = function(vert, g, svgId) { case 'stadium': _shape = 'stadium'; break; + case 'subroutine': + _shape = 'subroutine'; + break; case 'cylinder': _shape = 'cylinder'; break; diff --git a/src/diagrams/flowchart/flowRenderer.js b/src/diagrams/flowchart/flowRenderer.js index bfe407b16..6f86d638d 100644 --- a/src/diagrams/flowchart/flowRenderer.js +++ b/src/diagrams/flowchart/flowRenderer.js @@ -119,6 +119,9 @@ export const addVertices = function(vert, g, svgId) { case 'stadium': _shape = 'stadium'; break; + case 'subroutine': + _shape = 'subroutine'; + break; case 'cylinder': _shape = 'cylinder'; break; diff --git a/src/diagrams/flowchart/flowRenderer.spec.js b/src/diagrams/flowchart/flowRenderer.spec.js index 95419a5df..41ce5fe55 100644 --- a/src/diagrams/flowchart/flowRenderer.spec.js +++ b/src/diagrams/flowchart/flowRenderer.spec.js @@ -23,6 +23,7 @@ describe('the flowchart renderer', function() { ['circle', 'circle'], ['ellipse', 'ellipse'], ['stadium', 'stadium'], + ['subroutine', 'subroutine'], ['cylinder', 'cylinder'], ['group', 'rect'] ].forEach(function([type, expectedShape, expectedRadios = 0]) { diff --git a/src/diagrams/flowchart/parser/flow.jison b/src/diagrams/flowchart/parser/flow.jison index 58e4664a6..6cd7c6af8 100644 --- a/src/diagrams/flowchart/parser/flow.jison +++ b/src/diagrams/flowchart/parser/flow.jison @@ -87,6 +87,8 @@ "-)" return '-)'; "([" return 'STADIUMSTART'; "])" return 'STADIUMEND'; +"[[" return 'SUBROUTINESTART'; +"]]" return 'SUBROUTINEEND'; "[(" return 'CYLINDERSTART'; ")]" return 'CYLINDEREND'; \- return 'MINUS'; @@ -316,6 +318,8 @@ vertex: idString SQS text SQE {$$ = $1;yy.addVertex($1,$3,'ellipse');} | idString STADIUMSTART text STADIUMEND {$$ = $1;yy.addVertex($1,$3,'stadium');} + | idString SUBROUTINESTART text SUBROUTINEEND + {$$ = $1;yy.addVertex($1,$3,'subroutine');} | idString CYLINDERSTART text CYLINDEREND {$$ = $1;yy.addVertex($1,$3,'cylinder');} | idString PS text PE @@ -474,5 +478,5 @@ alphaNumToken : PUNCTUATION | AMP | UNICODE_TEXT | NUM| ALPHA | COLON | COMMA | idStringToken : ALPHA|UNDERSCORE |UNICODE_TEXT | NUM| COLON | COMMA | PLUS | MINUS | DOWN |EQUALS | MULT | BRKT | DOT | PUNCTUATION | AMP; -graphCodeTokens: STADIUMSTART | STADIUMEND | CYLINDERSTART | CYLINDEREND | TRAPSTART | TRAPEND | INVTRAPSTART | INVTRAPEND | PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAGSTART | TAGEND | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI; +graphCodeTokens: STADIUMSTART | STADIUMEND | SUBROUTINESTART | SUBROUTINEEND | CYLINDERSTART | CYLINDEREND | TRAPSTART | TRAPEND | INVTRAPSTART | INVTRAPEND | PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAGSTART | TAGEND | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI; %% From 530648e937e4199ff72d92edf9769dfd07d11490 Mon Sep 17 00:00:00 2001 From: Marc Faber Date: Fri, 10 Apr 2020 00:28:33 +0200 Subject: [PATCH 2/2] Trigger tests once more