From 614e9f4b873486a81a63dd55e323e3601d94aea5 Mon Sep 17 00:00:00 2001 From: Szymon Stasik Date: Fri, 11 Mar 2016 16:44:45 +0100 Subject: [PATCH] draw activation boxes --- .../sequenceDiagram/sequenceRenderer.js | 110 ++++++++++++------ src/diagrams/sequenceDiagram/svgDraw.js | 54 +++------ 2 files changed, 85 insertions(+), 79 deletions(-) diff --git a/src/diagrams/sequenceDiagram/sequenceRenderer.js b/src/diagrams/sequenceDiagram/sequenceRenderer.js index b65a781cc..1cf210cea 100644 --- a/src/diagrams/sequenceDiagram/sequenceRenderer.js +++ b/src/diagrams/sequenceDiagram/sequenceRenderer.js @@ -15,7 +15,7 @@ var conf = { diagramMarginY:10, // Margin between actors actorMargin:50, - // Width of actor moxes + // Width of actor boxes width:150, // Height of actor boxes height:65, @@ -29,7 +29,10 @@ var conf = { mirrorActors:false, // Depending on css styling this might need adjustment // Prolongs the edge of the diagram downwards - bottomMarginAdj:1 + bottomMarginAdj:1, + + // width of activation box + activationWidth:10 }; //var bb = getBBox('path'); @@ -42,11 +45,11 @@ exports.bounds = { }, verticalPos:0, - list: [], + sequenceItems: [], activations: [], init : function(){ - this.list = []; - this.activations = [], + this.sequenceItems = []; + this.activations = []; this.data = { startx:undefined, stopx :undefined, @@ -62,24 +65,31 @@ exports.bounds = { obj[key] = fun(val,obj[key]); } }, - updateLoops:function(startx,starty,stopx,stopy){ + updateBounds:function(startx,starty,stopx,stopy){ var _self = this; var cnt = 0; - this.list.forEach(function(loop){ + function updateFn(type) { return function updateItemBounds(item) { cnt++; - // The loop list is a stack so the biggest margins in the beginning of the list - var n = _self.list.length-cnt+1; + // 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(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(item, 'starty',starty - n*conf.boxMargin, Math.min); + _self.updateVal(item, '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); - }); + _self.updateVal(exports.bounds.data, 'startx', startx - n * conf.boxMargin, Math.min); + _self.updateVal(exports.bounds.data, 'stopx', stopx + n * conf.boxMargin, Math.max); + + if (!(type == 'activation')) { + _self.updateVal(item, 'startx',startx - n*conf.boxMargin, Math.min); + _self.updateVal(item, 'stopx' ,stopx + n*conf.boxMargin, Math.max); + + _self.updateVal(exports.bounds.data, 'starty', starty - n * conf.boxMargin, Math.min); + _self.updateVal(exports.bounds.data, 'stopy', stopy + n * conf.boxMargin, Math.max); + } + }} + + this.sequenceItems.forEach(updateFn()); + this.activations.forEach(updateFn('activation')); }, insert:function(startx,starty,stopx,stopy){ @@ -95,32 +105,34 @@ exports.bounds = { this.updateVal(exports.bounds.data,'stopx' ,_stopx ,Math.max); this.updateVal(exports.bounds.data,'stopy' ,_stopy ,Math.max); - this.updateLoops(_startx,_starty,_stopx,_stopy); + this.updateBounds(_startx,_starty,_stopx,_stopy); }, - newActivation:function(message){ - console.debug("new activation", message); - this.activations.push({startx:undefined,starty:this.verticalPos,stopx:undefined,stopy:undefined, actor: message.from.actor}); + newActivation:function(message, diagram){ + 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,starty:this.verticalPos,stopx:x+conf.activationWidth,stopy:undefined, + actor: message.from.actor, + anchored: svgDraw.anchorElement(diagram) + }); }, endActivation:function(){ var activation = this.activations.pop(); - console.debug("render end activation", activation); - //loop.stopy = exports.bounds.getVerticalPos(); return activation; }, newLoop:function(title){ - this.list.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.list.pop(); - //loop.stopy = exports.bounds.getVerticalPos(); + var loop = this.sequenceItems.pop(); return loop; }, addElseToLoop:function(message){ - var loop = this.list.pop(); + var loop = this.sequenceItems.pop(); loop.elsey = exports.bounds.getVerticalPos(); loop.elseText = message; - this.list.push(loop); + this.sequenceItems.push(loop); }, bumpVerticalPos:function(bump){ this.verticalPos = this.verticalPos + bump; @@ -266,7 +278,7 @@ module.exports.drawActors = function(diagram, actors, actorKeys,verticalPos){ // Add some rendering data to the object actors[key].x = i*conf.actorMargin +i*conf.width; actors[key].y = verticalPos; - actors[key].width = conf.diagramMarginY; + actors[key].width = conf.diagramMarginX; actors[key].height = conf.diagramMarginY; // Draw the box with the attached line @@ -288,6 +300,23 @@ module.exports.setConf = function(cnf){ conf[key] = cnf[key]; }); }; + +var actorActivations = function(actor) { + return module.exports.bounds.activations.filter(function(activation) { + return activation.actor == actor; + }); +}; + +var actorFlowVerticaBounds = function(actor) { + // handle multiple stacked activations for same actor + var actors = sq.yy.getActors(); + var activations = actorActivations(actor); + + var left = activations.reduce(function(acc,activation) { return Math.min(acc,activation.startx)}, actors[actor].x + conf.width/2); + var right = activations.reduce(function(acc,activation) { return Math.max(acc,activation.stopx)}, actors[actor].x + conf.width/2); + return [left,right]; +}; + /** * Draws a flowchart in the tag with id: id based on the graph definition in text. * @param text @@ -341,17 +370,15 @@ module.exports.draw = function (text, id) { } break; case sq.yy.LINETYPE.ACTIVE_START: - console.info('ACTIVE_START', msg); // exports.bounds.bumpVerticalPos(conf.boxMargin); - exports.bounds.newActivation(msg); + exports.bounds.newActivation(msg, diagram); // exports.bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin); break; case sq.yy.LINETYPE.ACTIVE_END: - console.info('ACTIVE_END', msg); var activationData = exports.bounds.endActivation(); + svgDraw.drawActivation(diagram, activationData, exports.bounds.getVerticalPos(), conf); - // svgDraw.drawActivation(diagram, activationData, conf); - // exports.bounds.bumpVerticalPos(conf.boxMargin); + exports.bounds.insert(activationData.startx, exports.bounds.getVerticalPos() -10, activationData.stopx, exports.bounds.getVerticalPos()); break; case sq.yy.LINETYPE.LOOP_START: exports.bounds.bumpVerticalPos(conf.boxMargin); @@ -394,15 +421,22 @@ module.exports.draw = function (text, id) { exports.bounds.bumpVerticalPos(conf.boxMargin); break; default: + try { exports.bounds.bumpVerticalPos(conf.messageMargin); - startx = actors[msg.from].x + conf.width/2; - stopx = actors[msg.to].x + conf.width/2; + var fromBounds = actorFlowVerticaBounds(msg.from); + var toBounds = actorFlowVerticaBounds(msg.to); + var forward = fromBounds[0] < toBounds[0]; + startx = fromBounds[forward?1:0]; + stopx = toBounds[forward?0:1]; drawMessage(diagram, startx, stopx, exports.bounds.getVerticalPos(), msg); - + } catch (e) { + console.error('error while drawing message', e); + } } }); + if(conf.mirrorActors){ // Draw actors below diagram exports.bounds.bumpVerticalPos(conf.boxMargin*2); diff --git a/src/diagrams/sequenceDiagram/svgDraw.js b/src/diagrams/sequenceDiagram/svgDraw.js index 8c776f553..5b08d180f 100644 --- a/src/diagrams/sequenceDiagram/svgDraw.js +++ b/src/diagrams/sequenceDiagram/svgDraw.js @@ -121,52 +121,24 @@ exports.drawActor = function(elem, left, verticalPos, description,conf){ ; }; +exports.anchorElement = function(elem) { + return elem.append('g'); +}; /** * 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 list of actors - * @param description The text in the box + * @param elem - element to append activation rect + * @param bounds - activation box bounds + * @param verticalPos - precise y cooridnate of bottom activation box edge */ -exports.drawActivation = function(elem,bounds,conf){ - +exports.drawActivation = function(elem,bounds,verticalPos){ var rect = exports.getNoteRect(); - rect.x = left; - rect.y = verticalPos; - rect.fill = '#ffffff'; - rect.width = conf.width; - rect.height = conf.height; - rect.class = 'actor'; + var g = bounds.anchored; + rect.x = bounds.startx; + rect.y = bounds.starty; + rect.fill = 'white'; + rect.width = bounds.stopx - bounds.startx; + rect.height = verticalPos - bounds.starty; exports.drawRect(g, rect); - - // drawBox(bounds.startx, bounds.starty, bounds.stopx , bounds.starty); - // drawBox(bounds.stopx , bounds.starty, bounds.stopx , bounds.stopy ); - // drawBox(bounds.startx, bounds.stopy , bounds.stopx , bounds.stopy ); - // drawBox(bounds.startx, bounds.starty, bounds.startx, bounds.stopy ); - - // var txt = exports.getTextObj(); - // txt.text = labelText; - // txt.x = bounds.startx; - // txt.y = bounds.starty; - // txt.labelMargin = 1.5 * 10; // This is the small box that says "loop" - // txt.class = 'labelText'; // Its size & position are fixed. - // txt.fill = 'white'; - // - // exports.drawLabel(g,txt); - // - // txt = exports.getTextObj(); - // txt.text = '[ ' + bounds.title + ' ]'; - // txt.x = bounds.startx + (bounds.stopx - bounds.startx)/2; - // txt.y = bounds.starty + 1.5 * conf.boxMargin; - // txt.anchor = 'middle'; - // txt.class = 'loopText'; - // - // exports.drawText(g,txt); - // - // if(typeof bounds.elseText !== 'undefined') { - // txt.text = '[ ' + bounds.elseText + ' ]'; - // txt.y = bounds.elsey + 1.5 * conf.boxMargin; - // exports.drawText(g, txt); - // } }; /**