“状态图(Statechart Diagram)是描述一个实体基于事件反应的动态行为,显示了该实体如何根据当前所处的状态对不同的事件做出反应。通常我们创建一个UML状态图是为了以下的研究目的:研究类、角色、子系统、或组件的复杂行为。” – 百度百科
Mermaid
可以渲染状态图。Mermaid
的语法试图与plantUml
中使用的语法保持一致,这样有助于用户在mermaid
和plantUml
之间共享图表。
CSDN mermaid v8.14.0
不支持标题 title
,以下是 mermaid v10.2.3
的代码
```mermaid
—
title: 简单示例
—
stateDiagram-v2
[*] --> 静止
静止 --> [*]
静止 --> 移动
移动 --> 静止
移动 --> 碰撞
碰撞 --> [*]
```
---
title: 简单示例
---
stateDiagram-v2
[*] --> 静止
静止 --> [*]
静止 --> 移动
移动 --> 静止
移动 --> 碰撞
碰撞 --> [*]
旧版本渲染效果:
```mermaid
stateDiagram
[*] --> 静止
静止 --> [*]
静止 --> 移动
移动 --> 静止
移动 --> 碰撞
碰撞 --> [*]
```
在状态图中,系统通过状态和状态之间的转换来描述。上面的示例图表展示了三个状态:静止
、移动
、碰撞
。你开始于静止
状态。从静止
可以转换到移动
状态。从 移动
可以转换回 静止
状态或转换至 碰撞
状态。从 静止
无法直接转换到 碰撞
。(如果你还静止
着,那就不可能碰撞
。)
一个状态可以有多种声明方式。最简单的方式是仅用序号
定义一个状态:
```mermaid
stateDiagram-v2
状态序号
```
另一种方法是使用 state
关键字和描述,如下所示:
```mermaid
stateDiagram-v2
state “这是状态1的描述” as 状态1
```
另一种定义带描述的状态的方法是先定义状态的序号
,接着加上冒号和该状态的描述,如下所示:
```mermaid
stateDiagram-v2
状态1 : 这是状态1的描述
```
转换是指一个状态通过路径/边缘转换到另一个状态的过程,这通常使用文本箭头“-->
”来表示。
当你在两个状态之间定义一个转换时,如果这些状态还没有被定义,那么这些未定义的状态会使用转换中的序号
进行定义。之后,你可以为这些使用转换ID定义的状态添加描述信息。
```mermaid
stateDiagram-v2
状态1 --> 状态2
```
可以向转换添加文本来描述其代表的内容:
```mermaid
stateDiagram-v2
状态1 --> 状态2: 转换
```
有两个特殊状态表示图表的起始和终止。它们使用的语法是 [*]
,转换的方向定义了它是起始状态还是终止状态。
```mermaid
stateDiagram-v2
[*] --> 状态1
状态1 --> [*]
```
在实际的状态图使用中,一个状态可能包含多个内部状态,从而产生了维度较高的状态图,这些状态被称为复合状态。
为定义一个复合状态,你需要使用 state
关键字,接着是复合状态的序号
,并将复合状态的内容放在大括号 {}
中。以下是一个示例:
```mermaid
stateDiagram-v2
[*] --> 复合状态1
state 复合状态1 {
[*] --> 状态2
状态2 --> [*]
}
```
你可以使用多层嵌套来定义复合状态:
```mermaid
stateDiagram-v2
[*] --> 复合状态1
state 复合状态1 {
[*] --> 复合状态2
state 复合状态2 {
[*] --> 状态2
状态2 --> 复合状态3
state 复合状态3 {
[*] --> 状态3
状态3 --> [*]
}
}
}
```
你也可以在复合状态之间定义转换:
```mermaid
stateDiagram-v2
[*] --> 复合状态1
复合状态1 --> 复合状态2
复合状态1 --> 复合状态3
state 复合状态1 {
[*] --> 状态1
状态1 --> [*]
}
state 复合状态2 {
[*] --> 状态2
状态2 --> [*]
}
state 复合状态3 {
[*] --> 状态3
状态3 --> [*]
}
```
你不能在属于不同复合状态的内部状态之间定义转换。
有时候你需要模拟在几条路径之间做出选择,可以使用 <
实现。
```mermaid
stateDiagram-v2
state 状态选择 <>
[*] --> 正数
正数 --> 状态选择
状态选择 --> 假: 如果 n < 0
状态选择 --> 真 : 如果 n >= 0
```
可以使用 <
<
在状态机中指定一个分支和合并。
```mermaid
stateDiagram-v2
state 分支 <>
[*] --> 分支
分支 --> 状态1
分支 --> 状态2
state 合并 <>
状态1 --> 合并
状态2 --> 合并
合并 --> 状态3
状态3 --> [*]
```
有时候,添加一个备注比任何语言都更能清晰地表达信息。在状态图中同样如此。
在状态图中,你可以选择将备注放置在节点的右侧或左侧。
```mermaid
stateDiagram-v2
direction LR
状态1: 这是状态1
note right of 状态1
重要信息!你可以写一些备注
end note
状态1 --> 状态2
note left of 状态2 : 这是在状态2左侧的备注.
```
在 plantUml
中,你可以使用 --
符号来指定并发行为。
```mermaid
stateDiagram-v2
[*] --> 激活
state 激活 {
[*] --> 数字锁定关闭
数字锁定关闭 --> 数字锁定开启 : 数字锁定键按下事件
数字锁定开启 --> 数字锁定关闭 : 数字锁定键按下事件
–
[*] --> 大写锁定关闭
大写锁定关闭 --> 大写锁定开启 : 大写锁定键按下事件
大写锁定开启 --> 大写锁定关闭 : 大写锁定键按下事件
–
[*] --> 滚动锁定关闭
滚动锁定关闭 --> 滚动锁定开启 : 滚动锁定键按下事件
滚动锁定开启 --> 滚动锁定关闭 : 滚动锁定键按下事件
}
```
可以设置以下几种方向:
在状态图中,你可以使用 direction
来设置状态图的排列方向,如下面的例子所示。
```mermaid
stateDiagram
direction LR
[*] --> 壹
壹 --> 贰
贰 --> 叁
state 贰 {
direction LR
一 --> 二
}
贰 --> 肆
```
在状态图中,可以添加注释来说明状态和转换之间的信息,这些注释对解析器来说是无效的。注释必须放在它们自己的一行上,并以 %%
(双百分号) 开头。任何在注释开始后到下一个新行之间的文本都将被视为注释,包括任何图表语法。
```mermaid
stateDiagram-v2
[*] --> 静止
静止 --> [*]
%% 这是一行注释
静止 --> 移动
移动 --> 静止 %% 这是行尾注释
移动 --> 碰撞
碰撞 --> [*]
```
与其他图表(如流程图)一样,在状态图中也可以定义样式,并将该命名样式应用于状态或状态集。
以下是目前使用状态图 classDefs 的限制:
您可以使用 classDef
关键字定义样式,它是“class definition
”的简称,其中 class
表示类似于 CSS
类的内容。接着是样式名称,然后是一个或多个属性-值对
。每个属性-值对
是有效的 CSS
属性名称,后面跟着一个冒号(:
),然后是一个值。
下面是一个只有一个属性-值对
的 classDef
示例。
classDef YiDongYangShi font-style:italic;
其中:
movement
是样式名称font-style
是唯一的属性,italic
是font-style
属性的值。如果您想使用多个属性-值对
,则可以在每个属性-值对
之间添加逗号(,
)。
这里有一个包含五个属性-值对
的示例:
classDef PengZhuangYangShi fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
其中:
badBadEvent
是样式名称属性-值对
的属性是fill
,其值是#f00
属性-值对
的属性是color
,其值是white
属性-值对
的属性是font-weight
,其值是bold
属性-值对
的属性是stroke-width
,其值是2px
属性-值对
的属性是stroke
,其值是yello
将 classDef 样式应用于状态有两种方法。
class
”关键字在单个语句中将 classDef 样式应用于一个或多个状态:::
”运算符在转换语句中将 classDef 样式应用于状态,例如通过箭头与另一个状态相连。class 语句告知 Mermaid 将指定的 classDef 应用于一个或多个元素。格式为:
class [一个或多个状态名, 使用逗号分开] [使用classDef定义的样式名]
以下是一个示例,将 PengZhuangYangShi
(碰撞样式) 样式应用于名为 PengZhuang
(碰撞) 的状态:
class PengZhuang PengZhuangYangShi
以下是一个示例,将 YiDongYangShi
(移动样式) 样式应用于名为YiDong
(移动) 和 PengZhuang
(碰撞) 两个状态:
class YiDong, PengZhuang YiDongYangShi
以下是一个图表,展示了这些示例的使用情况。请注意,Crash 状态应用了两种 classDef 样式:YiDongYangShi
和 PengZhuangYangShi
。
注意 classDef
和class
语句不支持Unicode字符(汉字等)。
CSDN mermaid v8.14.0
不支持样式设置 classDef
,class
,以下是 mermaid v10.2.3
的代码
```mermaid
stateDiagram
direction TB
accTitle: This is the accessible title
accDescr: This is an accessible description
classDef JingZhiYangShi fill:white
classDef YiDongYangShi font-style:italic
classDef PengZhuangYangShi fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
[*]–> JingZhi
JingZhi --> [*]
JingZhi --> YiDong
YiDong --> JingZhi
YiDong --> PengZhuang
PengZhuang --> [*]
class JingZhi JingZhiYangShi
class YiDong, PengZhuang YiDongYangShi
class PengZhuang PengZhuangYangShi
class end PengZhuangYangShi
```
stateDiagram
direction TB
accTitle: This is the accessible title
accDescr: This is an accessible description
classDef JingZhiYangShi fill:white
classDef YiDongYangShi font-style:italic
classDef PengZhuangYangShi fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
[*]--> JingZhi
JingZhi --> [*]
JingZhi --> YiDong
YiDong --> JingZhi
YiDong --> PengZhuang
PengZhuang --> [*]
class JingZhi JingZhiYangShi
class YiDong, PengZhuang YiDongYangShi
class PengZhuang PengZhuangYangShi
class end PengZhuangYangShi
您可以使用 :::
(三个冒号)运算符将 classDef 样式应用于状态。其语法为:
您可以在使用类语句的状态图中使用这个特性,包括开始和结束状态。例如:
CSDN mermaid v8.14.0
不支持样式设置 classDef
,:::
,以下是 mermaid v10.2.3
的代码
```mermaid
stateDiagram
direction TB
accTitle: This is the accessible title
accDescr: This is an accessible description
classDef JingZhiYangShi fill:white
classDef YiDongYangShi font-style:italic;
classDef PengZhuangYangShi fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
[*] --> 静止:::JingZhiYangShi
静止 --> [*]
静止 --> 移动:::YiDongYangShi
移动 --> 静止
移动 --> 碰撞:::YiDongYangShi
碰撞:::PengZhuangYangShi --> [*]
```
stateDiagram
direction TB
accTitle: This is the accessible title
accDescr: This is an accessible description
classDef JingZhiYangShi fill:white
classDef YiDongYangShi font-style:italic;
classDef PengZhuangYangShi fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
[*] --> 静止:::JingZhiYangShi
静止 --> [*]
静止 --> 移动:::YiDongYangShi
移动 --> 静止
移动 --> 碰撞:::YiDongYangShi
碰撞:::PengZhuangYangShi --> [*]
您可以通过先定义状态的序号
,然后在后面引用该序号
来添加空格到状态中。
在下面的示例中,有一个序号
为 状态2
并将其描述为带 空格 状态 2
的状态。定义好之后,状态2
在图表中用于第一个转换([*] --> 状态2
),并且还用于将其与另一个状态 状态3
连接的转换 (状态2 --> 状态3
)。
(状态2
已经被设置成名为KongGeZhuanTaiYangShi
(空格状态样式)的样式,以便与其他状态进行区分。)
CSDN mermaid v8.14.0
支持状态名带空格,但是不支持样式设置 classDef
,:::
,以下是 mermaid v10.2.3
的代码
```mermaid
stateDiagram
classDef KongGeZhuanTaiYangShi font-style:italic,font-weight:bold,fill:white
状态2: 带 空格 状态 2
[*] --> 状态2:::KongGeZhuanTaiYangShi
[*] --> 状态1
状态1 --> 状态3
状态2 --> 状态3
状态3 --> [*]
```
stateDiagram
classDef KongGeZhuanTaiYangShi font-style:italic,font-weight:bold,fill:white
状态2: 带 空格 状态 2
[*] --> 状态2
[*] --> 状态1
状态1 --> 状态3
状态2 --> 状态3
状态3 --> [*]