Mermaid 简单使用与实践

Mermaid 简单使用与实践

Mermaid 是什么?

Mermaid 是一个基于 JavaScript 的图表和制图工具,使用 Markdown 风格的文本定义和渲染器来创建和修改复杂的图表。Mermaid 的主要目的是帮助文档跟上开发进度

Mermaid 能画哪些图?

  • 流程图
  • 时序图
  • 类图
  • 状态图
  • 实体关系图
  • 用户旅程图
  • 甘特图
  • 饼图
  • 象限图
  • 需求图
  • Git 图表
  • C4 图表
  • 思维导图
  • 时间线图
  • ZenUML
  • Sankey
  • XY 图表
  • 块图
  • 数据包图
  • Kanban
  • 架构图

语法介绍

Mermaid 的图有很多, 这里只介绍流程图, 状态图饼图三种图的常用语法

更多的语法和其它图请参考官方文档

以下语法介绍基于 11.12.1 版本

让我们开始吧

流程图

先看一个完整的列子

1
2
3
4
5
6
7
8
9
10
---
title: 流程图演示
---
graph TD
%% 注释
node1[矩形节点] -- 普通剪头 --> node2(圆角矩形节点)
node2 == 加粗箭头 ==> node4{菱形节点}
node4 -. 虚线剪头 .-> node5[(圆柱)]
node4 <-- 双向箭头 --> node6((圆形))
node4 -- 自指向剪头 --> node4
---
title: 流程图演示
---
graph TD
    %% 注释
    node1[矩形节点] -- 普通剪头 --> node2(圆角矩形节点)
    node2 == 加粗箭头 ==> node4{菱形节点}
    node4 -. 虚线剪头 .-> node5[(圆柱)]
    node4 <-- 双向箭头 --> node6((圆形))
    node4 -- 自指向剪头 --> node4
图声明和方向

流程图可以使用 flowchart 或者 graph 来声明, 其后的 TD 表示流程图的方向

  • TB - 从上到下
  • TD - 从上到下/与从上到下相同
  • BT - 从下到上
  • RL - 从右到左
  • LR - 从左到右
1
graph TD
节点形状

语法形如 id<形状标识>

默认为矩形

1
2
3
4
5
6
graph TD
默认形状
node1[矩形]
node2((圆角矩形))
node3[(圆柱)]
node4{菱形}
graph TD
    默认形状
    node1[矩形]
    node2((圆角矩形))
    node3[(圆柱)]
    node4{菱形}
箭头

语法形如 ---->

1
2
3
4
5
6
7
8
graph TD
node1 -- 普通箭头 --> node2
node3 <-- 双向箭头 --> node4
node5 -. 虚线无向箭头 .- node6
node7 -. 虚线箭头 .-> node8
node9 == 加粗箭头 ==> node10
node11 ---- 长箭头 ----> node12
node13 ---- node14
graph TD
    node1 -- 普通箭头 --> node2
    node3 <-- 双向箭头 --> node4
    node5 -. 虚线无向箭头 .- node6
    node7 -. 虚线箭头 .-> node8
    node9 == 加粗箭头 ==> node10
    node11 ---- 长箭头 ----> node12
    node13 ---- node14
子图

需要有一对 subgraph ... end 的标签

1
2
3
4
5
6
7
graph TB
node1[节点1] ---> sub
sub ---> node2[节点2]

subgraph sub[子图]
sub_node1[子图节点1] --> sub_node2[子图节点2]
end
graph TB
    node1[节点1] ---> sub
    sub ---> node2[节点2]
    
    subgraph sub[子图]
        sub_node1[子图节点1] --> sub_node2[子图节点2]
    end

状态图

同样先看一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
---
title: 状态图演示
---
stateDiagram-v2
direction TB

state shipped <<choice>>
state pay {
direction LR
[*] --> init
init --> paying: 用户发起支付

state "初始化中" as init
state "支付中" as paying
}

[*] --> pay: 提交订单
pay --> processing: 支付成功
pay --> cancelled: 用户主动取消 / 支付超时
processing --> shipped: 商家 / 仓库发货
shipped --> refunded: 用户申请取消
shipped --> completed: 用户收货
cancelled --> [*]
refunded --> [*]
completed --> [*]

