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 277729f66..f33151662 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -338,6 +338,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;
%%