Refactor code

This commit is contained in:
Tyler Long
2017-04-16 23:48:36 +08:00
parent 87c7f73245
commit 5624453c87
17 changed files with 632 additions and 923 deletions

View File

@@ -4,12 +4,9 @@ var log = Logger.Log
var relations = []
var classes
// var idCache
classes = {
}
// Functions to be run after graph rendering
// var funs = []
/**
* Function called by parser when a node definition has been found.
* @param id

View File

@@ -39,88 +39,88 @@ var getGraphId = function (label) {
*/
var insertMarkers = function (elem) {
elem.append('defs').append('marker')
.attr('id', 'extensionStart')
.attr('class', 'extension')
.attr('refX', 0)
.attr('refY', 7)
.attr('markerWidth', 190)
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 1,7 L18,13 V 1 Z')
.attr('id', 'extensionStart')
.attr('class', 'extension')
.attr('refX', 0)
.attr('refY', 7)
.attr('markerWidth', 190)
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 1,7 L18,13 V 1 Z')
elem.append('defs').append('marker')
.attr('id', 'extensionEnd')
.attr('refX', 19)
.attr('refY', 7)
.attr('markerWidth', 20)
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 1,1 V 13 L18,7 Z') // this is actual shape for arrowhead
.attr('id', 'extensionEnd')
.attr('refX', 19)
.attr('refY', 7)
.attr('markerWidth', 20)
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 1,1 V 13 L18,7 Z') // this is actual shape for arrowhead
elem.append('defs').append('marker')
.attr('id', 'compositionStart')
.attr('class', 'extension')
.attr('refX', 0)
.attr('refY', 7)
.attr('markerWidth', 190)
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
.attr('id', 'compositionStart')
.attr('class', 'extension')
.attr('refX', 0)
.attr('refY', 7)
.attr('markerWidth', 190)
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
elem.append('defs').append('marker')
.attr('id', 'compositionEnd')
.attr('refX', 19)
.attr('refY', 7)
.attr('markerWidth', 20)
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
.attr('id', 'compositionEnd')
.attr('refX', 19)
.attr('refY', 7)
.attr('markerWidth', 20)
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
elem.append('defs').append('marker')
.attr('id', 'aggregationStart')
.attr('class', 'extension')
.attr('refX', 0)
.attr('refY', 7)
.attr('markerWidth', 190)
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
.attr('id', 'aggregationStart')
.attr('class', 'extension')
.attr('refX', 0)
.attr('refY', 7)
.attr('markerWidth', 190)
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
elem.append('defs').append('marker')
.attr('id', 'aggregationEnd')
.attr('refX', 19)
.attr('refY', 7)
.attr('markerWidth', 20)
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
.attr('id', 'aggregationEnd')
.attr('refX', 19)
.attr('refY', 7)
.attr('markerWidth', 20)
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
elem.append('defs').append('marker')
.attr('id', 'dependencyStart')
.attr('class', 'extension')
.attr('refX', 0)
.attr('refY', 7)
.attr('markerWidth', 190)
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z')
.attr('id', 'dependencyStart')
.attr('class', 'extension')
.attr('refX', 0)
.attr('refY', 7)
.attr('markerWidth', 190)
.attr('markerHeight', 240)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z')
elem.append('defs').append('marker')
.attr('id', 'dependencyEnd')
.attr('refX', 19)
.attr('refY', 7)
.attr('markerWidth', 20)
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z')
.attr('id', 'dependencyEnd')
.attr('refX', 19)
.attr('refY', 7)
.attr('markerWidth', 20)
.attr('markerHeight', 28)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z')
}
var edgeCount = 0
@@ -138,24 +138,23 @@ var drawEdge = function (elem, path, relation) {
}
}
// The data for our line
// The data for our line
var lineData = path.points
// This is the accessor function we talked about above
// This is the accessor function we talked about above
var lineFunction = d3.svg.line()
.x(function (d) {
return d.x
})
.y(function (d) {
return d.y
})
// .interpolate('cardinal');
.interpolate('basis')
.x(function (d) {
return d.x
})
.y(function (d) {
return d.y
})
.interpolate('basis')
var svgPath = elem.append('path')
.attr('d', lineFunction(lineData))
.attr('id', 'edge' + edgeCount)
.attr('class', 'relation')
.attr('d', lineFunction(lineData))
.attr('id', 'edge' + edgeCount)
.attr('class', 'relation')
var url = ''
if (conf.arrowMarkerAbsolute) {
url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search
@@ -163,7 +162,6 @@ var drawEdge = function (elem, path, relation) {
url = url.replace(/\)/g, '\\)')
}
// console.log(relation.relation.type1);
if (relation.relation.type1 !== 'none') {
svgPath.attr('marker-start', 'url(' + url + '#' + getRelationType(relation.relation.type1) + 'Start' + ')')
}
@@ -171,9 +169,6 @@ var drawEdge = function (elem, path, relation) {
svgPath.attr('marker-end', 'url(' + url + '#' + getRelationType(relation.relation.type2) + 'End' + ')')
}
// var bbox = svgPath[0][0].getBBox();
// var x = Math.floor(bbox.x + bbox.width/2.0);
// var y = Math.floor(bbox.y + bbox.height/2.0);
var x, y
var l = path.points.length
if ((l % 2) !== 0) {
@@ -189,28 +184,24 @@ var drawEdge = function (elem, path, relation) {
if (typeof relation.title !== 'undefined') {
var g = elem.append('g')
.attr('class', 'classLabel')
.attr('class', 'classLabel')
var label = g.append('text')
.attr('class', 'label')
.attr('x', x)
.attr('y', y)
.attr('fill', 'red')
.attr('text-anchor', 'middle')
.text(relation.title)
.attr('class', 'label')
.attr('x', x)
.attr('y', y)
.attr('fill', 'red')
.attr('text-anchor', 'middle')
.text(relation.title)
window.label = label
var bounds = label.node().getBBox()
g.insert('rect', ':first-child')
.attr('class', 'box')
.attr('x', bounds.x - conf.padding / 2)
.attr('y', bounds.y - conf.padding / 2)
.attr('width', bounds.width + 2 * conf.padding / 2)
.attr('height', bounds.height + 2 * conf.padding / 2)
// .append('textpath')
// .attr('xlink:href','#edge'+edgeCount)
// .attr('text-anchor','middle')
// .attr('startOffset','50%')
.attr('class', 'box')
.attr('x', bounds.x - conf.padding / 2)
.attr('y', bounds.y - conf.padding / 2)
.attr('width', bounds.width + 2 * conf.padding / 2)
.attr('height', bounds.height + 2 * conf.padding / 2)
}
edgeCount++
@@ -221,8 +212,8 @@ var drawClass = function (elem, classDef) {
var addTspan = function (textEl, txt, isFirst) {
var tSpan = textEl.append('tspan')
.attr('x', conf.padding)
.text(txt)
.attr('x', conf.padding)
.text(txt)
if (!isFirst) {
tSpan.attr('dy', conf.textHeight)
}
@@ -237,25 +228,25 @@ var drawClass = function (elem, classDef) {
}
var g = elem.append('g')
.attr('id', id)
.attr('class', 'classGroup')
.attr('id', id)
.attr('class', 'classGroup')
var title = g.append('text')
.attr('x', conf.padding)
.attr('y', conf.textHeight + conf.padding)
.text(classDef.id)
.attr('x', conf.padding)
.attr('y', conf.textHeight + conf.padding)
.text(classDef.id)
var titleHeight = title.node().getBBox().height
var membersLine = g.append('line') // text label for the x axis
.attr('x1', 0)
.attr('y1', conf.padding + titleHeight + conf.dividerMargin / 2)
.attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2)
.attr('x1', 0)
.attr('y1', conf.padding + titleHeight + conf.dividerMargin / 2)
.attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2)
var members = g.append('text') // text label for the x axis
.attr('x', conf.padding)
.attr('y', titleHeight + (conf.dividerMargin) + conf.textHeight)
.attr('fill', 'white')
.attr('class', 'classText')
.attr('x', conf.padding)
.attr('y', titleHeight + (conf.dividerMargin) + conf.textHeight)
.attr('fill', 'white')
.attr('class', 'classText')
var isFirst = true
@@ -263,23 +254,19 @@ var drawClass = function (elem, classDef) {
addTspan(members, member, isFirst)
isFirst = false
})
// for (var member of classDef.members) {
// addTspan(members, member, isFirst);
// isFirst = false;
// }
var membersBox = members.node().getBBox()
var methodsLine = g.append('line') // text label for the x axis
.attr('x1', 0)
.attr('y1', conf.padding + titleHeight + 3 * conf.dividerMargin / 2 + membersBox.height)
.attr('y2', conf.padding + titleHeight + 3 * conf.dividerMargin / 2 + membersBox.height)
.attr('x1', 0)
.attr('y1', conf.padding + titleHeight + 3 * conf.dividerMargin / 2 + membersBox.height)
.attr('y2', conf.padding + titleHeight + 3 * conf.dividerMargin / 2 + membersBox.height)
var methods = g.append('text') // text label for the x axis
.attr('x', conf.padding)
.attr('y', titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight)
.attr('fill', 'white')
.attr('class', 'classText')
.attr('x', conf.padding)
.attr('y', titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight)
.attr('fill', 'white')
.attr('class', 'classText')
isFirst = true
@@ -287,17 +274,13 @@ var drawClass = function (elem, classDef) {
addTspan(methods, method, isFirst)
isFirst = false
})
// for (var method of classDef.methods) {
// addTspan(methods, method, isFirst);
// isFirst = false;
// }
var classBox = g.node().getBBox()
g.insert('rect', ':first-child')
.attr('x', 0)
.attr('y', 0)
.attr('width', classBox.width + 2 * conf.padding)
.attr('height', classBox.height + conf.padding + 0.5 * conf.dividerMargin)
.attr('x', 0)
.attr('y', 0)
.attr('width', classBox.width + 2 * conf.padding)
.attr('height', classBox.height + conf.padding + 0.5 * conf.dividerMargin)
membersLine.attr('x2', classBox.width + 2 * conf.padding)
methodsLine.attr('x2', classBox.width + 2 * conf.padding)
@@ -328,22 +311,21 @@ module.exports.draw = function (text, id) {
log.info('Rendering diagram ' + text)
/// / Fetch the default direction, use TD if none was found
/// / Fetch the default direction, use TD if none was found
var diagram = d3.select('#' + id)
insertMarkers(diagram)
// var svg = diagram.append('svg');
// Layout graph, Create a new directed graph
// Layout graph, Create a new directed graph
var g = new dagre.graphlib.Graph({
multigraph: true
})
// Set an object for the graph label
// Set an object for the graph label
g.setGraph({
isMultiGraph: true
})
// Default to assigning a new object as a label for each new edge.
// Default to assigning a new object as a label for each new edge.
g.setDefaultEdgeLabel(function () {
return {}
})
@@ -354,37 +336,23 @@ module.exports.draw = function (text, id) {
for (i = 0; i < keys.length; i++) {
var classDef = classes[keys[i]]
var node = drawClass(diagram, classDef)
// Add nodes to the graph. The first argument is the node id. The second is
// metadata about the node. In this case we're going to add labels to each of
// our nodes.
// Add nodes to the graph. The first argument is the node id. The second is
// metadata about the node. In this case we're going to add labels to each of
// our nodes.
g.setNode(node.id, node)
log.info('Org height: ' + node.height)
// g.setNode("swilliams", { label: "Saul Williams", width: 160, height: 100 });
// g.setNode("bpitt", { label: "Brad Pitt", width: 108, height: 100 });
// g.setNode("hford", { label: "Harrison Ford", width: 168, height: 100 });
// g.setNode("lwilson", { label: "Luke Wilson", width: 144, height: 100 });
// g.setNode("kbacon", { label: "Kevin Bacon", width: 121, height: 100 });
}
var relations = cDDb.getRelations()
// var i = 0
relations.forEach(function (relation) {
// i = i + 1
log.info('tjoho' + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation))
g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2), {relation: relation})
g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2), { relation: relation })
})
// for (var relation of relations) {
// i = i + 1;
// log.info('tjoho' + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation));
// g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2), {relation: relation});
// }
dagre.layout(g)
g.nodes().forEach(function (v) {
if (typeof v !== 'undefined') {
log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v)))
d3.select('#' + v).attr('transform', 'translate(' + (g.node(v).x - (g.node(v).width / 2)) + ',' + (g.node(v).y - (g.node(v).height / 2)) + ' )')
// d3.select('#' +v +' rect').attr('x',(g.node(v).x-(g.node(v).width/2)))
// .attr('y',(g.node(v).y-(g.node(v).height/2)));
}
})
g.edges().forEach(function (e) {
@@ -392,21 +360,7 @@ module.exports.draw = function (text, id) {
drawEdge(diagram, g.edge(e), g.edge(e).relation)
})
//
diagram.attr('height', '100%')
diagram.attr('width', '100%')
diagram.attr('viewBox', '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20))
//
//
//
//
// if(conf.useMaxWidth) {
// diagram.attr('height', '100%');
// diagram.attr('width', '100%');
// diagram.attr('style', 'max-width:' + (width) + 'px;');
// }else{
// diagram.attr('height',height);
// diagram.attr('width', width );
// }
// diagram.attr('viewBox', (box.startx-conf.diagramMarginX) + ' -' +conf.diagramMarginY + ' ' + width + ' ' + height);
}

View File

@@ -1,90 +1,14 @@
/* eslint-env jasmine */
// var proxyquire = require('proxyquire');
// var newD3;
/// **
// * Created by knut on 14-11-18.
// */
//
// var d3 = {
// select:function(){
// return new newD3();
// },
// selectAll:function(){
// return new newD3();
// }
// };
// var classRenderer = proxyquire('./classRenderer', { '../../d3': d3 });
// var testDom = require('testdom')('<html><body><div id="tst"></div></body></html>');
// var classRenderer = require('./classRenderer')
// var parser = require('./parser/classDiagram').parser
/**
* Created by knut on 14-11-18.
*/
describe('class diagram, ', function () {
describe('when rendering a classDiagram', function () {
// var conf
beforeEach(function () {
/// /parser.yy = require('./classDb');
/// /parser.yy.clear();
/// /parseError = function(err, hash) {
/// / log.debug('Syntax error:' + err);
/// / log.debug(hash);
/// /};
/// /sq.yy.parseError = parseError;
//
// newD3 = function() {
// var o = {
// append: function () {
// return newD3();
// },
// attr: function () {
// return this;
// },
// style: function () {
// return this;
// },
// text: function () {
// return this;
// },
// 0:{
// 0: {
// getBBox: function () {
// return {
// height: 10,
// width: 20
// };
// }
// }
//
// }
// };
//
// return o;
// };
//
// conf = {
// diagramMarginX:50,
// diagramMarginY:10,
// actorMargin:50,
// width:150,
// // Height of actor boxes
// height:65,
// boxMargin:10,
// messageMargin:40,
// boxTextMargin:15,
// noteMargin:25,
// mirrorActors:true,
// // Depending on css styling this might need adjustment
// // Prolongs the edge of the diagram downwards
// bottomMarginAdj:1
// };
// classRenderer.setConf(conf);
// ... add whatever browser globals your tests might need ...
// }
Object.defineProperties(window.HTMLElement.prototype, {
getBBox: {
get: function () { return {x: 10, y: 10, width: 100, height: 100} }
get: function () { return { x: 10, y: 10, width: 100, height: 100 } }
},
offsetLeft: {
get: function () { return parseFloat(window.getComputedStyle(this).marginLeft) || 0 }
@@ -100,13 +24,5 @@ describe('class diagram, ', function () {
}
})
})
it('it should handle one actor', function () {
// var str = 'classDiagram\n' +
// 'Class01 --|> Class02'
// classRenderer.draw(str,'tst');
// console.log(document.body.innerHTML);
})
})
})

View File

@@ -7,7 +7,6 @@ var d3 = require('../../d3')
var Logger = require('../../logger')
var log = Logger.Log
// var log = new Logger.Log();
/**
* Draws a an info picture in the tag with id: id based on the graph definition in text.
@@ -19,29 +18,22 @@ exports.draw = function (txt, id, ver) {
parser = exampleParser.parser
parser.yy = db
log.debug('Renering example diagram')
// Parse the graph definition
// Parse the graph definition
parser.parse(txt)
// Fetch the default direction, use TD if none was found
// Fetch the default direction, use TD if none was found
var svg = d3.select('#' + id)
var g = svg.append('g')
g.append('text') // text label for the x axis
.attr('x', 100)
.attr('y', 40)
.attr('class', 'version')
.attr('font-size', '32px')
.style('text-anchor', 'middle')
.text('mermaid ' + ver)
/*
var box = exports.bounds.getBounds();
var height = box.stopy-box.starty+2*conf.diagramMarginY;
var width = box.stopx-box.startx+2*conf.diagramMarginX; */
.attr('x', 100)
.attr('y', 40)
.attr('class', 'version')
.attr('font-size', '32px')
.style('text-anchor', 'middle')
.text('mermaid ' + ver)
svg.attr('height', 100)
svg.attr('width', 400)
// svg.attr('viewBox', '0 0 300 150');
}

View File

@@ -50,8 +50,6 @@ exports.addVertices = function (vert, g) {
*/
var classStr = ''
// log.debug(vertice.classes);
if (vertice.classes.length > 0) {
classStr = vertice.classes.join(' ')
}
@@ -94,9 +92,6 @@ exports.addVertices = function (vert, g) {
labelTypeStr = 'svg'
verticeText = svgLabel
// verticeText = verticeText.replace(/<br\/>/g, '\n');
// labelTypeStr = 'text';
}
var radious = 0
@@ -242,7 +237,6 @@ exports.getClasses = function (text, isDot) {
// Add default class if undefined
if (typeof (classes.default) === 'undefined') {
classes.default = { id: 'default' }
// classes.default.styles = ['fill:#ffa','stroke:#666','stroke-width:3px'];
classes.default.styles = []
classes.default.clusterStyles = ['rx:4px', 'fill: rgb(255, 255, 222)', 'rx: 4px', 'stroke: rgb(170, 170, 51)', 'stroke-width: 1px']
classes.default.nodeLabelStyles = ['fill:#000', 'stroke:none', 'font-weight:300', 'font-family:"Helvetica Neue",Helvetica,Arial,sans-serf', 'font-size:14px']
@@ -307,7 +301,6 @@ exports.draw = function (text, id, isDot) {
// Fetch the verices/nodes and edges/links from the parsed graph definition
var vert = graph.getVertices()
// log.debug(vert);
var edges = graph.getEdges()
i = 0
@@ -318,7 +311,6 @@ exports.draw = function (text, id, isDot) {
d3.selectAll('cluster').append('text')
for (j = 0; j < subG.nodes.length; j++) {
// log.debug('Setting node',subG.nodes[j],' to subgraph '+id);
g.setParent(subG.nodes[j], subG.id)
}
}
@@ -435,35 +427,20 @@ exports.draw = function (text, id, isDot) {
// 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.
var element = d3.select('#' + id + ' g')
render(element, g)
// var tip = d3.tip().html(function(d) { return d; });
element.selectAll('g.node')
.attr('title', function () {
return graph.getTooltip(this.id)
})
/*
var xPos = document.querySelectorAll('.clusters rect')[0].x.baseVal.value;
var width = document.querySelectorAll('.clusters rect')[0].width.baseVal.value;
var cluster = d3.selectAll('.cluster');
var te = cluster.append('text');
te.attr('x', xPos+width/2);
te.attr('y', 12);
//te.stroke('black');
te.attr('id', 'apa12');
te.style('text-anchor', 'middle');
te.text('Title for cluster');
*/
if (conf.useMaxWidth) {
// Center the graph
svg.attr('height', '100%')
svg.attr('width', conf.width)
// svg.attr('viewBox', svgb.getBBox().x + ' 0 '+ g.graph().width+' '+ g.graph().height);
svg.attr('viewBox', '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20))
svg.attr('style', 'max-width:' + (g.graph().width + 20) + 'px;')
} else {
@@ -474,7 +451,6 @@ exports.draw = function (text, id, isDot) {
} else {
svg.attr('width', conf.width)
}
// svg.attr('viewBox', svgb.getBBox().x + ' 0 '+ g.graph().width+' '+ g.graph().height);
svg.attr('viewBox', '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20))
}
@@ -486,7 +462,6 @@ exports.draw = function (text, id, isDot) {
if (subG.title !== 'undefined') {
var clusterRects = document.querySelectorAll('#' + id + ' #' + subG.id + ' rect')
// log.debug('looking up: #' + id + ' #' + subG.id)
var clusterEl = document.querySelectorAll('#' + id + ' #' + subG.id)
var xPos = clusterRects[0].x.baseVal.value
@@ -504,7 +479,6 @@ exports.draw = function (text, id, isDot) {
if (typeof subG.title === 'undefined') {
te.text('Undef')
} else {
// te.text(subGraphs[subGraphs.length-i-1].title);
te.text(subG.title)
}
}

View File

@@ -33,12 +33,12 @@ exports.addVertex = function (id, text, type, style) {
}
if (typeof vertices[id] === 'undefined') {
vertices[id] = {id: id, styles: [], classes: []}
vertices[id] = { id: id, styles: [], classes: [] }
}
if (typeof text !== 'undefined') {
txt = text.trim()
// strip quotes if string starts and exnds with a quote
// strip quotes if string starts and exnds with a quote
if (txt[0] === '"' && txt[txt.length - 1] === '"') {
txt = txt.substring(1, txt.length - 1)
}
@@ -69,13 +69,13 @@ exports.addVertex = function (id, text, type, style) {
*/
exports.addLink = function (start, end, type, linktext) {
log.info('Got edge...', start, end)
var edge = {start: start, end: end, type: undefined, text: ''}
var edge = { start: start, end: end, type: undefined, text: '' }
linktext = type.text
if (typeof linktext !== 'undefined') {
edge.text = linktext.trim()
// strip quotes if string starts and exnds with a quote
// strip quotes if string starts and exnds with a quote
if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') {
edge.text = edge.text.substring(1, edge.text.length - 1)
}
@@ -119,7 +119,7 @@ exports.updateLink = function (pos, style) {
exports.addClass = function (id, style) {
if (typeof classes[id] === 'undefined') {
classes[id] = {id: id, styles: []}
classes[id] = { id: id, styles: [] }
}
if (typeof style !== 'undefined') {
@@ -252,39 +252,39 @@ var setupToolTips = function (element) {
var tooltipElem = d3.select('.mermaidTooltip')
if (tooltipElem[0][0] === null) {
tooltipElem = d3.select('body')
.append('div')
.attr('class', 'mermaidTooltip')
.style('opacity', 0)
.append('div')
.attr('class', 'mermaidTooltip')
.style('opacity', 0)
}
var svg = d3.select(element).select('svg')
var nodes = svg.selectAll('g.node')
nodes
.on('mouseover', function () {
var el = d3.select(this)
var title = el.attr('title')
// Dont try to draw a tooltip if no data is provided
if (title === null) {
return
}
var rect = this.getBoundingClientRect()
.on('mouseover', function () {
var el = d3.select(this)
var title = el.attr('title')
// Dont try to draw a tooltip if no data is provided
if (title === null) {
return
}
var rect = this.getBoundingClientRect()
tooltipElem.transition()
.duration(200)
.style('opacity', '.9')
tooltipElem.html(el.attr('title'))
.style('left', (rect.left + (rect.right - rect.left) / 2) + 'px')
.style('top', (rect.top - 14 + document.body.scrollTop) + 'px')
el.classed('hover', true)
})
.on('mouseout', function () {
tooltipElem.transition()
.duration(500)
.style('opacity', 0)
var el = d3.select(this)
el.classed('hover', false)
})
tooltipElem.transition()
.duration(200)
.style('opacity', '.9')
tooltipElem.html(el.attr('title'))
.style('left', (rect.left + (rect.right - rect.left) / 2) + 'px')
.style('top', (rect.top - 14 + document.body.scrollTop) + 'px')
el.classed('hover', true)
})
.on('mouseout', function () {
tooltipElem.transition()
.duration(500)
.style('opacity', 0)
var el = d3.select(this)
el.classed('hover', false)
})
}
funs.push(setupToolTips)
@@ -314,7 +314,7 @@ exports.defaultStyle = function () {
*/
exports.addSubGraph = function (list, title) {
function uniq (a) {
var prims = {'boolean': {}, 'number': {}, 'string': {}}
var prims = { 'boolean': {}, 'number': {}, 'string': {} }
var objs = []
return a.filter(function (item) {
@@ -330,9 +330,7 @@ exports.addSubGraph = function (list, title) {
nodeList = uniq(nodeList.concat.apply(nodeList, list))
var subGraph = {id: 'subGraph' + subCount, nodes: nodeList, title: title}
// log.debug('subGraph:' + subGraph.title + subGraph.id);
// log.debug(subGraph.nodes);
var subGraph = { id: 'subGraph' + subCount, nodes: nodeList, title: title }
subGraphs.push(subGraph)
subCount = subCount + 1
return subGraph.id
@@ -342,11 +340,9 @@ var getPosForId = function (id) {
var i
for (i = 0; i < subGraphs.length; i++) {
if (subGraphs[i].id === id) {
// log.debug('Found pos for ',id,' ',i);
return i
}
}
// log.debug('No pos found for ',id,' ',i);
return -1
}
var secCount = -1
@@ -357,9 +353,8 @@ var indexNodes = function (id, pos) {
if (secCount > 2000) {
return
}
// var nPos = getPosForId(subGraphs[pos].id);
posCrossRef[secCount] = pos
// Check if match
// Check if match
if (subGraphs[pos].id === id) {
return {
result: true,
@@ -371,7 +366,7 @@ var indexNodes = function (id, pos) {
var posCount = 1
while (count < nodes.length) {
var childPos = getPosForId(nodes[count])
// Ignore regular nodes (pos will be -1)
// Ignore regular nodes (pos will be -1)
if (childPos >= 0) {
var res = indexNodes(id, childPos)
if (res.result) {

View File

@@ -7,8 +7,6 @@ describe('when parsing a gantt diagram it', function () {
beforeEach(function () {
gantt = require('./parser/gantt').parser
gantt.yy = require('./ganttDb')
// ex.yy.parseError = parseError;
})
it('should handle an dateFormat definition', function () {
@@ -31,26 +29,24 @@ describe('when parsing a gantt diagram it', function () {
gantt.parse(str)
})
/**
* Beslutsflöde inligt nedan. Obs bla bla bla
* ```
* graph TD
* A[Hard pledge] -- text on link -->B(Round edge)
* B --> C{to do or not to do}
* C -->|Too| D[Result one]
* C -->|Doo| E[Result two]
```
* params bapa - a unique bapap
*/
/**
* Beslutsflöde inligt nedan. Obs bla bla bla
* ```
* graph TD
* A[Hard pledge] -- text on link -->B(Round edge)
* B --> C{to do or not to do}
* C -->|Too| D[Result one]
* C -->|Doo| E[Result two]
```
* params bapa - a unique bapap
*/
it('should handle a task definition', function () {
var str = 'gantt\n' +
'dateFormat yyyy-mm-dd\n' +
'title Adding gantt diagram functionality to mermaid\n' +
'section Documentation\n' +
'Design jison grammar:des1, 2014-01-01, 2014-01-04'
'dateFormat yyyy-mm-dd\n' +
'title Adding gantt diagram functionality to mermaid\n' +
'section Documentation\n' +
'Design jison grammar:des1, 2014-01-01, 2014-01-04'
gantt.parse(str)
})
})
// Ogiltigt id i after id

View File

@@ -53,23 +53,13 @@ exports.getTasks = function () {
tasks = rawTasks
// var i;
// for(i=10000;i<tasks.length;i++){
// tasks[i].startTime = moment(tasks[i].startTime).format(dateFormat);
// tasks[i].endTime = moment(tasks[i].endTime).format(dateFormat);
// }
return tasks
}
var getStartDate = function (prevTime, dateFormat, str) {
// console.log('Deciding start date:'+JSON.stringify(str));
// log.debug('Deciding start date:'+str);
// log.debug('with dateformat:'+dateFormat);
str = str.trim()
// Test for after
// Test for after
var re = /^after\s+([\d\w-]+)/
var afterStatement = re.exec(str.trim())
@@ -80,34 +70,32 @@ var getStartDate = function (prevTime, dateFormat, str) {
var dt = new Date()
dt.setHours(0, 0, 0, 0)
return dt
// return undefined;
}
return task.endTime
}
// Check for actual date set
// Check for actual date set
if (moment(str, dateFormat.trim(), true).isValid()) {
return moment(str, dateFormat.trim(), true).toDate()
} else {
log.debug('Invalid date:' + str)
log.debug('With date format:' + dateFormat.trim())
// log.debug('----');
}
// Default date - now
// Default date - now
return new Date()
}
var getEndDate = function (prevTime, dateFormat, str) {
str = str.trim()
// Check for actual date
// Check for actual date
if (moment(str, dateFormat.trim(), true).isValid()) {
return moment(str, dateFormat.trim()).toDate()
}
var d = moment(prevTime)
// Check for length
// Check for length
var re = /^([\d]+)([wdhms])/
var durationStatement = re.exec(str.trim())
@@ -131,7 +119,7 @@ var getEndDate = function (prevTime, dateFormat, str) {
}
return d.toDate()
}
// Default date - now
// Default date - now
return d.toDate()
}
@@ -168,7 +156,7 @@ var compileData = function (prevTask, dataStr) {
var task = {}
var df = exports.getDateFormat()
// Get tags like active, done cand crit
// Get tags like active, done cand crit
var matchFound = true
while (matchFound) {
matchFound = false
@@ -228,7 +216,7 @@ var parseData = function (prevTaskId, dataStr) {
var task = {}
// Get tags like active, done cand crit
// Get tags like active, done cand crit
var matchFound = true
while (matchFound) {
matchFound = false
@@ -256,18 +244,18 @@ var parseData = function (prevTaskId, dataStr) {
switch (data.length) {
case 1:
task.id = parseId()
task.startTime = {type: 'prevTaskEnd', id: prevTaskId}
task.endTime = {data: data[0]}
task.startTime = { type: 'prevTaskEnd', id: prevTaskId }
task.endTime = { data: data[0] }
break
case 2:
task.id = parseId()
task.startTime = {type: 'getStartDate', startData: data[0]}
task.endTime = {data: data[1]}
task.startTime = { type: 'getStartDate', startData: data[0] }
task.endTime = { data: data[1] }
break
case 3:
task.id = parseId(data[0])
task.startTime = {type: 'getStartDate', startData: data[1]}
task.endTime = {data: data[2]}
task.startTime = { type: 'getStartDate', startData: data[1] }
task.endTime = { data: data[2] }
break
default:
}
@@ -284,7 +272,7 @@ exports.addTask = function (descr, data) {
section: currentSection,
type: currentSection,
processed: false,
raw: {data: data},
raw: { data: data },
task: descr
}
var taskInfo = parseData(lastTaskID, data)
@@ -299,18 +287,11 @@ exports.addTask = function (descr, data) {
var pos = rawTasks.push(rawTask)
lastTaskID = rawTask.id
// Store cross ref
// Store cross ref
taskDb[rawTask.id] = pos - 1
}
exports.findTaskById = function (id) {
// var i;
// for(i=0;i<tasks.length;i++){
// if(tasks[i].id === id){
// return tasks[i];
// }
// }
var pos = taskDb[id]
return rawTasks[pos]
}

View File

@@ -7,11 +7,8 @@ describe('when using the ganttDb', function () {
var moment = require('moment')
beforeEach(function () {
// gantt = require('./parser/gantt').parser;
gDb = require('./ganttDb')
gDb.clear()
// ex.yy.parseError = parseError;
})
it('should handle an fixed dates', function () {
@@ -180,5 +177,3 @@ describe('when using the ganttDb', function () {
expect(tasks[2].endTime).toEqual(moment('2013-01-17', 'YYYY-MM-DD').toDate())
})
})
// Ogiltigt id i after id

View File

@@ -2,7 +2,6 @@ var gantt = require('./parser/gantt').parser
gantt.yy = require('./ganttDb')
var d3 = require('../../d3')
var moment = require('moment')
// var log = require('../../logger').create();
var daysInChart
var conf = {
@@ -49,8 +48,6 @@ module.exports.draw = function (text, id) {
elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h)
var svg = d3.select('#' + id)
// var dateFormat = d3.time.format('%Y-%m-%d');
var startDate = d3.min(taskArray, function (d) {
return d.startTime
})
@@ -67,7 +64,6 @@ module.exports.draw = function (text, id) {
return d.endTime
})])
.rangeRound([0, w - conf.leftPadding - conf.rightPadding])
// .nice(d3.time.monday);
var categories = []
@@ -188,7 +184,6 @@ module.exports.draw = function (text, id) {
return d.task
})
.attr('font-size', conf.fontSize)
// .attr('font-family',conf.fontFamily)
.attr('x', function (d) {
var startX = timeScale(d.startTime)
var endX = timeScale(d.endTime)
@@ -208,7 +203,6 @@ module.exports.draw = function (text, id) {
.attr('y', function (d, i) {
return i * theGap + (conf.barHeight / 2) + (conf.fontSize / 2 - 2) + theTopPad
})
// .attr('text-anchor', 'middle')
.attr('text-height', theBarHeight)
.attr('class', function (d) {
var startX = timeScale(d.startTime)
@@ -279,7 +273,6 @@ module.exports.draw = function (text, id) {
}],
// Day within a week (not monday)
['%a %d', function (d) {
// return d.getDay() ==1;
return d.getDay() && d.getDate() !== 1
}],
// within a month
@@ -346,7 +339,6 @@ module.exports.draw = function (text, id) {
if (i > 0) {
for (var j = 0; j < i; j++) {
prevGap += numOccurances[i - 1][1]
// log.debug(prevGap);
return d[1] * theGap / 2 + prevGap * theGap + theTopPad
}
} else {

View File

@@ -25,12 +25,12 @@ function getId () {
function isfastforwardable (currentCommit, otherCommit) {
log.debug('Entering isfastforwardable:', currentCommit.id, otherCommit.id)
while (currentCommit.seq <= otherCommit.seq && currentCommit !== otherCommit) {
// only if other branch has more commits
// only if other branch has more commits
if (otherCommit.parent == null) break
if (Array.isArray(otherCommit.parent)) {
log.debug('In merge commit:', otherCommit.parent)
return isfastforwardable(currentCommit, commits[otherCommit.parent[0]]) ||
isfastforwardable(currentCommit, commits[otherCommit.parent[1]])
isfastforwardable(currentCommit, commits[otherCommit.parent[1]])
} else {
otherCommit = commits[otherCommit.parent]
}
@@ -66,10 +66,12 @@ exports.getOptions = function () {
}
exports.commit = function (msg) {
var commit = { id: getId(),
var commit = {
id: getId(),
message: msg,
seq: seq++,
parent: head == null ? null : head.id}
parent: head == null ? null : head.id
}
head = commit
commits[commit.id] = commit
branches[curBranch] = commit.id
@@ -92,7 +94,7 @@ exports.merge = function (otherBranch) {
branches[curBranch] = branches[otherBranch]
head = commits[branches[curBranch]]
} else {
// create merge commit
// create merge commit
var commit = {
id: getId(),
message: 'merged branch ' + otherBranch + ' into ' + curBranch,
@@ -141,7 +143,6 @@ function upsert (arr, key, newval) {
} else {
arr.push(newval)
}
// console.log(arr);
}
function prettyPrintCommitHistory (commitArr) {
@@ -160,11 +161,9 @@ function prettyPrintCommitHistory (commitArr) {
})
log.debug(label.join(' '))
if (Array.isArray(commit.parent)) {
// console.log("here", commit.parent);
var newCommit = commits[commit.parent[0]]
upsert(commitArr, commit, newCommit)
commitArr.push(commits[commit.parent[1]])
// console.log("shoudl have 2", commitArr);
} else if (commit.parent == null) {
return
} else {
@@ -191,9 +190,8 @@ exports.clear = function () {
exports.getBranchesAsObjArray = function () {
var branchArr = _.map(branches, function (v, k) {
return {'name': k, 'commit': commits[v]}
return { 'name': k, 'commit': commits[v] }
})
// return _.orderBy(branchArr, [function(b) { return b.commit.seq}], ['desc']);
return branchArr
}

View File

@@ -11,11 +11,10 @@ describe('when parsing a gitGraph', function () {
})
it('should handle a gitGraph defintion', function () {
var str = 'gitGraph:\n' +
'commit\n'
'commit\n'
parser.parse(str)
var commits = parser.yy.getCommits()
// console.log(commits);
expect(Object.keys(commits).length).toBe(1)
expect(parser.yy.getCurrentBranch()).toBe('master')
@@ -25,13 +24,12 @@ describe('when parsing a gitGraph', function () {
it('should handle a gitGraph defintion with empty options', function () {
var str = 'gitGraph:\n' +
'options\n' +
'end\n' +
'commit\n'
'options\n' +
'end\n' +
'commit\n'
parser.parse(str)
var commits = parser.yy.getCommits()
// console.log(commits);
expect(parser.yy.getOptions()).toEqual({})
expect(Object.keys(commits).length).toBe(1)
@@ -42,15 +40,13 @@ describe('when parsing a gitGraph', function () {
it('should handle a gitGraph defintion with valid options', function () {
var str = 'gitGraph:\n' +
'options\n' +
'{"key": "value"}\n' +
'end\n' +
'commit\n'
'options\n' +
'{"key": "value"}\n' +
'end\n' +
'commit\n'
parser.parse(str)
var commits = parser.yy.getCommits()
// console.log(commits);
// console.log('options object', parser.yy.getOptions());
expect(parser.yy.getOptions()['key']).toBe('value')
expect(Object.keys(commits).length).toBe(1)
expect(parser.yy.getCurrentBranch()).toBe('master')
@@ -60,14 +56,13 @@ describe('when parsing a gitGraph', function () {
it('should not fail on a gitGraph with malformed json', function () {
var str = 'gitGraph:\n' +
'options\n' +
'{"key": "value"\n' +
'end\n' +
'commit\n'
'options\n' +
'{"key": "value"\n' +
'end\n' +
'commit\n'
parser.parse(str)
var commits = parser.yy.getCommits()
// console.log(commits);
expect(Object.keys(commits).length).toBe(1)
expect(parser.yy.getCurrentBranch()).toBe('master')
expect(parser.yy.getDirection()).toBe('LR')
@@ -76,11 +71,10 @@ describe('when parsing a gitGraph', function () {
it('should handle set direction', function () {
var str = 'gitGraph BT:\n' +
'commit\n'
'commit\n'
parser.parse(str)
var commits = parser.yy.getCommits()
// console.log(commits);
expect(Object.keys(commits).length).toBe(1)
expect(parser.yy.getCurrentBranch()).toBe('master')
@@ -90,8 +84,8 @@ describe('when parsing a gitGraph', function () {
it('should checkout a branch', function () {
var str = 'gitGraph:\n' +
'branch new\n' +
'checkout new\n'
'branch new\n' +
'checkout new\n'
parser.parse(str)
var commits = parser.yy.getCommits()
@@ -102,10 +96,10 @@ describe('when parsing a gitGraph', function () {
it('should add commits to checked out branch', function () {
var str = 'gitGraph:\n' +
'branch new\n' +
'checkout new\n' +
'commit\n' +
'commit\n'
'branch new\n' +
'checkout new\n' +
'commit\n' +
'commit\n'
parser.parse(str)
var commits = parser.yy.getCommits()
@@ -118,11 +112,10 @@ describe('when parsing a gitGraph', function () {
})
it('should handle commit with args', function () {
var str = 'gitGraph:\n' +
'commit "a commit"\n'
'commit "a commit"\n'
parser.parse(str)
var commits = parser.yy.getCommits()
// console.log(commits);
expect(Object.keys(commits).length).toBe(1)
var key = Object.keys(commits)[0]
@@ -132,12 +125,12 @@ describe('when parsing a gitGraph', function () {
it('it should reset a branch', function () {
var str = 'gitGraph:\n' +
'commit\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'reset master\n'
'commit\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'reset master\n'
parser.parse(str)
@@ -150,12 +143,12 @@ describe('when parsing a gitGraph', function () {
it('reset can take an argument', function () {
var str = 'gitGraph:\n' +
'commit\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'reset master^\n'
'commit\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'reset master^\n'
parser.parse(str)
@@ -168,18 +161,17 @@ describe('when parsing a gitGraph', function () {
it('it should handle fast forwardable merges', function () {
var str = 'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
'merge newbranch\n'
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
'merge newbranch\n'
parser.parse(str)
var commits = parser.yy.getCommits()
// console.log(commits);
expect(Object.keys(commits).length).toBe(3)
expect(parser.yy.getCurrentBranch()).toBe('master')
expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])
@@ -188,17 +180,16 @@ describe('when parsing a gitGraph', function () {
it('it should handle cases when merge is a noop', function () {
var str = 'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'merge master\n'
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'merge master\n'
parser.parse(str)
var commits = parser.yy.getCommits()
// console.log(commits);
expect(Object.keys(commits).length).toBe(3)
expect(parser.yy.getCurrentBranch()).toBe('newbranch')
expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master'])
@@ -207,19 +198,18 @@ describe('when parsing a gitGraph', function () {
it('it should handle merge with 2 parents', function () {
var str = 'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
'commit\n' +
'merge newbranch\n'
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
'commit\n' +
'merge newbranch\n'
parser.parse(str)
var commits = parser.yy.getCommits()
// console.log(commits);
expect(Object.keys(commits).length).toBe(5)
expect(parser.yy.getCurrentBranch()).toBe('master')
expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master'])
@@ -228,22 +218,21 @@ describe('when parsing a gitGraph', function () {
it('it should handle ff merge when history walk has two parents (merge commit)', function () {
var str = 'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
'commit\n' +
'merge newbranch\n' +
'commit\n' +
'checkout newbranch\n' +
'merge master\n'
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
'commit\n' +
'merge newbranch\n' +
'commit\n' +
'checkout newbranch\n' +
'merge master\n'
parser.parse(str)
var commits = parser.yy.getCommits()
// console.log(commits);
expect(Object.keys(commits).length).toBe(6)
expect(parser.yy.getCurrentBranch()).toBe('newbranch')
expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])

View File

@@ -32,43 +32,43 @@ exports.setConf = function (c) {
function svgCreateDefs (svg) {
svg
.append('defs')
.append('g')
.attr('id', 'def-commit')
.append('circle')
.attr('r', config.nodeRadius)
.attr('cx', 0)
.attr('cy', 0)
.append('defs')
.append('g')
.attr('id', 'def-commit')
.append('circle')
.attr('r', config.nodeRadius)
.attr('cx', 0)
.attr('cy', 0)
svg.select('#def-commit')
.append('foreignObject')
.attr('width', config.nodeLabel.width)
.attr('height', config.nodeLabel.height)
.attr('x', config.nodeLabel.x)
.attr('y', config.nodeLabel.y)
.attr('class', 'node-label')
.attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility')
.append('xhtml:p')
.html('')
.append('foreignObject')
.attr('width', config.nodeLabel.width)
.attr('height', config.nodeLabel.height)
.attr('x', config.nodeLabel.x)
.attr('y', config.nodeLabel.y)
.attr('class', 'node-label')
.attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility')
.append('xhtml:p')
.html('')
}
function svgDrawLine (svg, points, colorIdx, interpolate) {
interpolate = interpolate || 'basis'
var color = config.branchColors[colorIdx % config.branchColors.length]
var lineGen = d3.svg.line()
.x(function (d) {
return Math.round(d.x)
})
.y(function (d) {
return Math.round(d.y)
})
.interpolate(interpolate)
.x(function (d) {
return Math.round(d.x)
})
.y(function (d) {
return Math.round(d.y)
})
.interpolate(interpolate)
svg
.append('svg:path')
.attr('d', lineGen(points))
.style('stroke', color)
.style('stroke-width', config.lineStrokeWidth)
.style('fill', 'none')
.append('svg:path')
.attr('d', lineGen(points))
.style('stroke', color)
.style('stroke-width', config.lineStrokeWidth)
.style('fill', 'none')
}
// Pass in the element and its pre-transform coords
function getElementCoords (element, coords) {
@@ -76,7 +76,6 @@ function getElementCoords (element, coords) {
var ctm = element.node().getCTM()
var xn = ctm.e + coords.x * ctm.a
var yn = ctm.f + coords.y * ctm.d
// log.debug(ctm, coords);
return {
left: xn,
top: yn,
@@ -89,20 +88,19 @@ function svgDrawLineForCommits (svg, fromId, toId, direction, color) {
log.debug('svgDrawLineForCommits: ', fromId, toId)
var fromBbox = getElementCoords(svg.select('#node-' + fromId + ' circle'))
var toBbox = getElementCoords(svg.select('#node-' + toId + ' circle'))
// log.debug('svgDrawLineForCommits: ', fromBbox, toBbox);
switch (direction) {
case 'LR':
// (toBbox)
// +--------
// + (fromBbox)
// (toBbox)
// +--------
// + (fromBbox)
if (fromBbox.left - toBbox.left > config.nodeSpacing) {
var lineStart = { x: fromBbox.left - config.nodeSpacing, y: toBbox.top + toBbox.height / 2 }
var lineEnd = { x: toBbox.left + toBbox.width, y: toBbox.top + toBbox.height / 2 }
svgDrawLine(svg, [lineStart, lineEnd], color, 'linear')
svgDrawLine(svg, [
{x: fromBbox.left, y: fromBbox.top + fromBbox.height / 2},
{x: fromBbox.left - config.nodeSpacing / 2, y: fromBbox.top + fromBbox.height / 2},
{x: fromBbox.left - config.nodeSpacing / 2, y: lineStart.y},
{ x: fromBbox.left, y: fromBbox.top + fromBbox.height / 2 },
{ x: fromBbox.left - config.nodeSpacing / 2, y: fromBbox.top + fromBbox.height / 2 },
{ x: fromBbox.left - config.nodeSpacing / 2, y: lineStart.y },
lineStart], color)
} else {
svgDrawLine(svg, [{
@@ -121,18 +119,18 @@ function svgDrawLineForCommits (svg, fromId, toId, direction, color) {
}
break
case 'BT':
// + (fromBbox)
// |
// |
// + (toBbox)
// + (fromBbox)
// |
// |
// + (toBbox)
if (toBbox.top - fromBbox.top > config.nodeSpacing) {
lineStart = { x: toBbox.left + toBbox.width / 2, y: fromBbox.top + fromBbox.height + config.nodeSpacing }
lineEnd = { x: toBbox.left + toBbox.width / 2, y: toBbox.top }
svgDrawLine(svg, [lineStart, lineEnd], color, 'linear')
svgDrawLine(svg, [
{x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height},
{x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height + config.nodeSpacing / 2},
{x: toBbox.left + toBbox.width / 2, y: lineStart.y - config.nodeSpacing / 2},
{ x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height },
{ x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height + config.nodeSpacing / 2 },
{ x: toBbox.left + toBbox.width / 2, y: lineStart.y - config.nodeSpacing / 2 },
lineStart], color)
} else {
svgDrawLine(svg, [{
@@ -168,44 +166,44 @@ function renderCommitHistory (svg, commitid, branches, direction) {
return
}
svg
.append(function () {
return cloneNode(svg, '#def-commit')
})
.attr('class', 'commit')
.attr('id', function () {
return 'node-' + commit.id
})
.attr('transform', function () {
switch (direction) {
case 'LR':
return 'translate(' + (commit.seq * config.nodeSpacing + config.leftMargin) + ', ' +
(branchNum * config.branchOffset) + ')'
case 'BT':
return 'translate(' + (branchNum * config.branchOffset + config.leftMargin) + ', ' +
((numCommits - commit.seq) * config.nodeSpacing) + ')'
}
})
.attr('fill', config.nodeFillColor)
.attr('stroke', config.nodeStrokeColor)
.attr('stroke-width', config.nodeStrokeWidth)
.append(function () {
return cloneNode(svg, '#def-commit')
})
.attr('class', 'commit')
.attr('id', function () {
return 'node-' + commit.id
})
.attr('transform', function () {
switch (direction) {
case 'LR':
return 'translate(' + (commit.seq * config.nodeSpacing + config.leftMargin) + ', ' +
(branchNum * config.branchOffset) + ')'
case 'BT':
return 'translate(' + (branchNum * config.branchOffset + config.leftMargin) + ', ' +
((numCommits - commit.seq) * config.nodeSpacing) + ')'
}
})
.attr('fill', config.nodeFillColor)
.attr('stroke', config.nodeStrokeColor)
.attr('stroke-width', config.nodeStrokeWidth)
var branch = _.find(branches, ['commit', commit])
if (branch) {
log.debug('found branch ', branch.name)
svg.select('#node-' + commit.id + ' p')
.append('xhtml:span')
.attr('class', 'branch-label')
.text(branch.name + ', ')
.append('xhtml:span')
.attr('class', 'branch-label')
.text(branch.name + ', ')
}
svg.select('#node-' + commit.id + ' p')
.append('xhtml:span')
.attr('class', 'commit-id')
.text(commit.id)
.append('xhtml:span')
.attr('class', 'commit-id')
.text(commit.id)
if (commit.message !== '' && direction === 'BT') {
svg.select('#node-' + commit.id + ' p')
.append('xhtml:span')
.attr('class', 'commit-msg')
.text(', ' + commit.message)
.append('xhtml:span')
.attr('class', 'commit-msg')
.text(', ' + commit.message)
}
commitid = commit.parent
} while (commitid && allCommitsDict[commitid])
@@ -244,7 +242,7 @@ exports.draw = function (txt, id, ver) {
parser.yy = db
log.debug('in gitgraph renderer', txt, id, ver)
// Parse the graph definition
// Parse the graph definition
parser.parse(txt + '\n')
config = _.extend(config, apiConfig, db.getOptions())
@@ -269,10 +267,6 @@ exports.draw = function (txt, id, ver) {
if (direction === 'BT') return Object.keys(allCommitsDict).length * config.nodeSpacing
return (branches.length + 1) * config.branchOffset
})
// svg.attr('width', function() {
// if (direction === 'LR') return Object.keys(allCommitsDict).length * config.nodeSpacing + config.leftMargin;
// return (branches.length + 1) * config.branchOffset;
// });
} catch (e) {
log.error('Error while rendering gitgraph')
log.error(e.message)

View File

@@ -9,26 +9,23 @@ var Logger = require('../../logger')
var log = Logger.Log
exports.addActor = function (id, name, description) {
// Don't allow description nulling
// Don't allow description nulling
var old = actors[id]
if (old && name === old.name && description == null) return
// Don't allow null descriptions, either
// Don't allow null descriptions, either
if (description == null) description = name
actors[id] = {name: name, description: description}
actors[id] = { name: name, description: description }
}
exports.addMessage = function (idFrom, idTo, message, answer) {
messages.push({from: idFrom, to: idTo, message: message, answer: answer})
messages.push({ from: idFrom, to: idTo, message: message, answer: answer })
}
/**
*
*/
exports.addSignal = function (idFrom, idTo, message, messageType) {
log.debug('Adding message from=' + idFrom + ' to=' + idTo + ' message=' + message + ' type=' + messageType)
messages.push({from: idFrom, to: idTo, message: message, type: messageType})
messages.push({ from: idFrom, to: idTo, message: message, type: messageType })
}
exports.getMessages = function () {
@@ -87,13 +84,13 @@ exports.PLACEMENT = {
}
exports.addNote = function (actor, placement, message) {
var note = {actor: actor, placement: placement, message: message}
var note = { actor: actor, placement: placement, message: message }
// Coerce actor into a [to, from, ...] array
// Coerce actor into a [to, from, ...] array
var actors = [].concat(actor, actor)
notes.push(note)
messages.push({from: actors[0], to: actors[1], message: message, type: exports.LINETYPE.NOTE, placement: placement})
messages.push({ from: actors[0], to: actors[1], message: message, type: exports.LINETYPE.NOTE, placement: placement })
}
exports.setTitle = function (titleText) {
@@ -110,7 +107,6 @@ exports.apply = function (param) {
exports.apply(item)
})
} else {
// console.info(param);
switch (param.type) {
case 'addActor':
exports.addActor(param.actor, param.actor, param.description)
@@ -128,25 +124,19 @@ exports.apply = function (param) {
exports.addSignal(param.from, param.to, param.msg, param.signalType)
break
case 'loopStart':
// log.debug('Loop text: ',param.loopText);
exports.addSignal(undefined, undefined, param.loopText, param.signalType)
// yy.addSignal(undefined, undefined, $2, yy.LINETYPE.LOOP_START);
break
case 'loopEnd':
exports.addSignal(undefined, undefined, undefined, param.signalType)
break
case 'optStart':
// log.debug('Loop text: ',param.loopText);
exports.addSignal(undefined, undefined, param.optText, param.signalType)
// yy.addSignal(undefined, undefined, $2, yy.LINETYPE.LOOP_START);
break
case 'optEnd':
exports.addSignal(undefined, undefined, undefined, param.signalType)
break
case 'altStart':
// log.debug('Loop text: ',param.loopText);
exports.addSignal(undefined, undefined, param.altText, param.signalType)
// yy.addSignal(undefined, undefined, $2, yy.LINETYPE.LOOP_START);
break
case 'else':
exports.addSignal(undefined, undefined, param.altText, param.signalType)

View File

@@ -3,8 +3,6 @@ var proxyquire = require('proxyquire')
/**
* Created by knut on 14-11-18.
*/
// var proxyquire = require('proxyquire');
// var log = require('../../logger').create();
var sq = require('./parser/sequenceDiagram').parser
var NewD3
@@ -17,13 +15,8 @@ var d3 = {
return new NewD3()
}
}
// var sd = proxyquire('./sequenceRenderer', { './d3': d3 });
var sd = proxyquire('./sequenceRenderer', { '../../d3': d3 })
//
//
// var sd = require('./sequenceRenderer');
function addConf (conf, key, value) {
if (value !== undefined) {
conf[key] = value
@@ -36,17 +29,12 @@ describe('when parsing a sequenceDiagram', function () {
beforeEach(function () {
sq.yy = require('./sequenceDb')
sq.yy.clear()
// parseError = function(err, hash) {
// log.debug('Syntax error:' + err);
// log.debug(hash);
// };
// sq.yy.parseError = parseError;
})
it('it should handle a sequenceDiagram defintion', function () {
str = 'sequenceDiagram\n' +
'Alice->Bob:Hello Bob, how are you?\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!'
'Alice->Bob:Hello Bob, how are you?\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -61,10 +49,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle a sequenceDiagram definition with a title', function () {
str = 'sequenceDiagram\n' +
'title: Diagram Title\n' +
'Alice->Bob:Hello Bob, how are you?\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!'
'title: Diagram Title\n' +
'Alice->Bob:Hello Bob, how are you?\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -81,8 +69,8 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should space in actor names', function () {
str = 'sequenceDiagram\n' +
'Alice->Bob:Hello Bob, how are - you?\n' +
'Bob-->Alice: I am good thanks!'
'Alice->Bob:Hello Bob, how are - you?\n' +
'Bob-->Alice: I am good thanks!'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -97,10 +85,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should alias participants', function () {
str = 'sequenceDiagram\n' +
'participant A as Alice\n' +
'participant B as Bob\n' +
'A->B:Hello Bob, how are you?\n' +
'B-->A: I am good thanks!'
'participant A as Alice\n' +
'participant B as Bob\n' +
'A->B:Hello Bob, how are you?\n' +
'B-->A: I am good thanks!'
sq.parse(str)
@@ -116,7 +104,7 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle in async messages', function () {
var str = 'sequenceDiagram\n' +
'Alice-xBob:Hello Bob, how are you?'
'Alice-xBob:Hello Bob, how are you?'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -130,7 +118,7 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle in async dotted messages', function () {
var str = 'sequenceDiagram\n' +
'Alice--xBob:Hello Bob, how are you?'
'Alice--xBob:Hello Bob, how are you?'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -144,7 +132,7 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle in arrow messages', function () {
var str = 'sequenceDiagram\n' +
'Alice->>Bob:Hello Bob, how are you?'
'Alice->>Bob:Hello Bob, how are you?'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -158,7 +146,7 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle in arrow messages', function () {
var str = 'sequenceDiagram\n' +
'Alice-->>Bob:Hello Bob, how are you?'
'Alice-->>Bob:Hello Bob, how are you?'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -172,10 +160,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle actor activation', function () {
var str = 'sequenceDiagram\n' +
'Alice-->>Bob:Hello Bob, how are you?\n' +
'activate Bob\n' +
'Bob-->>Alice:Hello Alice, I\'m fine and you?\n' +
'deactivate Bob'
'Alice-->>Bob:Hello Bob, how are you?\n' +
'activate Bob\n' +
'Bob-->>Alice:Hello Alice, I\'m fine and you?\n' +
'deactivate Bob'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -194,8 +182,8 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle actor one line notation activation', function () {
var str = 'sequenceDiagram\n' +
'Alice-->>+Bob:Hello Bob, how are you?\n' +
'Bob-->>- Alice:Hello Alice, I\'m fine and you?'
'Alice-->>+Bob:Hello Bob, how are you?\n' +
'Bob-->>- Alice:Hello Alice, I\'m fine and you?'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -218,10 +206,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle stacked activations', function () {
var str = 'sequenceDiagram\n' +
'Alice-->>+Bob:Hello Bob, how are you?\n' +
'Bob-->>+Carol:Carol, let me introduce Alice?\n' +
'Bob-->>- Alice:Hello Alice, please meet Carol?\n' +
'Carol->>- Bob:Oh Bob, I\'m so happy to be here!'
'Alice-->>+Bob:Hello Bob, how are you?\n' +
'Bob-->>+Carol:Carol, let me introduce Alice?\n' +
'Bob-->>- Alice:Hello Alice, please meet Carol?\n' +
'Carol->>- Bob:Oh Bob, I\'m so happy to be here!'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -250,10 +238,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle comments in a sequenceDiagram', function () {
str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!'
'Alice->Bob: Hello Bob, how are you?\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -268,10 +256,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle new lines in a sequenceDiagram', function () {
str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!\n'
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!\n'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -286,9 +274,9 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle semicolons', function () {
str = 'sequenceDiagram;' +
'Alice->Bob: Hello Bob, how are you?;' +
'Note right of Bob: Bob thinks;' +
'Bob-->Alice: I am good thanks!;'
'Alice->Bob: Hello Bob, how are you?;' +
'Note right of Bob: Bob thinks;' +
'Bob-->Alice: I am good thanks!;'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -303,10 +291,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle one leading space in lines in a sequenceDiagram', function () {
str = 'sequenceDiagram\n' +
' Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!'
' Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -321,10 +309,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle several leading spaces in lines in a sequenceDiagram', function () {
str = 'sequenceDiagram\n' +
' Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!'
' Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'Bob-->Alice: I am good thanks!'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -339,16 +327,16 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle several leading spaces in lines in a sequenceDiagram', function () {
str = 'sequenceDiagram\n' +
'participant Alice\n' +
'participant Bob\n' +
'Alice->John: Hello John, how are you?\n' +
' loop Healthcheck\n' +
'John->John: Fight against hypochondria\n' +
' end\n' +
'Note right of John: Rational thoughts<br/>prevail...\n' +
' John-->Alice: Great!\n' +
' John->Bob: How about you?\n' +
'Bob-->John: Jolly good!'
'participant Alice\n' +
'participant Bob\n' +
'Alice->John: Hello John, how are you?\n' +
' loop Healthcheck\n' +
'John->John: Fight against hypochondria\n' +
' end\n' +
'Note right of John: Rational thoughts<br/>prevail...\n' +
' John-->Alice: Great!\n' +
' John->Bob: How about you?\n' +
'Bob-->John: Jolly good!'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -363,8 +351,8 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle notes over a single actor', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note over Bob: Bob thinks\n'
'Alice->Bob: Hello Bob, how are you?\n' +
'Note over Bob: Bob thinks\n'
sq.parse(str)
@@ -374,9 +362,9 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle notes over multiple actors', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note over Alice,Bob: confusion\n' +
'Note over Bob,Alice: resolution\n'
'Alice->Bob: Hello Bob, how are you?\n' +
'Note over Alice,Bob: confusion\n' +
'Note over Bob,Alice: resolution\n'
sq.parse(str)
@@ -388,12 +376,12 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle loop statements a sequenceDiagram', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'loop Multiple happy responses\n\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'loop Multiple happy responses\n\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -408,12 +396,12 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle opt statements a sequenceDiagram', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'opt Perhaps a happy response\n\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'opt Perhaps a happy response\n\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -428,14 +416,14 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle alt statements a sequenceDiagram', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'alt isWell\n\n' +
'Bob-->Alice: I am good thanks!\n' +
'else isSick\n' +
'Bob-->Alice: Feel sick...\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n\n' +
'%% Comment\n' +
'Note right of Bob: Bob thinks\n' +
'alt isWell\n\n' +
'Bob-->Alice: I am good thanks!\n' +
'else isSick\n' +
'Bob-->Alice: Feel sick...\n' +
'end'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -451,16 +439,16 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle par statements a sequenceDiagram', function () {
var str = 'sequenceDiagram\n' +
'par Parallel one\n' +
'Alice->>Bob: Hello Bob, how are you?\n' +
'Bob-->>Alice: I am good thanks!\n' +
'and Parallel two\n' +
'Alice->>Bob: Are you OK?\n' +
'Bob-->>Alice: Fine!\n' +
'and Parallel three\n' +
'Alice->>Bob: What do you think about it?\n' +
'Bob-->>Alice: It\'s good!\n' +
'end'
'par Parallel one\n' +
'Alice->>Bob: Hello Bob, how are you?\n' +
'Bob-->>Alice: I am good thanks!\n' +
'and Parallel two\n' +
'Alice->>Bob: Are you OK?\n' +
'Bob-->>Alice: Fine!\n' +
'and Parallel three\n' +
'Alice->>Bob: What do you think about it?\n' +
'Bob-->>Alice: It\'s good!\n' +
'end'
sq.parse(str)
var actors = sq.yy.getActors()
@@ -477,7 +465,7 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle special characters in signals', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: -:<>,;# comment'
'Alice->Bob: -:<>,;# comment'
sq.parse(str)
@@ -486,8 +474,8 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle special characters in notes', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note right of Bob: -:<>,;# comment'
'Alice->Bob: Hello Bob, how are you?\n' +
'Note right of Bob: -:<>,;# comment'
sq.parse(str)
@@ -496,10 +484,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle special characters in loop', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'loop -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n' +
'loop -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
sq.parse(str)
@@ -508,10 +496,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle special characters in opt', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'opt -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n' +
'opt -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
sq.parse(str)
@@ -520,12 +508,12 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle special characters in alt', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'alt -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'else ,<>:-#; comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n' +
'alt -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'else ,<>:-#; comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
sq.parse(str)
@@ -535,12 +523,12 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle special characters in par', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'par -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'and ,<>:-#; comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n' +
'par -:<>,;# comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'and ,<>:-#; comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
sq.parse(str)
@@ -550,10 +538,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle no-label loop', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'loop\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n' +
'loop\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
sq.parse(str)
@@ -563,10 +551,10 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle no-label opt', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'opt # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n' +
'opt # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
sq.parse(str)
@@ -576,12 +564,12 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle no-label alt', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'alt;' +
'Bob-->Alice: I am good thanks!\n' +
'else # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n' +
'alt;' +
'Bob-->Alice: I am good thanks!\n' +
'else # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
sq.parse(str)
@@ -593,12 +581,12 @@ describe('when parsing a sequenceDiagram', function () {
})
it('it should handle no-label par', function () {
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'par;' +
'Bob-->Alice: I am good thanks!\n' +
'and # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n' +
'par;' +
'Bob-->Alice: I am good thanks!\n' +
'and # comment\n' +
'Bob-->Alice: I am good thanks!\n' +
'end'
sq.parse(str)
@@ -615,18 +603,12 @@ describe('when checking the bounds in a sequenceDiagram', function () {
beforeEach(function () {
sq.yy = require('./sequenceDb')
sq.yy.clear()
// parseError = function(err, hash) {
// log.debug('Syntax error:' + err);
// log.debug(hash);
// };
// sq.yy.parseError = parseError;
conf = {
diagramMarginX: 50,
diagramMarginY: 10,
actorMargin: 50,
width: 150,
// Height of actor boxes
// Height of actor boxes
height: 65,
boxMargin: 10,
messageMargin: 40,
@@ -686,7 +668,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
expect(loop.stopx).toBe(150 + conf.boxMargin)
expect(loop.stopy).toBe(200 + conf.boxMargin)
// Check bounds of first loop
// Check bounds of first loop
var bounds = sd.bounds.getBounds()
expect(bounds.startx).toBe(25)
@@ -703,7 +685,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
sd.bounds.newLoop()
sd.bounds.insert(200, 200, 300, 300)
// Check bounds of first loop
// Check bounds of first loop
var loop = sd.bounds.endLoop()
expect(loop.startx).toBe(200 - conf.boxMargin)
@@ -711,7 +693,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
expect(loop.stopx).toBe(300 + conf.boxMargin)
expect(loop.stopy).toBe(300 + conf.boxMargin)
// Check bounds of second loop
// Check bounds of second loop
loop = sd.bounds.endLoop()
expect(loop.startx).toBe(200 - 2 * conf.boxMargin)
@@ -719,7 +701,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
expect(loop.stopx).toBe(300 + 2 * conf.boxMargin)
expect(loop.stopy).toBe(300 + 2 * conf.boxMargin)
// Check bounds of first loop
// Check bounds of first loop
var bounds = sd.bounds.getBounds()
expect(bounds.startx).toBe(100)
@@ -742,7 +724,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
expect(loop.stopx).toBe(300 + conf.boxMargin)
expect(loop.stopy).toBe(300 + conf.boxMargin)
// Check bounds after the loop
// Check bounds after the loop
var bounds = sd.bounds.getBounds()
expect(bounds.startx).toBe(loop.startx)
@@ -758,21 +740,8 @@ describe('when rendering a sequenceDiagram', function () {
sq.yy = require('./sequenceDb')
sq.yy.clear()
// var MockBrowser = require('mock-browser').mocks.MockBrowser;
// var mock = new MockBrowser();
delete global.mermaid_config
// and in the run-code inside some object
// global.document = mock.getDocument();
// global.window = mock.getWindow();
// parseError = function(err, hash) {
// log.debug('Syntax error:' + err);
// log.debug(hash);
// };
// sq.yy.parseError = parseError;
NewD3 = function () {
var o = {
append: function () {
@@ -808,7 +777,7 @@ describe('when rendering a sequenceDiagram', function () {
diagramMarginY: 10,
actorMargin: 50,
width: 150,
// Height of actor boxes
// Height of actor boxes
height: 65,
boxMargin: 10,
messageMargin: 40,
@@ -816,18 +785,13 @@ describe('when rendering a sequenceDiagram', function () {
noteMargin: 25
}
sd.setConf(conf)
// document.body.innerHTML = '<div id="tst"></div>';
// document.body.innerHTML = '<svg height="30" width="200"><text id="tst" x="0" y="15" fill="red">I love SVG!</text></svg>';
// document.body.innerHTML = '<svg height="30" width="200"><text x="0" y="15" fill="red"><tspan x="46" id="tst">Alice thinks</tspan></text></svg>';
// console.log('document.body');
// console.log(document.querySelector('#tst').getBBox());
});
['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) {
it('it should handle one actor, when textPlacement is ' + textPlacement, function () {
sd.setConf(addConf(conf, 'textPlacement', textPlacement))
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'participant Alice'
'participant Alice'
sq.parse(str)
sd.draw(str, 'tst')
@@ -842,8 +806,8 @@ describe('when rendering a sequenceDiagram', function () {
it('it should handle one actor and a centered note', function () {
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'participant Alice\n' +
'Note over Alice: Alice thinks\n'
'participant Alice\n' +
'Note over Alice: Alice thinks\n'
sq.parse(str)
sd.draw(str, 'tst')
@@ -852,14 +816,14 @@ describe('when rendering a sequenceDiagram', function () {
expect(bounds.startx).toBe(0)
expect(bounds.starty).toBe(0)
expect(bounds.stopx).toBe(conf.width)
// 10 comes from mock of text height
// 10 comes from mock of text height
expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
})
it('it should handle one actor and a note to the left', function () {
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'participant Alice\n' +
'Note left of Alice: Alice thinks'
'participant Alice\n' +
'Note left of Alice: Alice thinks'
sq.parse(str)
sd.draw(str, 'tst')
@@ -868,14 +832,14 @@ describe('when rendering a sequenceDiagram', function () {
expect(bounds.startx).toBe(-(conf.width / 2) - (conf.actorMargin / 2))
expect(bounds.starty).toBe(0)
expect(bounds.stopx).toBe(conf.width)
// 10 comes from mock of text height
// 10 comes from mock of text height
expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
})
it('it should handle one actor and a note to the right', function () {
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'participant Alice\n' +
'Note right of Alice: Alice thinks'
'participant Alice\n' +
'Note right of Alice: Alice thinks'
sq.parse(str)
sd.draw(str, 'tst')
@@ -884,13 +848,13 @@ describe('when rendering a sequenceDiagram', function () {
expect(bounds.startx).toBe(0)
expect(bounds.starty).toBe(0)
expect(bounds.stopx).toBe((conf.width / 2) + (conf.actorMargin / 2) + conf.width)
// 10 comes from mock of text height
// 10 comes from mock of text height
expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
})
it('it should handle two actors', function () {
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?'
'Alice->Bob: Hello Bob, how are you?'
sq.parse(str)
sd.draw(str, 'tst')
@@ -904,9 +868,9 @@ describe('when rendering a sequenceDiagram', function () {
it('it should handle two actors and two centered shared notes', function () {
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note over Alice,Bob: Looks\n' +
'Note over Bob,Alice: Looks back\n'
'Alice->Bob: Hello Bob, how are you?\n' +
'Note over Alice,Bob: Looks\n' +
'Note over Bob,Alice: Looks back\n'
sq.parse(str)
sd.draw(str, 'tst')
@@ -920,8 +884,8 @@ describe('when rendering a sequenceDiagram', function () {
it('it should draw two actors and two messages', function () {
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Bob->Alice: Fine!'
'Alice->Bob: Hello Bob, how are you?\n' +
'Bob->Alice: Fine!'
sq.parse(str)
sd.draw(str, 'tst')
@@ -935,9 +899,9 @@ describe('when rendering a sequenceDiagram', function () {
it('it should draw two actors notes to the right', function () {
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note right of Bob: Bob thinks\n' +
'Bob->Alice: Fine!'
'Alice->Bob: Hello Bob, how are you?\n' +
'Note right of Bob: Bob thinks\n' +
'Bob->Alice: Fine!'
sq.parse(str)
sd.draw(str, 'tst')
@@ -954,9 +918,9 @@ describe('when rendering a sequenceDiagram', function () {
it('it should draw two actors notes to the left', function () {
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'Note left of Alice: Bob thinks\n' +
'Bob->Alice: Fine!'
'Alice->Bob: Hello Bob, how are you?\n' +
'Note left of Alice: Bob thinks\n' +
'Bob->Alice: Fine!'
sq.parse(str)
sd.draw(str, 'tst')
@@ -971,10 +935,10 @@ describe('when rendering a sequenceDiagram', function () {
it('it should draw two loops', function () {
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'Alice->Bob: Hello Bob, how are you?\n' +
'loop Cheers\n' +
'Bob->Alice: Fine!\n' +
'end'
'Alice->Bob: Hello Bob, how are you?\n' +
'loop Cheers\n' +
'Bob->Alice: Fine!\n' +
'end'
sq.parse(str)
sd.draw(str, 'tst')
@@ -992,11 +956,6 @@ describe('when rendering a sequenceDiagram with actor mirror activated', functio
beforeEach(function () {
sq.yy = require('./sequenceDb')
sq.yy.clear()
// parseError = function(err, hash) {
// log.debug('Syntax error:' + err);
// log.debug(hash);
// };
// sq.yy.parseError = parseError;
NewD3 = function () {
var o = {
@@ -1033,15 +992,15 @@ describe('when rendering a sequenceDiagram with actor mirror activated', functio
diagramMarginY: 10,
actorMargin: 50,
width: 150,
// Height of actor boxes
// Height of actor boxes
height: 65,
boxMargin: 10,
messageMargin: 40,
boxTextMargin: 15,
noteMargin: 25,
mirrorActors: true,
// Depending on css styling this might need adjustment
// Prolongs the edge of the diagram downwards
// Depending on css styling this might need adjustment
// Prolongs the edge of the diagram downwards
bottomMarginAdj: 1
}
sd.setConf(conf)
@@ -1051,7 +1010,7 @@ describe('when rendering a sequenceDiagram with actor mirror activated', functio
sd.setConf(addConf(conf, 'textPlacement', textPlacement))
sd.bounds.init()
var str = 'sequenceDiagram\n' +
'participant Alice'
'participant Alice'
sq.parse(str)
sd.draw(str, 'tst')

View File

@@ -13,28 +13,28 @@ var conf = {
diagramMarginX: 50,
diagramMarginY: 30,
// Margin between actors
// Margin between actors
actorMargin: 50,
// Width of actor boxes
// Width of actor boxes
width: 150,
// Height of actor boxes
// Height of actor boxes
height: 65,
// Margin around loop boxes
// Margin around loop boxes
boxMargin: 10,
boxTextMargin: 5,
noteMargin: 10,
// Space between messages
// Space between messages
messageMargin: 35,
// mirror actors under diagram
// mirror actors under diagram
mirrorActors: false,
// Depending on css styling this might need adjustment
// Prolongs the edge of the diagram downwards
// Depending on css styling this might need adjustment
// Prolongs the edge of the diagram downwards
bottomMarginAdj: 1,
// width of activation box
// width of activation box
activationWidth: 10,
// text placement as: tspan | fo | old only text as before
// text placement as: tspan | fo | old only text as before
textPlacement: 'tspan'
}
@@ -73,7 +73,7 @@ exports.bounds = {
function updateFn (type) {
return function updateItemBounds (item) {
cnt++
// The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems
// The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems
var n = _self.sequenceItems.length - cnt + 1
_self.updateVal(item, 'starty', starty - n * conf.boxMargin, Math.min)
@@ -114,7 +114,8 @@ exports.bounds = {
var actorRect = sq.yy.getActors()[message.from.actor]
var stackedSize = actorActivations(message.from.actor).length
var x = actorRect.x + conf.width / 2 + (stackedSize - 1) * conf.activationWidth / 2
this.activations.push({startx: x,
this.activations.push({
startx: x,
starty: this.verticalPos + 2,
stopx: x + conf.activationWidth,
stopy: undefined,
@@ -123,15 +124,15 @@ exports.bounds = {
})
},
endActivation: function (message) {
// find most recent activation for given actor
// find most recent activation for given actor
var lastActorActivationIdx = this.activations
.map(function (activation) { return activation.actor })
.lastIndexOf(message.from.actor)
.map(function (activation) { return activation.actor })
.lastIndexOf(message.from.actor)
var activation = this.activations.splice(lastActorActivationIdx, 1)[0]
return activation
},
newLoop: function (title) {
this.sequenceItems.push({startx: undefined, starty: this.verticalPos, stopx: undefined, stopy: undefined, title: title})
this.sequenceItems.push({ startx: undefined, starty: this.verticalPos, stopx: undefined, stopy: undefined, title: title })
},
endLoop: function () {
var loop = this.sequenceItems.pop()
@@ -214,28 +215,26 @@ var drawMessage = function (elem, startx, stopx, verticalPos, msg) {
var txtCenter = startx + (stopx - startx) / 2
var textElem = g.append('text') // text label for the x axis
.attr('x', txtCenter)
.attr('y', verticalPos - 7)
.style('text-anchor', 'middle')
.attr('class', 'messageText')
.text(msg.message)
.attr('x', txtCenter)
.attr('y', verticalPos - 7)
.style('text-anchor', 'middle')
.attr('class', 'messageText')
.text(msg.message)
var textWidth
if (typeof textElem[0][0].getBBox !== 'undefined') {
textWidth = textElem[0][0].getBBox().width
} else {
// textWidth = getBBox(textElem).width; //.getComputedTextLength()
textWidth = textElem[0][0].getBoundingClientRect()
// textWidth = textElem[0][0].getComputedTextLength();
}
var line
if (startx === stopx) {
line = g.append('path')
.attr('d', 'M ' + startx + ',' + verticalPos + ' C ' + (startx + 60) + ',' + (verticalPos - 10) + ' ' + (startx + 60) + ',' +
(verticalPos + 30) + ' ' + startx + ',' + (verticalPos + 20))
.attr('d', 'M ' + startx + ',' + verticalPos + ' C ' + (startx + 60) + ',' + (verticalPos - 10) + ' ' + (startx + 60) + ',' +
(verticalPos + 30) + ' ' + startx + ',' + (verticalPos + 20))
exports.bounds.bumpVerticalPos(30)
var dx = Math.max(textWidth / 2, 100)
@@ -248,8 +247,8 @@ var drawMessage = function (elem, startx, stopx, verticalPos, msg) {
line.attr('y2', verticalPos)
exports.bounds.insert(startx, exports.bounds.getVerticalPos() - 10, stopx, exports.bounds.getVerticalPos())
}
// Make an SVG Container
// Draw the line
// Make an SVG Container
// Draw the line
if (msg.type === sq.yy.LINETYPE.DOTTED || msg.type === sq.yy.LINETYPE.DOTTED_CROSS || msg.type === sq.yy.LINETYPE.DOTTED_OPEN) {
line.style('stroke-dasharray', ('3, 3'))
line.attr('class', 'messageLine1')
@@ -278,23 +277,22 @@ var drawMessage = function (elem, startx, stopx, verticalPos, msg) {
module.exports.drawActors = function (diagram, actors, actorKeys, verticalPos) {
var i
// Draw the actors
// Draw the actors
for (i = 0; i < actorKeys.length; i++) {
var key = actorKeys[i]
// Add some rendering data to the object
// Add some rendering data to the object
actors[key].x = i * conf.actorMargin + i * conf.width
actors[key].y = verticalPos
actors[key].width = conf.diagramMarginX
actors[key].height = conf.diagramMarginY
// Draw the box with the attached line
// Draw the box with the attached line
svgDraw.drawActor(diagram, actors[key].x, verticalPos, actors[key].description, conf)
exports.bounds.insert(actors[key].x, verticalPos, actors[key].x + conf.width, conf.height)
}
// Add a margin between the actor boxes and the first arrow
// exports.bounds.bumpVerticalPos(conf.height+conf.messageMargin);
// Add a margin between the actor boxes and the first arrow
exports.bounds.bumpVerticalPos(conf.height)
}
@@ -313,7 +311,7 @@ var actorActivations = function (actor) {
}
var actorFlowVerticaBounds = function (actor) {
// handle multiple stacked activations for same actor
// handle multiple stacked activations for same actor
var actors = sq.yy.getActors()
var activations = actorActivations(actor)
@@ -338,14 +336,14 @@ module.exports.draw = function (text, id) {
var stopx
var forceWidth
// Fetch data from the parsing
// Fetch data from the parsing
var actors = sq.yy.getActors()
var actorKeys = sq.yy.getActorKeys()
var messages = sq.yy.getMessages()
var title = sq.yy.getTitle()
module.exports.drawActors(diagram, actors, actorKeys, 0)
// The arrow head definition is attached to the svg once
// The arrow head definition is attached to the svg once
svgDraw.insertArrowHead(diagram)
svgDraw.insertArrowCrossHead(diagram)
@@ -362,7 +360,7 @@ module.exports.draw = function (text, id) {
// var lastMsg
// Draw the messages/signals
// Draw the messages/signals
messages.forEach(function (msg) {
var loopData
@@ -378,13 +376,13 @@ module.exports.draw = function (text, id) {
} else if (msg.placement === sq.yy.PLACEMENT.LEFTOF) {
drawNote(diagram, startx - (conf.width + conf.actorMargin) / 2, exports.bounds.getVerticalPos(), msg)
} else if (msg.to === msg.from) {
// Single-actor over
// Single-actor over
drawNote(diagram, startx, exports.bounds.getVerticalPos(), msg)
} else {
// Multi-actor over
// Multi-actor over
forceWidth = Math.abs(startx - stopx) + conf.actorMargin
drawNote(diagram, (startx + stopx + conf.width - forceWidth) / 2, exports.bounds.getVerticalPos(), msg,
forceWidth)
forceWidth)
}
break
case sq.yy.LINETYPE.ACTIVE_START:
@@ -468,14 +466,14 @@ module.exports.draw = function (text, id) {
})
if (conf.mirrorActors) {
// Draw actors below diagram
// Draw actors below diagram
exports.bounds.bumpVerticalPos(conf.boxMargin * 2)
module.exports.drawActors(diagram, actors, actorKeys, exports.bounds.getVerticalPos())
}
var box = exports.bounds.getBounds()
// Adjust line height of actor lines now that the height of the diagram is known
// Adjust line height of actor lines now that the height of the diagram is known
log.debug('For line height fix Querying: #' + id + ' .actor-line')
var actorLines = d3.selectAll('#' + id + ' .actor-line')
actorLines.attr('y2', box.stopy)
@@ -490,9 +488,9 @@ module.exports.draw = function (text, id) {
if (title) {
diagram.append('text')
.text(title)
.attr('x', ((box.stopx - box.startx) / 2) - (2 * conf.diagramMarginX))
.attr('y', -25)
.text(title)
.attr('x', ((box.stopx - box.startx) / 2) - (2 * conf.diagramMarginX))
.attr('y', -25)
}
if (conf.useMaxWidth) {

View File

@@ -1,7 +1,6 @@
/**
* Created by knut on 14-12-20.
*/
// var log = require('../../logger').create();
exports.drawRect = function (elem, rectData) {
var rectElem = elem.append('rect')
rectElem.attr('x', rectData.x)
@@ -21,7 +20,7 @@ exports.drawRect = function (elem, rectData) {
}
exports.drawText = function (elem, textData, width) {
// Remove and ignore br:s
// Remove and ignore br:s
var nText = textData.text.replace(/<br\/?>/ig, ' ')
var textElem = elem.append('text')
@@ -32,17 +31,9 @@ exports.drawText = function (elem, textData, width) {
if (typeof textData.class !== 'undefined') {
textElem.attr('class', textData.class)
}
/* textData.text.split(/<br\/?>/ig).forEach(function(rowText){
var span = textElem.append('tspan');
span.attr('x', textData.x +textData.textMargin);
span.attr('dy', textData.dy);
span.text(rowText);
}); */
var span = textElem.append('tspan')
// span.attr('x', textData.x);
span.attr('x', textData.x + textData.textMargin * 2)
// span.attr('dy', textData.dy);
span.attr('fill', textData.fill)
span.text(nText)
if (typeof textElem.textwrap !== 'undefined') {
@@ -60,10 +51,10 @@ exports.drawText = function (elem, textData, width) {
exports.drawLabel = function (elem, txtObject) {
function genPoints (x, y, width, height, cut) {
return x + ',' + y + ' ' +
(x + width) + ',' + y + ' ' +
(x + width) + ',' + (y + height - cut) + ' ' +
(x + width - cut * 1.2) + ',' + (y + height) + ' ' +
(x) + ',' + (y + height)
(x + width) + ',' + y + ' ' +
(x + width) + ',' + (y + height - cut) + ' ' +
(x + width - cut * 1.2) + ',' + (y + height) + ' ' +
(x) + ',' + (y + height)
}
var polygon = elem.append('polygon')
polygon.attr('points', genPoints(txtObject.x, txtObject.y, 50, 20, 7))
@@ -73,8 +64,6 @@ exports.drawLabel = function (elem, txtObject) {
txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin
txtObject.fill = 'white'
exports.drawText(elem, txtObject)
// return textElem;
}
var actorCnt = -1
/**
@@ -89,14 +78,14 @@ exports.drawActor = function (elem, left, verticalPos, description, conf) {
if (verticalPos === 0) {
actorCnt++
g.append('line')
.attr('id', 'actor' + actorCnt)
.attr('x1', center)
.attr('y1', 5)
.attr('x2', center)
.attr('y2', 2000)
.attr('class', 'actor-line')
.attr('stroke-width', '0.5px')
.attr('stroke', '#999')
.attr('id', 'actor' + actorCnt)
.attr('x1', center)
.attr('y1', 5)
.attr('x2', center)
.attr('y2', 2000)
.attr('class', 'actor-line')
.attr('stroke-width', '0.5px')
.attr('stroke', '#999')
}
var rect = exports.getNoteRect()
@@ -111,7 +100,7 @@ exports.drawActor = function (elem, left, verticalPos, description, conf) {
exports.drawRect(g, rect)
_drawTextCandidateFunc(conf)(description, g,
rect.x, rect.y, rect.width, rect.height, {'class': 'actor'})
rect.x, rect.y, rect.width, rect.height, { 'class': 'actor' })
}
exports.anchorElement = function (elem) {
@@ -144,13 +133,13 @@ exports.drawLoop = function (elem, bounds, labelText, conf) {
var g = elem.append('g')
var drawLoopLine = function (startx, starty, stopx, stopy) {
return g.append('line')
.attr('x1', startx)
.attr('y1', starty)
.attr('x2', stopx)
.attr('y2', stopy)
.attr('stroke-width', 2)
.attr('stroke', '#526e52')
.attr('class', 'loopLine')
.attr('x1', startx)
.attr('y1', starty)
.attr('x2', stopx)
.attr('y2', stopy)
.attr('stroke-width', 2)
.attr('stroke', '#526e52')
.attr('class', 'loopLine')
}
drawLoopLine(bounds.startx, bounds.starty, bounds.stopx, bounds.starty)
drawLoopLine(bounds.stopx, bounds.starty, bounds.stopx, bounds.stopy)
@@ -197,14 +186,14 @@ exports.drawLoop = function (elem, bounds, labelText, conf) {
*/
exports.insertArrowHead = function (elem) {
elem.append('defs').append('marker')
.attr('id', 'arrowhead')
.attr('refX', 5)
.attr('refY', 2)
.attr('markerWidth', 6)
.attr('markerHeight', 4)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 0,0 V 4 L6,2 Z') // this is actual shape for arrowhead
.attr('id', 'arrowhead')
.attr('refX', 5)
.attr('refY', 2)
.attr('markerWidth', 6)
.attr('markerHeight', 4)
.attr('orient', 'auto')
.append('path')
.attr('d', 'M 0,0 V 4 L6,2 Z') // this is actual shape for arrowhead
}
/**
* Setup arrow head and define the marker. The result is appended to the svg.
@@ -212,29 +201,29 @@ exports.insertArrowHead = function (elem) {
exports.insertArrowCrossHead = function (elem) {
var defs = elem.append('defs')
var marker = defs.append('marker')
.attr('id', 'crosshead')
.attr('markerWidth', 15)
.attr('markerHeight', 8)
.attr('orient', 'auto')
.attr('refX', 16)
.attr('refY', 4)
.attr('id', 'crosshead')
.attr('markerWidth', 15)
.attr('markerHeight', 8)
.attr('orient', 'auto')
.attr('refX', 16)
.attr('refY', 4)
// The arrow
// The arrow
marker.append('path')
.attr('fill', 'black')
.attr('stroke', '#000000')
.style('stroke-dasharray', ('0, 0'))
.attr('stroke-width', '1px')
.attr('d', 'M 9,2 V 6 L16,4 Z')
.attr('fill', 'black')
.attr('stroke', '#000000')
.style('stroke-dasharray', ('0, 0'))
.attr('stroke-width', '1px')
.attr('d', 'M 9,2 V 6 L16,4 Z')
// The cross
// The cross
marker.append('path')
.attr('fill', 'none')
.attr('stroke', '#000000')
.style('stroke-dasharray', ('0, 0'))
.attr('stroke-width', '1px')
.attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7')
// this is actual shape for arrowhead
.attr('fill', 'none')
.attr('stroke', '#000000')
.style('stroke-dasharray', ('0, 0'))
.attr('stroke-width', '1px')
.attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7')
// this is actual shape for arrowhead
}
exports.getTextObj = function () {
@@ -271,32 +260,32 @@ exports.getNoteRect = function () {
var _drawTextCandidateFunc = (function () {
function byText (content, g, x, y, width, height, textAttrs) {
var text = g.append('text')
.attr('x', x + width / 2).attr('y', y + height / 2 + 5)
.style('text-anchor', 'middle')
.text(content)
.attr('x', x + width / 2).attr('y', y + height / 2 + 5)
.style('text-anchor', 'middle')
.text(content)
_setTextAttrs(text, textAttrs)
}
function byTspan (content, g, x, y, width, height, textAttrs) {
var text = g.append('text')
.attr('x', x + width / 2).attr('y', y)
.style('text-anchor', 'middle')
.attr('x', x + width / 2).attr('y', y)
.style('text-anchor', 'middle')
text.append('tspan')
.attr('x', x + width / 2).attr('dy', '0')
.text(content)
.attr('x', x + width / 2).attr('dy', '0')
.text(content)
if (typeof (text.textwrap) !== 'undefined') {
text.textwrap({ // d3textwrap
x: x + width / 2, y: y, width: width, height: height
}, 0)
// vertical aligment after d3textwrap expans tspan to multiple tspans
// vertical aligment after d3textwrap expans tspan to multiple tspans
var tspans = text.selectAll('tspan')
if (tspans.length > 0 && tspans[0].length > 0) {
tspans = tspans[0]
// set y of <text> to the mid y of the first line
// set y of <text> to the mid y of the first line
text.attr('y', y + (height / 2.0 - text[0][0].getBBox().height * (1 - 1.0 / tspans.length) / 2.0))
.attr('dominant-baseline', 'central')
.attr('alignment-baseline', 'central')
.attr('dominant-baseline', 'central')
.attr('alignment-baseline', 'central')
}
}
_setTextAttrs(text, textAttrs)
@@ -305,15 +294,15 @@ var _drawTextCandidateFunc = (function () {
function byFo (content, g, x, y, width, height, textAttrs) {
var s = g.append('switch')
var f = s.append('foreignObject')
.attr('x', x).attr('y', y)
.attr('width', width).attr('height', height)
.attr('x', x).attr('y', y)
.attr('width', width).attr('height', height)
var text = f.append('div').style('display', 'table')
.style('height', '100%').style('width', '100%')
.style('height', '100%').style('width', '100%')
text.append('div').style('display', 'table-cell')
.style('text-align', 'center').style('vertical-align', 'middle')
.text(content)
.style('text-align', 'center').style('vertical-align', 'middle')
.text(content)
byTspan(content, s, x, y, width, height, textAttrs)
_setTextAttrs(text, textAttrs)
@@ -329,6 +318,6 @@ var _drawTextCandidateFunc = (function () {
return function (conf) {
return conf.textPlacement === 'fo' ? byFo : (
conf.textPlacement === 'old' ? byText : byTspan)
conf.textPlacement === 'old' ? byText : byTspan)
}
})()