pay: 待支付
note right of pay: 待支付子状态
processing: 待发货
refunded: 已退款
cancelled: 已取消
completed: 已完成
---
title: 状态图演示
---
stateDiagram-v2
    direction TB
    
    state shipped <>
    state pay {
        direction LR
        [*] --> init
    init --> paying: 用户发起支付
        
        state "初始化中" as init
        state "支付中" as paying
    }
    
    [*] --> pay: 提交订单
    pay --> processing: 支付成功
    pay --> cancelled: 用户主动取消 / 支付超时
    processing --> shipped: 商家 / 仓库发货
    shipped --> refunded: 用户申请取消
    shipped --> completed: 用户收货
    cancelled --> [*]
    refunded --> [*]
    completed --> [*]
    
    pay: 待支付
    note right of pay: 待支付子状态
    processing: 待发货
    refunded: 已退款
    cancelled: 已取消
    completed: 已完成
图声明

状态图的声明关键字是 stateDiagram-v2

节点形状

状态图并没有像是流程图那种丰富的节点形状

1
2
3
4
5
6
7
8
9
10
11
12
13
14
stateDiagram-v2
%% 起始节点 和 结束节点
direction LR
[*] --> [*]

%% 选择节点: 无法添加注释,添加注释之后会变成圆角矩形
state choice <<choice>>

%% 子状态图
state sub_state_diagram {
direction LR
[*] --> [*]
}
sub_state_diagram: 子状态图
stateDiagram-v2
    %% 起始节点 和 结束节点
    direction LR
    [*] --> [*]
    
    %% 选择节点: 无法添加注释,添加注释之后会变成圆角矩形
    state choice <>
    
    %% 子状态图
    state sub_state_diagram {
        direction LR
        [*] --> [*]
    }
    sub_state_diagram: 子状态图
关系描述

状态流转的关系描述可以直接使用 : <关系描述>

1
2
3
4
5
stateDiagram-v2
[*] --> node: 关系描述1
node --> [*]: 关系描述2

node: 节点
stateDiagram-v2
    [*] --> node: 关系描述1
    node --> [*]: 关系描述2
    
    node: 节点
箭头

状态图中的箭头只能是 -->

状态描述

状态图中有两种添加状态描述的方式

  1. 形如 id: <状态描述>
  2. 形如 state "<状态描述>" as id
1
2
3
4
5
6
7
stateDiagram-v2
[*] --> node1
node1 --> node2
node2 --> [*]

node1: 节点1
state "节点2" as node2
stateDiagram-v2
    [*] --> node1
    node1 --> node2
    node2 --> [*]
    
    node1: 节点1
    state "节点2" as node2
子图

子图的声明和选择节点有点像

1
2
3
4
5
6
7
8
9
10
11
12
13
stateDiagram-v2
state sub_state_diagram {
direction LR
[*] --> sub_node
sub_node --> [*]

sub_node: 子节点
}

[*] --> sub_state_diagram
sub_state_diagram --> [*]

sub_state_diagram: 子图
stateDiagram-v2
    state sub_state_diagram {
        direction LR
        [*] --> sub_node
        sub_node --> [*]
        
        sub_node: 子节点 
    }
    
    [*] --> sub_state_diagram
    sub_state_diagram --> [*]
    
    sub_state_diagram: 子图

饼图

饼图相对来说比较简单

1
2
3
4
5
6
pie showData
title 饼图演示
"Apple": 5
"Banana": 10
"Orange": 3
"Strawberry": 2
pie showData
    title 饼图演示
    "Apple": 5
    "Banana": 10
    "Orange": 3
    "Strawberry": 2
图声明

饼图的声明以 pie 来标识, 可以使用 title 为饼图自定义标题

1
2
3
pie
title 饼图
"full": 1
pie
    title 饼图
    "full": 1
比例

每个项目的占比使用 k-v 的形式声明, 要求 k 必须要使用双引号包裹, v 为正数(支持小数)

也可以使用 showData 来展示具体的占比的实际值

1
2
3
4
5
6
pie showData
title 饼图
"one": 1
"two": 2
"three": 3.00
"four": 4.0
pie showData
    title 饼图
    "one": 1
    "two": 2
    "three": 3.00
    "four": 4.0

写在最后

还有许多其它常用的图, 比如 时序图, XY 图表, 思维导图, 它们的定义就会比较复杂一些了

我觉得应该在 Mermaid 这种编码图和二进制图之间做一个取舍, 编码图固然方便, 既没有二进制图片存储的负担, 修改也方便, 实时渲染且样式统一简洁; 但面对一些复杂的图形(比如流程节点众多的流程图), 有一些网站(比如 draw.io)提供的在线绘图能力在作图成本上还是占优的,而且不需要记忆编码图的语法

引用

Mermaid 英文官方文档

Mermaid 中文文档

作者

wuhunyu

发布于

2025-12-01

更新于

2025-12-01

许可协议