跳至内容

状态图

"状态图是一种在计算机科学及相关领域中用于描述系统行为的图。 状态图要求所描述的系统由有限数量的状态组成; 在某些情况下,情况确实如此,而在其他情况下,这是一种合理的抽象。" 维基百科

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

旧渲染器

在状态图中,系统用状态和一个状态如何通过转换变为另一个状态来描述。 上面的示例图表显示了三个状态:StillMovingCrash。 你从Still 状态开始。 从Still 状态,你可以变为Moving 状态。 从Moving 状态,你可以变回Still 状态或变为Crash 状态。 从Still 状态到Crash 状态没有转换。(如果你还处于静止状态,你无法坠毁。)

状态

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

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

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

转换

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

当你在两个状态之间定义一个转换,而这两个状态尚未定义时,未定义的状态将使用转换中的 ID 来定义。 你以后可以为这样定义的状态添加描述。

可以在转换中添加文本以描述它所代表的内容。

开始和结束

有两个特殊状态,分别表示图表的开始和停止。 它们用 [*] 语法写成,指向它的转换的方向定义了它是开始状态还是结束状态。

复合状态

在现实世界中使用状态图时,你通常会得到多维的图,因为一个状态可以有多个内部状态。 在此术语中,这些被称为复合状态。

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

你可以在多个层级中执行此操作

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

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

选择

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

分叉

可以使用 <<fork>> <<join>> 在图中指定一个分叉。

注释

有时没有什么比便签更能说明问题了。 这在状态图中也是如此。

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

并发

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

设置图表的绘制方向

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

注释

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

使用 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 [one or more state names, separated by commas] [name of a style defined with classDef]

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

txt
class Crash badBadEvent

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

txt
class Moving, Crash movement

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

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

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

txt
[state]:::[style name]

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

状态名称中的空格

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

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