diff --git a/src/diagrams/flowchart/flowRenderer.js b/src/diagrams/flowchart/flowRenderer.js
new file mode 100644
index 000000000..49cad4fb1
--- /dev/null
+++ b/src/diagrams/flowchart/flowRenderer.js
@@ -0,0 +1,278 @@
+/**
+ * Created by knut on 14-12-11.
+ */
+var graph = require('./graphDb');
+var flow = require('./parser/flow');
+var dot = require('./parser/dot');
+var utils = require('../../utils');
+var he = require('he');
+var dagreD3 = require('dagre-d3');
+/**
+ * Function that adds the vertices found in the graph definition to the graph to be rendered.
+ * @param vert Object containing the vertices.
+ * @param g The graph that is to be drawn.
+ */
+exports.addVertices = function (vert, g) {
+ var keys = Object.keys(vert);
+
+ var styleFromStyleArr = function(styleStr,arr){
+ var i;
+ // Create a compound style definition from the style definitions found for the node in the graph definition
+ for (i = 0; i < arr.length; i++) {
+ if (typeof arr[i] !== 'undefined') {
+ styleStr = styleStr + arr[i] + ';';
+ }
+ }
+
+ return styleStr;
+ };
+
+ // Iterate through each item in the vertice object (containing all the vertices found) in the graph definition
+ keys.forEach(function (id) {
+ var vertice = vert[id];
+ var verticeText;
+
+ var i;
+
+ /**
+ * Variable for storing the extracted style for the vertice
+ * @type {string}
+ */
+ var style = '';
+ var classes = graph.getClasses();
+ // Check if class is defined for the node
+
+ if(vertice.classes.length >0){
+ for (i = 0; i < vertice.classes.length; i++) {
+ style = styleFromStyleArr(style,classes[vertice.classes[i]].styles);
+ }
+ }
+ else{
+ // Use default classes
+ style = styleFromStyleArr(style,classes.default.styles);
+ }
+
+
+ // Create a compound style definition from the style definitions found for the node in the graph definition
+ style = styleFromStyleArr(style, vertice.styles);
+
+ // Use vertice id as text in the box if no text is provided by the graph definition
+ if (typeof vertice.text === 'undefined') {
+ verticeText = vertice.id;
+ }
+ else {
+ verticeText = vertice.text;
+ }
+
+ var radious = 0;
+ var _shape = '';
+
+ // Set the shape based parameters
+ switch(vertice.type){
+ case 'round':
+ radious = 5;
+ _shape = 'rect';
+ break;
+ case 'square':
+ _shape = 'rect';
+ break;
+ case 'diamond':
+ _shape = 'question';
+ break;
+ case 'odd':
+ _shape = 'rect_left_inv_arrow';
+ break;
+ case 'circle':
+ _shape = 'circle';
+ break;
+ default:
+ _shape = 'rect';
+ }
+ // Add the node
+ g.setNode(vertice.id, {labelType: "html",shape:_shape, label: verticeText, rx: radious, ry: radious, style: style, id:vertice.id});
+ });
+};
+
+/**
+ * Add edges to graph based on parsed graph defninition
+ * @param {Object} edges The edges to add to the graph
+ * @param {Object} g The graph object
+ */
+exports.addEdges = function (edges, g) {
+ var cnt=0;
+ var aHead;
+ edges.forEach(function (edge) {
+ cnt++;
+
+ // Set link type for rendering
+ if(edge.type === 'arrow_open'){
+ aHead = 'none';
+ }
+ else{
+ aHead = 'normal';
+ }
+
+ var style = '';
+ if(typeof edge.style !== 'undefined'){
+ edge.style.forEach(function(s){
+ style = style + s +';';
+ });
+ }
+
+ // Add the edge to the graph
+ if (typeof edge.text === 'undefined') {
+ if(typeof edge.style === 'undefined'){
+ g.setEdge(edge.start, edge.end,{ style: "stroke: #333; stroke-width: 1.5px;fill:none", arrowheadStyle: "fill: #333", arrowhead: aHead},cnt);
+ }else{
+ g.setEdge(edge.start, edge.end, {
+ style: style, arrowheadStyle: "fill: #333", arrowhead: aHead
+ },cnt);
+ }
+ }
+ // Edge with text
+ else {
+
+ if(typeof edge.style === 'undefined'){
+ g.setEdge(edge.start, edge.end,{labelType: "html",style: "stroke: #333; stroke-width: 1.5px;fill:none", labelpos:'c', label: ''+edge.text+'', arrowheadStyle: "fill: #333", arrowhead: aHead},cnt);
+ }else{
+ g.setEdge(edge.start, edge.end, {
+ labelType: "html",style: style, arrowheadStyle: "fill: #333", label: edge.text, arrowhead: aHead
+ },cnt);
+ }
+ }
+ });
+};
+
+/**
+ * Draws a flowchart in the tag with id: id based on the graph definition in text.
+ * @param text
+ * @param id
+ */
+exports.draw = function (text, id,isDot) {
+ var parser;
+ graph.clear();
+ if(isDot){
+ parser = dot.parser;
+
+ }else{
+ parser = flow.parser;
+ }
+ parser.yy = graph;
+
+ // Parse the graph definition
+ parser.parse(text);
+
+ // Fetch the default direction, use TD if none was found
+ var dir;
+ dir = graph.getDirection();
+ if(typeof dir === 'undefined'){
+ dir='TD';
+ }
+
+ // Create the input mermaid.graph
+ var g = new dagreD3.graphlib.Graph({multigraph:true})
+ .setGraph({
+ rankdir: dir,
+ marginx: 20,
+ marginy: 20
+
+ })
+ .setDefaultEdgeLabel(function () {
+ return {};
+ });
+
+ // Fetch the verices/nodes and edges/links from the parsed graph definition
+ var vert = graph.getVertices();
+ var edges = graph.getEdges();
+ var classes = graph.getClasses();
+
+ if(typeof classes.default === 'undefined'){
+ classes.default = {id:'default'};
+ classes.default.styles = ['fill:#eaeaea','stroke:#666','stroke-width:1.5px'];
+ }
+ exports.addVertices(vert, g);
+ exports.addEdges(edges, g);
+
+ // Create the renderer
+ var render = new dagreD3.render();
+
+ // Add custom shape for rhombus type of boc (decision)
+ render.shapes().question = function (parent, bbox, node) {
+ var w = bbox.width,
+ h = bbox.height,
+ s = (w + h) * 0.8,
+ points = [
+ {x: s / 2, y: 0},
+ {x: s, y: -s / 2},
+ {x: s / 2, y: -s},
+ {x: 0, y: -s / 2}
+ ];
+ shapeSvg = parent.insert("polygon", ":first-child")
+ .attr("points", points.map(function (d) {
+ return d.x + "," + d.y;
+ }).join(" "))
+ .style("fill", "#fff")
+ .style("stroke", "#333")
+ .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) {
+ var w = bbox.width,
+ h = bbox.height,
+ points = [
+ {x: -h/2, y: 0},
+ {x: w, y: 0},
+ {x: w, y: -h},
+ {x: -h/2, y: -h},
+ {x: 0, y: -h/2},
+ ];
+ shapeSvg = parent.insert("polygon", ":first-child")
+ .attr("points", points.map(function (d) {
+ return d.x + "," + d.y;
+ }).join(" "))
+ .style("fill", "#fff")
+ .style("stroke", "#333")
+ .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
+ render.arrows().none = function normal(parent, id, edge, type) {
+ var marker = parent.append("marker")
+ .attr("id", id)
+ .attr("viewBox", "0 0 10 10")
+ .attr("refX", 9)
+ .attr("refY", 5)
+ .attr("markerUnits", "strokeWidth")
+ .attr("markerWidth", 8)
+ .attr("markerHeight", 6)
+ .attr("orient", "auto");
+
+ var path = marker.append("path")
+ .attr("d", "M 0 0 L 0 0 L 0 0 z");
+ dagreD3.util.applyStyle(path, edge[type + "Style"]);
+ };
+
+ // Set up an SVG group so that we can translate the final graph.
+ var svg = d3.select("#" + id);
+ svgGroup = d3.select("#" + id + " g");
+
+ // Run the renderer. This is what draws the final graph.
+ render(d3.select("#" + id + " g"), g);
+
+ // Center the graph
+ var xCenterOffset = (svg.attr("width") - g.graph().width) / 2;
+ //svgGroup.attr("transform", "translate(" + xCenterOffset + ", 20)");
+ svg.attr("height", g.graph().height );
+ svg.attr("width", g.graph().width );
+};
\ No newline at end of file
diff --git a/src/graphDb.js b/src/diagrams/flowchart/graphDb.js
similarity index 100%
rename from src/graphDb.js
rename to src/diagrams/flowchart/graphDb.js
diff --git a/src/parser/dot.jison b/src/diagrams/flowchart/parser/dot.jison
similarity index 100%
rename from src/parser/dot.jison
rename to src/diagrams/flowchart/parser/dot.jison
diff --git a/src/parser/dot.js b/src/diagrams/flowchart/parser/dot.js
similarity index 100%
rename from src/parser/dot.js
rename to src/diagrams/flowchart/parser/dot.js
diff --git a/src/parser/flow.jison b/src/diagrams/flowchart/parser/flow.jison
similarity index 100%
rename from src/parser/flow.jison
rename to src/diagrams/flowchart/parser/flow.jison
diff --git a/src/parser/flow.js b/src/diagrams/flowchart/parser/flow.js
similarity index 100%
rename from src/parser/flow.js
rename to src/diagrams/flowchart/parser/flow.js
diff --git a/src/parser/flow.spec.js b/src/diagrams/flowchart/parser/flow.spec.js
similarity index 100%
rename from src/parser/flow.spec.js
rename to src/diagrams/flowchart/parser/flow.spec.js
diff --git a/src/parser/js-sequence-diagram.jison b/src/diagrams/sequenceDiagram/parser/js-sequence-diagram.jison
similarity index 100%
rename from src/parser/js-sequence-diagram.jison
rename to src/diagrams/sequenceDiagram/parser/js-sequence-diagram.jison
diff --git a/src/parser/sequence.jison b/src/diagrams/sequenceDiagram/parser/sequence.jison
similarity index 100%
rename from src/parser/sequence.jison
rename to src/diagrams/sequenceDiagram/parser/sequence.jison
diff --git a/src/parser/sequence.js b/src/diagrams/sequenceDiagram/parser/sequence.js
similarity index 100%
rename from src/parser/sequence.js
rename to src/diagrams/sequenceDiagram/parser/sequence.js
diff --git a/src/parser/sequenceDiagram.js b/src/diagrams/sequenceDiagram/parser/sequenceDiagram.js
similarity index 100%
rename from src/parser/sequenceDiagram.js
rename to src/diagrams/sequenceDiagram/parser/sequenceDiagram.js
diff --git a/src/sequence.spec.js b/src/diagrams/sequenceDiagram/sequence.spec.js
similarity index 100%
rename from src/sequence.spec.js
rename to src/diagrams/sequenceDiagram/sequence.spec.js
diff --git a/src/sequenceDb.js b/src/diagrams/sequenceDiagram/sequenceDb.js
similarity index 100%
rename from src/sequenceDb.js
rename to src/diagrams/sequenceDiagram/sequenceDb.js
diff --git a/src/sequenceDiagram.spec.js b/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js
similarity index 100%
rename from src/sequenceDiagram.spec.js
rename to src/diagrams/sequenceDiagram/sequenceDiagram.spec.js
diff --git a/src/sequenceRenderer.js b/src/diagrams/sequenceDiagram/sequenceRenderer.js
similarity index 100%
rename from src/sequenceRenderer.js
rename to src/diagrams/sequenceDiagram/sequenceRenderer.js
diff --git a/src/main.js b/src/main.js
index b1b773258..35dc5ba38 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,279 +1,9 @@
-var graph = require('./graphDb');
-var flow = require('./parser/flow');
-var dot = require('./parser/dot');
+var graph = require('./diagrams/flowchart/graphDb');
+var flow = require('./diagrams/flowchart/parser/flow');
var utils = require('./utils');
-var seq = require('./sequenceRenderer');
+var flowRenderer = require('./diagrams/flowchart/flowRenderer');
+var seq = require('./diagrams/sequenceDiagram/sequenceRenderer');
var he = require('he');
-var dagreD3 = require('dagre-d3');
-/**
- * Function that adds the vertices found in the graph definition to the graph to be rendered.
- * @param vert Object containing the vertices.
- * @param g The graph that is to be drawn.
- */
-exports.addVertices = function (vert, g) {
- var keys = Object.keys(vert);
-
- var styleFromStyleArr = function(styleStr,arr){
- var i;
- // Create a compound style definition from the style definitions found for the node in the graph definition
- for (i = 0; i < arr.length; i++) {
- if (typeof arr[i] !== 'undefined') {
- styleStr = styleStr + arr[i] + ';';
- }
- }
-
- return styleStr;
- };
-
- // Iterate through each item in the vertice object (containing all the vertices found) in the graph definition
- keys.forEach(function (id) {
- var vertice = vert[id];
- var verticeText;
-
- var i;
-
- /**
- * Variable for storing the extracted style for the vertice
- * @type {string}
- */
- var style = '';
- var classes = graph.getClasses();
- // Check if class is defined for the node
-
- if(vertice.classes.length >0){
- for (i = 0; i < vertice.classes.length; i++) {
- style = styleFromStyleArr(style,classes[vertice.classes[i]].styles);
- }
- }
- else{
- // Use default classes
- style = styleFromStyleArr(style,classes.default.styles);
- }
-
-
- // Create a compound style definition from the style definitions found for the node in the graph definition
- style = styleFromStyleArr(style, vertice.styles);
-
- // Use vertice id as text in the box if no text is provided by the graph definition
- if (typeof vertice.text === 'undefined') {
- verticeText = vertice.id;
- }
- else {
- verticeText = vertice.text;
- }
-
- var radious = 0;
- var _shape = '';
-
- // Set the shape based parameters
- switch(vertice.type){
- case 'round':
- radious = 5;
- _shape = 'rect';
- break;
- case 'square':
- _shape = 'rect';
- break;
- case 'diamond':
- _shape = 'question';
- break;
- case 'odd':
- _shape = 'rect_left_inv_arrow';
- break;
- case 'circle':
- _shape = 'circle';
- break;
- default:
- _shape = 'rect';
- }
- // Add the node
- g.setNode(vertice.id, {labelType: "html",shape:_shape, label: verticeText, rx: radious, ry: radious, style: style, id:vertice.id});
- });
-};
-
-/**
- * Add edges to graph based on parsed graph defninition
- * @param {Object} edges The edges to add to the graph
- * @param {Object} g The graph object
- */
-exports.addEdges = function (edges, g) {
- var cnt=0;
- var aHead;
- edges.forEach(function (edge) {
- cnt++;
-
- // Set link type for rendering
- if(edge.type === 'arrow_open'){
- aHead = 'none';
- }
- else{
- aHead = 'normal';
- }
-
- var style = '';
- if(typeof edge.style !== 'undefined'){
- edge.style.forEach(function(s){
- style = style + s +';';
- });
- }
-
- // Add the edge to the graph
- if (typeof edge.text === 'undefined') {
- if(typeof edge.style === 'undefined'){
- g.setEdge(edge.start, edge.end,{ style: "stroke: #333; stroke-width: 1.5px;fill:none", arrowheadStyle: "fill: #333", arrowhead: aHead},cnt);
- }else{
- g.setEdge(edge.start, edge.end, {
- style: style, arrowheadStyle: "fill: #333", arrowhead: aHead
- },cnt);
- }
- }
- // Edge with text
- else {
-
- if(typeof edge.style === 'undefined'){
- g.setEdge(edge.start, edge.end,{labelType: "html",style: "stroke: #333; stroke-width: 1.5px;fill:none", labelpos:'c', label: ''+edge.text+'', arrowheadStyle: "fill: #333", arrowhead: aHead},cnt);
- }else{
- g.setEdge(edge.start, edge.end, {
- labelType: "html",style: style, arrowheadStyle: "fill: #333", label: edge.text, arrowhead: aHead
- },cnt);
- }
- }
- });
-};
-
-/**
- * Draws a flowchart in the tag with id: id based on the graph definition in text.
- * @param text
- * @param id
- */
-var draw = function (text, id,isDot) {
- var parser;
- graph.clear();
- if(isDot){
- parser = dot.parser;
-
- }else{
- parser = flow.parser;
- }
- parser.yy = graph;
-
- // Parse the graph definition
- parser.parse(text);
-
- // Fetch the default direction, use TD if none was found
- var dir;
- dir = graph.getDirection();
- if(typeof dir === 'undefined'){
- dir='TD';
- }
-
- // Create the input mermaid.graph
- var g = new dagreD3.graphlib.Graph({multigraph:true})
- .setGraph({
- rankdir: dir,
- marginx: 20,
- marginy: 20
-
- })
- .setDefaultEdgeLabel(function () {
- return {};
- });
-
- // Fetch the verices/nodes and edges/links from the parsed graph definition
- var vert = graph.getVertices();
- var edges = graph.getEdges();
- var classes = graph.getClasses();
-
- if(typeof classes.default === 'undefined'){
- classes.default = {id:'default'};
- classes.default.styles = ['fill:#eaeaea','stroke:#666','stroke-width:1.5px'];
- }
- exports.addVertices(vert, g);
- exports.addEdges(edges, g);
-
- // Create the renderer
- var render = new dagreD3.render();
-
- // Add custom shape for rhombus type of boc (decision)
- render.shapes().question = function (parent, bbox, node) {
- var w = bbox.width,
- h = bbox.height,
- s = (w + h) * 0.8,
- points = [
- {x: s / 2, y: 0},
- {x: s, y: -s / 2},
- {x: s / 2, y: -s},
- {x: 0, y: -s / 2}
- ];
- shapeSvg = parent.insert("polygon", ":first-child")
- .attr("points", points.map(function (d) {
- return d.x + "," + d.y;
- }).join(" "))
- .style("fill", "#fff")
- .style("stroke", "#333")
- .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) {
- var w = bbox.width,
- h = bbox.height,
- points = [
- {x: -h/2, y: 0},
- {x: w, y: 0},
- {x: w, y: -h},
- {x: -h/2, y: -h},
- {x: 0, y: -h/2},
- ];
- shapeSvg = parent.insert("polygon", ":first-child")
- .attr("points", points.map(function (d) {
- return d.x + "," + d.y;
- }).join(" "))
- .style("fill", "#fff")
- .style("stroke", "#333")
- .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
- render.arrows().none = function normal(parent, id, edge, type) {
- var marker = parent.append("marker")
- .attr("id", id)
- .attr("viewBox", "0 0 10 10")
- .attr("refX", 9)
- .attr("refY", 5)
- .attr("markerUnits", "strokeWidth")
- .attr("markerWidth", 8)
- .attr("markerHeight", 6)
- .attr("orient", "auto");
-
- var path = marker.append("path")
- .attr("d", "M 0 0 L 0 0 L 0 0 z");
- dagreD3.util.applyStyle(path, edge[type + "Style"]);
- };
-
- // Set up an SVG group so that we can translate the final graph.
- var svg = d3.select("#" + id);
- svgGroup = d3.select("#" + id + " g");
-
- // Run the renderer. This is what draws the final graph.
- render(d3.select("#" + id + " g"), g);
-
- // Center the graph
- var xCenterOffset = (svg.attr("width") - g.graph().width) / 2;
- //svgGroup.attr("transform", "translate(" + xCenterOffset + ", 20)");
- svg.attr("height", g.graph().height );
- svg.attr("width", g.graph().width );
-};
/**
* Function that goes through the document to find the chart definitions in there and render them.
@@ -290,6 +20,7 @@ var draw = function (text, id,isDot) {
*/
var init = function () {
var arr = document.querySelectorAll('.mermaid');
+ var i;
var cnt = 0;
for (i = 0; i < arr.length; i++) {
@@ -318,11 +49,12 @@ var init = function () {
switch(graphType){
case 'graph':
- draw(txt, id,false);
+ console.log('FC');
+ flowRenderer.draw(txt, id,false);
graph.bindFunctions();
break;
case 'dotGraph':
- draw(txt, id,true);
+ flowRenderer.draw(txt, id,true);
break;
case 'sequenceDiagram':
seq.draw(txt,id);
diff --git a/src/main.spec.js b/src/main.spec.js
index ae240a4b5..10c0ca230 100644
--- a/src/main.spec.js
+++ b/src/main.spec.js
@@ -19,12 +19,7 @@ describe('when using main and ',function() {
});
- xit('should have a version', function () {
- div = document.createElement('div');
- mermaid_config ={startOnLoad : false};
- main = rewire('./main');
- expect(main.version()).toBe('0.2.10');
- });
+
it('should not call start anything with an empty document', function () {
mermaid_config ={startOnLoad : false};
@@ -46,8 +41,9 @@ describe('when using main and ',function() {
describe('when calling addEdges ',function() {
var main;
- var graph = require('./graphDb');
- var flow = require('./parser/flow');
+ var graph = require('./diagrams/flowchart/graphDb');
+ var flow = require('./diagrams/flowchart/parser/flow');
+ var flowRend = require('./diagrams/flowchart/flowRenderer');
beforeEach(function () {
mermaid_config ={startOnLoad : false};
@@ -72,7 +68,7 @@ describe('when using main and ',function() {
}
};
- main.addEdges(edges,mockG);
+ flowRend.addEdges(edges,mockG);
});
it('should handle edges without text', function () {
@@ -88,7 +84,7 @@ describe('when using main and ',function() {
}
};
- main.addEdges(edges,mockG);
+ flowRend.addEdges(edges,mockG);
});
@@ -105,7 +101,7 @@ describe('when using main and ',function() {
}
};
- main.addEdges(edges,mockG);
+ flowRend.addEdges(edges,mockG);
});
it('should handle edges with styles defined', function () {
@@ -122,7 +118,7 @@ describe('when using main and ',function() {
}
};
- main.addEdges(edges,mockG);
+ flowRend.addEdges(edges,mockG);
});
it('should handle edges with text and styles defined', function () {
var res = flow.parser.parse('graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;');
@@ -139,7 +135,7 @@ describe('when using main and ',function() {
}
};
- main.addEdges(edges,mockG);
+ flowRend.addEdges(edges,mockG);
});
});
});
\ No newline at end of file