diff --git a/dist/index.html b/dist/index.html
index 2fb6f2ab6..eb27c6593 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -300,6 +300,19 @@ click B testClick "click test"
classDef someclass fill:#f96;
class A someclass;
+
+ graph TD
+ A([stadium 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;
+
diff --git a/docs/flowchart.md b/docs/flowchart.md
index a8e40a145..7f0603008 100644
--- a/docs/flowchart.md
+++ b/docs/flowchart.md
@@ -78,6 +78,17 @@ graph LR
id1(This is the text in the box)
```
+### A stadium-shaped node
+
+```
+graph LR
+ id1([This is the text in the box])
+```
+```mermaid
+graph LR
+ id1([This is the text in the box])
+```
+
### A node in the form of a circle
```
diff --git a/src/diagrams/flowchart/flowChartShapes.js b/src/diagrams/flowchart/flowChartShapes.js
index ed69c4801..1da63ebe3 100644
--- a/src/diagrams/flowchart/flowChartShapes.js
+++ b/src/diagrams/flowchart/flowChartShapes.js
@@ -135,9 +135,29 @@ function rect_right_inv_arrow(parent, bbox, node) {
return shapeSvg;
}
+function stadium(parent, bbox, node) {
+ const h = bbox.height;
+ const w = bbox.width + h / 4;
+
+ const shapeSvg = parent
+ .insert('rect', ':first-child')
+ .attr('rx', h / 2)
+ .attr('ry', h / 2)
+ .attr('x', -w / 2)
+ .attr('y', -h / 2)
+ .attr('width', w)
+ .attr('height', h);
+
+ node.intersect = function(point) {
+ return dagreD3.intersect.rect(node, point);
+ };
+ return shapeSvg;
+}
+
export function addToRender(render) {
render.shapes().question = question;
render.shapes().hexagon = hexagon;
+ render.shapes().stadium = stadium;
// Add custom shape for box with inverted arrow on left side
render.shapes().rect_left_inv_arrow = rect_left_inv_arrow;
diff --git a/src/diagrams/flowchart/flowChartShapes.spec.js b/src/diagrams/flowchart/flowChartShapes.spec.js
index de3f05a1d..415a4f026 100644
--- a/src/diagrams/flowchart/flowChartShapes.spec.js
+++ b/src/diagrams/flowchart/flowChartShapes.spec.js
@@ -1,6 +1,29 @@
import { addToRender } from './flowChartShapes';
describe('flowchart shapes', function() {
+ // rect-based shapes
+ [
+ ['stadium', useWidth, useHeight]
+ ].forEach(function([shapeType, getW, getH]) {
+ it(`should add a ${shapeType} shape that renders a properly positioned rect element`, function() {
+ const mockRender = MockRender();
+ const mockSvg = MockSvg();
+ addToRender(mockRender);
+
+ [[100, 100], [123, 45], [71, 300]].forEach(function([width, height]) {
+ const shape = mockRender.shapes()[shapeType](mockSvg, { width, height }, {});
+ const w = width + height / 4;
+ const h = height;
+ const dx = -getW(w, h) / 2;
+ const dy = -getH(w, h) / 2;
+ expect(shape.__tag).toEqual('rect');
+ expect(shape.__attrs).toHaveProperty('x', dx);
+ expect(shape.__attrs).toHaveProperty('y', dy);
+ });
+ });
+ });
+
+ // polygon-based shapes
[
[
'question',
diff --git a/src/diagrams/flowchart/flowRenderer.js b/src/diagrams/flowchart/flowRenderer.js
index 99eda4b3f..ee680532f 100644
--- a/src/diagrams/flowchart/flowRenderer.js
+++ b/src/diagrams/flowchart/flowRenderer.js
@@ -154,6 +154,9 @@ export const addVertices = function(vert, g, svgId) {
case 'ellipse':
_shape = 'ellipse';
break;
+ case 'stadium':
+ _shape = 'stadium';
+ break;
case 'group':
_shape = 'rect';
break;
diff --git a/src/diagrams/flowchart/flowRenderer.spec.js b/src/diagrams/flowchart/flowRenderer.spec.js
index e1c1931a6..0e49dbf71 100644
--- a/src/diagrams/flowchart/flowRenderer.spec.js
+++ b/src/diagrams/flowchart/flowRenderer.spec.js
@@ -22,6 +22,7 @@ describe('the flowchart renderer', function() {
['odd_right', 'rect_left_inv_arrow'],
['circle', 'circle'],
['ellipse', 'ellipse'],
+ ['stadium', 'stadium'],
['group', 'rect']
].forEach(function([type, expectedShape, expectedRadios = 0]) {
it(`should add the correct shaped node to the graph for vertex type ${type}`, function() {
diff --git a/src/diagrams/flowchart/parser/flow.jison b/src/diagrams/flowchart/parser/flow.jison
index 80a53b01a..ec67972cf 100644
--- a/src/diagrams/flowchart/parser/flow.jison
+++ b/src/diagrams/flowchart/parser/flow.jison
@@ -82,6 +82,8 @@
\s*\=\=\s* return '==';
"(-" return '(-';
"-)" return '-)';
+"([" return 'STADIUMSTART';
+"])" return 'STADIUMEND';
\- return 'MINUS';
"." return 'DOT';
[\_] return 'UNDERSCORE';
@@ -96,8 +98,8 @@
[A-Za-z]+ return 'ALPHA';
"\\]" return 'TRAPEND';
"[/" return 'TRAPSTART';
-"/]" return 'INVTRAPEND';
-"[\\" return 'INVTRAPSTART';
+"/]" return 'INVTRAPEND';
+"[\\" return 'INVTRAPSTART';
[!"#$%&'*+,-.`?\\_/] return 'PUNCTUATION';
[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|
[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|
@@ -305,6 +307,10 @@ vertex: idString SQS text SQE
{$$ = $1;yy.addVertex($1,$3,'ellipse');}
| idString '(-' text '-)' spaceList
{$$ = $1;yy.addVertex($1,$3,'ellipse');}
+ | idString STADIUMSTART text STADIUMEND
+ {$$ = $1;yy.addVertex($1,$3,'stadium');}
+ | idString STADIUMSTART text STADIUMEND spaceList
+ {$$ = $1;yy.addVertex($1,$3,'stadium');}
| idString PS text PE
{$$ = $1;yy.addVertex($1,$3,'round');}
| idString PS text PE spaceList
@@ -563,5 +569,5 @@ alphaNumToken : PUNCTUATION | UNICODE_TEXT | NUM| ALPHA | COLON | COMMA | PLUS
idStringToken : ALPHA|UNDERSCORE |UNICODE_TEXT | NUM| COLON | COMMA | PLUS | MINUS | DOWN |EQUALS | MULT | BRKT | DOT | PUNCTUATION;
-graphCodeTokens: 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 | 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;
%%