diff --git a/dist/dataflowchart.html b/dist/dataflowchart.html
new file mode 100644
index 000000000..258a94201
--- /dev/null
+++ b/dist/dataflowchart.html
@@ -0,0 +1,53 @@
+
+
+
+
+
+ Mermaid Quick Test Page
+
+
+
+
+ Data Flow Diagram Example
+
+ flowchart LR
+ DataStore[|borders:tb|Database] -->|input| Process((System)) -->|output| Entity[Customer];
+
+
+ Borders Example
+
+ flowchart TD
+ allSides[ stroke all sides ];
+ allSides2[|borders:ltrb| stroke all sides ];
+ rbSides[|borders:rb| stroke right and bottom sides ];
+ ltSides[|borders:lt| stroke left and top sides ];
+ lrSides[|borders:lr| stroke left and right sides ];
+ noSide[|borders:no| stroke no side ];
+
+
+
+
+
+
+
diff --git a/src/dagre-wrapper/nodes.js b/src/dagre-wrapper/nodes.js
index b006f1343..40444f921 100644
--- a/src/dagre-wrapper/nodes.js
+++ b/src/dagre-wrapper/nodes.js
@@ -313,6 +313,8 @@ const rect = (parent, node) => {
// add the rect
const rect = shapeSvg.insert('rect', ':first-child');
+ const totalWidth = bbox.width + node.padding;
+ const totalHeight = bbox.height + node.padding;
rect
.attr('class', 'basic label-container')
.attr('style', node.style)
@@ -320,8 +322,19 @@ const rect = (parent, node) => {
.attr('ry', node.ry)
.attr('x', -bbox.width / 2 - halfPadding)
.attr('y', -bbox.height / 2 - halfPadding)
- .attr('width', bbox.width + node.padding)
- .attr('height', bbox.height + node.padding);
+ .attr('width', totalWidth)
+ .attr('height', totalHeight);
+
+ if (node.props) {
+ const propKeys = new Set(Object.keys(node.props));
+ if (node.props.borders) {
+ applyNodePropertyBorders(rect, node.props.borders, totalWidth, totalHeight);
+ propKeys.delete('borders');
+ }
+ propKeys.forEach((propKey) => {
+ log.warn(`Unknown node property ${propKey}`);
+ });
+ }
updateNodeBounds(node, rect);
@@ -332,6 +345,43 @@ const rect = (parent, node) => {
return shapeSvg;
};
+function applyNodePropertyBorders(rect, borders, totalWidth, totalHeight) {
+ const strokeDashArray = [];
+ const addBorder = (length) => {
+ strokeDashArray.push(length);
+ strokeDashArray.push(0);
+ };
+ const skipBorder = (length) => {
+ strokeDashArray.push(0);
+ strokeDashArray.push(length);
+ };
+ if (borders.includes('t')) {
+ log.debug('add top border');
+ addBorder(totalWidth);
+ } else {
+ skipBorder(totalWidth);
+ }
+ if (borders.includes('r')) {
+ log.debug('add right border');
+ addBorder(totalHeight);
+ } else {
+ skipBorder(totalHeight);
+ }
+ if (borders.includes('b')) {
+ log.debug('add bottom border');
+ addBorder(totalWidth);
+ } else {
+ skipBorder(totalWidth);
+ }
+ if (borders.includes('l')) {
+ log.debug('add left border');
+ addBorder(totalHeight);
+ } else {
+ skipBorder(totalHeight);
+ }
+ rect.attr('stroke-dasharray', strokeDashArray.join(' '));
+}
+
const rectWithTitle = (parent, node) => {
// const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, 'node ' + node.classes);
diff --git a/src/diagrams/flowchart/flowDb.js b/src/diagrams/flowchart/flowDb.js
index ba326fb8a..e3b132b0c 100644
--- a/src/diagrams/flowchart/flowDb.js
+++ b/src/diagrams/flowchart/flowDb.js
@@ -52,8 +52,9 @@ export const lookUpDomId = function (id) {
* @param style
* @param classes
* @param dir
+ * @param props
*/
-export const addVertex = function (_id, text, type, style, classes, dir) {
+export const addVertex = function (_id, text, type, style, classes, dir, props = {}) {
let txt;
let id = _id;
if (typeof id === 'undefined') {
@@ -109,6 +110,7 @@ export const addVertex = function (_id, text, type, style, classes, dir) {
if (typeof dir !== 'undefined') {
vertices[id].dir = dir;
}
+ vertices[id].props = props;
};
/**
diff --git a/src/diagrams/flowchart/flowRenderer-v2.js b/src/diagrams/flowchart/flowRenderer-v2.js
index d7e55f0cf..b046d9c67 100644
--- a/src/diagrams/flowchart/flowRenderer-v2.js
+++ b/src/diagrams/flowchart/flowRenderer-v2.js
@@ -152,6 +152,7 @@ export const addVertices = function (vert, g, svgId) {
width: vertex.type === 'group' ? 500 : undefined,
dir: vertex.dir,
type: vertex.type,
+ props: vertex.props,
padding: getConfig().flowchart.padding,
});
@@ -168,6 +169,7 @@ export const addVertices = function (vert, g, svgId) {
width: vertex.type === 'group' ? 500 : undefined,
type: vertex.type,
dir: vertex.dir,
+ props: vertex.props,
padding: getConfig().flowchart.padding,
});
});
diff --git a/src/diagrams/flowchart/parser/flow.jison b/src/diagrams/flowchart/parser/flow.jison
index a0b1b0019..b920720a4 100644
--- a/src/diagrams/flowchart/parser/flow.jison
+++ b/src/diagrams/flowchart/parser/flow.jison
@@ -118,6 +118,7 @@ that id.
"])" return 'STADIUMEND';
"[[" return 'SUBROUTINESTART';
"]]" return 'SUBROUTINEEND';
+"[|" return 'VERTEX_WITH_PROPS_START';
"[(" return 'CYLINDERSTART';
")]" return 'CYLINDEREND';
\- return 'MINUS';
@@ -380,6 +381,8 @@ vertex: idString SQS text SQE
{$$ = $1;yy.addVertex($1,$3,'stadium');}
| idString SUBROUTINESTART text SUBROUTINEEND
{$$ = $1;yy.addVertex($1,$3,'subroutine');}
+ | idString VERTEX_WITH_PROPS_START ALPHA COLON ALPHA PIPE text SQE
+ {$$ = $1;yy.addVertex($1,$7,'rect',undefined,undefined,undefined, Object.fromEntries([[$3, $5]]));}
| idString CYLINDERSTART text CYLINDEREND
{$$ = $1;yy.addVertex($1,$3,'cylinder');}
| idString PS text PE
@@ -559,5 +562,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 | 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;
+graphCodeTokens: STADIUMSTART | STADIUMEND | SUBROUTINESTART | SUBROUTINEEND | VERTEX_WITH_PROPS_START | 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;
%%