+ flowchart LR
+ a --> b
+
+ subgraph b [Test]
+ c --> d -->e
+ end
+
flowchart LR
a --> b
@@ -40,7 +48,7 @@
Eating
}
-
+
stateDiagram-v2
state Active {
[*] --> NumLockOff
@@ -73,8 +81,8 @@
stateDiagram-v2
[*] --> First
- First --> Second
-% First --> Third
+ First --> Third
+ First --> sec
state First {
[*] --> fir
@@ -83,9 +91,14 @@ stateDiagram-v2
state Second {
[*] --> sec
sec --> [*]
- }
+ }
+ state Third {
+ [*] --> thi
+ thi --> [*]
+ }
+ thi --> sec
-
+
flowchart TD
subgraph A
a
@@ -101,7 +114,7 @@ flowchart TD
A -- oAo --o B
A --> C
-
+
flowchart TD
subgraph A
a
@@ -133,28 +146,27 @@ stateDiagram-v2
stateDiagram-v2
- [*]-->TV
+ [*]-->TV
- state TV {
- [*] --> Off: Off to start with
- On --> Off : Turn off
- Off --> On : Turn on
- }
+ state TV {
+ [*] --> Off: Off to start with
+ On --> Off : Turn off
+ Off --> On : Turn on
+ }
- TV--> Console
+ TV--> Console
- state Console {
- [*] --> Off2: Off to start with
- On2--> Off2 : Turn off
- Off2 --> On2 : Turn on
- On2-->Playing
-
- state Playing {
- Alive --> Dead
- Dead-->Alive
- }
- }
+ state Console {
+ [*] --> Off2: Off to start with
+ On2--> Off2 : Turn off
+ Off2 --> On2 : Turn on
+ On2-->Playing
+ state Playing {
+ Alive --> Dead
+ Dead-->Alive
+ }
+ }
diff --git a/src/dagre-wrapper/clusters.js b/src/dagre-wrapper/clusters.js
index ac1163be8..a1f76477e 100644
--- a/src/dagre-wrapper/clusters.js
+++ b/src/dagre-wrapper/clusters.js
@@ -149,7 +149,64 @@ const roundedWithTitle = (parent, node) => {
return shapeSvg;
};
-const shapes = { rect, roundedWithTitle, noteGroup };
+const divider = (parent, node) => {
+ // Add outer g element
+ const shapeSvg = parent
+ .insert('g')
+ .attr('class', node.classes)
+ .attr('id', node.id);
+
+ // add the rect
+ const rect = shapeSvg.insert('rect', ':first-child');
+
+ // Create the label and insert it after the rect
+ const label = shapeSvg.insert('g').attr('class', 'cluster-label');
+ const innerRect = shapeSvg.append('rect');
+
+ const text = label.node().appendChild(createLabel(node.labelText, node.labelStyle));
+
+ // Get the size of the label
+ const bbox = text.getBBox();
+
+ const padding = 0 * node.padding;
+ const halfPadding = padding / 2;
+
+ // center the rect around its coordinate
+ rect
+ .attr('class', 'divider')
+ .attr('x', node.x - node.width / 2 - halfPadding)
+ .attr('y', node.y - node.height / 2 - halfPadding)
+ .attr('width', node.width + padding)
+ .attr('height', node.height + padding);
+ // innerRect
+ // .attr('class', 'inner')
+ // .attr('x', node.x - node.width / 2 - halfPadding)
+ // .attr('y', node.y - node.height / 2 - halfPadding + bbox.height - 1)
+ // .attr('width', node.width + padding)
+ // .attr('height', node.height + padding - bbox.height);
+
+ // Center the label
+ label.attr(
+ 'transform',
+ 'translate(' +
+ (node.x - bbox.width / 2) +
+ ', ' +
+ (node.y - node.height / 2 - node.padding / 3 + 3) +
+ ')'
+ );
+
+ const rectBox = rect.node().getBBox();
+ node.width = rectBox.width;
+ node.height = rectBox.height;
+
+ node.intersect = function(point) {
+ return intersectRect(node, point);
+ };
+
+ return shapeSvg;
+};
+
+const shapes = { rect, roundedWithTitle, noteGroup, divider };
let clusterElems = {};
diff --git a/src/dagre-wrapper/index.js b/src/dagre-wrapper/index.js
index dca32ddc8..5d33e9a2e 100644
--- a/src/dagre-wrapper/index.js
+++ b/src/dagre-wrapper/index.js
@@ -14,7 +14,7 @@ import { insertEdgeLabel, positionEdgeLabel, insertEdge, clear as clearEdges } f
import { logger as log } from '../logger';
const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
- log.trace('Graph in recursive render:', graphlib.json.write(graph), parentCluster);
+ log.info('Graph in recursive render:', graphlib.json.write(graph), parentCluster);
const elem = _elem.insert('g').attr('class', 'root'); // eslint-disable-line
if (!graph.nodes()) {
log.trace('No nodes found for', graph);
diff --git a/src/dagre-wrapper/mermaid-graphlib.js b/src/dagre-wrapper/mermaid-graphlib.js
index 9b8e61fdd..786af7b46 100644
--- a/src/dagre-wrapper/mermaid-graphlib.js
+++ b/src/dagre-wrapper/mermaid-graphlib.js
@@ -31,13 +31,17 @@ const isDecendant = (id, ancenstorId) => {
};
const edgeInCluster = (edge, clusterId) => {
+ log.info('Decendants of ', clusterId, ' is ', decendants[clusterId]);
+ log.info('Edge is ', edge);
// Edges to/from the cluster is not in the cluster, they are in the parent
- if (!(edge.v === clusterId || edge.w === clusterId)) return false;
+ if (edge.v === clusterId) return false;
+ if (edge.w === clusterId) return false;
if (!decendants[clusterId]) {
log.debug('Tilt, ', clusterId, ',not in decendants');
return false;
}
+ log.info('Here ');
if (decendants[clusterId].indexOf(edge.v) >= 0) return true;
if (isDecendant(edge.v, clusterId)) return true;
@@ -80,17 +84,26 @@ const copy = (clusterId, graph, newGraph, rootId) => {
const edges = graph.edges(node);
log.debug('Copying Edges', edges);
edges.forEach(edge => {
- log.trace('Edge', edge);
+ log.info('Edge', edge);
const data = graph.edge(edge.v, edge.w, edge.name);
- log.trace('Edge data', data, rootId);
+ log.info('Edge data', data, rootId);
try {
// Do not copy edges in and out of the root cluster, they belong to the parent graph
if (edgeInCluster(edge, rootId)) {
- log.trace('Copying as ', edge.v, edge.w, data, edge.name);
+ log.info('Copying as ', edge.v, edge.w, data, edge.name);
newGraph.setEdge(edge.v, edge.w, data, edge.name);
- log.trace('newGraph edges ', newGraph.edges(), newGraph.edge(newGraph.edges()[0]));
+ log.info('newGraph edges ', newGraph.edges(), newGraph.edge(newGraph.edges()[0]));
} else {
- log.trace('Skipping copy of edge as ', rootId, edge.v, edge.w, clusterId);
+ log.info(
+ 'Skipping copy of edge ',
+ edge.v,
+ '-->',
+ edge.w,
+ ' rootId: ',
+ rootId,
+ ' clusterId:',
+ clusterId
+ );
}
} catch (e) {
log.error(e);
diff --git a/src/dagre-wrapper/mermaid-graphlib.spec.js b/src/dagre-wrapper/mermaid-graphlib.spec.js
index 33fea60de..73bc9a5a7 100644
--- a/src/dagre-wrapper/mermaid-graphlib.spec.js
+++ b/src/dagre-wrapper/mermaid-graphlib.spec.js
@@ -314,6 +314,34 @@ describe('Graphlib decorations', () => {
// expect(edgeData.data).toBe('link2');
// expect(validate(g)).toBe(true);
});
+ it('adjustClustersAndEdges the extracted graphs shall contain the correct links GLB20', function () {
+ /*
+ a --> b
+ subgraph b [Test]
+ c --> d -->e
+ end
+ */
+ g.setNode('a', { data: 1 });
+ g.setNode('b', { data: 2 });
+ g.setNode('c', { data: 3 });
+ g.setNode('d', { data: 3 });
+ g.setNode('e', { data: 3 });
+ g.setParent('c', 'b');
+ g.setParent('d', 'b');
+ g.setParent('e', 'b');
+ g.setEdge('a', 'b', { data: 'link1' }, '1');
+ g.setEdge('c', 'd', { data: 'link2' }, '2');
+ g.setEdge('d', 'e', { data: 'link2' }, '2');
+
+ logger.info('Graph before', graphlib.json.write(g))
+ adjustClustersAndEdges(g);
+ const bGraph = g.node('b').graph;
+ // logger.trace('Graph after', graphlib.json.write(g))
+ logger.info('Graph after', graphlib.json.write(bGraph));
+ expect(bGraph.nodes().length).toBe(3);
+ expect(bGraph.edges().length).toBe(2);
+ });
+
});
});
describe('extractDecendants', function () {
diff --git a/src/dagre-wrapper/nodes.js b/src/dagre-wrapper/nodes.js
index 08a0e36db..809f09701 100644
--- a/src/dagre-wrapper/nodes.js
+++ b/src/dagre-wrapper/nodes.js
@@ -253,6 +253,7 @@ const rect = (parent, node) => {
const rect = shapeSvg.insert('rect', ':first-child');
rect
+ .attr('class', 'basic')
.attr('rx', node.rx)
.attr('ry', node.ry)
.attr('x', -bbox.width / 2 - halfPadding)
diff --git a/src/dagre-wrapper/patterns.js b/src/dagre-wrapper/patterns.js
new file mode 100644
index 000000000..f607433d7
--- /dev/null
+++ b/src/dagre-wrapper/patterns.js
@@ -0,0 +1,54 @@
+/**
+ * Setup arrow head and define the marker. The result is appended to the svg.
+ */
+
+import { logger } from '../logger';
+
+// Only add the number of markers that the diagram needs
+const insertPatterns = (elem, patternArray, type, id) => {
+ patternArray.forEach(patternName => {
+ patterns[patternName](elem, type, id);
+ });
+};
+
+{
+ /* ; */
+}
+
+const dots = (elem, type) => {
+ elem
+ .append('defs')
+ .append('marker')
+ .attr('id', type + '-barbEnd')
+ .attr('refX', 19)
+ .attr('refY', 7)
+ .attr('markerWidth', 20)
+ .attr('markerHeight', 14)
+ .attr('markerUnits', 0)
+ .attr('orient', 'auto')
+ .append('path')
+ .attr('d', 'M 19,7 L9,13 L14,7 L9,1 Z');
+};
+
+// TODO rename the class diagram markers to something shape descriptive and semanitc free
+const patterns = {
+ dots
+};
+export default insertPatterns;
diff --git a/src/diagrams/state/stateRenderer-v2.js b/src/diagrams/state/stateRenderer-v2.js
index f69d94ed3..5952f96dc 100644
--- a/src/diagrams/state/stateRenderer-v2.js
+++ b/src/diagrams/state/stateRenderer-v2.js
@@ -64,7 +64,7 @@ const setupNode = (g, parent, node, altFlag) => {
if (!nodeDb[node.id].type && node.doc) {
logger.info('Setting cluser for ', node.id);
nodeDb[node.id].type = 'group';
- nodeDb[node.id].shape = 'roundedWithTitle';
+ nodeDb[node.id].shape = node.type === 'divider' ? 'divider' : 'roundedWithTitle';
nodeDb[node.id].classes =
nodeDb[node.id].classes +
' ' +
diff --git a/src/themes/state.scss b/src/themes/state.scss
index aa8bd4df3..6055db2d9 100644
--- a/src/themes/state.scss
+++ b/src/themes/state.scss
@@ -85,6 +85,8 @@ g.stateGroup line {
fill: $nodeBkg;
stroke: $nodeBorder;
stroke-width: 1px;
+}
+.statediagram-cluster rect.outer {
rx: 5px;
ry: 5px;
}
@@ -100,10 +102,14 @@ g.stateGroup line {
ry:0;
}
-.statediagram-state rect {
+.statediagram-state rect.basic {
rx: 5px;
ry: 5px;
}
+.statediagram-state rect.divider {
+ stroke-dasharray: 10,10;
+ fill: #efefef;
+}
.note-edge {
stroke-dasharray: 5;