mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
Support sequenceDiagram "over" notes
This commit is contained in:
parent
76130bc485
commit
26ebbf82ee
@ -103,8 +103,16 @@ statement
|
||||
;
|
||||
|
||||
note_statement
|
||||
: 'note' placement actor text2 {$$=[$3,{type:'addNote', placement:$2, actor:$3.actor, text:$4}];}
|
||||
| 'note' 'over' spaceList actor_pair actor
|
||||
: 'note' placement actor text2
|
||||
{
|
||||
$$ = [$3, {type:'addNote', placement:$2, actor:$3.actor, text:$4}];}
|
||||
| 'note' 'over' actor_pair text2
|
||||
{
|
||||
// Coerce actor_pair into a [to, from, ...] array
|
||||
$2 = [].concat($3, $3).slice(0, 2);
|
||||
$2[0] = $2[0].actor;
|
||||
$2[1] = $2[1].actor;
|
||||
$$ = [$3, {type:'addNote', placement:yy.PLACEMENT.OVER, actor:$2.slice(0, 2), text:$4}];}
|
||||
;
|
||||
|
||||
spaceList
|
||||
@ -112,8 +120,8 @@ spaceList
|
||||
| SPACE
|
||||
;
|
||||
actor_pair
|
||||
: actor { $$ = $1; }
|
||||
| actor ',' actor { $$ = [$1, $3]; }
|
||||
: actor ',' actor { $$ = [$1, $3]; }
|
||||
| actor { $$ = $1; }
|
||||
;
|
||||
|
||||
placement
|
||||
|
@ -77,8 +77,11 @@ exports.PLACEMENT = {
|
||||
exports.addNote = function (actor, placement, message){
|
||||
var note = {actor:actor, placement: placement, message:message};
|
||||
|
||||
// Coerce actor into a [to, from, ...] array
|
||||
var actors = [].concat(actor, actor);
|
||||
|
||||
notes.push(note);
|
||||
messages.push({from:actor, to:actor, message:message, type:exports.LINETYPE.NOTE, placement: placement});
|
||||
messages.push({from:actors[0], to:actors[1], message:message, type:exports.LINETYPE.NOTE, placement: placement});
|
||||
};
|
||||
|
||||
|
||||
|
@ -231,6 +231,31 @@ describe('when parsing a sequenceDiagram',function() {
|
||||
expect(messages[0].from).toBe('Alice');
|
||||
expect(messages[2].from).toBe('John');
|
||||
});
|
||||
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';
|
||||
|
||||
sq.parse(str);
|
||||
|
||||
var messages = sq.yy.getMessages();
|
||||
expect(messages[1].from).toBe('Bob');
|
||||
expect(messages[1].to).toBe('Bob');
|
||||
});
|
||||
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';
|
||||
|
||||
sq.parse(str);
|
||||
|
||||
var messages = sq.yy.getMessages();
|
||||
expect(messages[1].from).toBe('Alice');
|
||||
expect(messages[1].to).toBe('Bob');
|
||||
expect(messages[2].from).toBe('Bob');
|
||||
expect(messages[2].to).toBe('Alice');
|
||||
});
|
||||
it('it should handle loop statements a sequenceDiagram', function () {
|
||||
var str = 'sequenceDiagram\n' +
|
||||
'Alice->Bob: Hello Bob, how are you?\n\n' +
|
||||
@ -623,7 +648,23 @@ describe('when rendering a sequenceDiagram',function() {
|
||||
expect(bounds.stopy ).toBe(conf.height);
|
||||
|
||||
});
|
||||
it('it should handle one actor and a note', 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';
|
||||
|
||||
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);
|
||||
// 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' +
|
||||
@ -668,7 +709,22 @@ describe('when rendering a sequenceDiagram',function() {
|
||||
expect(bounds.starty).toBe(0);
|
||||
expect(bounds.stopx ).toBe(conf.width*2 + conf.actorMargin);
|
||||
expect(bounds.stopy ).toBe(0 + conf.messageMargin + conf.height);
|
||||
});
|
||||
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';
|
||||
|
||||
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);
|
||||
expect(bounds.stopy ).toBe( conf.height + conf.messageMargin + 2*(conf.boxMargin + 2*conf.noteMargin + 10));
|
||||
});
|
||||
it('it should draw two actors and two messages', function () {
|
||||
sd.bounds.init();
|
||||
|
@ -129,11 +129,11 @@ 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, forceWidth){
|
||||
var rect = svgDraw.getNoteRect();
|
||||
rect.x = startx;
|
||||
rect.y = verticalPos;
|
||||
rect.width = conf.width;
|
||||
rect.width = forceWidth || conf.width;
|
||||
rect.class = 'note';
|
||||
|
||||
var g = elem.append('g');
|
||||
@ -147,21 +147,19 @@ var drawNote = function(elem, startx, verticalPos, msg){
|
||||
textObj.text = msg.message;
|
||||
textObj.class = 'noteText';
|
||||
|
||||
var textElem = svgDraw.drawText(g,textObj, conf.width-conf.noteMargin);
|
||||
var textElem = svgDraw.drawText(g,textObj, rect.width-conf.noteMargin);
|
||||
|
||||
var textHeight = textElem[0][0].getBBox().height;
|
||||
if(textHeight > conf.width){
|
||||
if(!forceWidth && textHeight > conf.width){
|
||||
textElem.remove();
|
||||
g = elem.append('g');
|
||||
|
||||
//textObj.x = textObj.x - conf.width;
|
||||
//textElem = svgDraw.drawText(g,textObj, 2*conf.noteMargin);
|
||||
textElem = svgDraw.drawText(g,textObj, 2*conf.width-conf.noteMargin);
|
||||
textElem = svgDraw.drawText(g,textObj, 2*rect.width-conf.noteMargin);
|
||||
textHeight = textElem[0][0].getBBox().height;
|
||||
rectElem.attr('width',2*conf.width);
|
||||
exports.bounds.insert(startx, verticalPos, startx + 2*conf.width, verticalPos + 2*conf.noteMargin + textHeight);
|
||||
rectElem.attr('width',2*rect.width);
|
||||
exports.bounds.insert(startx, verticalPos, startx + 2*rect.width, verticalPos + 2*conf.noteMargin + textHeight);
|
||||
}else{
|
||||
exports.bounds.insert(startx, verticalPos, startx + conf.width, verticalPos + 2*conf.noteMargin + textHeight);
|
||||
exports.bounds.insert(startx, verticalPos, startx + rect.width, verticalPos + 2*conf.noteMargin + textHeight);
|
||||
}
|
||||
|
||||
rectElem.attr('height',textHeight+ 2*conf.noteMargin);
|
||||
@ -290,6 +288,7 @@ module.exports.draw = function (text, id) {
|
||||
|
||||
var startx;
|
||||
var stopx;
|
||||
var forceWidth;
|
||||
|
||||
// Fetch data from the parsing
|
||||
var actors = sq.yy.getActors();
|
||||
@ -312,13 +311,19 @@ module.exports.draw = function (text, id) {
|
||||
startx = actors[msg.from].x;
|
||||
stopx = actors[msg.to].x;
|
||||
|
||||
if(msg.placement !== 0){
|
||||
// Right of
|
||||
if(msg.placement === sq.yy.PLACEMENT.RIGHTOF){
|
||||
drawNote(diagram, startx + (conf.width + conf.actorMargin)/2, exports.bounds.getVerticalPos(), msg);
|
||||
|
||||
}else{
|
||||
// Left of
|
||||
}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
|
||||
drawNote(diagram, startx, exports.bounds.getVerticalPos(), msg);
|
||||
}else{
|
||||
// Multi-actor over
|
||||
forceWidth = Math.abs(startx - stopx) + conf.actorMargin;
|
||||
drawNote(diagram, (startx + stopx + conf.width - forceWidth)/2, exports.bounds.getVerticalPos(), msg,
|
||||
forceWidth);
|
||||
}
|
||||
break;
|
||||
case sq.yy.LINETYPE.LOOP_START:
|
||||
|
Loading…
x
Reference in New Issue
Block a user