State Diagram
State diagrams are used to give an abstract description of the behavior of a system. This behavior is represented as a series of events that can occur in one or more possible states.
Composite state
A state can also be composite. You have to define it using the state
keywords and brackets.
Internal sub-state
@startuml
scale 350 width
[*] --> NotShooting
state NotShooting {
[*] --> Idle
Idle --> Configuring : EvConfig
Configuring --> Idle : EvConfig
}
state Configuring {
[*] --> NewValueSelection
NewValueSelection --> NewValuePreview : EvNewValue
NewValuePreview --> NewValueSelection : EvNewValueRejected
NewValuePreview --> NewValueSelection : EvNewValueSaved
state NewValuePreview {
State1 -> State2
}
}
@enduml
Sub-state to sub-state
[Ref. QA-3300]
Long name
You can also use the state
keyword to use long description
for states.
@startuml
scale 600 width
[*] -> State1
State1 --> State2 : Succeeded
State1 --> [*] : Aborted
State2 --> State3 : Succeeded
State2 --> [*] : Aborted
state State3 {
state "Accumulate Enough Data\nLong State Name" as long1
long1 : Just a test
[*] --> long1
long1 --> long1 : New Data
long1 --> ProcessData : Enough Data
}
State3 --> State3 : Failed
State3 --> [*] : Succeeded / Save Result
State3 --> [*] : Aborted
@enduml
History [[H], [H\*]]
You can use [H]
for the history and [H*]
for the deep history of a substate.
@startuml
[*] -> State1
State1 --> State2 : Succeeded
State1 --> [*] : Aborted
State2 --> State3 : Succeeded
State2 --> [*] : Aborted
state State3 {
state "Accumulate Enough Data" as long1
long1 : Just a test
[*] --> long1
long1 --> long1 : New Data
long1 --> ProcessData : Enough Data
State2 --> [H]: Resume
}
State3 --> State2 : Pause
State2 --> State3[H*]: DeepResume
State3 --> State3 : Failed
State3 --> [*] : Succeeded / Save Result
State3 --> [*] : Aborted
@enduml
Concurrent state [--, \|\|]
You can define concurrent state into a composite state using either --
or ||
symbol as separator.
Horizontal separator --
@startuml
[*] --> Active
state Active {
[*] -> NumLockOff
NumLockOff --> NumLockOn : EvNumLockPressed
NumLockOn --> NumLockOff : EvNumLockPressed
--
[*] -> CapsLockOff
CapsLockOff --> CapsLockOn : EvCapsLockPressed
CapsLockOn --> CapsLockOff : EvCapsLockPressed
--
[*] -> ScrollLockOff
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
}
@enduml
Vertical separator ||
@startuml
[*] --> Active
state Active {
[*] -> NumLockOff
NumLockOff --> NumLockOn : EvNumLockPressed
NumLockOn --> NumLockOff : EvNumLockPressed
||
[*] -> CapsLockOff
CapsLockOff --> CapsLockOn : EvCapsLockPressed
CapsLockOn --> CapsLockOff : EvCapsLockPressed
||
[*] -> ScrollLockOff
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
}
@enduml
Stereotypes full example [start, choice, fork, join, end]
@startuml
state start1 <>
state choice1 <>
state fork1 <>
state join2 <>
state end3 <>
[*] --> choice1 : from start\nto choice
start1 --> choice1 : from start stereo\nto choice
choice1 --> fork1 : from choice\nto fork
choice1 --> join2 : from choice\nto join
choice1 --> end3 : from choice\nto end stereo
fork1 ---> State1 : from fork\nto state
fork1 --> State2 : from fork\nto state
State2 --> join2 : from state\nto join
State1 --> [*] : from state\nto end
join2 --> [*] : from join\nto end
@enduml
Pin [inputPin, outputPin]
You can added pin with <<inputPin>>
and <<outputPin>>
stereotypes:
@startuml
state Somp {
state entry1 <>
state entry2 <>
state sin
entry1 --> sin
entry2 -> sin
sin -> sin2
sin2 --> exitA <>
}
[*] --> entry1
exitA --> Foo
Foo1 -> entry2
@enduml
[Ref. QA-4309]
Expansion [expansionInput, expansionOutput]
You can added expansion with <<expansionInput>>
and <<expansionOutput>>
stereotypes:
@startuml
state Somp {
state entry1 <>
state entry2 <>
state sin
entry1 --> sin
entry2 -> sin
sin -> sin2
sin2 --> exitA <>
}
[*] --> entry1
exitA --> Foo
Foo1 -> entry2
@enduml
[Ref. QA-4309]
Arrow direction
You can use ->
for horizontal arrows. It is possible to
force arrow’s direction using the following syntax:
* -down->
or -->
* -right->
or ->
(default arrow)
* -left->
* -up->
You can shorten the arrow definition by using only the first character of the direction (for example, -d-
instead of
-down-
)
or the two first characters (-do-
).
Please note that you should not abuse this functionality : Graphviz gives usually good results without tweaking.
Change line color and style
Note
You can also define notes using
note left of
, note right of
, note top of
, note bottom of
keywords.
You can also define notes on several lines.
@startuml
[*] --> Active
Active --> Inactive
note left of Active : this is a short\nnote
note right of Inactive
A note can also
be defined on
several lines
end note
@enduml
You can also have floating notes.
Inline color
@startuml
state CurrentSite #pink {
state HardwareSetup #lightblue {
state Site #brown
Site -[hidden]-> Controller
Controller -[hidden]-> Devices
}
state PresentationSetup{
Groups -[hidden]-> PlansAndGraphics
}
state Trends #FFFF77
state Schedule #magenta
state AlarmSupression
}
@enduml
[Ref. QA-1812]
Skinparam
You can use the link::skinparam[skinparam] command to change colors and fonts for the drawing.
You can use this command : * In the diagram definition, like any other commands, * In an link::preprocessing[included file], * In a configuration file, provided in the link::command-line[command line] or the link::ant-task[Ant task]. You can define specific color and fonts for stereotyped states.
@startuml
skinparam backgroundColor LightYellow
skinparam state {
StartColor MediumBlue
EndColor Red
BackgroundColor Peru
BackgroundColor<> Olive
BorderColor Gray
FontName Impact
}
[*] --> NotShooting
state "Not Shooting State" as NotShooting {
state "Idle mode" as Idle <>
state "Configuring mode" as Configuring
[*] --> Idle
Idle --> Configuring : EvConfig
Configuring --> Idle : EvConfig
}
NotShooting --> [*]
@enduml
Test of all specific skinparam to State Diagrams
@startuml
skinparam State {
AttributeFontColor blue
AttributeFontName serif
AttributeFontSize 9
AttributeFontStyle italic
BackgroundColor palegreen
BorderColor violet
EndColor gold
FontColor red
FontName Sanserif
FontSize 15
FontStyle bold
StartColor silver
}
state A : a a a\na
state B : b b b\nb
[*] -> A : start
A -> B : a2b
B -> [*] : end
@enduml
Changing style
You can change link::style-evolution[style].
@startuml
[*] --> NotShooting
state "Not Shooting State" as NotShooting {
state "Idle mode" as Idle <>
state "Configuring mode" as Configuring
[*] --> Idle
Idle --> Configuring : EvConfig
Configuring --> Idle : EvConfig
}
NotShooting --> [*]
@enduml
@startuml
state state1
state state2
state choice1 <>
state end3 <>
state1 --> choice1 : 1
choice1 --> state2 : 2
choice1 --> end3 : 3
@enduml
[Ref. GH-880]
Change state color and style (inline style)
You can change the link::color[color] or style of individual state using the following notation:
-
#color ##[style]color
With background color first (#color
), then line style and line color (##[style]color
).
@startuml
state FooGradient #red-green ##00FFFF
state FooDashed #red|green ##[dashed]blue {
}
state FooDotted ##[dotted]blue {
}
state FooBold ##[bold] {
}
state Foo1 ##[dotted]green {
state inner1 ##[dotted]yellow
}
state out ##[dotted]gold
state Foo2 ##[bold]green {
state inner2 ##[dotted]yellow
}
inner1 -> inner2
out -> inner2
@enduml
[Ref. QA-1487]
-
#color;line:color;line.[bold|dashed|dotted];text:color
[[#FFD700#FIXME]] 🚩
text:color
seems not to be taken into account
[[#FFD700#FIXME]]
@startuml
@startuml
state FooGradient #red-green;line:00FFFF
state FooDashed #red|green;line.dashed;line:blue {
}
state FooDotted #line.dotted;line:blue {
}
state FooBold #line.bold {
}
state Foo1 #line.dotted;line:green {
state inner1 #line.dotted;line:yellow
}
state out #line.dotted;line:gold
state Foo2 #line.bold;line:green {
state inner2 #line.dotted;line:yellow
}
inner1 -> inner2
out -> inner2
@enduml
@enduml
@startuml
state s1 : s1 description
state s2 #pink;line:red;line.bold;text:red : s2 description
state s3 #palegreen;line:green;line.dashed;text:green : s3 description
state s4 #aliceblue;line:blue;line.dotted;text:blue : s4 description
@enduml
[Adapted from QA-3770]
Alias
With State you can use alias
, like:
@startuml
state alias1
state "alias2"
state "long name" as alias3
state alias4 as "long name"
alias1 : ""state alias1""
alias2 : ""state "alias2"""
alias3 : ""state "long name" as alias3""
alias4 : ""state alias4 as "long name"""
alias1 -> alias2
alias2 -> alias3
alias3 -> alias4
@enduml
or:
Display JSON Data on State diagram
Simple example
@startuml
state "A" as stateA
state "C" as stateC {
state B
}
json jsonJ {
"fruit":"Apple",
"size":"Large",
"color": ["Red", "Green"]
}
@enduml
[Ref. QA-17275]
For another example, see on link::json#wqimfur1rox7ld5sjljq[JSON page].