diff --git a/cypress/platform/knsv.html b/cypress/platform/knsv.html index 558de5f9d..0e598b6bc 100644 --- a/cypress/platform/knsv.html +++ b/cypress/platform/knsv.html @@ -55,9 +55,13 @@ flowchart TD class T TestSub linkStyle 0,1 color:orange, stroke: orange; + -> ->> ->>> -)
-graph TD - C -->|fa:fa-car Car| F[fa:fa-car Car] + sequenceDiagram + Actor1 -) Actor2:Async + Actor1 --) Actor2:Async dotted + Actor1 ->> Actor2:Sync + Actor1 -->> Actor2:Sync dotted
flowchart TD diff --git a/src/diagrams/sequence/parser/sequenceDiagram.jison b/src/diagrams/sequence/parser/sequenceDiagram.jison index e33574f90..5ffd4b276 100644 --- a/src/diagrams/sequence/parser/sequenceDiagram.jison +++ b/src/diagrams/sequence/parser/sequenceDiagram.jison @@ -56,13 +56,15 @@ "autonumber" return 'autonumber'; "," return ','; ";" return 'NEWLINE'; -[^\+\->:\n,;]+((?!(\-x|\-\-x))[\-]*[^\+\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; } +[^\+\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; } "->>" return 'SOLID_ARROW'; "-->>" return 'DOTTED_ARROW'; "->" return 'SOLID_OPEN_ARROW'; "-->" return 'DOTTED_OPEN_ARROW'; \-[x] return 'SOLID_CROSS'; \-\-[x] return 'DOTTED_CROSS'; +\-[\)] return 'SOLID_POINT'; +\-\-[\)] return 'DOTTED_POINT'; ":"(?:(?:no)?wrap:)?[^#\n;]+ return 'TXT'; "+" return '+'; "-" return '-'; @@ -206,6 +208,8 @@ signaltype | DOTTED_ARROW { $$ = yy.LINETYPE.DOTTED; } | SOLID_CROSS { $$ = yy.LINETYPE.SOLID_CROSS; } | DOTTED_CROSS { $$ = yy.LINETYPE.DOTTED_CROSS; } + | SOLID_POINT { $$ = yy.LINETYPE.SOLID_POINT; } + | DOTTED_POINT { $$ = yy.LINETYPE.DOTTED_POINT; } ; text2 diff --git a/src/diagrams/sequence/sequenceDb.js b/src/diagrams/sequence/sequenceDb.js index 59018dfea..b7df75f1b 100644 --- a/src/diagrams/sequence/sequenceDb.js +++ b/src/diagrams/sequence/sequenceDb.js @@ -168,7 +168,9 @@ export const LINETYPE = { PAR_AND: 20, PAR_END: 21, RECT_START: 22, - RECT_END: 23 + RECT_END: 23, + SOLID_POINT: 24, + DOTTED_POINT: 25 }; export const ARROWTYPE = { diff --git a/src/diagrams/sequence/sequenceDiagram.spec.js b/src/diagrams/sequence/sequenceDiagram.spec.js index 6cb6d55c4..8cb1b9a9e 100644 --- a/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/src/diagrams/sequence/sequenceDiagram.spec.js @@ -161,6 +161,36 @@ Alice--xBob:Hello Bob, how are you?`; expect(messages.length).toBe(1); 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() { const str = ` sequenceDiagram diff --git a/src/diagrams/sequence/sequenceRenderer.js b/src/diagrams/sequence/sequenceRenderer.js index efdb831b6..c63f2c922 100644 --- a/src/diagrams/sequence/sequenceRenderer.js +++ b/src/diagrams/sequence/sequenceRenderer.js @@ -360,6 +360,7 @@ const drawMessage = function(g, msgModel) { if ( type === parser.yy.LINETYPE.DOTTED || type === parser.yy.LINETYPE.DOTTED_CROSS || + type === parser.yy.LINETYPE.DOTTED_POINT || type === parser.yy.LINETYPE.DOTTED_OPEN ) { 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) { 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) { 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 svgDraw.insertArrowHead(diagram); svgDraw.insertArrowCrossHead(diagram); + svgDraw.insertArrowFilledHead(diagram); svgDraw.insertSequenceNumber(diagram); function activeEnd(msg, verticalPos) { @@ -667,7 +672,9 @@ export const draw = function(text, id) { parser.yy.LINETYPE.SOLID, parser.yy.LINETYPE.DOTTED, 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) ) { sequenceIndex++; @@ -955,7 +962,9 @@ const buildMessageModel = function(msg, actors) { parser.yy.LINETYPE.SOLID, parser.yy.LINETYPE.DOTTED, 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) ) { process = true; diff --git a/src/diagrams/sequence/svgDraw.js b/src/diagrams/sequence/svgDraw.js index f23de8784..88ba29b21 100644 --- a/src/diagrams/sequence/svgDraw.js +++ b/src/diagrams/sequence/svgDraw.js @@ -373,13 +373,30 @@ export const insertArrowHead = function(elem) { .append('defs') .append('marker') .attr('id', 'arrowhead') - .attr('refX', 5) - .attr('refY', 2) - .attr('markerWidth', 6) - .attr('markerHeight', 4) + .attr('refX', 9) + .attr('refY', 5) + .attr('markerUnits', 'userSpaceOnUse') + .attr('markerWidth', 12) + .attr('markerHeight', 12) .attr('orient', 'auto') .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. @@ -554,6 +571,7 @@ export default { drawLoop, drawBackgroundRect, insertArrowHead, + insertArrowFilledHead, insertSequenceNumber, insertArrowCrossHead, getTextObj,