mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-11-04 12:54:08 +01:00 
			
		
		
		
	Refactor code
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -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');
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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'])
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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')
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
  }
 | 
			
		||||
})()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user