Sequence diagram: activation bars and control flow blocks#174
Conversation
- Parser: activate/deactivate (standalone and +/- shorthand on messages) - Parser: loop/alt/par/critical/break CF blocks; else/and/option separators - Parser: unified openBlocks stack for rect and CF blocks; auto-close unclosed activations - Layout: position activation bars on lifelines with nesting level offsets - Layout: position CF blocks as full-width bands (same logic as rect bands) - Renderer: AppendActivationBars after lifelines; AppendSequenceCfBlock with dashed border + label tab - Tests: 27 new unit tests covering all new parser features - E2E: two new snapshot fixtures (activation, cf-blocks) Agent-Logs-Url: https://github.com/jongalloway/DiagramForge/sessions/a7c2c7e5-637e-4b72-8a9c-2d2df2ed3f02 Co-authored-by: jongalloway <68539+jongalloway@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds Mermaid sequence-diagram support for activation bars and UML-style control-flow (combined-fragment) blocks, spanning parser → layout → SVG rendering, with new unit + snapshot tests.
Changes:
- Parser: adds
activate/deactivate,+/-shorthand handling, and CF blocks (loop/alt/par/critical/break+ separators). - Layout: computes activation bar geometry and reuses index-range → Y-range logic for CF blocks.
- Rendering: draws activation bars after lifelines and renders CF blocks as dashed bordered regions with a keyword tab.
Show a summary per file
| File | Description |
|---|---|
src/DiagramForge/Parsers/Mermaid/MermaidSequenceParser.cs |
Parses activation directives/shorthand and CF blocks; unifies open block tracking. |
src/DiagramForge/Layout/DefaultLayoutEngine.Sequence.cs |
Lays out activation bars and positions CF-block groups using message index ranges. |
src/DiagramForge/Rendering/SvgStructureWriter.cs |
Renders CF blocks (combined fragments) and activation bars (dedicated pass). |
src/DiagramForge/Rendering/SvgRenderer.cs |
Integrates activation bar rendering into the sequence render pipeline. |
tests/DiagramForge.Tests/Parsers/Mermaid/MermaidSequenceParserTests.cs |
Adds unit coverage for activation and CF parsing behaviors. |
tests/DiagramForge.E2ETests/Fixtures/mermaid-sequence-activation.* |
Adds snapshot fixture for activation bar rendering. |
tests/DiagramForge.E2ETests/Fixtures/mermaid-sequence-cf-blocks.* |
Adds snapshot fixture for CF block rendering. |
Copilot's findings
- Files reviewed: 7/9 changed files
- Comments generated: 3
| || line.Equals("end", StringComparison.OrdinalIgnoreCase) | ||
| || IsCfSeparator(line) | ||
| || TryParseCfKeyword(line, out _, out _) | ||
| || TryParseMessage(line, out _, out _, out _, out _, out _); |
There was a problem hiding this comment.
IsSequenceKeyword now treats control-flow separators/keywords (else/and/option, loop/alt/etc.) as hard sequence keywords. This can break multi-line note continuation: an indented note line beginning with e.g. and/else will stop being appended to the pending note, and then gets swallowed by the IsCfSeparator(line) branch—dropping user text. Consider excluding CF separators/keywords from the note-continuation keyword check (or only treating them as keywords when actually inside an open CF block).
| kind = label = null; | ||
|
|
||
| ReadOnlySpan<string> keywords = ["loop", "alt", "par", "critical", "break"]; | ||
|
|
||
| foreach (var kw in keywords) |
There was a problem hiding this comment.
TryParseCfKeyword builds the keywords span from a collection expression on each call. Since this runs once per input line (and is also invoked from IsSequenceKeyword), it can introduce avoidable allocations/overhead. Consider hoisting the keyword set to a static readonly field (or similar) and matching against it.
| @@ -168,14 +174,20 @@ private static void LayoutSequenceDiagram( | |||
|
|
|||
| diagram.Metadata["sequence:canvasWidth"] = canvasWidth; | |||
|
|
|||
There was a problem hiding this comment.
Sequence canvasWidth is finalized and stored before CF groups are laid out, but CF rendering adds a keyword/label tab whose width is based on estimated text width. For long CF labels the tab can exceed canvasWidth, and because SvgRenderer uses sequence:canvasWidth as the final SVG width, the tab/text can be clipped at the right edge. Consider expanding canvasWidth during layout based on the maximum CF tab width (and updating group widths accordingly).
|
@copilot apply changes based on the comments in this thread |
- Remove IsCfSeparator/TryParseCfKeyword from IsSequenceKeyword so CF words in multi-line note continuations are preserved (e.g. 'else', 'and', 'loop') - Hoist CfKeywords array to a static readonly field to avoid per-call allocations - Expand canvasWidth in layout when a CF block's keyword tab exceeds the current canvas width, preventing long labels from being clipped - Add regression test for CF words in note continuation lines Agent-Logs-Url: https://github.com/jongalloway/DiagramForge/sessions/0f3c8c0d-de52-4b1e-a99d-360569395469 Co-authored-by: jongalloway <68539+jongalloway@users.noreply.github.com>
All three review points addressed in b3c22f7:
|
Adds support for Mermaid sequence diagram activation bars (
activate/deactivate,+/-shorthand) and control flow blocks (loop,alt,par,critical,break).Parser
activate X/deactivate Xstandalone directives+/-activation shorthand on message targets:A->>+B: callactivates B;B-->>-A: replydeactivates the source (B)loop/alt/par/critical/break [label]open a CF block;else/and/optionare consumed as section separators without closing;endcloses the innermost blockopenBlocksstack replacesopenRects— handles both rect bands and CF blocksLayout
LayoutSequenceActivationBars: places 8px-wide bars centered on participant lifelines; nesting level offsets bars to the right so stacked activations remain distinctRendering
AppendActivationBars(new, called afterAppendLifelines): renders narrow theme-colored<rect>elements on lifelinesAppendSequenceCfBlock(new): renders UML combined-fragment style — dashed border, light fill, solid keyword tab at top-left (e.g.loop [Retry up to 3 times])AppendGrouppassTests
mermaid-sequence-activation,mermaid-sequence-cf-blocks