State diagram
Mermaid state diagram syntax is compatible with the syntax used in plantUml, which makes it easier for users to share diagrams between mermaid and plantUml.
Copy
Embed
---
title: Simple sample
---
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
Old editor:
Copy
Embed
stateDiagram
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
New editor:
In a state diagram, a system is described in terms of states and how one state changes to another through transitions. The example diagram above shows three states: Still, Moving, and Crash. You start in the Still state, and from the Still state you can change to Moving. From Moving, you can go back to Still, or change to Crash. There is no transition from Still to Crash. (If you remain still, you will not crash.)
状态
States can be declared in several ways; the simplest is to define a state with just an id:
Copy
Embed
stateDiagram-v2
stateId
Another way is to use the state syntax and add the following description:
Copy
Embed
stateDiagram-v2
state "This is a state description" as s2
Another way to define a state with a description is to first define the state ID, then add a colon and the description:
Copy
Embed
stateDiagram-v2
s2 : This is a state description
Transitions
A transition is the link when one state moves to another state, represented by the text arrow "-->".
When you define a transition between two states and the states are not yet defined, the undefined states will be defined using the id from the transition. Afterwards, you can add descriptions for the states defined in this way.
Copy
Embed
stateDiagram-v2
s1 --> s2
Text can be added to a transition to describe what it represents:
Copy
Embed
stateDiagram-v2
s1 --> s2: A transition
Start and end
There are two special states that represent the start and stop of a diagram. These two states are represented by the [*] syntax, and the direction of the transition to that state determines whether it is a start state or an end state.
Copy
Embed
stateDiagram-v2
[*] --> s1
s1 --> [*]
Composite states
When using state diagrams in the real world, you will often encounter multi-dimensional diagrams, because a state can have multiple internal states; this is called a composite state.
To define a composite state, you need to use the state syntax, followed by an id, and write the body of the composite state in braces {}. You can name a composite state on a separate line just as you would define a simple state. See the example below:
Copy
Embed
stateDiagram-v2
[*] --> First
state First {
[*] --> second
second --> [*]
}
[*] --> NamedComposite
NamedComposite: Another Composite
state NamedComposite {
[*] --> namedSimple
namedSimple --> [*]
namedSimple: Another simple
}
You can operate at several levels:
Copy
Embed
stateDiagram-v2
[*] --> First
state First {
[*] --> Second
state Second {
[*] --> second
second --> Third
state Third {
[*] --> third
third --> [*]
}
}
}
You can also define transitions between composite states:
Copy
Embed
stateDiagram-v2
[*] --> First
First --> Second
First --> Third
state First {
[*] --> fir
fir --> [*]
}
state Second {
[*] --> sec
sec --> [*]
}
state Third {
[*] --> thi
thi --> [*]
}
Note: transitions between internal states belonging to different composite states cannot be defined.
Choice
Sometimes you need to model a choice between two or more paths; this can be done using <<choice>>.
Copy
Embed
stateDiagram-v2
state if_state <<choice>>
[*] --> IsPositive
IsPositive --> if_state
if_state --> False: if n < 0
if_state --> True : if n >= 0
Fork/merge
You can use <<fork>> <<join>> to specify a fork/join in the diagram.
Copy
Embed
stateDiagram-v2
state fork_state <<fork>>
[*] --> fork_state
fork_state --> State2
fork_state --> State3
state join_state <<join>>
State2 --> join_state
State3 --> join_state
join_state --> State4
State4 --> [*]
Note
Using notes in a state diagram expresses things more clearly; a note can optionally be placed on the right or left side of a node.
Copy
Embed
stateDiagram-v2
State1: The state with a note
note right of State1
Important information! You can write
notes.
end note
State1 --> State2
note left of State2 : This is the note to the left.
Concurrency
As in plantUml, you can use the dash symbol -- to specify concurrency.
Copy
Embed
stateDiagram-v2
[*] --> Active
state Active {
[*] --> NumLockOff
NumLockOff --> NumLockOn : EvNumLockPressed
NumLockOn --> NumLockOff : EvNumLockPressed
--
[*] --> CapsLockOff
CapsLockOff --> CapsLockOn : EvCapsLockPressed
CapsLockOn --> CapsLockOff : EvCapsLockPressed
--
[*] --> ScrollLockOff
ScrollLockOff --> ScrollLockOn : EvScrollLockPressed
ScrollLockOn --> ScrollLockOff : EvScrollLockPressed
}
Setting the diagram direction
For a state diagram, you can use a direction statement to set the diagram rendering direction, as shown in this example.
Copy
Embed
stateDiagram
direction LR
[*] --> A
A --> B
B --> C
state B {
direction LR
a --> b
}
B --> D
Notes
Comments can be entered in a state diagram and will be ignored by the editor. Comments must begin with a double percent sign (%%), and all text from that marker to the next line break will be treated as a comment, including any diagram syntax. Comments can occupy a line by themselves or be placed at the end of a statement.
Copy
Embed
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
Styling with classDefs
Current limitations of state diagram classDef:
1. Cannot be applied to the start or end state
2. Cannot be applied to a composite state or inside a composite state
You can use the classDef syntax (short for class definition, where "class" is similar to a class in CSS) to define styles. classDef is followed by the style name, then one or more 'property-value' pairs, each consisting of a valid CSS property name, a colon (:), and the corresponding value.
The following is an example of a classDef with only one 'property-value':
Copy
Embed
classDef movement font-style:italic;
- The style name is movement
- The only property is font-style, and the value is italic
If you want to have multiple 'property-value' pairs, you can place a comma (,) between each 'property-value'.
The following is an example containing three 'property-value' pairs:
Copy
Embed
classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
- The style name is badBadEvent
- The first property is fill, whose value is #f00
- The second property is color, whose value is white
- The third property is font-weight, whose value is bold
- The fourth property is stroke-width, whose value is 2px
- The fifth property is stroke, whose value is yellow
Applying classDef styles to states
There are two ways to apply classDef styles to states:
- Use the class syntax to apply a classDef style to one or more states in a single statement
- Use the ::: operator to apply a classDef style when a state is used in a transition statement (for example, with arrows pointing to/from another state)
1. class statement
The class statement tells Mermaid to apply the specified classDef to one or more classes. The form is:
Copy
Embed
class [one or more state names, separated by commas] [name of a style defined with classDef]
The following is an example of applying the badBadEvent style to a state named Crash:
Copy
Embed
class Crash badBadEvent
The following is an example of applying the movement style to the two states Moving and Crash:
Copy
Embed
class Moving,Crash movement
Here is an example. Note that the Crash state has two classDef styles applied: movement and badBadEvent
Copy
Embed
stateDiagram
direction TB
accTitle: This is the accessible title
accDescr: This is an accessible description
classDef notMoving fill:white
classDef movement font-style:italic
classDef badBadEvent fill:pink,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
[*]--> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
class Still notMoving
class Moving, Crash movement
class Crash badBadEvent
class end badBadEvent
2. Applying styles to states using the ::: operator
You can use the operator ::: to apply a classDef style to a state. The syntax is:
Copy
Embed
[state]:::[style name]
You can apply it in statements that use a class, including the start state and the end state. For example:
Copy
Embed
stateDiagram
direction TB
accTitle: This is the accessible title
accDescr: This is an accessible description
classDef notMoving fill:white
classDef movement font-style:italic;
classDef badBadEvent fill:pink,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
[*] --> Still:::notMoving
Still --> [*]
Still --> Moving:::movement
Moving --> Still
Moving --> Crash:::movement
Crash:::badBadEvent --> [*]
Spaces in state names
You can first define a state with an id, then reference that id afterwards to add spaces to the state.
In the following example, there is a state whose ID is yswsii and whose description is ''Your state with spaces in it''. After being defined, yswsii is used in the first transition of the diagram ([*] --> yswsii), and it is also used in the transition to YetAnotherState (yswsii --> YetAnotherState). yswsii has been styled so that it differs from the other states.
Copy
Embed
stateDiagram
classDef yourState font-style:italic,font-weight:bold,fill:white
yswsii: Your state with spaces in it
[*] --> yswsii:::yourState
[*] --> SomeOtherState
SomeOtherState --> YetAnotherState
yswsii --> YetAnotherState
YetAnotherState --> [*]