狀態圖
Mermaid 狀態圖語法與 plantUml 中使用的語法相容,這將使使用者更容易在 Mermaid 和 plantUml 之間共用圖表。
複製
嵌入
---
title: Simple sample
---
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
舊編輯器:
複製
嵌入
stateDiagram
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
新編輯器:
在狀態圖中,系統是根據狀態以及一個狀態如何透過轉換變更為另一種狀態來描述的。上面的範例圖顯示了三種狀態:靜止、移動和碰撞。你從靜止狀態開始,從靜止狀態可以變為移動狀態。從移動狀態,你可以回到靜止狀態,或者變為碰撞狀態。沒有從靜止狀態到碰撞狀態的轉換。(如果保持靜止,你不會發生碰撞。)
状态
可以透過多種方式宣告狀態,最簡單的方法是僅用一個 id 來定義狀態:
複製
嵌入
stateDiagram-v2
stateId
另一種方法是使用 state 語法,並新增以下描述:
複製
嵌入
stateDiagram-v2
state "This is a state description" as s2
定義帶有描述的狀態的另一種方法是先定義狀態 ID,然後新增冒號和描述:
複製
嵌入
stateDiagram-v2
s2 : This is a state description
轉換
轉換是指當一個狀態進入另一個狀態時的連接線,使用文字箭頭 "-->" 表示。
當你定義兩個狀態之間的轉換,並且狀態尚未定義時,未定義的狀態將使用轉換中的 id 進行定義。之後,你可以為以這種方式定義的狀態新增描述。
複製
嵌入
stateDiagram-v2
s1 --> s2
可以向轉換中新增文字來描述它所代表的內容:
複製
嵌入
stateDiagram-v2
s1 --> s2: A transition
開始和結束
有兩種特殊狀態表示圖表的開始和停止。這兩個狀態使用 [*] 語法表示,其到該狀態的轉移方向決定了它是開始狀態還是結束狀態。
複製
嵌入
stateDiagram-v2
[*] --> s1
s1 --> [*]
複合狀態
在現實世界中使用狀態圖時,你經常會遇到多維的圖,因為一個狀態可以有多個內部狀態,這被稱為複合狀態。
為了定義複合狀態,你需要使用 state 語法,後面跟一個 id,並在大括號 {} 中寫出複合狀態的主體。你可以像定義簡單狀態一樣,在單獨的一行上命名複合狀態。請參閱下面的範例:
複製
嵌入
stateDiagram-v2
[*] --> First
state First {
[*] --> second
second --> [*]
}
[*] --> NamedComposite
NamedComposite: Another Composite
state NamedComposite {
[*] --> namedSimple
namedSimple --> [*]
namedSimple: Another simple
}
你可以分幾個層次來操作:
複製
嵌入
stateDiagram-v2
[*] --> First
state First {
[*] --> Second
state Second {
[*] --> second
second --> Third
state Third {
[*] --> third
third --> [*]
}
}
}
你還可以定義複合狀態之間的轉換:
複製
嵌入
stateDiagram-v2
[*] --> First
First --> Second
First --> Third
state First {
[*] --> fir
fir --> [*]
}
state Second {
[*] --> sec
sec --> [*]
}
state Third {
[*] --> thi
thi --> [*]
}
注意:不能定義屬於不同複合狀態的內部狀態之間的轉換。
選擇
有時你需要模擬在兩條或多條路徑之間做出選擇,可以使用 <<choice>> 來實現。
複製
嵌入
stateDiagram-v2
state if_state <<choice>>
[*] --> IsPositive
IsPositive --> if_state
if_state --> False: if n < 0
if_state --> True : if n >= 0
分叉/合併
可以使用 <<fork>> <<join>> 在圖中指定一個分叉/合併。
複製
嵌入
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 --> [*]
注意
狀態圖中使用註解更能清晰地表達,可以選擇將註解放在節點的右側或左側。
複製
嵌入
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.
並行
與在 plantUml 中一樣,你可以使用連字號符號 -- 指定並行性。
複製
嵌入
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
}
設定圖表方向
對於狀態圖,你可以使用方向陳述式來設定圖表渲染方向,如本例所示。
複製
嵌入
stateDiagram
direction LR
[*] --> A
A --> B
B --> C
state B {
direction LR
a --> b
}
B --> D
註解
可以在狀態圖表中輸入註解,編輯器將忽略這些註解。註解必須以雙百分比符號 (%%) 開頭,從該標記到下一個換行字元之間的所有文字都將被視為註解,包括任何圖表語法。註解可以單獨佔一行,也可以放在陳述式的末尾。
複製
嵌入
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
使用 classDefs 設定樣式
狀態圖 classDef 目前限制:
1. 不能套用於開始或結束狀態
2. 不能套用於複合狀態或複合狀態內部
你可以使用 classDef 語法(即 class definition 的縮寫,其中的「class」類似於 CSS 中的類別)來定義樣式。classDef 後面是樣式名稱,再接一個或多個「屬性-值」,每個「屬性-值」由一個合法的 CSS 屬性名稱、一個冒號(:)以及相應的值組成。
下面是只有一個「屬性-值」的 classDef 的範例:
複製
嵌入
classDef movement font-style:italic;
- 樣式名稱是 movement
- 唯一的屬性是 font-style,值是 italic
如果你想擁有多個「屬性-值」,則可以在每個「屬性-值」之間放置一個逗號 (,)。
下面是一個包含三個「屬性-值」的範例:
複製
嵌入
classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
- 樣式名稱是 badBadEvent
- 第一個屬性是 fill,其值是 #f00
- 第二個屬性是 color,其值是 white
- 第三個屬性是 font-weight,其值是 bold
- 第四個屬性是 stroke-width,其值是 2px
- 第五個屬性是 stroke,其值是 yellow
將 classDef 樣式套用於狀態
有兩種方法可以將 classDef 樣式套用於狀態:
- 使用 class 語法在一個陳述式中將 classDef 樣式套用到一個或多個狀態
- 使用 ::: 運算子在狀態被用於轉換陳述式時套用 classDef 樣式(例如,帶箭頭指向/來自另一個狀態)
1. class 陳述式
class 陳述式告訴 Mermaid 將指定的 classDef 套用於一個或多個類別。形式為:
複製
嵌入
class [one or more state names, separated by commas] [name of a style defined with classDef]
以下是將 badBadEvent 樣式套用於名為 Crash 的狀態的範例:
複製
嵌入
class Crash badBadEvent
以下是將 movement 樣式套用於 Moving 和 Crash 兩個狀態的範例:
複製
嵌入
class Moving,Crash movement
這裡有一個範例。請注意,Crash 狀態套用了兩個 classDef 樣式:movement 和 badBadEvent
複製
嵌入
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. 使用 ::: 運算子為狀態套用樣式
你可以使用運算子 ::: 將 classDef 樣式套用於狀態。語法是:
複製
嵌入
[state]:::[style name]
你可以在使用類別的陳述式套用它,這包括開始狀態和結束狀態。例如:
複製
嵌入
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 --> [*]
狀態名稱的空格
可以先使用 id 定義狀態,然後在之後引用該 id 來為狀態新增空格。
在以下範例中,有一個狀態,其 ID 為 yswsii,描述為「Your state with spaces in it」。定義後,yswsii 在圖表的第一個轉換中使用 ([*] --> yswsii),並且在轉換到 YetAnotherState 時也使用了它 (yswsii --> YetAnotherState)。yswsii 已被設定樣式,使其與其他狀態不同。
複製
嵌入
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 --> [*]