mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-07 09:36:41 +02:00
Sequence diagram loop margins
Handling of arrows to the left in loops in sequence diagrams Addition of labels
This commit is contained in:
@@ -121,6 +121,7 @@ describe('when checking the bounds in a sequenceDiagram',function() {
|
|||||||
height:65,
|
height:65,
|
||||||
boxMargin:10,
|
boxMargin:10,
|
||||||
messageMargin:40,
|
messageMargin:40,
|
||||||
|
boxTextMargin:15,
|
||||||
noteMargin:25
|
noteMargin:25
|
||||||
};
|
};
|
||||||
sd.setConf(conf);
|
sd.setConf(conf);
|
||||||
@@ -169,6 +170,7 @@ describe('when checking the bounds in a sequenceDiagram',function() {
|
|||||||
sd.bounds.init();
|
sd.bounds.init();
|
||||||
|
|
||||||
sd.bounds.insert(25,50,300,400);
|
sd.bounds.insert(25,50,300,400);
|
||||||
|
sd.bounds.verticalPos = 150;
|
||||||
sd.bounds.newLoop();
|
sd.bounds.newLoop();
|
||||||
sd.bounds.insert(125,150,150,200);
|
sd.bounds.insert(125,150,150,200);
|
||||||
|
|
||||||
@@ -193,6 +195,7 @@ describe('when checking the bounds in a sequenceDiagram',function() {
|
|||||||
sd.bounds.init();
|
sd.bounds.init();
|
||||||
|
|
||||||
sd.bounds.insert(100,100,1000,1000);
|
sd.bounds.insert(100,100,1000,1000);
|
||||||
|
sd.bounds.verticalPos = 200;
|
||||||
sd.bounds.newLoop();
|
sd.bounds.newLoop();
|
||||||
sd.bounds.newLoop();
|
sd.bounds.newLoop();
|
||||||
sd.bounds.insert(200,200,300,300);
|
sd.bounds.insert(200,200,300,300);
|
||||||
@@ -226,6 +229,7 @@ describe('when checking the bounds in a sequenceDiagram',function() {
|
|||||||
sd.bounds.init();
|
sd.bounds.init();
|
||||||
|
|
||||||
sd.bounds.insert(100,100,200,200);
|
sd.bounds.insert(100,100,200,200);
|
||||||
|
sd.bounds.verticalPos = 200;
|
||||||
sd.bounds.newLoop();
|
sd.bounds.newLoop();
|
||||||
sd.bounds.insert(50,50,300,300);
|
sd.bounds.insert(50,50,300,300);
|
||||||
|
|
||||||
@@ -328,6 +332,7 @@ describe('when rendering a sequenceDiagram',function() {
|
|||||||
height:65,
|
height:65,
|
||||||
boxMargin:10,
|
boxMargin:10,
|
||||||
messageMargin:40,
|
messageMargin:40,
|
||||||
|
boxTextMargin:15,
|
||||||
noteMargin:25
|
noteMargin:25
|
||||||
};
|
};
|
||||||
sd.setConf(conf);
|
sd.setConf(conf);
|
||||||
@@ -430,7 +435,7 @@ describe('when rendering a sequenceDiagram',function() {
|
|||||||
var expStopX = conf.actorMargin +conf.width+ (conf.width/2) + conf.noteMargin + conf.width;
|
var expStopX = conf.actorMargin +conf.width+ (conf.width/2) + conf.noteMargin + conf.width;
|
||||||
|
|
||||||
expect(bounds.stopx ).toBe(expStopX);
|
expect(bounds.stopx ).toBe(expStopX);
|
||||||
expect(bounds.stopy ).toBe(2*conf.messageMargin + conf.height + conf.boxMargin);
|
expect(bounds.stopy ).toBe(2*conf.messageMargin + conf.height + conf.boxMargin + 10+ 2*conf.noteMargin);
|
||||||
|
|
||||||
});
|
});
|
||||||
it('it should draw two actors notes to the left', function () {
|
it('it should draw two actors notes to the left', function () {
|
||||||
@@ -448,7 +453,7 @@ describe('when rendering a sequenceDiagram',function() {
|
|||||||
expect(bounds.starty).toBe(0);
|
expect(bounds.starty).toBe(0);
|
||||||
|
|
||||||
expect(bounds.stopx ).toBe( conf.width*2 + conf.actorMargin);
|
expect(bounds.stopx ).toBe( conf.width*2 + conf.actorMargin);
|
||||||
expect(bounds.stopy ).toBe( 2*conf.messageMargin + conf.height + conf.boxMargin);
|
expect(bounds.stopy ).toBe( 2*conf.messageMargin + conf.height + conf.boxMargin +10+ 2*conf.noteMargin);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -467,7 +472,7 @@ describe('when rendering a sequenceDiagram',function() {
|
|||||||
expect(bounds.starty).toBe(0);
|
expect(bounds.starty).toBe(0);
|
||||||
|
|
||||||
expect(bounds.stopx ).toBe(0 + conf.width*2 + conf.actorMargin);
|
expect(bounds.stopx ).toBe(0 + conf.width*2 + conf.actorMargin);
|
||||||
expect(bounds.stopy ).toBe(0 + 2*conf.messageMargin + conf.height + conf.boxMargin);
|
expect(bounds.stopy ).toBe(0 + 2*conf.messageMargin + conf.height + 3*conf.boxMargin + conf.boxTextMargin);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
@@ -18,6 +18,7 @@ var conf = {
|
|||||||
height:65,
|
height:65,
|
||||||
// Margin around loop boxes
|
// Margin around loop boxes
|
||||||
boxMargin:10,
|
boxMargin:10,
|
||||||
|
boxTextMargin:15,
|
||||||
|
|
||||||
noteMargin:10,
|
noteMargin:10,
|
||||||
// Space between messages
|
// Space between messages
|
||||||
@@ -72,15 +73,23 @@ exports.bounds = {
|
|||||||
},
|
},
|
||||||
insert:function(startx,starty,stopx,stopy){
|
insert:function(startx,starty,stopx,stopy){
|
||||||
|
|
||||||
this.updateVal(exports.bounds.data,'startx',startx,Math.min);
|
var _startx, _starty, _stopx, _stopy;
|
||||||
this.updateVal(exports.bounds.data,'starty',starty,Math.min);
|
|
||||||
this.updateVal(exports.bounds.data,'stopx' ,stopx ,Math.max);
|
_startx = Math.min(startx,stopx);
|
||||||
this.updateVal(exports.bounds.data,'stopy' ,stopy ,Math.max);
|
_stopx = Math.max(startx,stopx);
|
||||||
|
_starty = Math.min(starty,stopy);
|
||||||
|
_stopy = Math.max(starty,stopy);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
this.updateLoops(startx,starty,stopx,stopy);
|
|
||||||
},
|
},
|
||||||
newLoop:function(){
|
newLoop:function(title){
|
||||||
this.list.push({startx:undefined,starty:undefined,stopx:undefined,stopy:undefined});
|
this.list.push({startx:undefined,starty:this.verticalPos,stopx:undefined,stopy:undefined, title:title});
|
||||||
},
|
},
|
||||||
endLoop:function(){
|
endLoop:function(){
|
||||||
var loop = this.list.pop();
|
var loop = this.list.pop();
|
||||||
@@ -127,12 +136,13 @@ var drawNote = function(elem, startx, verticalPos, msg){
|
|||||||
exports.bounds.insert(startx, verticalPos, startx + conf.width, verticalPos + 2*conf.noteMargin + textHeight);
|
exports.bounds.insert(startx, verticalPos, startx + conf.width, verticalPos + 2*conf.noteMargin + textHeight);
|
||||||
|
|
||||||
rectElem.attr('height',textHeight+ 2*conf.noteMargin);
|
rectElem.attr('height',textHeight+ 2*conf.noteMargin);
|
||||||
|
exports.bounds.bumpVerticalPos(textHeight+ 2*conf.noteMargin);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws an actor in the diagram with the attaced line
|
* Draws an actor in the diagram with the attaced line
|
||||||
* @param center - The center of the the actor
|
* @param center - The center of the the actor
|
||||||
* @param pos The position if the actor in the liost of actors
|
* @param pos The position if the actor in the list of actors
|
||||||
* @param description The text in the box
|
* @param description The text in the box
|
||||||
*/
|
*/
|
||||||
exports.drawLoop = function(elem,bounds){
|
exports.drawLoop = function(elem,bounds){
|
||||||
@@ -144,14 +154,31 @@ exports.drawLoop = function(elem,bounds){
|
|||||||
.attr("x2", stopx )
|
.attr("x2", stopx )
|
||||||
.attr("y2", stopy )
|
.attr("y2", stopy )
|
||||||
.attr("stroke-width", 2)
|
.attr("stroke-width", 2)
|
||||||
.attr("stroke", "#339999");
|
.attr("stroke", "#339933");
|
||||||
};
|
};
|
||||||
drawLoopLine(bounds.startx, bounds.starty, bounds.stopx , bounds.starty);
|
drawLoopLine(bounds.startx, bounds.starty, bounds.stopx , bounds.starty);
|
||||||
drawLoopLine(bounds.stopx , bounds.starty, bounds.stopx , bounds.stopy );
|
drawLoopLine(bounds.stopx , bounds.starty, bounds.stopx , bounds.stopy );
|
||||||
drawLoopLine(bounds.startx, bounds.stopy , bounds.stopx , bounds.stopy );
|
drawLoopLine(bounds.startx, bounds.stopy , bounds.stopx , bounds.stopy );
|
||||||
drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy );
|
drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy );
|
||||||
|
|
||||||
|
var txt = svgDraw.getTextObj();
|
||||||
|
txt.text = "Loop";
|
||||||
|
txt.x = bounds.startx;
|
||||||
|
txt.y = bounds.starty;
|
||||||
|
txt.labelMargin = 1.5 * conf.boxMargin;
|
||||||
|
|
||||||
|
svgDraw.drawLabel(g,txt);
|
||||||
|
|
||||||
|
txt = svgDraw.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';
|
||||||
|
|
||||||
|
svgDraw.drawText(g,txt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup arrow head and define the marker. The result is appended to the svg.
|
* Setup arrow head and define the marker. The result is appended to the svg.
|
||||||
*/
|
*/
|
||||||
@@ -179,6 +206,7 @@ var insertArrowHead = function(elem){
|
|||||||
var drawMessage = function(elem, startx, stopx, verticalPos, msg){
|
var drawMessage = function(elem, startx, stopx, verticalPos, msg){
|
||||||
var g = elem.append("g");
|
var g = elem.append("g");
|
||||||
var txtCenter = startx + (stopx-startx)/2;
|
var txtCenter = startx + (stopx-startx)/2;
|
||||||
|
|
||||||
//Make an SVG Container
|
//Make an SVG Container
|
||||||
//Draw the line
|
//Draw the line
|
||||||
if(msg.type !== 2) {
|
if(msg.type !== 2) {
|
||||||
@@ -212,7 +240,6 @@ var drawMessage = function(elem, startx, stopx, verticalPos, msg){
|
|||||||
.attr("y", verticalPos - 10)
|
.attr("y", verticalPos - 10)
|
||||||
.style("text-anchor", "middle")
|
.style("text-anchor", "middle")
|
||||||
.text(msg.message);
|
.text(msg.message);
|
||||||
|
|
||||||
exports.bounds.insert(startx, exports.bounds.getVerticalPos() -10, stopx, exports.bounds.getVerticalPos());
|
exports.bounds.insert(startx, exports.bounds.getVerticalPos() -10, stopx, exports.bounds.getVerticalPos());
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@@ -318,6 +345,7 @@ module.exports.draw = function (text, id) {
|
|||||||
switch(msg.type){
|
switch(msg.type){
|
||||||
case sq.yy.LINETYPE.NOTE:
|
case sq.yy.LINETYPE.NOTE:
|
||||||
exports.bounds.bumpVerticalPos(conf.boxMargin);
|
exports.bounds.bumpVerticalPos(conf.boxMargin);
|
||||||
|
|
||||||
startx = actors[msg.from].x;
|
startx = actors[msg.from].x;
|
||||||
stopx = actors[msg.to].x;
|
stopx = actors[msg.to].x;
|
||||||
|
|
||||||
@@ -331,14 +359,15 @@ module.exports.draw = function (text, id) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case sq.yy.LINETYPE.LOOP_START:
|
case sq.yy.LINETYPE.LOOP_START:
|
||||||
//var loop = exports.bounds.newLoop();
|
exports.bounds.bumpVerticalPos(conf.boxMargin);
|
||||||
exports.bounds.newLoop();
|
exports.bounds.newLoop(msg.message);
|
||||||
|
exports.bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin);
|
||||||
break;
|
break;
|
||||||
case sq.yy.LINETYPE.LOOP_END:
|
case sq.yy.LINETYPE.LOOP_END:
|
||||||
var loopData = exports.bounds.endLoop();
|
var loopData = exports.bounds.endLoop();
|
||||||
//var loopData = loopList.pop();
|
|
||||||
//loopData.stopy = exports.bounds.getVerticalPos();
|
|
||||||
exports.drawLoop(diagram, loopData);
|
exports.drawLoop(diagram, loopData);
|
||||||
|
exports.bounds.bumpVerticalPos(conf.boxMargin);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
exports.bounds.bumpVerticalPos(conf.messageMargin);
|
exports.bounds.bumpVerticalPos(conf.messageMargin);
|
||||||
|
@@ -19,7 +19,8 @@ exports.drawText = function(elem , textData){
|
|||||||
var textElem = elem.append('text');
|
var textElem = elem.append('text');
|
||||||
textElem.attr('x', textData.x);
|
textElem.attr('x', textData.x);
|
||||||
textElem.attr('y', textData.y);
|
textElem.attr('y', textData.y);
|
||||||
textElem.style('text-anchor', 'start');
|
textElem.style('text-anchor', textData.anchor);
|
||||||
|
textElem.style('fill', textData.fill);
|
||||||
|
|
||||||
textData.text.split('<br>').forEach(function(rowText){
|
textData.text.split('<br>').forEach(function(rowText){
|
||||||
var span = textElem.append('tspan');
|
var span = textElem.append('tspan');
|
||||||
@@ -31,14 +32,37 @@ exports.drawText = function(elem , textData){
|
|||||||
return textElem;
|
return textElem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.drawLabel = function(elem , txtObject){
|
||||||
|
var rectData = exports.getNoteRect();
|
||||||
|
rectData.x = txtObject.x;
|
||||||
|
rectData.y = txtObject.y;
|
||||||
|
rectData.width = 50;
|
||||||
|
rectData.height = 20;
|
||||||
|
rectData.fill = '#339933';
|
||||||
|
rectData.stroke = 'none';
|
||||||
|
//rectData.color = 'white';
|
||||||
|
|
||||||
|
var label = exports.drawRect(elem, rectData);
|
||||||
|
|
||||||
|
txtObject.y = txtObject.y + txtObject.labelMargin;
|
||||||
|
txtObject.x = txtObject.x + 0.5*txtObject.labelMargin;
|
||||||
|
txtObject.fill = 'white';
|
||||||
|
exports.drawText(elem, txtObject);
|
||||||
|
|
||||||
|
//return textElem;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.getTextObj = function(){
|
exports.getTextObj = function(){
|
||||||
var rect = {
|
var rect = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
|
'fill':'black',
|
||||||
'text-anchor': 'start',
|
'text-anchor': 'start',
|
||||||
style: '#666',
|
style: '#666',
|
||||||
width: 100,
|
width: 100,
|
||||||
height: 100,
|
height: 100,
|
||||||
|
textMargin:0,
|
||||||
rx: 0,
|
rx: 0,
|
||||||
ry: 0
|
ry: 0
|
||||||
};
|
};
|
||||||
@@ -52,6 +76,7 @@ exports.getNoteRect = function(){
|
|||||||
fill: '#EDF2AE',
|
fill: '#EDF2AE',
|
||||||
stroke: '#666',
|
stroke: '#666',
|
||||||
width: 100,
|
width: 100,
|
||||||
|
anchor:'start',
|
||||||
height: 100,
|
height: 100,
|
||||||
rx: 0,
|
rx: 0,
|
||||||
ry: 0
|
ry: 0
|
||||||
|
Reference in New Issue
Block a user