Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text based labels, new shape #101

Merged
merged 22 commits into from
Jan 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 136 additions & 57 deletions dist/mermaid.full.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dist/mermaid.full.min.js

Large diffs are not rendered by default.

193 changes: 136 additions & 57 deletions dist/mermaid.slim.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dist/mermaid.slim.min.js

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,23 @@ gulp.task('less', function () {

var browserify = require('gulp-browserify');

//var slim_ext_libs = [
// 'dagre-d3',
// 'd3'
//];

// Basic usage
gulp.task('slimDist', function() {
// Single entry point to browserify
return gulp.src('src/main.js')
.pipe(browserify())
/*.pipe(browserify({standalone: 'mermaid'}))
.on('prebundle', function(bundle) {
// Keep these external for the slim version.
slim_ext_libs.forEach(function(lib) {
bundle.external(lib);
});
})*/
.pipe(rename('mermaid.slim.js'))
.pipe(gulp.dest('./dist/'))
.pipe(uglify())
Expand Down
15 changes: 15 additions & 0 deletions src/diagrams/flowchart/dagre-d3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* global window */

var dagreD3;

if (require) {
try {
dagreD3 = require("dagre-d3");
} catch (e) {}
}

if (!dagreD3) {
dagreD3 = window.dagreD3;
}

module.exports = dagreD3;
57 changes: 47 additions & 10 deletions src/diagrams/flowchart/flowRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
var graph = require('./graphDb');
var flow = require('./parser/flow');
var dot = require('./parser/dot');
var dagreD3 = require('dagre-d3');
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.
Expand Down Expand Up @@ -60,7 +60,13 @@ exports.addVertices = function (vert, g) {
verticeText = vertice.text;
}

console.log(verticeText);
var labelTypeStr = '';
if(global.mermaid.htmlLabels) {
labelTypeStr = 'html';
} else {
verticeText = verticeText.replace(/<br>/g, "\n");
labelTypeStr = 'text';
}

var radious = 0;
var _shape = '';
Expand All @@ -80,14 +86,17 @@ exports.addVertices = function (vert, g) {
case 'odd':
_shape = 'rect_left_inv_arrow';
break;
case 'odd_right':
_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, class: classStr, style: style, id:vertice.id});
g.setNode(vertice.id, {labelType: labelTypeStr, shape:_shape, label: verticeText, rx: radious, ry: radious, class: classStr, style: style, id:vertice.id});
});
};

