Merge pull request #1854 from mermaid-js/1528_sequence_async_arrows

#1528 Adding async arrow type in sequence diagrams
This commit is contained in:
Knut Sveidqvist 2021-01-12 21:40:02 +01:00 committed by GitHub
commit 071fd8b569
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 11 deletions

View File

@ -55,9 +55,13 @@ flowchart TD
class T TestSub class T TestSub
linkStyle 0,1 color:orange, stroke: orange; linkStyle 0,1 color:orange, stroke: orange;
</div> </div>
-> ->> ->>> -)
<div class="mermaid" style="width: 50%; height: 20%;"> <div class="mermaid" style="width: 50%; height: 20%;">
graph TD sequenceDiagram
C -->|fa:fa-car Car| F[fa:fa-car Car] Actor1 -) Actor2:Async
Actor1 --) Actor2:Async dotted
Actor1 ->> Actor2:Sync
Actor1 -->> Actor2:Sync dotted
</div> </div>
<div class="mermaid" style="width: 50%; height: 20%;"> <div class="mermaid" style="width: 50%; height: 20%;">
flowchart TD flowchart TD

View File

@ -56,13 +56,15 @@
"autonumber" return 'autonumber'; "autonumber" return 'autonumber';
"," return ','; "," return ',';
";" return 'NEWLINE'; ";" return 'NEWLINE';
[^\+\->:\n,;]+((?!(\-x|\-\-x))[\-]*[^\+\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; } [^\+\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; }
"->>" return 'SOLID_ARROW'; "->>" return 'SOLID_ARROW';
"-->>" return 'DOTTED_ARROW'; "-->>" return 'DOTTED_ARROW';
"->" return 'SOLID_OPEN_ARROW'; "->" return 'SOLID_OPEN_ARROW';
"-->" return 'DOTTED_OPEN_ARROW'; "-->" return 'DOTTED_OPEN_ARROW';
\-[x] return 'SOLID_CROSS'; \-[x] return 'SOLID_CROSS';
\-\-[x] return 'DOTTED_CROSS'; \-\-[x] return 'DOTTED_CROSS';
\-[\)] return 'SOLID_POINT';
\-\-[\)] return 'DOTTED_POINT';
":"(?:(?:no)?wrap:)?[^#\n;]+ return 'TXT'; ":"(?:(?:no)?wrap:)?[^#\n;]+ return 'TXT';
"+" return '+'; "+" return '+';
"-" return '-'; "-" return '-';
@ -206,6 +208,8 @@ signaltype
| DOTTED_ARROW { $$ = yy.LINETYPE.DOTTED; } | DOTTED_ARROW { $$ = yy.LINETYPE.DOTTED; }
| SOLID_CROSS { $$ = yy.LINETYPE.SOLID_CROSS; } | SOLID_CROSS { $$ = yy.LINETYPE.SOLID_CROSS; }
| DOTTED_CROSS { $$ = yy.LINETYPE.DOTTED_CROSS; } | DOTTED_CROSS { $$ = yy.LINETYPE.DOTTED_CROSS; }
| SOLID_POINT { $$ = yy.LINETYPE.SOLID_POINT; }
| DOTTED_POINT { $$ = yy.LINETYPE.DOTTED_POINT; }
; ;
text2 text2

View File

@ -168,7 +168,9 @@ export const LINETYPE = {
PAR_AND: 20, PAR_AND: 20,
PAR_END: 21, PAR_END: 21,
RECT_START: 22, RECT_START: 22,
RECT_END: 23 RECT_END: 23,
SOLID_POINT: 24,
DOTTED_POINT: 25
}; };
export const ARROWTYPE = { export const ARROWTYPE = {

View File

@ -161,6 +161,36 @@ Alice--xBob:Hello Bob, how are you?`;
expect(messages.length).toBe(1); expect(messages.length).toBe(1);
expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_CROSS); expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_CROSS);
}); });
it('it should handle in sync messages', function() {
const str = `
sequenceDiagram
Alice-)Bob:Hello Bob, how are you?`;
mermaidAPI.parse(str);
const actors = parser.yy.getActors();
expect(actors.Alice.description).toBe('Alice');
expect(actors.Bob.description).toBe('Bob');
const messages = parser.yy.getMessages();
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID_POINT);
});
it('it should handle in sync dotted messages', function() {
const str = `
sequenceDiagram
Alice--)Bob:Hello Bob, how are you?`;
mermaidAPI.parse(str);
const actors = parser.yy.getActors();
expect(actors.Alice.description).toBe('Alice');
expect(actors.Bob.description).toBe('Bob');
const messages = parser.yy.getMessages();
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_POINT);
});
it('it should handle in arrow messages', function() { it('it should handle in arrow messages', function() {
const str = ` const str = `
sequenceDiagram sequenceDiagram

View File

@ -360,6 +360,7 @@ const drawMessage = function(g, msgModel) {
if ( if (
type === parser.yy.LINETYPE.DOTTED || type === parser.yy.LINETYPE.DOTTED ||
type === parser.yy.LINETYPE.DOTTED_CROSS || type === parser.yy.LINETYPE.DOTTED_CROSS ||
type === parser.yy.LINETYPE.DOTTED_POINT ||
type === parser.yy.LINETYPE.DOTTED_OPEN type === parser.yy.LINETYPE.DOTTED_OPEN
) { ) {
line.style('stroke-dasharray', '3, 3'); line.style('stroke-dasharray', '3, 3');
@ -386,6 +387,9 @@ const drawMessage = function(g, msgModel) {
if (type === parser.yy.LINETYPE.SOLID || type === parser.yy.LINETYPE.DOTTED) { if (type === parser.yy.LINETYPE.SOLID || type === parser.yy.LINETYPE.DOTTED) {
line.attr('marker-end', 'url(' + url + '#arrowhead)'); line.attr('marker-end', 'url(' + url + '#arrowhead)');
} }
if (type === parser.yy.LINETYPE.SOLID_POINT || type === parser.yy.LINETYPE.DOTTED_POINT) {
line.attr('marker-end', 'url(' + url + '#filled-head)');
}
if (type === parser.yy.LINETYPE.SOLID_CROSS || type === parser.yy.LINETYPE.DOTTED_CROSS) { if (type === parser.yy.LINETYPE.SOLID_CROSS || type === parser.yy.LINETYPE.DOTTED_CROSS) {
line.attr('marker-end', 'url(' + url + '#crosshead)'); line.attr('marker-end', 'url(' + url + '#crosshead)');
@ -523,6 +527,7 @@ export const draw = function(text, id) {
// The arrow head definition is attached to the svg once // The arrow head definition is attached to the svg once
svgDraw.insertArrowHead(diagram); svgDraw.insertArrowHead(diagram);
svgDraw.insertArrowCrossHead(diagram); svgDraw.insertArrowCrossHead(diagram);
svgDraw.insertArrowFilledHead(diagram);
svgDraw.insertSequenceNumber(diagram); svgDraw.insertSequenceNumber(diagram);
function activeEnd(msg, verticalPos) { function activeEnd(msg, verticalPos) {
@ -667,7 +672,9 @@ export const draw = function(text, id) {
parser.yy.LINETYPE.SOLID, parser.yy.LINETYPE.SOLID,
parser.yy.LINETYPE.DOTTED, parser.yy.LINETYPE.DOTTED,
parser.yy.LINETYPE.SOLID_CROSS, parser.yy.LINETYPE.SOLID_CROSS,
parser.yy.LINETYPE.DOTTED_CROSS parser.yy.LINETYPE.DOTTED_CROSS,
parser.yy.LINETYPE.SOLID_POINT,
parser.yy.LINETYPE.DOTTED_POINT
].includes(msg.type) ].includes(msg.type)
) { ) {
sequenceIndex++; sequenceIndex++;
@ -955,7 +962,9 @@ const buildMessageModel = function(msg, actors) {
parser.yy.LINETYPE.SOLID, parser.yy.LINETYPE.SOLID,
parser.yy.LINETYPE.DOTTED, parser.yy.LINETYPE.DOTTED,
parser.yy.LINETYPE.SOLID_CROSS, parser.yy.LINETYPE.SOLID_CROSS,
parser.yy.LINETYPE.DOTTED_CROSS parser.yy.LINETYPE.DOTTED_CROSS,
parser.yy.LINETYPE.SOLID_POINT,
parser.yy.LINETYPE.DOTTED_POINT
].includes(msg.type) ].includes(msg.type)
) { ) {
process = true; process = true;

View File

@ -373,13 +373,30 @@ export const insertArrowHead = function(elem) {
.append('defs') .append('defs')
.append('marker') .append('marker')
.attr('id', 'arrowhead') .attr('id', 'arrowhead')
.attr('refX', 5) .attr('refX', 9)
.attr('refY', 2) .attr('refY', 5)
.attr('markerWidth', 6) .attr('markerUnits', 'userSpaceOnUse')
.attr('markerHeight', 4) .attr('markerWidth', 12)
.attr('markerHeight', 12)
.attr('orient', 'auto') .attr('orient', 'auto')
.append('path') .append('path')
.attr('d', 'M 0,0 V 4 L6,2 Z'); // this is actual shape for arrowhead .attr('d', 'M 0 0 L 10 5 L 0 10 z'); // this is actual shape for arrowhead
};
/**
* Setup arrow head and define the marker. The result is appended to the svg.
*/
export const insertArrowFilledHead = function(elem) {
elem
.append('defs')
.append('marker')
.attr('id', 'filled-head')
.attr('refX', 18)
.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');
}; };
/** /**
* Setup node number. The result is appended to the svg. * Setup node number. The result is appended to the svg.
@ -554,6 +571,7 @@ export default {
drawLoop, drawLoop,
drawBackgroundRect, drawBackgroundRect,
insertArrowHead, insertArrowHead,
insertArrowFilledHead,
insertSequenceNumber, insertSequenceNumber,
insertArrowCrossHead, insertArrowCrossHead,
getTextObj, getTextObj,