mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-17 14:29:48 +02:00
Merge pull request #970 from mearns/issue-530-hexagon
Add hex shape for flow charts
This commit is contained in:
2
dist/index.html
vendored
2
dist/index.html
vendored
@@ -291,7 +291,7 @@ graph TB
|
|||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
graph TD
|
graph TD
|
||||||
A[Christmas] -->|Get money| B(Go shopping)
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
B --> C{Let me think}
|
B --> C{{Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?}}
|
||||||
C -->|One| D[Laptop]
|
C -->|One| D[Laptop]
|
||||||
C -->|Two| E[iPhone]
|
C -->|Two| E[iPhone]
|
||||||
C -->|Three| F[Car]
|
C -->|Three| F[Car]
|
||||||
|
@@ -112,6 +112,17 @@ graph LR
|
|||||||
id1{This is the text in the box}
|
id1{This is the text in the box}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### A hexagon node
|
||||||
|
|
||||||
|
```
|
||||||
|
graph LR
|
||||||
|
id1{{This is the text in the box}}
|
||||||
|
```
|
||||||
|
```mermaid
|
||||||
|
graph LR
|
||||||
|
id1{{This is the text in the box}}
|
||||||
|
```
|
||||||
|
|
||||||
### Trapezoid
|
### Trapezoid
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
@@ -77,7 +77,7 @@ This option decides the amount of logging to be used.
|
|||||||
|
|
||||||
Sets the level of trust to be used on the parsed diagrams.
|
Sets the level of trust to be used on the parsed diagrams.
|
||||||
|
|
||||||
- **strict**: (**default**) tags in text are encoded, click functionality is disabled
|
- **strict**: (**default**) tags in text are encoded, click functionality is disabeled
|
||||||
- **loose**: tags in text are allowed, click functionality is enabled
|
- **loose**: tags in text are allowed, click functionality is enabled
|
||||||
|
|
||||||
## startOnLoad
|
## startOnLoad
|
||||||
|
177
src/diagrams/flowchart/flowChartShapes.js
Normal file
177
src/diagrams/flowchart/flowChartShapes.js
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
import dagreD3 from 'dagre-d3-renderer';
|
||||||
|
|
||||||
|
function question(parent, bbox, node) {
|
||||||
|
const w = bbox.width;
|
||||||
|
const h = bbox.height;
|
||||||
|
const s = (w + h) * 0.9;
|
||||||
|
const points = [
|
||||||
|
{ x: s / 2, y: 0 },
|
||||||
|
{ x: s, y: -s / 2 },
|
||||||
|
{ x: s / 2, y: -s },
|
||||||
|
{ x: 0, y: -s / 2 }
|
||||||
|
];
|
||||||
|
const shapeSvg = insertPolygonShape(parent, s, s, points);
|
||||||
|
node.intersect = function(point) {
|
||||||
|
return dagreD3.intersect.polygon(node, points, point);
|
||||||
|
};
|
||||||
|
return shapeSvg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hexagon(parent, bbox, node) {
|
||||||
|
const f = 4;
|
||||||
|
const h = bbox.height;
|
||||||
|
const m = h / f;
|
||||||
|
const w = bbox.width + 2 * m;
|
||||||
|
const points = [
|
||||||
|
{ x: m, y: 0 },
|
||||||
|
{ x: w - m, y: 0 },
|
||||||
|
{ x: w, y: -h / 2 },
|
||||||
|
{ x: w - m, y: -h },
|
||||||
|
{ x: m, y: -h },
|
||||||
|
{ x: 0, y: -h / 2 }
|
||||||
|
];
|
||||||
|
const shapeSvg = insertPolygonShape(parent, w, h, points);
|
||||||
|
node.intersect = function(point) {
|
||||||
|
return dagreD3.intersect.polygon(node, points, point);
|
||||||
|
};
|
||||||
|
return shapeSvg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function rect_left_inv_arrow(parent, bbox, node) {
|
||||||
|
const w = bbox.width;
|
||||||
|
const h = bbox.height;
|
||||||
|
const points = [
|
||||||
|
{ x: -h / 2, y: 0 },
|
||||||
|
{ x: w, y: 0 },
|
||||||
|
{ x: w, y: -h },
|
||||||
|
{ x: -h / 2, y: -h },
|
||||||
|
{ x: 0, y: -h / 2 }
|
||||||
|
];
|
||||||
|
const shapeSvg = insertPolygonShape(parent, w, h, points);
|
||||||
|
node.intersect = function(point) {
|
||||||
|
return dagreD3.intersect.polygon(node, points, point);
|
||||||
|
};
|
||||||
|
return shapeSvg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function lean_right(parent, bbox, node) {
|
||||||
|
const w = bbox.width;
|
||||||
|
const h = bbox.height;
|
||||||
|
const points = [
|
||||||
|
{ x: (-2 * h) / 6, y: 0 },
|
||||||
|
{ x: w - h / 6, y: 0 },
|
||||||
|
{ x: w + (2 * h) / 6, y: -h },
|
||||||
|
{ x: h / 6, y: -h }
|
||||||
|
];
|
||||||
|
const shapeSvg = insertPolygonShape(parent, w, h, points);
|
||||||
|
node.intersect = function(point) {
|
||||||
|
return dagreD3.intersect.polygon(node, points, point);
|
||||||
|
};
|
||||||
|
return shapeSvg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function lean_left(parent, bbox, node) {
|
||||||
|
const w = bbox.width;
|
||||||
|
const h = bbox.height;
|
||||||
|
const points = [
|
||||||
|
{ x: (2 * h) / 6, y: 0 },
|
||||||
|
{ x: w + h / 6, y: 0 },
|
||||||
|
{ x: w - (2 * h) / 6, y: -h },
|
||||||
|
{ x: -h / 6, y: -h }
|
||||||
|
];
|
||||||
|
const shapeSvg = insertPolygonShape(parent, w, h, points);
|
||||||
|
node.intersect = function(point) {
|
||||||
|
return dagreD3.intersect.polygon(node, points, point);
|
||||||
|
};
|
||||||
|
return shapeSvg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function trapezoid(parent, bbox, node) {
|
||||||
|
const w = bbox.width;
|
||||||
|
const h = bbox.height;
|
||||||
|
const points = [
|
||||||
|
{ x: (-2 * h) / 6, y: 0 },
|
||||||
|
{ x: w + (2 * h) / 6, y: 0 },
|
||||||
|
{ x: w - h / 6, y: -h },
|
||||||
|
{ x: h / 6, y: -h }
|
||||||
|
];
|
||||||
|
const shapeSvg = insertPolygonShape(parent, w, h, points);
|
||||||
|
node.intersect = function(point) {
|
||||||
|
return dagreD3.intersect.polygon(node, points, point);
|
||||||
|
};
|
||||||
|
return shapeSvg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function inv_trapezoid(parent, bbox, node) {
|
||||||
|
const w = bbox.width;
|
||||||
|
const h = bbox.height;
|
||||||
|
const points = [
|
||||||
|
{ x: h / 6, y: 0 },
|
||||||
|
{ x: w - h / 6, y: 0 },
|
||||||
|
{ x: w + (2 * h) / 6, y: -h },
|
||||||
|
{ x: (-2 * h) / 6, y: -h }
|
||||||
|
];
|
||||||
|
const shapeSvg = insertPolygonShape(parent, w, h, points);
|
||||||
|
node.intersect = function(point) {
|
||||||
|
return dagreD3.intersect.polygon(node, points, point);
|
||||||
|
};
|
||||||
|
return shapeSvg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function rect_right_inv_arrow(parent, bbox, node) {
|
||||||
|
const w = bbox.width;
|
||||||
|
const h = bbox.height;
|
||||||
|
const points = [
|
||||||
|
{ x: 0, y: 0 },
|
||||||
|
{ x: w + h / 2, y: 0 },
|
||||||
|
{ x: w, y: -h / 2 },
|
||||||
|
{ x: w + h / 2, y: -h },
|
||||||
|
{ x: 0, y: -h }
|
||||||
|
];
|
||||||
|
const shapeSvg = insertPolygonShape(parent, w, h, points);
|
||||||
|
node.intersect = function(point) {
|
||||||
|
return dagreD3.intersect.polygon(node, points, point);
|
||||||
|
};
|
||||||
|
return shapeSvg;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addToRender(render) {
|
||||||
|
render.shapes().question = question;
|
||||||
|
render.shapes().hexagon = hexagon;
|
||||||
|
|
||||||
|
// Add custom shape for box with inverted arrow on left side
|
||||||
|
render.shapes().rect_left_inv_arrow = rect_left_inv_arrow;
|
||||||
|
|
||||||
|
// Add custom shape for box with inverted arrow on left side
|
||||||
|
render.shapes().lean_right = lean_right;
|
||||||
|
|
||||||
|
// Add custom shape for box with inverted arrow on left side
|
||||||
|
render.shapes().lean_left = lean_left;
|
||||||
|
|
||||||
|
// Add custom shape for box with inverted arrow on left side
|
||||||
|
render.shapes().trapezoid = trapezoid;
|
||||||
|
|
||||||
|
// Add custom shape for box with inverted arrow on left side
|
||||||
|
render.shapes().inv_trapezoid = inv_trapezoid;
|
||||||
|
|
||||||
|
// Add custom shape for box with inverted arrow on right side
|
||||||
|
render.shapes().rect_right_inv_arrow = rect_right_inv_arrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertPolygonShape(parent, w, h, points) {
|
||||||
|
return parent
|
||||||
|
.insert('polygon', ':first-child')
|
||||||
|
.attr(
|
||||||
|
'points',
|
||||||
|
points
|
||||||
|
.map(function(d) {
|
||||||
|
return d.x + ',' + d.y;
|
||||||
|
})
|
||||||
|
.join(' ')
|
||||||
|
)
|
||||||
|
.attr('transform', 'translate(' + -w / 2 + ',' + h / 2 + ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
addToRender
|
||||||
|
};
|
91
src/diagrams/flowchart/flowChartShapes.spec.js
Normal file
91
src/diagrams/flowchart/flowChartShapes.spec.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import { addToRender } from './flowChartShapes';
|
||||||
|
|
||||||
|
describe('flowchart shapes', function() {
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'question',
|
||||||
|
4,
|
||||||
|
function(w, h) {
|
||||||
|
return (w + h) * 0.9;
|
||||||
|
},
|
||||||
|
function(w, h) {
|
||||||
|
return (w + h) * 0.9;
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'hexagon',
|
||||||
|
6,
|
||||||
|
function(w, h) {
|
||||||
|
return w + h / 2;
|
||||||
|
},
|
||||||
|
useHeight
|
||||||
|
],
|
||||||
|
['rect_left_inv_arrow', 5, useWidth, useHeight],
|
||||||
|
['rect_right_inv_arrow', 5, useWidth, useHeight],
|
||||||
|
['lean_right', 4, useWidth, useHeight],
|
||||||
|
['lean_left', 4, useWidth, useHeight],
|
||||||
|
['trapezoid', 4, useWidth, useHeight],
|
||||||
|
['inv_trapezoid', 4, 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();
|
||||||
|
const mockSvg = MockSvg();
|
||||||
|
addToRender(mockRender);
|
||||||
|
|
||||||
|
[[100, 100], [123, 45], [71, 300]].forEach(function([width, height]) {
|
||||||
|
const shape = mockRender.shapes()[shapeType](mockSvg, { width, height }, {});
|
||||||
|
const dx = -getW(width, height) / 2;
|
||||||
|
const dy = getH(width, height) / 2;
|
||||||
|
const points = shape.__attrs.points.split(' ');
|
||||||
|
expect(shape.__tag).toEqual('polygon');
|
||||||
|
expect(shape.__attrs).toHaveProperty('transform', `translate(${dx},${dy})`);
|
||||||
|
expect(points).toHaveLength(expectedPointCount);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function MockRender() {
|
||||||
|
const shapes = {};
|
||||||
|
return {
|
||||||
|
shapes() {
|
||||||
|
return shapes;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function MockSvg(tag, ...args) {
|
||||||
|
const children = [];
|
||||||
|
const attributes = {};
|
||||||
|
return {
|
||||||
|
get __args() {
|
||||||
|
return args;
|
||||||
|
},
|
||||||
|
get __tag() {
|
||||||
|
return tag;
|
||||||
|
},
|
||||||
|
get __children() {
|
||||||
|
return children;
|
||||||
|
},
|
||||||
|
get __attrs() {
|
||||||
|
return attributes;
|
||||||
|
},
|
||||||
|
insert: function(tag, ...args) {
|
||||||
|
const child = MockSvg(tag, ...args);
|
||||||
|
children.push(child);
|
||||||
|
return child;
|
||||||
|
},
|
||||||
|
attr(name, value) {
|
||||||
|
this.__attrs[name] = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function useWidth(w, h) {
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
function useHeight(w, h) {
|
||||||
|
return h;
|
||||||
|
}
|
@@ -8,6 +8,7 @@ import dagreD3 from 'dagre-d3-renderer';
|
|||||||
import addHtmlLabel from 'dagre-d3-renderer/lib/label/add-html-label.js';
|
import addHtmlLabel from 'dagre-d3-renderer/lib/label/add-html-label.js';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
import { interpolateToCurve } from '../../utils';
|
import { interpolateToCurve } from '../../utils';
|
||||||
|
import flowChartShapes from './flowChartShapes';
|
||||||
|
|
||||||
const conf = {};
|
const conf = {};
|
||||||
export const setConf = function(cnf) {
|
export const setConf = function(cnf) {
|
||||||
@@ -121,6 +122,9 @@ export const addVertices = function(vert, g, svgId) {
|
|||||||
case 'diamond':
|
case 'diamond':
|
||||||
_shape = 'question';
|
_shape = 'question';
|
||||||
break;
|
break;
|
||||||
|
case 'hexagon':
|
||||||
|
_shape = 'hexagon';
|
||||||
|
break;
|
||||||
case 'odd':
|
case 'odd':
|
||||||
_shape = 'rect_left_inv_arrow';
|
_shape = 'rect_left_inv_arrow';
|
||||||
break;
|
break;
|
||||||
@@ -328,199 +332,8 @@ export const draw = function(text, id) {
|
|||||||
const Render = dagreD3.render;
|
const Render = dagreD3.render;
|
||||||
const render = new Render();
|
const render = new Render();
|
||||||
|
|
||||||
// Add custom shape for rhombus type of boc (decision)
|
// Add custom shapes
|
||||||
render.shapes().question = function(parent, bbox, node) {
|
flowChartShapes.addToRender(render);
|
||||||
const w = bbox.width;
|
|
||||||
const h = bbox.height;
|
|
||||||
const s = (w + h) * 0.9;
|
|
||||||
const points = [
|
|
||||||
{ x: s / 2, y: 0 },
|
|
||||||
{ x: s, y: -s / 2 },
|
|
||||||
{ x: s / 2, y: -s },
|
|
||||||
{ x: 0, y: -s / 2 }
|
|
||||||
];
|
|
||||||
const shapeSvg = parent
|
|
||||||
.insert('polygon', ':first-child')
|
|
||||||
.attr(
|
|
||||||
'points',
|
|
||||||
points
|
|
||||||
.map(function(d) {
|
|
||||||
return d.x + ',' + d.y;
|
|
||||||
})
|
|
||||||
.join(' ')
|
|
||||||
)
|
|
||||||
.attr('rx', 5)
|
|
||||||
.attr('ry', 5)
|
|
||||||
.attr('transform', 'translate(' + -s / 2 + ',' + (s * 2) / 4 + ')');
|
|
||||||
node.intersect = function(point) {
|
|
||||||
return dagreD3.intersect.polygon(node, points, point);
|
|
||||||
};
|
|
||||||
return shapeSvg;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add custom shape for box with inverted arrow on left side
|
|
||||||
render.shapes().rect_left_inv_arrow = function(parent, bbox, node) {
|
|
||||||
const w = bbox.width;
|
|
||||||
const h = bbox.height;
|
|
||||||
const points = [
|
|
||||||
{ x: -h / 2, y: 0 },
|
|
||||||
{ x: w, y: 0 },
|
|
||||||
{ x: w, y: -h },
|
|
||||||
{ x: -h / 2, y: -h },
|
|
||||||
{ x: 0, y: -h / 2 }
|
|
||||||
];
|
|
||||||
const shapeSvg = parent
|
|
||||||
.insert('polygon', ':first-child')
|
|
||||||
.attr(
|
|
||||||
'points',
|
|
||||||
points
|
|
||||||
.map(function(d) {
|
|
||||||
return d.x + ',' + d.y;
|
|
||||||
})
|
|
||||||
.join(' ')
|
|
||||||
)
|
|
||||||
.attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
|
|
||||||
node.intersect = function(point) {
|
|
||||||
return dagreD3.intersect.polygon(node, points, point);
|
|
||||||
};
|
|
||||||
return shapeSvg;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add custom shape for box with inverted arrow on left side
|
|
||||||
render.shapes().lean_right = function(parent, bbox, node) {
|
|
||||||
const w = bbox.width;
|
|
||||||
const h = bbox.height;
|
|
||||||
const points = [
|
|
||||||
{ x: (-2 * h) / 6, y: 0 },
|
|
||||||
{ x: w - h / 6, y: 0 },
|
|
||||||
{ x: w + (2 * h) / 6, y: -h },
|
|
||||||
{ x: h / 6, y: -h }
|
|
||||||
];
|
|
||||||
const shapeSvg = parent
|
|
||||||
.insert('polygon', ':first-child')
|
|
||||||
.attr(
|
|
||||||
'points',
|
|
||||||
points
|
|
||||||
.map(function(d) {
|
|
||||||
return d.x + ',' + d.y;
|
|
||||||
})
|
|
||||||
.join(' ')
|
|
||||||
)
|
|
||||||
.attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
|
|
||||||
node.intersect = function(point) {
|
|
||||||
return dagreD3.intersect.polygon(node, points, point);
|
|
||||||
};
|
|
||||||
return shapeSvg;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add custom shape for box with inverted arrow on left side
|
|
||||||
render.shapes().lean_left = function(parent, bbox, node) {
|
|
||||||
const w = bbox.width;
|
|
||||||
const h = bbox.height;
|
|
||||||
const points = [
|
|
||||||
{ x: (2 * h) / 6, y: 0 },
|
|
||||||
{ x: w + h / 6, y: 0 },
|
|
||||||
{ x: w - (2 * h) / 6, y: -h },
|
|
||||||
{ x: -h / 6, y: -h }
|
|
||||||
];
|
|
||||||
const shapeSvg = parent
|
|
||||||
.insert('polygon', ':first-child')
|
|
||||||
.attr(
|
|
||||||
'points',
|
|
||||||
points
|
|
||||||
.map(function(d) {
|
|
||||||
return d.x + ',' + d.y;
|
|
||||||
})
|
|
||||||
.join(' ')
|
|
||||||
)
|
|
||||||
.attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
|
|
||||||
node.intersect = function(point) {
|
|
||||||
return dagreD3.intersect.polygon(node, points, point);
|
|
||||||
};
|
|
||||||
return shapeSvg;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add custom shape for box with inverted arrow on left side
|
|
||||||
render.shapes().trapezoid = function(parent, bbox, node) {
|
|
||||||
const w = bbox.width;
|
|
||||||
const h = bbox.height;
|
|
||||||
const points = [
|
|
||||||
{ x: (-2 * h) / 6, y: 0 },
|
|
||||||
{ x: w + (2 * h) / 6, y: 0 },
|
|
||||||
{ x: w - h / 6, y: -h },
|
|
||||||
{ x: h / 6, y: -h }
|
|
||||||
];
|
|
||||||
const shapeSvg = parent
|
|
||||||
.insert('polygon', ':first-child')
|
|
||||||
.attr(
|
|
||||||
'points',
|
|
||||||
points
|
|
||||||
.map(function(d) {
|
|
||||||
return d.x + ',' + d.y;
|
|
||||||
})
|
|
||||||
.join(' ')
|
|
||||||
)
|
|
||||||
.attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
|
|
||||||
node.intersect = function(point) {
|
|
||||||
return dagreD3.intersect.polygon(node, points, point);
|
|
||||||
};
|
|
||||||
return shapeSvg;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add custom shape for box with inverted arrow on left side
|
|
||||||
render.shapes().inv_trapezoid = function(parent, bbox, node) {
|
|
||||||
const w = bbox.width;
|
|
||||||
const h = bbox.height;
|
|
||||||
const points = [
|
|
||||||
{ x: h / 6, y: 0 },
|
|
||||||
{ x: w - h / 6, y: 0 },
|
|
||||||
{ x: w + (2 * h) / 6, y: -h },
|
|
||||||
{ x: (-2 * h) / 6, y: -h }
|
|
||||||
];
|
|
||||||
const shapeSvg = parent
|
|
||||||
.insert('polygon', ':first-child')
|
|
||||||
.attr(
|
|
||||||
'points',
|
|
||||||
points
|
|
||||||
.map(function(d) {
|
|
||||||
return d.x + ',' + d.y;
|
|
||||||
})
|
|
||||||
.join(' ')
|
|
||||||
)
|
|
||||||
.attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
|
|
||||||
node.intersect = function(point) {
|
|
||||||
return dagreD3.intersect.polygon(node, points, point);
|
|
||||||
};
|
|
||||||
return shapeSvg;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add custom shape for box with inverted arrow on right side
|
|
||||||
render.shapes().rect_right_inv_arrow = function(parent, bbox, node) {
|
|
||||||
const w = bbox.width;
|
|
||||||
const h = bbox.height;
|
|
||||||
const points = [
|
|
||||||
{ x: 0, y: 0 },
|
|
||||||
{ x: w + h / 2, y: 0 },
|
|
||||||
{ x: w, y: -h / 2 },
|
|
||||||
{ x: w + h / 2, y: -h },
|
|
||||||
{ x: 0, y: -h }
|
|
||||||
];
|
|
||||||
const shapeSvg = parent
|
|
||||||
.insert('polygon', ':first-child')
|
|
||||||
.attr(
|
|
||||||
'points',
|
|
||||||
points
|
|
||||||
.map(function(d) {
|
|
||||||
return d.x + ',' + d.y;
|
|
||||||
})
|
|
||||||
.join(' ')
|
|
||||||
)
|
|
||||||
.attr('transform', 'translate(' + -w / 2 + ',' + (h * 2) / 4 + ')');
|
|
||||||
node.intersect = function(point) {
|
|
||||||
return dagreD3.intersect.polygon(node, points, point);
|
|
||||||
};
|
|
||||||
return shapeSvg;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add our custom arrow - an empty arrowhead
|
// Add our custom arrow - an empty arrowhead
|
||||||
render.arrows().none = function normal(parent, id, edge, type) {
|
render.arrows().none = function normal(parent, id, edge, type) {
|
||||||
|
57
src/diagrams/flowchart/flowRenderer.spec.js
Normal file
57
src/diagrams/flowchart/flowRenderer.spec.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { addVertices } from './flowRenderer';
|
||||||
|
import { setConfig } from '../../config';
|
||||||
|
|
||||||
|
setConfig({
|
||||||
|
flowchart: {
|
||||||
|
htmlLabels: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('the flowchart renderer', function() {
|
||||||
|
describe('when adding vertices to a graph', function() {
|
||||||
|
[
|
||||||
|
['round', 'rect', 5],
|
||||||
|
['square', 'rect'],
|
||||||
|
['diamond', 'question'],
|
||||||
|
['hexagon', 'hexagon'],
|
||||||
|
['odd', 'rect_left_inv_arrow'],
|
||||||
|
['lean_right', 'lean_right'],
|
||||||
|
['lean_left', 'lean_left'],
|
||||||
|
['trapezoid', 'trapezoid'],
|
||||||
|
['inv_trapezoid', 'inv_trapezoid'],
|
||||||
|
['odd_right', 'rect_left_inv_arrow'],
|
||||||
|
['circle', 'circle'],
|
||||||
|
['ellipse', 'ellipse'],
|
||||||
|
['group', 'rect']
|
||||||
|
].forEach(function([type, expectedShape, expectedRadios = 0]) {
|
||||||
|
it(`should add the correct shaped node to the graph for vertex type ${type}`, function() {
|
||||||
|
const addedNodes = [];
|
||||||
|
const mockG = {
|
||||||
|
setNode: function(id, object) {
|
||||||
|
addedNodes.push([id, object]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addVertices(
|
||||||
|
{
|
||||||
|
v1: {
|
||||||
|
type,
|
||||||
|
id: 'my-node-id',
|
||||||
|
classes: [],
|
||||||
|
styles: [],
|
||||||
|
text: 'my vertex text'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mockG,
|
||||||
|
'svg-id'
|
||||||
|
);
|
||||||
|
expect(addedNodes).toHaveLength(1);
|
||||||
|
expect(addedNodes[0][0]).toEqual('my-node-id');
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('id', 'my-node-id');
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('labelType', 'svg');
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('shape', expectedShape);
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('rx', expectedRadios);
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('ry', expectedRadios);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@@ -313,6 +313,10 @@ vertex: idString SQS text SQE
|
|||||||
{$$ = $1;yy.addVertex($1,$3,'diamond');}
|
{$$ = $1;yy.addVertex($1,$3,'diamond');}
|
||||||
| idString DIAMOND_START text DIAMOND_STOP spaceList
|
| idString DIAMOND_START text DIAMOND_STOP spaceList
|
||||||
{$$ = $1;yy.addVertex($1,$3,'diamond');}
|
{$$ = $1;yy.addVertex($1,$3,'diamond');}
|
||||||
|
| idString DIAMOND_START DIAMOND_START text DIAMOND_STOP DIAMOND_STOP
|
||||||
|
{$$ = $1;yy.addVertex($1,$4,'hexagon');}
|
||||||
|
| idString DIAMOND_START DIAMOND_START text DIAMOND_STOP DIAMOND_STOP spaceList
|
||||||
|
{$$ = $1;yy.addVertex($1,$4,'hexagon');}
|
||||||
| idString TAGEND text SQE
|
| idString TAGEND text SQE
|
||||||
{$$ = $1;yy.addVertex($1,$3,'odd');}
|
{$$ = $1;yy.addVertex($1,$3,'odd');}
|
||||||
| idString TAGEND text SQE spaceList
|
| idString TAGEND text SQE spaceList
|
||||||
|
@@ -1391,6 +1391,16 @@ describe('when parsing ', function() {
|
|||||||
expect(edges.length).toBe(0);
|
expect(edges.length).toBe(0);
|
||||||
expect(vert['a'].type).toBe('diamond');
|
expect(vert['a'].type).toBe('diamond');
|
||||||
});
|
});
|
||||||
|
it('should handle a single diamond 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('diamond');
|
||||||
|
});
|
||||||
it('should handle a single diamond node with html in it', function() {
|
it('should handle a single diamond node with html in it', function() {
|
||||||
// Silly but syntactically correct
|
// Silly but syntactically correct
|
||||||
const res = flow.parser.parse('graph TD;a{A <br> end};');
|
const res = flow.parser.parse('graph TD;a{A <br> end};');
|
||||||
@@ -1402,6 +1412,27 @@ describe('when parsing ', function() {
|
|||||||
expect(vert['a'].type).toBe('diamond');
|
expect(vert['a'].type).toBe('diamond');
|
||||||
expect(vert['a'].text).toBe('A <br/> end');
|
expect(vert['a'].text).toBe('A <br/> end');
|
||||||
});
|
});
|
||||||
|
it('should handle a single hexagon 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('hexagon');
|
||||||
|
});
|
||||||
|
it('should handle a single hexagon node with html in it', 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('hexagon');
|
||||||
|
expect(vert['a'].text).toBe('A <br/> end');
|
||||||
|
});
|
||||||
it('should handle a single round node with html in it', function() {
|
it('should handle a single round node with html in it', function() {
|
||||||
// Silly but syntactically correct
|
// Silly but syntactically correct
|
||||||
const res = flow.parser.parse('graph TD;a(A <br> end);');
|
const res = flow.parser.parse('graph TD;a(A <br> end);');
|
||||||
|
Reference in New Issue
Block a user