diff --git a/e2e/platform/subgraph.html b/e2e/platform/subgraph.html
new file mode 100644
index 000000000..5b8ca8c93
--- /dev/null
+++ b/e2e/platform/subgraph.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+ Mermaid Quick Test Page
+
+
+
+
+ graph TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ subgraph 1test["Text"]
+ A
+ end
+
+
+
+
+
diff --git a/src/diagrams/flowchart/flowDb.js b/src/diagrams/flowchart/flowDb.js
index f3717458a..9fbffc409 100644
--- a/src/diagrams/flowchart/flowDb.js
+++ b/src/diagrams/flowchart/flowDb.js
@@ -357,6 +357,7 @@ export const addSubGraph = function (id, list, title) {
nodeList = uniq(nodeList.concat.apply(nodeList, list))
id = id || ('subGraph' + subCount)
+ id = 's' + id
title = title || ''
title = sanitize(title)
subCount = subCount + 1
diff --git a/src/diagrams/flowchart/parser/flow.spec.js b/src/diagrams/flowchart/parser/flow.spec.js
index c01d7c92a..2efeee235 100644
--- a/src/diagrams/flowchart/parser/flow.spec.js
+++ b/src/diagrams/flowchart/parser/flow.spec.js
@@ -27,54 +27,6 @@ describe('when parsing ', function () {
expect(edges[0].text).toBe('')
})
- it('should handle subgraph with tab indentation', function () {
- const res = flow.parser.parse('graph TB\nsubgraph One\n\ta1-->a2\nend')
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
- expect(subgraph.nodes.length).toBe(2)
- expect(subgraph.nodes[0]).toBe('a1')
- expect(subgraph.nodes[1]).toBe('a2')
- expect(subgraph.title).toBe('One')
- expect(subgraph.id).toBe('One')
- })
-
- it('should handle subgraph with multiple words in title', function () {
- const res = flow.parser.parse('graph TB\nsubgraph "Some Title"\n\ta1-->a2\nend')
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
- expect(subgraph.nodes.length).toBe(2)
- expect(subgraph.nodes[0]).toBe('a1')
- expect(subgraph.nodes[1]).toBe('a2')
- expect(subgraph.title).toBe('Some Title')
- expect(subgraph.id).toBe('subGraph0')
- });
-
- it('should handle subgraph with id and title notation', function () {
- const res = flow.parser.parse('graph TB\nsubgraph some-id[Some Title]\n\ta1-->a2\nend')
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
- expect(subgraph.nodes.length).toBe(2)
- expect(subgraph.nodes[0]).toBe('a1')
- expect(subgraph.nodes[1]).toBe('a2')
- expect(subgraph.title).toBe('Some Title')
- expect(subgraph.id).toBe('some-id')
- });
-
- xit('should handle subgraph without id and space in title', function () {
- const res = flow.parser.parse('graph TB\nsubgraph Some Title\n\ta1-->a2\nend')
- const subgraphs = flow.parser.yy.getSubGraphs()
- expect(subgraphs.length).toBe(1)
- const subgraph = subgraphs[0]
- expect(subgraph.nodes.length).toBe(2)
- expect(subgraph.nodes[0]).toBe('a1')
- expect(subgraph.nodes[1]).toBe('a2')
- expect(subgraph.title).toBe('Some Title')
- expect(subgraph.id).toBe('some-id')
- });
-
it("should handle angle bracket ' > ' as direction LR", function () {
const res = flow.parser.parse('graph >;A-->B;')
@@ -384,53 +336,6 @@ describe('when parsing ', function () {
expect(edges[0].type).toBe('arrow_circle')
})
- it('should handle subgraphs', function () {
- const res = flow.parser.parse('graph TD;A-->B;subgraph myTitle;c-->d;end;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow')
- })
-
- it('should handle subgraphs', function () {
- const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\n\n c-->d \nend\n')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow')
- })
-
- it('should handle nested subgraphs', function () {
- const str = 'graph TD\n' +
- 'A-->B\n' +
- 'subgraph myTitle\n\n' +
- ' c-->d \n\n' +
- ' subgraph inner\n\n e-->f \n end \n\n' +
- ' subgraph inner\n\n h-->i \n end \n\n' +
- 'end\n'
- const res = flow.parser.parse(str)
- })
-
- it('should handle subgraphs', function () {
- const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-->d\nend;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow')
- })
-
- it('should handle subgraphs', function () {
- const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-- text -->d\nd-->e\n end;')
-
- const vert = flow.parser.yy.getVertices()
- const edges = flow.parser.yy.getEdges()
-
- expect(edges[0].type).toBe('arrow')
- })
-
it('should handle classDefs with style in classes', function () {
const res = flow.parser.parse('graph TD\nA-->B\nclassDef exClass font-style:bold;')
@@ -449,7 +354,7 @@ describe('when parsing ', function () {
expect(edges[0].type).toBe('arrow')
})
- it('should handle style definitons with more then 1 digit in a row', function () {
+ it('should handle style definitions with more then 1 digit in a row', function () {
const res = flow.parser.parse('graph TD\n' +
'A-->B1\n' +
'A-->B2\n' +
@@ -613,10 +518,10 @@ describe('when parsing ', function () {
describe('point', function () {
it('should handle double edged nodes and edges', function () {
const res = flow.parser.parse('graph TD;\nA<-->B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -627,10 +532,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes with text', function () {
const res = flow.parser.parse('graph TD;\nA<-- text -->B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -642,10 +547,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes and edges on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA<==>B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -657,10 +562,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes with text on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA<== text ==>B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -672,10 +577,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes and edges on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA<-.->B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -687,10 +592,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes with text on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA<-. text .->B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -704,10 +609,10 @@ describe('when parsing ', function () {
describe('cross', function () {
it('should handle double edged nodes and edges', function () {
const res = flow.parser.parse('graph TD;\nA x--x B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -718,10 +623,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes with text', function () {
const res = flow.parser.parse('graph TD;\nA x-- text --x B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -733,10 +638,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes and edges on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA x==x B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -748,10 +653,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes with text on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA x== text ==x B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -763,10 +668,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes and edges on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA x-.-x B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -778,10 +683,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes with text on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA x-. text .-x B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -795,10 +700,10 @@ describe('when parsing ', function () {
describe('circle', function () {
it('should handle double edged nodes and edges', function () {
const res = flow.parser.parse('graph TD;\nA o--o B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -809,10 +714,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes with text', function () {
const res = flow.parser.parse('graph TD;\nA o-- text --o B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -824,10 +729,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes and edges on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA o==o B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -839,10 +744,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes with text on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA o== text ==o B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -854,10 +759,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes and edges on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA o-.-o B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -869,10 +774,10 @@ describe('when parsing ', function () {
})
it('should handle double edged nodes with text on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA o-. text .-o B;')
-
+
const vert = flow.parser.yy.getVertices()
const edges = flow.parser.yy.getEdges()
-
+
expect(vert['A'].id).toBe('A')
expect(vert['B'].id).toBe('B')
expect(edges.length).toBe(1)
@@ -1530,7 +1435,7 @@ describe('when parsing ', function () {
expect(edges.length).toBe(0)
expect(vert['i_d'].styles.length).toBe(0)
})
-
+
// log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
it('should handle styles for vertices', function () {
const res = flow.parser.parse('graph TD;style Q background:#fff;')
diff --git a/src/diagrams/flowchart/parser/subgraph.spec.js b/src/diagrams/flowchart/parser/subgraph.spec.js
new file mode 100644
index 000000000..547c4a189
--- /dev/null
+++ b/src/diagrams/flowchart/parser/subgraph.spec.js
@@ -0,0 +1,124 @@
+import flowDb from '../flowDb'
+import flow from './flow'
+import { setConfig } from '../../../config'
+
+setConfig({
+ securityLevel: 'strict',
+})
+
+describe('when parsing subgraphs', function () {
+ beforeEach(function () {
+ flow.parser.yy = flowDb
+ flow.parser.yy.clear()
+ })
+ it('should handle subgraph with tab indentation', function () {
+ const res = flow.parser.parse('graph TB\nsubgraph One\n\ta1-->a2\nend')
+ const subgraphs = flow.parser.yy.getSubGraphs()
+ expect(subgraphs.length).toBe(1)
+ const subgraph = subgraphs[0]
+ expect(subgraph.nodes.length).toBe(2)
+ expect(subgraph.nodes[0]).toBe('a1')
+ expect(subgraph.nodes[1]).toBe('a2')
+ expect(subgraph.title).toBe('One')
+ expect(subgraph.id).toBe('One')
+ })
+
+ it('should handle subgraph with multiple words in title', function () {
+ const res = flow.parser.parse('graph TB\nsubgraph "Some Title"\n\ta1-->a2\nend')
+ const subgraphs = flow.parser.yy.getSubGraphs()
+ expect(subgraphs.length).toBe(1)
+ const subgraph = subgraphs[0]
+ expect(subgraph.nodes.length).toBe(2)
+ expect(subgraph.nodes[0]).toBe('a1')
+ expect(subgraph.nodes[1]).toBe('a2')
+ expect(subgraph.title).toBe('Some Title')
+ expect(subgraph.id).toBe('subGraph0')
+ });
+
+ it('should handle subgraph with id and title notation', function () {
+ const res = flow.parser.parse('graph TB\nsubgraph some-id[Some Title]\n\ta1-->a2\nend')
+ const subgraphs = flow.parser.yy.getSubGraphs()
+ expect(subgraphs.length).toBe(1)
+ const subgraph = subgraphs[0]
+ expect(subgraph.nodes.length).toBe(2)
+ expect(subgraph.nodes[0]).toBe('a1')
+ expect(subgraph.nodes[1]).toBe('a2')
+ expect(subgraph.title).toBe('Some Title')
+ expect(subgraph.id).toBe('some-id')
+ });
+
+ xit('should handle subgraph without id and space in title', function () {
+ const res = flow.parser.parse('graph TB\nsubgraph Some Title\n\ta1-->a2\nend')
+ const subgraphs = flow.parser.yy.getSubGraphs()
+ expect(subgraphs.length).toBe(1)
+ const subgraph = subgraphs[0]
+ expect(subgraph.nodes.length).toBe(2)
+ expect(subgraph.nodes[0]).toBe('a1')
+ expect(subgraph.nodes[1]).toBe('a2')
+ expect(subgraph.title).toBe('Some Title')
+ expect(subgraph.id).toBe('some-id')
+ });
+
+ it('should handle subgraph id starting with a number', function () {
+ const res = flow.parser.parse(`graph TD
+ A[Christmas] -->|Get money| B(Go shopping)
+ subgraph 1test
+ A
+ end`)
+
+ const subgraphs = flow.parser.yy.getSubGraphs()
+ expect(subgraphs.length).toBe(1)
+ const subgraph = subgraphs[0]
+ expect(subgraph.nodes.length).toBe(1)
+ expect(subgraph.nodes[0]).toBe('A')
+ expect(subgraph.id).toBe('1test')
+ });
+
+ it('should handle subgraphs1', function () {
+ const res = flow.parser.parse('graph TD;A-->B;subgraph myTitle;c-->d;end;')
+
+ const vert = flow.parser.yy.getVertices()
+ const edges = flow.parser.yy.getEdges()
+
+ expect(edges[0].type).toBe('arrow')
+ })
+
+ it('should handle subgraphs2', function () {
+ const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\n\n c-->d \nend\n')
+
+ const vert = flow.parser.yy.getVertices()
+ const edges = flow.parser.yy.getEdges()
+
+ expect(edges[0].type).toBe('arrow')
+ })
+
+ it('should handle nested subgraphs', function () {
+ const str = 'graph TD\n' +
+ 'A-->B\n' +
+ 'subgraph myTitle\n\n' +
+ ' c-->d \n\n' +
+ ' subgraph inner\n\n e-->f \n end \n\n' +
+ ' subgraph inner\n\n h-->i \n end \n\n' +
+ 'end\n'
+ const res = flow.parser.parse(str)
+ })
+
+ it('should handle subgraphs4', function () {
+ const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-->d\nend;')
+
+ const vert = flow.parser.yy.getVertices()
+ const edges = flow.parser.yy.getEdges()
+
+ expect(edges[0].type).toBe('arrow')
+ })
+
+ it('should handle subgraphs5', function () {
+ const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-- text -->d\nd-->e\n end;')
+
+ const vert = flow.parser.yy.getVertices()
+ const edges = flow.parser.yy.getEdges()
+
+ expect(edges[0].type).toBe('arrow')
+ })
+
+})
diff --git a/src/mermaidAPI.js b/src/mermaidAPI.js
index e8b75071a..cb4ad9478 100644
--- a/src/mermaidAPI.js
+++ b/src/mermaidAPI.js
@@ -497,14 +497,14 @@ const render = function (id, txt, cb, container) {
svgCode = decodeEntities(svgCode)
if (typeof cb !== 'undefined') {
- switch(graphType) {
+ switch (graphType) {
case 'flowchart':
cb(svgCode, flowDb.bindFunctions)
- break;
+ break
case 'gantt':
cb(svgCode, ganttDb.bindFunctions)
- break;
- default:
+ break
+ default:
}
} else {
logger.debug('CB = undefined!')