Markdown 状态图

1. 前言

Markdown 的原生语法不支持绘制图形,但通过扩展模块,我们可以将一些格式化的文字渲染成我们需要的图形。常用的图形有 “流程图”、“时序图”、“类图”、“状态图”、“甘特图”、"饼图" 等。

本节将重点介绍如何通过 Mermaid 绘制「状态图」。

状态图 (Statechart) 是描述一个实体基于事件反应的动态行为,是使对象达到某种状态的事件、条件或操作的图形化描述。

一个完整的状态图由状态、转换组成。

环境说明
考虑到 Markdown 工具之间的不兼容,有的内容直接从页面复制粘贴到本地不会正常显示,大家学习时自己动手写是肯定没问题的。本节所有实例代码及演示效果均使用 Typora 工具完成。
Mermaid 为 Markdown 扩展语法,需要在 Typora 设置中开启对图表的语法支持。其方式为:「设置」->「Markdown」->「Markdown 扩展语法」-> 勾选「图表」,如下图:
图片描述

2. 语法详解

2.1 状态图中的「状态」

状态代表某一对象在某一特定的条件、时间下所保持的静态值。

使用 Mermaid 扩展绘制状态图时,有多种方式声明一个状态节点。

实例 1

通过设置状态 ID 声明状态

​```mermaid
stateDiagram
    状态1
​```

上述代码将会渲染成如下效果:

图片描述

实例 2

使用 「state」关键字来描述共同声明状态节点。

​```mermaid
stateDiagram
    state "状态描述性文字" as 状态2
​```

上述代码将会渲染成如下效果:

图片描述

实例 3

使用「状态 ID + 冒号」的方式简化状态节点的声明。

​```mermaid
stateDiagram
    状态3 : 状态3的文字描述
​```

上述代码将会渲染成如下效果:

图片描述

2.2 状态图中的「转换」

「转换」在状态图中表现为连接两个状态节点的单向箭头,在 Mermaid 扩展语法中的写法为「字符箭头 -->」。

实例 4

用单向箭头表示转换。

​```mermaid
stateDiagram
    状态1 --> 状态2
​```

此代码渲染效果如下:

图片描述

通过 (行内容):label 的形式,为转换添加描述文本。

实例 5

增加描述。

​```mermaid
stateDiagram
    状态1 --> 状态2: 咻~
​```

渲染效果如下:

图片描述

状态图中有两个特殊的状态节点:开始节点和结束节点。如果需要在状态图中显示开始或结束节点,可以通过 [*] 方式声明。

实例 6

增加开始和结束节点。

​```mermaid
stateDiagram
    [*] --> 状态节点
    状态节点 --> [*]
​```

渲染结果如下:

图片描述

2.3 状态图中的「嵌套」

在负责的状态描述中,有的状态节点会包含一系列的子状态,我们可以用组合「嵌套」的方式来描绘它们。在 Mermaid 扩展中,描述嵌套的方式,是使用「花括号 {}」描述子状态。

实例 7

​```mermaid
stateDiagram
    [*] --> 父状态节点
    state 父状态节点 {
        [*] --> 子状态节点
        子状态节点 --> [*]
    }
​```

渲染结果如下:

图片描述

「嵌套」的层数没有限制。

实例 8

多层嵌套。

​```mermaid
stateDiagram
    [*] --> 第一层状态节点

    state 第一层状态节点 {
        [*] --> 第二层

        state 第二层 {
            [*] --> 第二层
            第二层 --> 第三层

            state 第三层 {
                [*] --> 第三层
                第三层 --> [*]
            }
        }
    }
​```

渲染效果如下:

图片描述

状态转换可以在「嵌套」的外层,也就是群组间实现。

实例 9

群组之间的嵌套。

​```mermaid
stateDiagram
    [*] --> 第一层
    第一层 --> 第二层
    第一层 --> 第三层

    state 第一层 {
        [*] --> 第一层子节点
        第一层子节点 --> [*]
    }
    state 第二层 {
        [*] --> 第二层子节点
        第二层子节点 --> [*]
    }
    state 第三层 {
        [*] --> 第三层子节点
        第三层子节点 --> [*]
    }
​```

渲染效果如下:

图片描述

2.4 状态图中的「分支」

对于非单一结果的状态转换,我们可以使用 <<fork>><<join>> 标签实现。

实例 10

使用 <<fork>> 描述分支,使用 <<join>> 描述聚合。

​```mermaid
stateDiagram
    state 分支 <<fork>>
      [*] --> 分支
      分支 --> 分支2
      分支 --> 分支3

      state 合并 <<join>>
      分支2 --> 合并
      分支3 --> 合并
      合并 --> 状态4
      状态4 --> [*]
​```

渲染效果如下:

图片描述

2.5 状态图中的「并行」

对于一些同步完成的状态转换,我们可以用 -- 符号声明并行效果。

实例 11

​```mermaid
stateDiagram
        [*] --> 激活状态

        state 激活状态 {
            [*] --> NumLock关
            NumLock关 --> NumLock开 : 按下 NumLock 键
            NumLock开 --> NumLock关 : 按下 NumLock 键
            --
            [*] --> CapsLock关
            CapsLock关 --> CapsLock开 : 按下 CapsLock 键
            CapsLock开 --> CapsLock关 : 按下 CapsLock 键
            --
            [*] --> ScrollLock关
            ScrollLock关 --> ScrollLock开 : 按下 ScrollLock 键
            ScrollLock开 --> ScrollLock关 : 按下 ScrollLock 键
        }
​```

渲染效果如下:

图片描述

2.6 为状态图增加「备注」

有时候图表元素不能完全表达我们的设计思路,这时候需要在图中加入文字描述。在 Mermaid 语法中,使用 note <right|left> of <state ID> 备注内容 end notes 的方式,将备注添加到状态节点的右侧(左侧)。

实例 12

​```mermaid
stateDiagram
        状态1 : 描述将出现在右侧
        note right of 状态1
            这里添加描述内容
        end note
        状态1 --> 状态2
        note left of 状态2 : 在节点左侧添加描述
​```

渲染效果如下:

图片描述

3. 使用场景及实例

状态图专门用于表示依赖于状态的行为。

实例 13

出货状态示意图。

​```mermaid
stateDiagram
        [*] --> 下单成功
        下单成功 --> 备货
        state 出货中 <<fork>>
        备货 --> 出货中
        出货中 --> 出货失败
        出货失败 --> [*]
        出货中 --> 出货确认
        出货确认 --> 出货完毕
        出货完毕 --> 订单完成
        订单完成 --> [*]
​```

其渲染效果如下:

图片描述

4. 小结

  • Mermaid 为 Markdown 扩展了使用普通文本生成状态图的语法及渲染支持;
  • Mermaid 状态图的基本元素包含「状态节点」、「转换」;
  • Mermaid 状态图还可以将节点合并,实现「嵌套」的效果;
  • Mermaid 状态图的逻辑支持「分支」、「并行」;
  • Mermaid 状态图还可以通过「备注」的方式,为状态图提供更多的细节描述。