Skip to content

状态图

“状态图是一种用于计算机科学和相关领域描述系统行为的图。状态图要求所描述的系统由有限数量的状态组成;有时确实如此,而其他时候这是一种合理的抽象。” 维基百科

Mermaid 可以渲染状态图。该语法尝试与 plantUml 中使用的语法兼容,这将使用户更容易在 mermaid 和 plantUml 之间共享图表。

Code:
mermaid

旧渲染器:

Code:
mermaid

在状态图中,系统用状态以及一个状态如何通过转换变为另一个状态来描述。上图示例显示了三个状态:StillMovingCrash。你从 Still 状态开始。从 Still 你可以更改到 Moving 状态。从 Moving 你可以更改回 Still 状态或 Crash 状态。从 StillCrash 没有转换。(如果你静止不动,你就不会崩溃。)

状态

状态可以通过多种方式声明。最简单的方法是用一个 ID 定义一个状态:

Code:
mermaid

另一种方法是使用 state 关键字以及如下所示的描述:

Code:
mermaid

另一种定义带描述的状态的方法是定义状态 ID,后跟冒号和描述:

Code:
mermaid

转换

转换是在一个状态变为另一个状态时的路径/边。这用文本箭头“-->”表示。

当你定义两个状态之间的转换并且这些状态尚未定义时,未定义的状态将使用转换中的 ID 定义。你可以稍后添加对这样定义的状态的描述。

Code:
mermaid

可以向转换添加文本以描述它所代表的内容:

Code:
mermaid

开始和结束

有两个特殊状态表示图表的开始和停止。这些用 [*] 语法编写,到它的转换方向将其定义为起始状态或停止状态。

Code:
mermaid

组合状态

在状态图的实际应用中,你经常会遇到多维图表,因为一个状态可以具有多个内部状态。在本术语中,这些称为组合状态。

为了定义一个组合状态,你需要使用 state 关键字后跟一个 ID,以及组合状态的主体位于 {} 之间。你可以像简单状态一样在单独的行上命名组合状态。请参见下面的示例:

Code:
mermaid

你可以分层进行:

Code:
mermaid

你也可以在组合状态之间定义转换:

Code:
mermaid

你不能在属于不同组合状态的内部状态之间定义转换

选择

有时你需要对两条或多条路径之间的选择进行建模,你可以使用 <<choice>> 来做到这一点。

Code:
mermaid

分支

可以使用 <<fork>> <<join>> 指定图表中的分支。

Code:
mermaid

注释

有时没有什么比便利贴更能说明问题了。状态图也是如此。

在这里,你可以选择将注释放在节点的右侧或左侧。

Code:
mermaid

并发

与 plantUml 一样,你可以使用 -- 符号指定并发。

Code:
mermaid

设置图表的方位

在状态图中,你可以使用 direction 语句来设置图表将要渲染的方向,例如在这个示例中。

Code:
mermaid

注释

可以在状态图图表中输入注释,解析器会忽略这些注释。注释必须位于它们自己的行上,并且必须以 %%(双百分号)为前缀。从注释开始到下一换行符后的任何文本都将被视为注释,包括任何图表语法

使用 classDefs 进行样式设置

与其他图表(如流程图)一样,你可以在图表本身中定义样式,并将该命名样式应用于图表中的一个或多个状态。

状态图 classDefs 的当前限制:

  1. 不能应用于起始状态或结束状态
  2. 不能应用于组合状态或组合状态内

这些正在开发中,将在未来版本中提供。

你可以使用 classDef 关键字定义样式,它是“类定义”的缩写(其中“类”的意思类似于CSS 类),后跟样式的名称,然后是一个或多个属性值对。每个属性值对都是一个有效的 CSS 属性名称,后跟冒号 (:),然后是一个值。

这是一个只有一个属性值对的 classDef 示例:

txt
classDef movement font-style:italic;

其中

  • 样式的名称是 movement
  • 唯一的属性是 font-style,其值是 italic

如果你想拥有多个属性值对,那么你就在每个属性值对之间放一个逗号 (,)。

这是一个具有三个属性值对的示例:

txt
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 样式应用于状态:

  1. 使用 class 关键字将 classDef 样式应用于单个语句中的一个或多个状态,或者
  2. 使用 ::: 运算符在转换语句中使用时将 classDef 样式应用于状态(例如,使用指向另一个状态的箭头)

1. class 语句

class 语句告诉 Mermaid 将命名 classDef 应用于一个或多个类。表单为:

txt
class [一个或多个状态名称,用逗号分隔] [用 classDef 定义的样式的名称]

这是一个将 badBadEvent 样式应用于名为 Crash 的状态的示例:

txt
class Crash badBadEvent

这是一个将 movement 样式应用于 MovingCrash 两个状态的示例:

txt
class Moving, Crash movement

这是一个显示正在使用的示例的图表。请注意,Crash 状态应用了两个 classDef 样式:movementbadBadEvent

Code:
mermaid

2. ::: 运算符用于将样式应用于状态

你可以使用 :::(三个冒号)运算符将 classDef 样式应用于状态。语法是

txt
[状态]:::[样式名称]

你可以在使用类的语句中在图表中使用它。这包括起始状态和结束状态。例如:

Code:
mermaid

状态名称中的空格

可以通过首先使用 ID 定义状态,然后稍后引用该 ID 来在状态中添加空格。

在以下示例中,有一个 ID 为 yswsii 且描述为 Your state with spaces in it 的状态。定义它之后,yswsii 在第一个转换 ([*] --> yswsii) 和到 YetAnotherState 的转换 (yswsii --> YetAnotherState) 中的图中使用。(yswsii 已进行样式设置,使其与其他状态不同。)

Code:
mermaid