State diagrams
stateDiagram-v2 opens a state diagram. There is no in-diagram direction keyword; the author default is top-to-bottom.
With a Viewport, responsive layout may flip wide diagrams to horizontal so they use available width (same rules as
flowcharts). Without a viewport, layout stays vertical.
MermoidAscent.svgDiagram(orderFsm)Transitions
From --> To declares a transition; : label names it. States do not need declaring — every id mentioned by a
transition becomes a state, rendered as a Round node labelled with its own id.
MermoidAscent.svgDiagram("""stateDiagram-v2
Idle --> Running: start
Running --> Idle: stop
""".stripMargin)That is a two-state cycle, and it lays out rather than looping forever — layering breaks cycles.
Start and end
[*] is the start/end pseudo-state: a filled 16×16 circle carrying the start-end class, with no label. Whether it
reads as start or end is positional: [*] --> A versus A --> [*].
When a diagram uses both, mermoid paints two markers (start keeps id [*], end is [*]-end) so ranking does not
cycle through a shared node and flip the layout. A diagram that only has one role still uses a single [*] node.
MermoidAscent.svgDiagram("""stateDiagram-v2
[*] --> Active
Active --> [*]
""".stripMargin)Notes
note right of Idle
waiting for work
end note
right of and left of are both supported. Note text is multi-line; each line is trimmed and blank lines dropped. A
note renders as a dashed box joined to its state by a dashed connector, and the diagram's bounding box grows to hold it,
including shifting the whole diagram right when a left of note would otherwise fall outside the canvas.
When the preferred side would overlap another node (common in horizontal / flipped layouts), the placer tries the other side and then a vertical offset before settling.
MermoidAscent.svgDiagram("""stateDiagram-v2
[*] --> Idle
Idle --> Running: start
Running --> Idle: finish
note right of Idle
no work in flight
polls every 5s
end note
note left of Running
at most one job
end note
""".stripMargin)Styling from the diagram source
classDef, class, :::, and style are the same statements as on flowcharts. classDef becomes
a CSS rule, class / ::: put the name on the state's node, and style can still set noteAlign as well as fill and
stroke.
MermoidAscent.svgDiagram("""stateDiagram-v2
classDef happy fill:#1f4a35,stroke:#7dcea0
classDef warn fill:#4a4030,stroke:#e0c070
classDef sad fill:#5c2a2a,stroke:#f0a0a0
[*] --> Green
Green --> Yellow: Timer
Yellow --> Red: Timer
Red --> Green: Timer
class Green happy
class Yellow warn
class Red sad
""".stripMargin)Green:::happy --> Yellow:::warn is the same assignment written on the transition.
Note text alignment
style <state> noteAlign: left | center | right sets how that state's note text is aligned. The default is left.
MermoidAscent.svgDiagram("""stateDiagram-v2
[*] --> Ready
Ready --> Done: go
style Ready noteAlign: center
note right of Ready
centered
note text
end note
""".stripMargin)Note aliases
Like edges, notes take as <name> to pin their element id. Without it a note is note-{stateId}-{index}, so adding an
earlier note on the same state renumbers the later ones.
MermoidAscent.svgDiagram("""stateDiagram-v2
[*] --> Idle
Idle --> Done: go
note right of Idle as caveat
do not skip idle
end note
""".stripMargin)Self-transitions
A state can transition to itself, and stacked self-transitions stack their labels. The diagram's height accounts for the loops, and for notes pushed below them.
MermoidAscent.svgDiagram("""stateDiagram-v2
[*] --> Retrying
Retrying --> Retrying: attempt failed
Retrying --> Retrying: backoff elapsed
Retrying --> Done: succeeded
""".stripMargin)Not yet implemented
Composite (nested) states, concurrency (--), an in-diagram direction, and state X as "long name" declarations are
not implemented. click is flowchart-only; state diagrams have no click statement. A state diagram that needs nesting
can be expressed as a flowchart with subgraphs today.