From 000ffbb6224f14a1a8c0242c0fea73cd7bbc87a6 Mon Sep 17 00:00:00 2001 From: knsv Date: Sat, 20 Dec 2014 08:40:48 +0100 Subject: [PATCH] Modifications of sequence diagram rendering + tests --- src/diagrams/flowchart/parser/flow.spec.js | 14 +- .../sequenceDiagram/sequenceDiagram.spec.js | 239 +++++++++++++++++- .../sequenceDiagram/sequenceRenderer.js | 219 +++++++++------- src/diagrams/sequenceDiagram/svgDraw.js | 31 +++ 4 files changed, 392 insertions(+), 111 deletions(-) create mode 100644 src/diagrams/sequenceDiagram/svgDraw.js diff --git a/src/diagrams/flowchart/parser/flow.spec.js b/src/diagrams/flowchart/parser/flow.spec.js index a1b957d1d..e199b9322 100644 --- a/src/diagrams/flowchart/parser/flow.spec.js +++ b/src/diagrams/flowchart/parser/flow.spec.js @@ -10,7 +10,7 @@ describe('when parsing ',function(){ flow.parser.yy = require('../graphDb'); flow.parser.yy.clear(); /*flow.parser.parse.parseError= function parseError(str, hash) { - console.log(str); + console.logconsole.log(str); }*/ }); @@ -308,6 +308,18 @@ describe('when parsing ',function(){ expect(edges[0].type).toBe('arrow_cross'); expect(edges[0].text).toBe('text including URL space'); + }); + + it('should handle text on edges with space dir',function(){ + var res = flow.parser.parse('graph TD;A--x|text including R TD space|B;'); + + var vert = flow.parser.yy.getVertices(); + var edges = flow.parser.yy.getEdges(); + + + expect(edges[0].type).toBe('arrow_cross'); + expect(edges[0].text).toBe('text including R TD space'); + }); it('should handle text on edges with graph keyword',function(){ var res = flow.parser.parse('graph TD;A--x|text including graph space|B;'); diff --git a/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js b/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js index d92983549..5a72298b0 100644 --- a/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js +++ b/src/diagrams/sequenceDiagram/sequenceDiagram.spec.js @@ -99,6 +99,177 @@ describe('when parsing a sequenceDiagram',function() { }); }); + +describe('when checking the bounds in a sequenceDiagram',function() { + var parseError, _d3, conf; + beforeEach(function () { + sq.yy = require('./sequenceDb'); + sq.yy.clear(); + parseError = function(err, hash) { + console.log('Syntax error:' + err); + console.log(hash); + }; + sq.yy.parseError = parseError; + + + conf = { + diagramMarginX:50, + diagramMarginY:10, + actorMargin:50, + width:150, + // Height of actor boxes + height:65, + boxMargin:10, + messageMargin:40, + noteMargin:25 + }; + sd.setConf(conf); + }); + it('it should handle a simple bound call', function () { + sd.bounds.init(); + + sd.bounds.insert(100,100,200,200); + + var bounds = sd.bounds.getBounds(); + expect(bounds.startx).toBe(100); + expect(bounds.starty).toBe(100); + expect(bounds.stopx ).toBe(200); + expect(bounds.stopy ).toBe(200); + + }); + it('it should handle an expanding bound', function () { + sd.bounds.init(); + + sd.bounds.insert(100,100,200,200); + sd.bounds.insert(25,50,300,400); + + var bounds = sd.bounds.getBounds(); + expect(bounds.startx).toBe(25); + expect(bounds.starty).toBe(50); + expect(bounds.stopx ).toBe(300); + expect(bounds.stopy ).toBe(400); + + }); + it('it should handle inserts within the bound without changing the outer bounds', function () { + sd.bounds.init(); + + sd.bounds.insert(100,100,200,200); + sd.bounds.insert(25,50,300,400); + sd.bounds.insert(125,150,150,200); + + var bounds = sd.bounds.getBounds(); + expect(bounds.startx).toBe(25); + expect(bounds.starty).toBe(50); + expect(bounds.stopx ).toBe(300); + expect(bounds.stopy ).toBe(400); + + }); + + it('it should handle a loop without expanding the area', function () { + sd.bounds.init(); + + sd.bounds.insert(25,50,300,400); + sd.bounds.newLoop(); + sd.bounds.insert(125,150,150,200); + + var loop = sd.bounds.endLoop(); + + expect(loop.startx).toBe(125-conf.boxMargin); + expect(loop.starty).toBe(150-conf.boxMargin); + expect(loop.stopx ).toBe(150+conf.boxMargin); + expect(loop.stopy ).toBe(200+conf.boxMargin); + + // Check bounds of first loop + var bounds = sd.bounds.getBounds(); + + expect(bounds.startx).toBe(25); + expect(bounds.starty).toBe(50); + expect(bounds.stopx ).toBe(300); + expect(bounds.stopy ).toBe(400); + }); + + + it('it should handle multiple loops withtout expanding the bounds', function () { + sd.bounds.init(); + + sd.bounds.insert(100,100,1000,1000); + sd.bounds.newLoop(); + sd.bounds.newLoop(); + sd.bounds.insert(200,200,300,300); + + // Check bounds of first loop + var loop = sd.bounds.endLoop(); + + expect(loop.startx).toBe(200-conf.boxMargin); + expect(loop.starty).toBe(200-conf.boxMargin); + expect(loop.stopx ).toBe(300+conf.boxMargin); + expect(loop.stopy ).toBe(300+conf.boxMargin); + + // Check bounds of second loop + loop = sd.bounds.endLoop(); + + expect(loop.startx).toBe(200-2*conf.boxMargin); + expect(loop.starty).toBe(200-2*conf.boxMargin); + expect(loop.stopx ).toBe(300+2*conf.boxMargin); + expect(loop.stopy ).toBe(300+2*conf.boxMargin); + + // Check bounds of first loop + var bounds = sd.bounds.getBounds(); + + expect(bounds.startx).toBe(100); + expect(bounds.starty).toBe(100); + expect(bounds.stopx ).toBe(1000); + expect(bounds.stopy ).toBe(1000); + }); + + it('it should handle a loop that expands the area', function () { + sd.bounds.init(); + + sd.bounds.insert(100,100,200,200); + sd.bounds.newLoop(); + sd.bounds.insert(50,50,300,300); + + var loop = sd.bounds.endLoop(); + + expect(loop.startx).toBe(50 - conf.boxMargin); + expect(loop.starty).toBe(50 - conf.boxMargin); + expect(loop.stopx ).toBe(300 + conf.boxMargin); + expect(loop.stopy ).toBe(300 + conf.boxMargin); + + // Check bounds after the loop + var bounds = sd.bounds.getBounds(); + + expect(bounds.startx).toBe(loop.startx); + expect(bounds.starty).toBe(loop.starty); + expect(bounds.stopx ).toBe(loop.stopx); + expect(bounds.stopy ).toBe(loop.stopy); + }); + + xit('it should handle multiple loops that expands the area', function () { + sd.bounds.init(); + + sd.bounds.insert(100,100,200,200); + sd.bounds.newLoop(); + sd.bounds.newLoop(); + sd.bounds.insert(50,50,300,300); + + var loop = sd.bounds.endLoop(); + loop = sd.bounds.endLoop(); + + expect(loop.startx).toBe(50 - 2 * conf.boxMargin); + expect(loop.starty).toBe(50 - 2 * conf.boxMargin); + expect(loop.stopx ).toBe(300 + 2 * conf.boxMargin); + expect(loop.stopy ).toBe(300 + 2 * conf.boxMargin); + + // Check bounds after the loop + var bounds = sd.bounds.getBounds(); + + expect(bounds.startx).toBe(loop.startx); + expect(bounds.starty).toBe(loop.starty); + expect(bounds.stopx ).toBe(loop.stopx); + expect(bounds.stopy ).toBe(loop.stopy); + }); +}); describe('when rendering a sequenceDiagram',function() { var parseError, _d3, conf; beforeEach(function () { @@ -151,19 +322,65 @@ describe('when rendering a sequenceDiagram',function() { conf = { diagramMarginX:50, diagramMarginY:10, - margin:50, + actorMargin:50, width:150, // Height of actor boxes height:65, - loopMargin:10, + boxMargin:10, messageMargin:40, noteMargin:25 }; sd.setConf(conf); }); + it('it should handle one actor', function () { + sd.bounds.init(); + var str = 'sequenceDiagram\n' + + 'participant Alice\n'; + + sq.parse(str); + sd.draw(str,'tst'); + + var bounds = sd.bounds.getBounds(); + expect(bounds.startx).toBe(0); + expect(bounds.starty).toBe(0); + expect(bounds.stopx ).toBe( conf.width); + expect(bounds.stopy ).toBe(conf.height); + + }); + it('it should handle one actor and a note', function () { + sd.bounds.init(); + var str = 'sequenceDiagram\n' + + 'participant Alice\n' + + 'Note left of Alice: Alice thinks\n'; + + sq.parse(str); + sd.draw(str,'tst'); + + var bounds = sd.bounds.getBounds(); + 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 + expect(bounds.stopy ).toBe( conf.height + conf.boxMargin + 2*conf.noteMargin +10); + }); + iit('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\n'; + + sq.parse(str); + sd.draw(str,'tst'); + + var bounds = sd.bounds.getBounds(); + 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 + expect(bounds.stopy ).toBe( conf.height + conf.boxMargin + 2*conf.noteMargin +10); + }); it('it should handle two actors', function () { sd.bounds.init(); - sd.bounds.newLoop(0); var str = 'sequenceDiagram\n' + 'Alice->Bob: Hello Bob, how are you?\n'; @@ -173,14 +390,13 @@ describe('when rendering a sequenceDiagram',function() { var bounds = sd.bounds.getBounds(); expect(bounds.startx).toBe(conf.diagramMarginX); expect(bounds.starty).toBe(conf.diagramMarginY); - expect(bounds.stopx ).toBe(conf.diagramMarginX + conf.width*2 + conf.margin); + expect(bounds.stopx ).toBe(conf.diagramMarginX + conf.width*2 + conf.actorMargin); expect(bounds.stopy ).toBe(conf.diagramMarginY + conf.messageMargin + conf.height); }); it('it should draw two actors and two messages', function () { sd.bounds.init(); - sd.bounds.newLoop(0); var str = 'sequenceDiagram\n' + 'Alice->Bob: Hello Bob, how are you?\n'+ 'Bob->Alice: Fine!\n'; @@ -191,7 +407,7 @@ describe('when rendering a sequenceDiagram',function() { var bounds = sd.bounds.getBounds(); expect(bounds.startx).toBe(conf.diagramMarginX); expect(bounds.starty).toBe(conf.diagramMarginY); - expect(bounds.stopx ).toBe(conf.diagramMarginX + conf.width*2 + conf.margin); + expect(bounds.stopx ).toBe(conf.diagramMarginX + conf.width*2 + conf.actorMargin); expect(bounds.stopy ).toBe(conf.diagramMarginY + 2*conf.messageMargin + conf.height); }); @@ -199,7 +415,6 @@ describe('when rendering a sequenceDiagram',function() { it('it should draw two actors notes to the right', function () { sd.bounds.init(); - sd.bounds.newLoop(0); var str = 'sequenceDiagram\n' + 'Alice->Bob: Hello Bob, how are you?\n'+ 'Note right of Bob: Bob thinks\n' + @@ -220,7 +435,6 @@ describe('when rendering a sequenceDiagram',function() { }); it('it should draw two actors notes to the left', function () { sd.bounds.init(); - sd.bounds.newLoop(0); var str = 'sequenceDiagram\n' + 'Alice->Bob: Hello Bob, how are you?\n'+ 'Note left of Alice: Bob thinks\n' + @@ -230,17 +444,16 @@ describe('when rendering a sequenceDiagram',function() { sd.draw(str,'tst'); var bounds = sd.bounds.getBounds(); - expect(bounds.startx).toBe(conf.diagramMarginX - conf.width + conf.margin); + expect(bounds.startx).toBe(conf.diagramMarginX - conf.width + conf.actorMargin); expect(bounds.starty).toBe(conf.diagramMarginY); - expect(bounds.stopx ).toBe(conf.diagramMarginX + conf.width*2 + conf.margin); + expect(bounds.stopx ).toBe(conf.diagramMarginX + conf.width*2 + conf.actorMargin); expect(bounds.stopy ).toBe(conf.diagramMarginY + 3*conf.messageMargin + conf.height); }); it('it should draw two loops', function () { sd.bounds.init(); - sd.bounds.newLoop(0); var str = 'sequenceDiagram\n' + 'Alice->Bob: Hello Bob, how are you?\n'+ 'loop Cheers\n' + @@ -254,8 +467,8 @@ describe('when rendering a sequenceDiagram',function() { expect(bounds.startx).toBe(conf.diagramMarginX); expect(bounds.starty).toBe(conf.diagramMarginY); - expect(bounds.stopx ).toBe(conf.diagramMarginX + conf.width*2 + conf.margin); - expect(bounds.stopy ).toBe(conf.diagramMarginY + 3*conf.messageMargin + conf.height); + expect(bounds.stopx ).toBe(conf.diagramMarginX + conf.width*2 + conf.actorMargin); + expect(bounds.stopy ).toBe(conf.diagramMarginY + 3*conf.messageMargin + conf.height + conf.boxMargin); }); }); \ No newline at end of file diff --git a/src/diagrams/sequenceDiagram/sequenceRenderer.js b/src/diagrams/sequenceDiagram/sequenceRenderer.js index 0d67b8bf6..11a954e85 100644 --- a/src/diagrams/sequenceDiagram/sequenceRenderer.js +++ b/src/diagrams/sequenceDiagram/sequenceRenderer.js @@ -5,6 +5,24 @@ var sq = require('./parser/sequenceDiagram').parser; sq.yy = require('./sequenceDb'); +var svgDraw = require('./svgDraw'); +var conf = { + + diagramMarginX:50, + diagramMarginY:10, + // Margin between actors + actorMargin:50, + // Width of actor moxes + width:150, + // Height of actor boxes + height:65, + // Margin around loop boxes + boxMargin:10, + + noteMargin:10, + // Space between messages + messageMargin:40 +}; exports.bounds = { data:{ @@ -26,56 +44,53 @@ exports.bounds = { }; this.verticalPos =0; }, - applyMin:function(minVal, margin){ - var minValue = minVal; - this.list.forEach(function(loop){ - if(typeof loop.startx === 'undefined'){ - loop.startx = minValue - margin; - }else{ - loop.startx = Math.min(minValue - margin,loop.startx); - } - minValue = loop.startx; - }); - return minValue; + updateVal : function (obj,key,val,fun){ + if(typeof obj[key] === 'undefined'){ + //console.log('Setting startx',startx); + obj[key] = val; + }else{ + obj[key] = fun(val,obj[key]); + } }, - applyMax:function(maxVal, margin){ - var maxValue = maxVal; + updateLoops:function(startx,starty,stopx,stopy){ + var _self = this; + var cnt = 0; this.list.forEach(function(loop){ - if(typeof loop.stopx === 'undefined'){ - loop.stopx = maxValue + margin; - }else{ - loop.stopx = Math.max(maxValue + margin,loop.stopx); - } - maxValue = loop.stopx; - }); + cnt++; + // The loop list is a stack so the biggest margins in the beginning of the list + var n = _self.list.length-cnt+1; - return maxValue; + _self.updateVal(loop, 'startx',startx - n*conf.boxMargin, Math.min); + _self.updateVal(loop, 'starty',starty - n*conf.boxMargin, Math.min); + _self.updateVal(loop, 'stopx' ,stopx + n*conf.boxMargin, Math.max); + _self.updateVal(loop, 'stopy' ,stopy + n*conf.boxMargin, Math.max); + + _self.updateVal(exports.bounds.data,'startx',startx - n*conf.boxMargin ,Math.min); + _self.updateVal(exports.bounds.data,'starty',starty - n*conf.boxMargin ,Math.min); + _self.updateVal(exports.bounds.data,'stopx' ,stopx + n*conf.boxMargin ,Math.max); + _self.updateVal(exports.bounds.data,'stopy' ,stopy + n*conf.boxMargin ,Math.max); + }); }, insert:function(startx,starty,stopx,stopy){ - var updateVal = function (key,val,fun){ - if(typeof exports.bounds.data[key] === 'undefined'){ - //console.log('Setting startx',startx); - exports.bounds.data[key] = val; - }else{ - exports.bounds.data[key] = fun(val,exports.bounds.data[key]); - } - }; - updateVal('startx',startx,Math.min); - updateVal('starty',starty,Math.min); - updateVal('stopx' ,stopx ,Math.max); - updateVal('stopy' ,stopy ,Math.max); - //updateLoops(); + this.updateVal(exports.bounds.data,'startx',startx,Math.min); + this.updateVal(exports.bounds.data,'starty',starty,Math.min); + this.updateVal(exports.bounds.data,'stopx' ,stopx ,Math.max); + this.updateVal(exports.bounds.data,'stopy' ,stopy ,Math.max); + + this.updateLoops(startx,starty,stopx,stopy); }, newLoop:function(){ - this.list.push({startx:undefined,starty:exports.bounds.getVerticalPos(),stopx:undefined,stopy:undefined}); + this.list.push({startx:undefined,starty:undefined,stopx:undefined,stopy:undefined}); }, endLoop:function(){ var loop = this.list.pop(); - loop.stopy = exports.bounds.getVerticalPos(); + //loop.stopy = exports.bounds.getVerticalPos(); + return loop; }, bumpVerticalPos:function(bump){ this.verticalPos = this.verticalPos + bump; + this.data.stopy = this.verticalPos; }, getVerticalPos:function(){ return this.verticalPos; @@ -91,11 +106,20 @@ exports.bounds = { * @param pos The position if the actor in the liost of actors * @param description The text in the box */ -var drawNote = function(elem, startX, verticalPos, msg){ +var drawNote = function(elem, startx, verticalPos, msg){ + var rect = svgDraw.getNoteRect(); + rect.x = startx; + rect.y = verticalPos; + rect.width = conf.width; + + //svgDraw.drawRect(elem, rect); + var g = elem.append("g"); + //svgDraw.drawRect(g, rect); + var rectElem = g.append("rect"); - rectElem.attr("x", startX + conf.noteMargin); - rectElem.attr("y", verticalPos - conf.noteMargin); + rectElem.attr("x", startx); + rectElem.attr("y", verticalPos); rectElem.attr("fill", '#EDF2AE'); rectElem.attr("stroke", '#666'); rectElem.attr("width", conf.width); @@ -104,27 +128,45 @@ var drawNote = function(elem, startX, verticalPos, msg){ rectElem.attr("ry", 0); var textElem = g.append("text"); - textElem.attr("x", startX + 10); - textElem.attr("y", verticalPos - 15); + textElem.attr("x", startx); + textElem.attr("y", verticalPos+conf.noteMargin); textElem.style("text-anchor", "start"); msg.message.split('
').forEach(function(rowText){ var span = textElem.append("tspan"); - span.attr("x", startX + 35 ); + span.attr("x", startx +conf.noteMargin); span.attr("dy", '1em'); span.text(rowText); }); var textHeight = textElem[0][0].getBBox().height; - exports.bounds.insert(startX + conf.noteMargin, verticalPos -conf.noteMargin, startX + conf.noteMargin + conf.width, verticalPos -conf.noteMargin + textHeight+20); + exports.bounds.insert(startx, verticalPos, startx + conf.width, verticalPos + 2*conf.noteMargin + textHeight); - rectElem.attr('height',textHeight+20); - - exports.bounds.verticalPos = verticalPos + textHeight - 10; - - return verticalPos + textHeight - 10; + rectElem.attr('height',textHeight+ 2*conf.noteMargin); }; +/** + * Draws an actor in the diagram with the attaced line + * @param center - The center of the the actor + * @param pos The position if the actor in the liost of actors + * @param description The text in the box + */ +exports.drawLoop = function(elem,bounds){ + var g = elem.append("g"); + var drawLoopLine = function(startx,starty,stopx,stopy){ + g.append("line") + .attr("x1", startx) + .attr("y1", starty) + .attr("x2", stopx ) + .attr("y2", stopy ) + .attr("stroke-width", 2) + .attr("stroke", "#339999"); + }; + drawLoopLine(bounds.startx, bounds.starty, bounds.stopx , bounds.starty); + drawLoopLine(bounds.stopx , bounds.starty, bounds.stopx , bounds.stopy ); + drawLoopLine(bounds.startx, bounds.stopy , bounds.stopx , bounds.stopy ); + drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy ); +}; /** * Setup arrow head and define the marker. The result is appended to the svg. @@ -209,19 +251,20 @@ var drawMessage = function(elem, startx, stopx, verticalPos, msg){ * @param pos The position if the actor in the liost of actors * @param description The text in the box */ -var drawActor = function(elem, center, pos, description,i){ +var drawActor = function(elem, left,description){ + var center = left + (conf.width/2); var g = elem.append("g"); g.append("line") .attr("x1", center) - .attr("y1", conf.diagramMarginY) + .attr("y1", 5) .attr("x2", center) .attr("y2", 2000) .attr("stroke-width", '0.5px') .attr("stroke", '#999'); g.append("rect") - .attr("x", conf.diagramMarginX + pos*conf.messageMargin +i*150) - .attr("y", conf.diagramMarginY) + .attr("x", left) + .attr("y", 0) .attr("fill", '#eaeaea') .attr("stroke", '#666') .attr("width", conf.width) @@ -229,13 +272,13 @@ var drawActor = function(elem, center, pos, description,i){ .attr("rx", 3) .attr("ry", 3); g.append("text") // text label for the x axis - .attr("x", conf.diagramMarginX + pos*conf.messageMargin +i*conf.width + 75) - .attr("y", conf.diagramMarginY+37.5) + .attr("x", center) + .attr("y", (conf.height/2)+5) .style("text-anchor", "middle") .text(description) ; - exports.bounds.insert(conf.diagramMarginX + pos*conf.margin +i*150, conf.diagramMarginY, conf.diagramMarginX + pos*conf.margin +i*150 + conf.width, conf.diagramMarginY + conf.height); + exports.bounds.insert(left, 0, left + conf.width, conf.height); }; module.exports.drawActors = function(diagram, actors, actorKeys){ @@ -245,41 +288,21 @@ module.exports.drawActors = function(diagram, actors, actorKeys){ var key = actorKeys[i]; // Add some rendering data to the object - actors[key].x = conf.diagramMarginX + i*conf.messageMargin +i*conf.width; - actors[key].y = conf.diagramMarginY; + actors[key].x = i*conf.messageMargin +i*conf.width; + actors[key].y = 0; actors[key].width = conf.diagramMarginY; actors[key].height = conf.diagramMarginY; - var center = actors[key].x + (conf.width/2); - - // Keep track of width for with setting on the svg - //maxX = Math.max(maxX,actors[key].x); - // Draw the box with the attached line - drawActor(diagram, center,i, actors[key].description, i); + drawActor(diagram, actors[key].x, actors[key].description); } // Add a margin between the actor boxes and the first arrow - exports.bounds.bumpVerticalPos(conf.diagramMarginY + conf.height); + //exports.bounds.bumpVerticalPos(conf.height+conf.messageMargin); + exports.bounds.bumpVerticalPos(conf.height); }; -var conf = { - diagramMarginX:50, - diagramMarginY:10, - // Margin between actors - margin:50, - // Width of actor moxes - width:150, - // Height of actor boxes - height:65, - // Margin around loop boxes - loopMargin:10, - - noteMargin:25, - // Space between messages - messageMargin:40 -}; module.exports.setConf = function(cnf){ conf = cnf; }; @@ -291,7 +314,7 @@ module.exports.setConf = function(cnf){ module.exports.draw = function (text, id) { sq.yy.clear(); sq.parse(text); - + exports.bounds.init(); var diagram = d3.select('#'+id); // Fetch data from the parsing @@ -299,8 +322,6 @@ module.exports.draw = function (text, id) { var actorKeys = sq.yy.getActorKeys(); var messages = sq.yy.getMessages(); - var i, maxX = 0, minX=0; - module.exports.drawActors(diagram, actors, actorKeys); // The arrow head definition is attached to the svg once @@ -309,21 +330,23 @@ module.exports.draw = function (text, id) { // Draw the messages/signals messages.forEach(function(msg){ - exports.bounds.bumpVerticalPos(conf.messageMargin); + var startx; var stopx; switch(msg.type){ case sq.yy.LINETYPE.NOTE: - startx = actors[msg.from].x + conf.width/2; - stopx = actors[msg.to].x + conf.width/2; + exports.bounds.bumpVerticalPos(conf.boxMargin); + startx = actors[msg.from].x; + stopx = actors[msg.to].x; if(msg.placement !== 0){ // Right of - drawNote(diagram, startx, exports.bounds.getVerticalPos(), msg); + console.log(exports.bounds.getVerticalPos()); + drawNote(diagram, startx + (conf.width + conf.actorMargin)/2, exports.bounds.getVerticalPos(), msg); }else{ // Left of - drawNote(diagram, startx - conf.width - conf.margin, exports.bounds.getVerticalPos(), msg); + drawNote(diagram, startx - (conf.width + conf.actorMargin)/2, exports.bounds.getVerticalPos(), msg); } break; case sq.yy.LINETYPE.LOOP_START: @@ -331,25 +354,27 @@ module.exports.draw = function (text, id) { exports.bounds.newLoop(); break; case sq.yy.LINETYPE.LOOP_END: - exports.bounds.endLoop(); + var loopData = exports.bounds.endLoop(); //var loopData = loopList.pop(); //loopData.stopy = exports.bounds.getVerticalPos(); - //drawLoop(loopData,10); + exports.drawLoop(diagram, loopData); break; default: + exports.bounds.bumpVerticalPos(conf.messageMargin); startx = actors[msg.from].x + conf.width/2; stopx = actors[msg.to].x + conf.width/2; drawMessage(diagram, startx, stopx, exports.bounds.getVerticalPos(), msg); - // Keep track of width for with setting on the svg - maxX = Math.max(maxX,startx + 176); - exports.bounds.applyMax(maxX,conf.loopMargin); } }); - // TODO fetch from bounds - diagram.attr("height", exports.bounds.getVerticalPos() + 40); - diagram.attr("width", maxX ); - diagram.attr("viewBox", minX + ' 0 '+maxX+ ' ' +(exports.bounds.getVerticalPos() + 40)); + var box = exports.bounds.getBounds(); + + var height = box.stopy-box.starty+2*conf.diagramMarginY; + var width = box.stopx-box.startx+2*conf.diagramMarginX; + + diagram.attr("height",height); + diagram.attr("width", width ); + diagram.attr("viewBox", (box.startx-conf.diagramMarginX) + ' -' +conf.diagramMarginY + ' ' + width + ' ' + height); }; diff --git a/src/diagrams/sequenceDiagram/svgDraw.js b/src/diagrams/sequenceDiagram/svgDraw.js new file mode 100644 index 000000000..f8ef05120 --- /dev/null +++ b/src/diagrams/sequenceDiagram/svgDraw.js @@ -0,0 +1,31 @@ +/** + * Created by knut on 14-12-20. + */ +exports.drawRect = function(elem , rectData){ + var g = elem.append("g"); + var rectElem = g.append("rect"); + rectElem.attr("x", rectData.x); + rectElem.attr("y", rectData.x); + rectElem.attr("fill", rectData.fill); + rectElem.attr("stroke", rectData.stroke); + rectElem.attr("width", rectData.width); + rectElem.attr("height", rectData.height); + rectElem.attr("rx", rectData.rx); + rectElem.attr("ry", rectData.ry); + + return rectElem; +}; + +exports.getNoteRect = function(){ + var rect = { + x: 0, + y: 0, + fill: '#EDF2AE', + stroke: '#666', + width: 100, + height: 100, + rx: 0, + ry: 0 + }; + return rect; +};