Skip to content

Mermaid

Edgar Mesquita edited this page Aug 12, 2026 · 6 revisions

Mermaid

Since 0.2.0-preview.25

Mermaid, drawn by the design system — no mermaid.js, no SVG document, no target-specific renderer. A diagram is just more UI: nodes are Boxes on the theme's surface tokens, the decision diamond is a single-path Vector rhombus (the same vector door icons use on both targets), edges are orthogonal hairline Boxes with vector arrowheads, labels are Text. One tree, realized by the web realizer and by Photon, themed by the app's own IAppTheme.

Inside Markdown it is automatic — a ```mermaid fence renders as the diagram — and Mermaid(source) works standalone.

Mermaid(source)                       // standalone

Markdown(chatAnswer)                  // a ```mermaid fence inside renders natively

The v1 grammar

Spoken Notes
graph TD / graph TB / flowchart LR the two flow axes; BT/RL fall back
A[rect], A(rounded), A((circle)), A{diamond} quoted labels lose their quotes
A --> B --> C, A --- B, `A --> label
sequenceDiagram, participant A as Alice messages auto-declare unseen participants
A->>B: text, A-->>B: text, self messages a self message loops out and back
%% comments, subgraph/end, style, click, notes skipped, never fatal — the graph still draws

Graceful by contract: a grammar outside the subset (gantt, classDiagram, state, pie) renders as the fenced code it came from — a chat answer with an exotic diagram degrades to something true, never to a broken picture.

Layout parity is pinned, not hoped for

The parser and the layout run on every side — C# for SSR and Photon, the transpiled twin in the browser — so the layout's math is integers and exact halves throughout: node sizes come from a flat character-advance estimate, positions accumulate by addition, and barycenter ORDER is decided by cross-multiplied integer sums (sumA·countB < sumB·countA), never a division. Ranking is Sugiyama-lite over the DAG: an iterative DFS marks cycle-closing edges, so a back edge routes upward instead of inflating every rank before it.

The pinned fixture (__fixtures__/mermaid-layout.txt, regenerate with EQ_UPDATE_MERMAID_FIXTURE=1) is asserted character-identical by MermaidTests.cs and mermaid.spec.ts — if the two compilations ever placed a box differently, a suite breaks before a page jumps at hydration.

Fences (v1, deliberate)

  • Text width is an estimate, not a measurement — honest for a diagram, deterministic everywhere.
  • Diamonds are square by construction (a Vector draws into a square box); long decision labels ellipsize.
  • Edges are orthogonal — the curved splines mermaid.js draws would need a stroked-path node the vocabulary doesn't have yet (the same future gap as italic text: named, not hidden).
  • One nesting rung for flowchart ranks' siblings; subgraph GROUPING is skipped (statements inside still parse).

Clone this wiki locally