Skip to content

Commit

Permalink
Merge pull request #346 from AlanHohn/line-interpolation
Browse files Browse the repository at this point in the history
add line interpolation to linkStyle in flowchart
  • Loading branch information
knsv committed Apr 29, 2016
2 parents 6ffef61 + 0068216 commit 8f8856b
Show file tree
Hide file tree
Showing 7 changed files with 339 additions and 103 deletions.
53 changes: 29 additions & 24 deletions src/diagrams/flowchart/flowRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,23 +151,22 @@ exports.addVertices = function (vert, g) {
*/
exports.addEdges = function (edges, g) {
var cnt=0;
var aHead;

var defaultStyle;
if(typeof edges.defaultStyle !== 'undefined'){
defaultStyle = edges.defaultStyle.toString().replace(/,/g , ';');

}

edges.forEach(function (edge) {
cnt++;
var edgeData = {};

// Set link type for rendering
if(edge.type === 'arrow_open'){
aHead = 'none';
edgeData.arrowhead = 'none';
}
else{
aHead = 'normal';
edgeData.arrowhead = 'normal';
}

var style = '';
Expand All @@ -194,32 +193,38 @@ exports.addEdges = function (edges, g) {
break;
}
}
edgeData.style = style;

if (typeof edge.interpolate !== 'undefined') {
edgeData.lineInterpolate = edge.interpolate;
} else {
if (typeof edges.defaultInterpolate !== 'undefined') {
edgeData.lineInterpolate = edges.defaultInterpolate;
}
}

// Add the edge to the graph
if (typeof edge.text === 'undefined') {
if(typeof edge.style === 'undefined'){
g.setEdge(edge.start, edge.end,{ style: style, arrowhead: aHead},cnt);
}else{
g.setEdge(edge.start, edge.end, {
style: style, arrowheadStyle: 'fill: #333', arrowhead: aHead
},cnt);
if (typeof edge.style !== 'undefined') {
edgeData.arrowheadStyle = 'fill: #333';
}
}
// Edge with text
else {
var edgeText = edge.text.replace(/<br>/g, '\n');
if(typeof edge.style === 'undefined'){
if (conf.htmlLabels){
g.setEdge(edge.start, edge.end,{labelType: 'html',style: style, labelpos:'c', label: '<span class="edgeLabel">'+edge.text+'</span>', arrowheadStyle: 'fill: #333', arrowhead: aHead},cnt);
}else{
g.setEdge(edge.start, edge.end,{labelType: 'text', style: 'stroke: #333; stroke-width: 1.5px;fill:none', labelpos:'c', label: edgeText, arrowheadStyle: 'fill: #333', arrowhead: aHead},cnt);
} else {
edgeData.arrowheadStyle = 'fill: #333';
if(typeof edge.style === 'undefined') {
edgeData.labelpos = 'c';
if (conf.htmlLabels) {
edgeData.labelType = 'html';
edgeData.label = '<span class="edgeLabel">'+edge.text+'</span>';
} else {
edgeData.labelType = 'text';
edgeData.style = 'stroke: #333; stroke-width: 1.5px;fill:none';
edgeData.label = edge.text.replace(/<br>/g, '\n');
}
}else{
g.setEdge(edge.start, edge.end, {
labelType: 'text', style: style, arrowheadStyle: 'fill: #333', label: edgeText, arrowhead: aHead
},cnt);
} else {
edgeData.label = edge.text.replace(/<br>/g, '\n');
}
}
// Add the edge to the graph
g.setEdge(edge.start, edge.end, edgeData, cnt);
});
};

Expand Down
14 changes: 14 additions & 0 deletions src/diagrams/flowchart/graphDb.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ exports.addLink = function (start, end, type, linktext) {
}
edges.push(edge);
};

/**
* Updates a link's line interpolation algorithm
* @param pos
* @param interpolate
*/
exports.updateLinkInterpolate = function (pos, interp) {
if(pos === 'default'){
edges.defaultInterpolate = interp;
}else{
edges[pos].interpolate = interp;
}
};

/**
* Updates a link with a style
* @param pos
Expand Down
9 changes: 9 additions & 0 deletions src/diagrams/flowchart/parser/flow.jison
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"style" return 'STYLE';
"default" return 'DEFAULT';
"linkStyle" return 'LINKSTYLE';
"interpolate" return 'INTERPOLATE';
"classDef" return 'CLASSDEF';
"class" return 'CLASS';
"click" return 'CLICK';
Expand Down Expand Up @@ -412,6 +413,14 @@ linkStyleStatement
{$$ = $1;yy.updateLink($3,$5);}
| LINKSTYLE SPACE NUM SPACE stylesOpt
{$$ = $1;yy.updateLink($3,$5);}
| LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt
{$$ = $1;yy.updateLinkInterpolate($3,$7);yy.updateLink($3,$9);}
| LINKSTYLE SPACE NUM SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt
{$$ = $1;yy.updateLinkInterpolate($3,$7);yy.updateLink($3,$9);}
| LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum
{$$ = $1;yy.updateLinkInterpolate($3,$7);}
| LINKSTYLE SPACE NUM SPACE INTERPOLATE SPACE alphaNum
{$$ = $1;yy.updateLinkInterpolate($3,$7);}
;

commentStatement: PCT PCT commentText;
Expand Down
162 changes: 83 additions & 79 deletions src/diagrams/flowchart/parser/flow.js

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions src/diagrams/flowchart/parser/flow.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,58 @@ describe('when parsing ',function(){
expect(edges[0].type).toBe('arrow');
});

it('should handle line interpolation default definitions',function(){
var res = flow.parser.parse('graph TD\n' +
'A-->B\n' +
'linkStyle default interpolate basis');

var vert = flow.parser.yy.getVertices();
var edges = flow.parser.yy.getEdges();


expect(edges.defaultInterpolate).toBe('basis');
});

it('should handle line interpolation numbered definitions',function(){
var res = flow.parser.parse('graph TD\n' +
'A-->B\n' +
'A-->C\n' +
'linkStyle 0 interpolate basis\n' +
'linkStyle 1 interpolate cardinal');

var vert = flow.parser.yy.getVertices();
var edges = flow.parser.yy.getEdges();

expect(edges[0].interpolate).toBe('basis');
expect(edges[1].interpolate).toBe('cardinal');
});

it('should handle line interpolation default with style',function(){
var res = flow.parser.parse('graph TD\n' +
'A-->B\n' +
'linkStyle default interpolate basis stroke-width:1px;');

var vert = flow.parser.yy.getVertices();
var edges = flow.parser.yy.getEdges();


expect(edges.defaultInterpolate).toBe('basis');
});

it('should handle line interpolation numbered with style',function(){
var res = flow.parser.parse('graph TD\n' +
'A-->B\n' +
'A-->C\n' +
'linkStyle 0 interpolate basis stroke-width:1px;\n' +
'linkStyle 1 interpolate cardinal stroke-width:1px;');

var vert = flow.parser.yy.getVertices();
var edges = flow.parser.yy.getEdges();

expect(edges[0].interpolate).toBe('basis');
expect(edges[1].interpolate).toBe('cardinal');
});

describe('it should handle interaction, ',function(){

it('it should be possible to use click to a callback',function(){
Expand Down
16 changes: 16 additions & 0 deletions src/mermaid.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,22 @@ describe('when using mermaid and ',function() {

flowRend.addEdges(edges,mockG);
});
it('should handle edges with interpolation defined', function () {
flow.parser.parse('graph TD;A---B; linkStyle 0 interpolate basis');
flow.parser.yy.getVertices();
var edges = flow.parser.yy.getEdges();

var mockG = {
setEdge:function(start, end,options){
expect(start).toBe('A');
expect(end).toBe('B');
expect(options.arrowhead).toBe('none');
expect(options.lineInterpolate).toBe('basis');
}
};

flowRend.addEdges(edges,mockG);
});
it('should handle edges with text and styles defined', function () {
flow.parser.parse('graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;');
flow.parser.yy.getVertices();
Expand Down
136 changes: 136 additions & 0 deletions test/web_interpolate.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../dist/mermaid.forest.css"/>
<script src="../dist/mermaid.js"></script>
<script>
var config = {
startOnLoad:true,
callback:function(id){
console.log(id,' rendered');
},
flowchart:{
useMaxWidth:false,
htmlLabels:true
},
logLevel:5
};
mermaid.initialize(config);
</script>

</head>
<body>

<h1>Line Interpolation Linear (default)</h1>
<div class="mermaid" id="linear">

graph TB
A --> B
B --> C
C --> D
D --> A

</div>
<h1>Line Interpolation Basis</h1>
<div class="mermaid" id="basis">

graph TB
linkStyle default interpolate basis fill:none;
A --> B
B --> C
C --> D
D --> A

</div>
<h1>Line Interpolation Step-After</h1>
<div class="mermaid" id="step-after">

graph TB
linkStyle default interpolate step-after fill:none;
A --> B
B --> C
C --> D
D --> A

</div>
<h1>Hierarchy Using Defaults</h1>
<div class="mermaid" id="default-hier">

graph TB
A --> B
A --> C
A --> D
A --> E
B --> B1
B --> B2

</div>
<h1>Hierarchy Using step-after</h1>
<div class="mermaid" id="hierarchy">

graph TB
linkStyle default interpolate step-after fill:none;
A --> B
A --> C
A --> D
A --> E
B --> B1
B --> B2

</div>
<h1>LR Hierarchy Using step-before</h1>
<div>step-after works here too</div>
<div class="mermaid" id="hierarchy">

graph LR
linkStyle default interpolate step-before fill:none;
A --> B
A --> C
A --> D
A --> E
B --> B1
B --> B2

</div>
<h1>Line Interpolation Cardinal</h1>
<div class="mermaid" id="cardinal">

graph TB
linkStyle default interpolate cardinal fill:none;
A --> B
A --> C
A --> D
D --> A

</div>
<h1>Line Interpolation Monotone</h1>
<div>Monotone is monotonic in y, so it only looks good LR</div>
<div class="mermaid" id="monotone">

graph LR
linkStyle default interpolate monotone fill:none;
A --> B
B --> C
C --> D
D --> A

</div>
<h1>Mixing Line Interpolation Types</h1>
<div>Specify the link number; the link must be defined first</div>
<div class="mermaid" id="mixed">

graph TB
A -- basis --> B
A -- linear --> C
C -- step-after --> D
D -- cardinal --> A
linkStyle 0 interpolate basis fill:none;
linkStyle 1 interpolate linear fill:none;
linkStyle 2 interpolate step-after fill:none;
linkStyle 3 interpolate cardinal fill:none;

</div>

</body>
</html>

0 comments on commit 8f8856b

Please sign in to comment.