Expand Down Expand Up @@ -147,12 +156,16 @@ exports.addEdges = function (edges, g) {
}
// Edge with text
else {

var edgeText = edge.text.replace(/<br>/g, "\n");
if(typeof edge.style === 'undefined'){
g.setEdge(edge.start, edge.end,{labelType: "html",style: style, labelpos:'c', label: '<span style="background:#e8e8e8">'+edge.text+'</span>', arrowheadStyle: "fill: #333", arrowhead: aHead},cnt);
}else{
if (global.mermaid.htmlLabels){
g.setEdge(edge.start, edge.end,{labelType: "html",style: style, labelpos:'c', label: '<span style="background:#e8e8e8">'+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{
g.setEdge(edge.start, edge.end, {
labelType: "html",style: style, arrowheadStyle: "fill: #333", label: edge.text, arrowhead: aHead
labelType: "text", style: style, arrowheadStyle: "fill: #333", label: edgeText, arrowhead: aHead
},cnt);
}
}
Expand Down Expand Up @@ -183,10 +196,12 @@ exports.getClasses = function (text, isDot) {
var classes = graph.getClasses();

// Add default class if undefined
if(typeof classes.default === 'undefined') {
if(typeof(classes.default) === 'undefined') {
classes.default = {id:'default'};
classes.default.styles = ['fill:#eaeaea','stroke:#666','stroke-width:1.5px'];
}
classes.default.styles = ['fill:#ffa','stroke:#666','stroke-width:3px'];
classes.default.nodeLabelStyles = ['fill:#000','stroke:none','font-weight:300','font-family:"Helvetica Neue",Helvetica,Arial,sans-serf','font-size:14px'];
classes.default.edgeLabelStyles = ['fill:#000','stroke:none','font-weight:300','font-family:"Helvetica Neue",Helvetica,Arial,sans-serf','font-size:14px'];
}
return classes;
};

Expand Down Expand Up @@ -312,6 +327,28 @@ exports.draw = function (text, id,isDot) {
return shapeSvg;
};

// Add custom shape for box with inverted arrow on right side
render.shapes().rect_right_inv_arrow = function (parent, bbox, node) {
var w = bbox.width,
h = bbox.height,
points = [
{x: 0, y: 0},
{x: w+h/2, y: 0},
{x: w, y: -h/2},
{x: w+h/2, y: -h},
{x: 0, y: -h},
];
var shapeSvg = parent.insert("polygon", ":first-child")
.attr("points", points.map(function (d) {
return d.x + "," + d.y;
}).join(" "))
.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")
Expand Down
4 changes: 4 additions & 0 deletions src/diagrams/flowchart/parser/flow.jison
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ vertex: alphaNum SQS text SQE
{$$ = $1;yy.addVertex($1,$3,'odd');}
| alphaNum TAGEND text SQE SPACE
{$$ = $1;yy.addVertex($1,$3,'odd');}
/* | alphaNum SQS text TAGSTART
{$$ = $1;yy.addVertex($1,$3,'odd_right');}
| alphaNum SQS text TAGSTART SPACE
{$$ = $1;yy.addVertex($1,$3,'odd_right');} */
| alphaNum
{$$ = $1;yy.addVertex($1);}
| alphaNum SPACE
Expand Down
9 changes: 8 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ var equals = function (val, variable){

global.mermaid = {
startOnLoad:true,
htmlLabels:true,
init:function(){
init();
},
Expand All @@ -109,6 +110,12 @@ exports.contentLoaded = function(){
// Check state of start config mermaid namespece
//console.log('global.mermaid.startOnLoad',global.mermaid.startOnLoad);
//console.log('mermaid_config',mermaid_config);
if (typeof mermaid_config !== 'undefined') {
if (equals(false, mermaid_config.htmlLabels)) {
global.mermaid.htmlLabels = false;
}
}

if(global.mermaid.startOnLoad) {

// For backwards compatability reasons also check mermaid_config variable
Expand All @@ -128,7 +135,7 @@ exports.contentLoaded = function(){

if(typeof document !== 'undefined'){
/**
* Wait for coument loaded before starting the execution
* Wait for document loaded before starting the execution
*/
document.addEventListener('DOMContentLoaded', function(){
exports.contentLoaded();
Expand Down
16 changes: 13 additions & 3 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,19 @@ module.exports.cloneCssStyles = function(svg, classes){
for (var className in classes) {
if (classes.hasOwnProperty(className) && typeof(className) != "undefined") {
if (className === 'default') {
defaultStyles = '.node' + ' { ' + classes[className].styles.join("; ") + '; }\n';
if (classes.default.styles instanceof Array) {
defaultStyles += "#" + svg.id.trim() + ' .node' + ' { ' + classes[className].styles.join("; ") + '; }\n';
}
if (classes.default.nodeLabelStyles instanceof Array) {
defaultStyles += "#" + svg.id.trim() + ' .node text ' + ' { ' + classes[className].nodeLabelStyles.join("; ") + '; }\n';
}
if (classes.default.edgeLabelStyles instanceof Array) {
defaultStyles += "#" + svg.id.trim() + ' .edgeLabel text ' + ' { ' + classes[className].edgeLabelStyles.join("; ") + '; }\n';
}
} else {
embeddedStyles += '.' + className + ' { ' + classes[className].styles.join("; ") + '; }\n';
//embeddedStyles += svg.id.trim() + ' .' + className + ' { ' + classes[className].styles.join("; ") + '; }\n';
if (classes[className].styles instanceof Array) {
embeddedStyles += "#" + svg.id.trim() + ' .' + className + ' { ' + classes[className].styles.join("; ") + '; }\n';
}
}
}
}
Expand All @@ -71,6 +80,7 @@ module.exports.cloneCssStyles = function(svg, classes){
s.setAttribute('type', 'text/css');
s.setAttribute('title', 'mermaid-svg-internal-css');
s.innerHTML = "/* <![CDATA[ */\n";
// Make this CSS local to this SVG
if (defaultStyles !== "") {
s.innerHTML += defaultStyles;
}
Expand Down
58 changes: 24 additions & 34 deletions src/utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,22 @@ describe('when cloning CSS ',function() {
}

function addStyleToDocument() {
var styleSheetCount = document.styleSheets.length;
var s = document.createElement('style');
s.innerHTML = '.node { stroke:#eee; }\n.node-square { stroke:#bbb; }\n';
document.body.appendChild(s);
}

function addSecondStyleToDocument() {
var styleSheetCount = document.styleSheets.length;
var s = document.createElement('style');
s.innerHTML = '.node2 { stroke:#eee; }\n.node-square { stroke:#beb; }\n';
document.body.appendChild(s);
}

function generateSVG() {
var svg = document.createElement('svg');
svg.setAttribute('id', 'mermaid-01');
var g1 = document.createElement('g');
g1.setAttribute('class', 'node');
svg.appendChild(g1);
Expand All @@ -107,29 +110,22 @@ describe('when cloning CSS ',function() {
return svg;
}

function addSVGwithStyleToDocument() {
var svg = document.createElement('svg');
var s = document.createElement('style');
s.innerHTML = '.node2 { stroke:#eee; }\n.node-square { stroke:#bfb; }\n';
svg.appendChild(s);
document.body.appendChild(svg);
}

function addMermaidSVGwithStyleToDocument(id) {
function addMermaidSVGwithStyleToDocument() {
var styleSheetCount = document.styleSheets.length;
var svg = document.createElement('svg');
svg.setAttribute('id', 'mermaid-03');
var s = document.createElement('style');
s.setAttribute('type', 'text/css');
s.setAttribute('title', 'mermaid-svg-internal-css');
s.innerHTML = '.node2 { stroke:#eee; }\n.node-square { stroke:#bfe; }\n';
s.innerHTML = '#mermaid-05 .node2 { stroke:#eee; }\n.node-square { stroke:#bfe; }\n';
svg.appendChild(s);
document.body.appendChild(svg);
// The Mock-browser seems not to support stylesheets title attribute, so we add it manually
var sheets = document.styleSheets;
sheets[id].title = "mermaid-svg-internal-css";
document.styleSheets[styleSheetCount].title = 'mermaid-svg-internal-css';
}

it('should handle an empty set of classes', function () {
var svg = document.createElement('svg');
svg.setAttribute('id', 'mermaid-01');

utils.cloneCssStyles(svg, {});
// Should not create style element if not needed
Expand All @@ -138,16 +134,19 @@ describe('when cloning CSS ',function() {

it('should handle a default class', function () {
var svg = document.createElement('svg');
svg.setAttribute('id', 'mermaid-01');

utils.cloneCssStyles(svg, { "default": { "styles": ["stroke:#fff","stroke-width:1.5px"] } });
expect(stylesToArray(svg)).toEqual([ '.node { stroke:#fff; stroke-width:1.5px; }']);
expect(stylesToArray(svg)).toEqual([ '#mermaid-01 .node { stroke:#fff; stroke-width:1.5px; }' ]);
// Also verify the elements around the styling
expect(svg.innerHTML).toBe('<style type="text/css" title="mermaid-svg-internal-css">/* <![CDATA[ */\n.node { stroke:#fff; stroke-width:1.5px; }\n/* ]]> */\n</style>');
expect(svg.innerHTML).toBe('<style type="text/css" title="mermaid-svg-internal-css">/* <![CDATA[ */\n#mermaid-01 .node { stroke:#fff; stroke-width:1.5px; }\n/* ]]> */\n</style>');
});

it('should handle stylesheet in document with no classes in SVG', function () {
var svg = document.createElement('svg');
addStyleToDocument();
svg.setAttribute('id', 'mermaid-01');

addStyleToDocument('mermaid');
utils.cloneCssStyles(svg, {});
// Should not create style element if not needed
expect(svg.innerHTML).toBe('');
Expand All @@ -168,43 +167,34 @@ describe('when cloning CSS ',function() {
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }', '.node-square { stroke: #beb; }']);
});

it('should handle multiple stylesheets + styles in other SVG', function () {
it('should handle multiple stylesheets + ignore styles in other mermaid SVG', function () {
var svg = generateSVG();
addStyleToDocument();
addSecondStyleToDocument();
addSVGwithStyleToDocument();
addMermaidSVGwithStyleToDocument();
utils.cloneCssStyles(svg, {});
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }', '.node-square { stroke: #beb; }', '.node-square { stroke: #bfb; }']);
});

it('should handle multiple stylesheets + ignore styles in mermaid SVG', function () {
var svg = generateSVG();
addStyleToDocument();
addSecondStyleToDocument();
addSVGwithStyleToDocument();
addMermaidSVGwithStyleToDocument(3);
utils.cloneCssStyles(svg, {});
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }', '.node-square { stroke: #beb; }', '.node-square { stroke: #bfb; }']);
expect(stylesToArray(svg)).toEqual([ '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }', '.node-square { stroke: #beb; }']);
});

it('should handle a default class together with stylesheet in document with classes in SVG', function () {
var svg = generateSVG();
addStyleToDocument();
utils.cloneCssStyles(svg, { "default": { "styles": ["stroke:#fff","stroke-width:1.5px"] } });
expect(stylesToArray(svg)).toEqual([ '.node { stroke:#fff; stroke-width:1.5px; }', '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }']);
expect(stylesToArray(svg)).toEqual([ '#mermaid-01 .node { stroke:#fff; stroke-width:1.5px; }', '.node { stroke: #eee; }', '.node-square { stroke: #bbb; }']);
});

xit('should handle a default class together with stylesheet in document and classDefs', function () {
it('should handle a default class together with stylesheet in document and classDefs', function () {
var svg = generateSVG();
addStyleToDocument();
utils.cloneCssStyles(svg, { "default": { "styles": ["stroke:#fff","stroke-width:1.5px"] },
"node-square": { "styles": ["fill:#eee", "stroke:#aaa"] },
"node-circle": { "styles": ["fill:#444", "stroke:#111"] } });
expect(stylesToArray(svg)).toEqual([ '.node { stroke:#fff; stroke-width:1.5px; }',
expect(stylesToArray(svg)).toEqual([ '#mermaid-01 .node { stroke:#fff; stroke-width:1.5px; }',
'.node { stroke: #eee; }',
'.node-square { stroke: #bbb; }',
'.node-square { fill:#eee; stroke:#aaa; }',
'.node-circle { fill:#444; stroke:#111; }' ]);
'#mermaid-01 .node-square { fill:#eee; stroke:#aaa; }',
'#mermaid-01 .node-circle { fill:#444; stroke:#111; }'
]);
});
});

5 changes: 3 additions & 2 deletions test/web.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

<script src="../dist/mermaid.full.js"></script>
<scrpt src="https://cdn.rawgit.com/knsv/mermaid/0.3.0/dist/mermaid.full.min.js"></scrpt>
<scrpt src="https://cdn.rawgit.com/knsv/mermaid/0.3.2/dist/mermaid.full.min.js"></scrpt>
<script>
var mermaid_config = {
startOnLoad:true
Expand Down Expand Up @@ -34,9 +35,9 @@ <h1>Shapes</h1>
A-->D;
B-->D;
A-->|Link text|B
classDef default fill:#9f6,stroke:#333,stroke-width:2px;
classDef default fill:#696,stroke:#333,stroke-width:2px;
classDef green fill:#9f6,stroke:#333,stroke-width:2px;
class green B;
class B green;
</div>
<h1>Sub graphs</h1>
<div class="mermaid">graph LR
Expand Down
Loading