Introducing subgraphs

This commit is contained in:
knsv
2015-01-07 21:02:58 +01:00
parent 273eb63efb
commit 5a720b6d63
12 changed files with 770 additions and 457 deletions

View File

@@ -38,6 +38,8 @@ exports.addVertices = function (vert, g) {
*/
var classStr = '';
//console.log(vertice.classes);
if(vertice.classes.length >0){
classStr = vertice.classes.join(" ");
}
@@ -195,7 +197,10 @@ exports.draw = function (text, id,isDot) {
}
// Create the input mermaid.graph
var g = new dagreD3.graphlib.Graph({multigraph:true})
var g = new dagreD3.graphlib.Graph({
multigraph:true,
compound: true
})
.setGraph({
rankdir: dir,
marginx: 20,
@@ -206,9 +211,33 @@ exports.draw = function (text, id,isDot) {
return {};
});
var subGraphs = graph.getSubGraphs();
var i = 0;
subGraphs.forEach(function(subG){
i = i + 1;
var id = 'subG'+i;
graph.addVertex(id,undefined,undefined,undefined);
});
// Fetch the verices/nodes and edges/links from the parsed graph definition
var vert = graph.getVertices();
//console.log(vert);
var edges = graph.getEdges();
//g.setParent("A", "p");
//g.setParent("B", "p");
//console.log(subGraphs);
i = 0;
subGraphs.forEach(function(subG){
i = i + 1;
var id = 'subG'+i;
//console.log('Setting id '+id);
subG.forEach(function(node){
//console.log('Setting node',node,' to subgraph '+id);
g.setParent(node,id);
});
});
exports.addVertices(vert, g);
exports.addEdges(edges, g);

View File

@@ -5,6 +5,7 @@
var vertices = {};
var edges = [];
var classes = [];
var subGraphs = [];
var direction;
// Functions to be run after graph rendering
var funs = [];
@@ -197,6 +198,7 @@ exports.clear = function () {
classes = {};
edges = [];
funs = [];
subGraphs = [];
};
/**
*
@@ -205,3 +207,29 @@ exports.clear = function () {
exports.defaultStyle = function () {
return "fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;";
};
/**
* Clears the internal graph db so that a new graph can be parsed.
*/
exports.addSubGraph = function (list) {
function uniq(a) {
var prims = {"boolean":{}, "number":{}, "string":{}}, objs = [];
return a.filter(function(item) {
var type = typeof item;
if(type in prims)
return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true);
else
return objs.indexOf(item) >= 0 ? false : objs.push(item);
});
}
var subG = [];
subG = uniq(subG.concat.apply(subG,list));
subGraphs.push(subG);
};
exports.getSubGraphs = function (list) {
return subGraphs;
};

View File

@@ -10,6 +10,8 @@
"class" return 'CLASS';
"click" return 'CLICK';
"graph" return 'GRAPH';
"subgraph" return 'subgraph';
"end" return 'end';
"LR" return 'DIR';
"RL" return 'DIR';
"TB" return 'DIR';
@@ -117,18 +119,31 @@
%left '^'
%start expressions
%start mermaidDoc
%% /* language grammar */
expressions
: graphConfig statements EOF
| graphConfig statements
| graphConfig spaceListNewline statements EOF
{$$=$1;}
| graphConfig spaceListNewline statements
{$$=$1;}
;
mermaidDoc: graphConfig document ;
document
: /* empty */
{ $$ = [];}
| document line
{
if($2 !== []){
$1.push($2);
}
$$=$1;}
;
line
: spaceListNewline statement
{$$=$2;}
| statement
{$$=$1;}
| SEMI
| EOF
;
graphConfig
: GRAPH SPACE DIR FirstStmtSeperator
@@ -146,12 +161,6 @@ graphConfig
FirstStmtSeperator
: SEMI | NEWLINE | spaceList NEWLINE ;
statements
: statement spaceListNewline statements
| statement statements
| statement
;
spaceListNewline
: SPACE spaceListNewline
@@ -168,19 +177,32 @@ spaceList
statement
: commentStatement NEWLINE
{$$=[];}
| verticeStatement separator
{$$=$1}
| styleStatement separator
{$$=[];}
| linkStyleStatement separator
{$$=[];}
| classDefStatement separator
{$$=[];}
| classStatement separator
{$$=[];}
| clickStatement separator
{$$=[];}
| subgraph document endStatement separator
{yy.addSubGraph($2);}
;
endStatement: end
| SPACE endStatement
;
separator: NEWLINE | SEMI | EOF ;
verticeStatement:
vertex link vertex
{ yy.addLink($1,$3,$2);$$ = 'oy'}
{ yy.addLink($1,$3,$2);$$ = [$1,$3];}
| vertex
{$$ = 'yo';}
;
@@ -273,7 +295,7 @@ commentText: commentToken
keywords
: STYLE | LINKSTYLE | CLASSDEF | CLASS | CLICK | GRAPH | DIR;
: STYLE | LINKSTYLE | CLASSDEF | CLASS | CLICK | GRAPH | DIR | subgraph | end ;
textNoTags: textNoTagsToken

File diff suppressed because one or more lines are too long

View File

@@ -15,7 +15,7 @@ describe('when parsing ',function(){
});
it('should handle a nodes and edges',function(){
var res = flow.parser.parse('graph TD;A-->B;');
var res = flow.parser.parse('graph TD;\nA-->B;');
var vert = flow.parser.yy.getVertices();
@@ -204,7 +204,7 @@ describe('when parsing ',function(){
});
it('it should handle a trailing whitespaces after statememnts',function(){
var res = flow.parser.parse('graph TD;\n\n\n %% CComment\n A-->B; \nB-->C;');
var res = flow.parser.parse('graph TD;\n\n\n %% CComment\n A-->B; \n B-->C;');
var vert = flow.parser.yy.getVertices();
@@ -248,6 +248,45 @@ describe('when parsing ',function(){
expect(edges[0].type).toBe('arrow_circle');
});
it('should handle subgraphs',function(){
var res = flow.parser.parse('graph TD;A-->B;subgraph;c-->d;end;');
var vert = flow.parser.yy.getVertices();
var edges = flow.parser.yy.getEdges();
expect(edges[0].type).toBe('arrow');
});
it('should handle subgraphs',function(){
var res = flow.parser.parse('graph TD\nA-->B\nsubgraph\nc-->d\nend\n');
var vert = flow.parser.yy.getVertices();
var edges = flow.parser.yy.getEdges();
expect(edges[0].type).toBe('arrow');
});
it('should handle subgraphs',function(){
var res = flow.parser.parse('graph TD\nA-->B\nsubgraph\nc-->d\nend;');
var vert = flow.parser.yy.getVertices();
var edges = flow.parser.yy.getEdges();
expect(edges[0].type).toBe('arrow');
});
it('should handle subgraphs',function(){
var res = flow.parser.parse('graph TD\nA-->B\nsubgraph\nc-- text -->d\nd-->e\n end;');
var vert = flow.parser.yy.getVertices();
var edges = flow.parser.yy.getEdges();
expect(edges[0].type).toBe('arrow');
});
describe("it should handle text on edges",function(){
it('it should handle text without space',function(){