mermaid 概述

  • 怎么使用Mermaid?

    • 使用特定的Mermaid渲染器;
    • 使用集成了Mermaid渲染功能的Markdown编辑器,如Typora。使用时,需要将代码块的语言选择为Mermaid。
    • 行首加%%代表注释
  • Mermaid能绘制哪些图?

    • 饼状图:使用pie关键字,具体用法后文将详细介绍
    • 流程图:使用graph关键字,具体用法后文将详细介绍
    • 序列图:使用sequenceDiagram关键字
    • 甘特图:使用gantt关键字
    • 类图:使用classDiagram关键字
    • 状态图:使用stateDiagram关键字
    • 用户旅程图:使用journey关键字
  • 在线渲染器:Online FlowChart & Diagrams Editor


饼状图(pie)

数值最多支持2位小数——数据会以百分比的形式展示

1
2
3
4
5
pie
title 为什么总是宅在家里?
"喜欢宅" : 15
"天气太热或太冷" : 20
"穷" : 500
1
2
3
4
5
pie
title 为什么总是宅在家里?
"喜欢宅" : 15
"天气太热或太冷" : 20
"穷" : 500

流程图(graph)

1
2
3
4
5
6
graph LR
A[Start] --> B{Is it?};
B -- Yes --> C[OK];
C --> D[Rethink];
D --> B;
B -- No ----> E[End];
1
2
3
4
5
6
graph LR
A[Start] --> B{Is it?};
B -- Yes --> C[OK];
C --> D[Rethink];
D --> B;
B -- No ----> E[End];

方向

用于开头,声明流程图的方向。

  • graphgraph TBgraph TD:从上往下
  • graph BT:从下往上
  • graph LR:从左往右
  • graph RL:从右往左

结点

  • 无名字的结点:直接写内容,此时结点边框为方形;节点内容不能有空格
  • 有名字的结点:节点名后书写内容,内容左右有特定符号,结点边框由符号决定;节点内容可以有空格
1
2
3
4
5
6
7
8
graph
默认方形
id1[方形]
id2(圆边矩形)
id3([体育场形])
id4[[子程序形]]
id5[(圆柱形)]
id6((圆形))
1
2
3
4
5
6
7
8
graph
默认方形
id1[方形]
id2(圆边矩形)
id3([体育场形])
id4[[子程序形]]
id5[(圆柱形)]
id6((圆形))

1
2
3
4
5
6
7
8
graph
id1{菱形}
id2{{六角形}}
id3[/平行四边形/]
id4[\反向平行四边形\]
id5[/梯形\]
id6[\反向梯形/]
id7>非对称形状]
1
2
3
4
5
6
7
8
graph
id1{菱形}
id2{{六角形}}
id3[/平行四边形/]
id4[\反向平行四边形\]
id5[/梯形\]
id6[\反向梯形/]
id7>非对称形状]

连线样式

1
2
graph LR
a-->b--文本1-->c-->|文本2|d
1
2
graph LR
a-->b--文本1-->c-->|文本2|d

1
2
graph LR
a==>b==文本==>c
1
2
graph LR
a==>b==文本==>c

1
2
graph LR
a-.->b-.文本.->c
1
2
graph LR
a-.->b-.文本.->c

1
2
3
4
5
6
7
8
graph LR
a---b
b--文本1---c
c---|文本2|d
d===e
e==文本3===f
f-.-g
g-.文本.-h
1
2
3
4
5
6
7
8
graph LR
a---b
b--文本1---c
c---|文本2|d
d===e
e==文本3===f
f-.-g
g-.文本.-h

  • 其他连线:需要将graph关键字改为flowchart,除了新增加的连线形式外,上面三种线的渲染效果也会不同 (好像网页显示不了<-->)
1
2
3
4
5
flowchart LR
A o--o B
B <--> C
C x--x D
旧连线 --文本--> 也会不同
1
2
3
4
5
6
flowchart LR
A o--o B
B <--> C
C x--x D

旧连线 --文本--> 也会不同

  • 延长连线:增加相应字符即可,如下图中的B到E,连线中增加了一个-。字符可多次添加。
1
2
3
4
5
6
graph LR
A[Start] --> B{Is it?};
B -->|Yes| C[OK];
C --> D[Rethink];
D --> B;
B --->|No| E[End];
1
2
3
4
5
6
graph LR
A[Start] --> B{Is it?};
B -->|Yes| C[OK];
C --> D[Rethink];
D --> B;
B --->|No| E[End];

连线形式

直链

1
2
graph LR
A -- text --> B -- text2 --> C
1
2
graph LR
A -- text --> B -- text2 --> C

多重链

可以使用&字符,或单个描述

1
2
3
4
5
6
7
graph
a --> b & c--> d
A & B--> C & D
X --> M
X --> N
Y --> M
Y --> N
1
2
3
4
5
6
7
graph
a --> b & c--> d
A & B--> C & D
X --> M
X --> N
Y --> M
Y --> N

特殊字符

如果文本中有字符可以用双引号:

1
2
flowchart LR
A["括号 (text)"]---B["中括号 [text]"]
1
2
flowchart LR
A["括号 (text)"]---B["中括号 [text]"]

如果文本中要使用双引号或者其它更多特殊字符,可以使用HTML 实体来表示:

1
2
flowchart LR
A["引号#quot;"]---B["美元符号#36;"]---C["笑脸#128512;"]
1
2
flowchart LR
A["引号#quot;"]---B["美元符号#36;"]---C["笑脸#128512;"]

  • 实例:朱元璋家谱简图,圆圈代表皇帝
1
2
3
4
5
6
7
8
9
10
graph LR
emperor((朱八八))-.子.->father(朱五四)-.子.->朱四九-.子.->朱百六


朱雄英--长子-->朱标--长子-->emperor
emperor2((朱允炆))--次子-->朱标
朱樉--次子-->emperor
朱棡--三子-->emperor
emperor3((朱棣))--四子-->emperor
emperor4((朱高炽))--长子-->emperor3

子图(subgraph)

  • 需要将graph关键字改为flowchart,在代码段的开始加入subgraph,尾部加入end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
flowchart TB
c1-->a2
subgraph one
a1-->a2
end
subgraph two
b1-->b2
end
subgraph three
c1-->c2
end
one --> two
three --> two
two --> c2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
flowchart TB
c1-->a2
subgraph one
a1-->a2
end
subgraph two
b1-->b2
end
subgraph three
c1-->c2
end
one --> two
three --> two
two --> c2

  • 注释:在行首加入%%即可。
1
2
3
4
5
6
graph LR
%%这是一条注释,在渲染图中不可见
A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision}
C -->|One| D[Result one]
C -->|Two| E[Result two]
1
2
3
4
5
6
graph LR
%%这是一条注释,在渲染图中不可见
A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision}
C -->|One| D[Result one]
C -->|Two| E[Result two]

序列图(sequenceDiagram)

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
sequenceDiagram
title: hello
autonumber
participant B as Browser
participant C as Controller
participant M as Model
participant V as View
note left of C: 左note
note right of C: 右note
note over B, C: 共note
B -> C: 实线
activate C
C ->> B: 箭头实线
deactivate C
%%加号等价于activate M,减号等价于deactivate M
C -->+ M: 虚线
M -x+ V: 打叉箭头实线
V --x- M: 打叉箭头虚线
M -->>- C: 箭头虚线
%% 循环
loop 每5分钟
%% Highlight background
rect rgba(0, 0, 255, 0.1)
V ->> V: 自环
end
end
loop 每5分钟
B-->>C:汇报
end
%% 可选条件
opt 心情好
M-->>V:唱歌
end
%% 条件判断
alt Controller没睡
B-->>C:吃宵夜吗
else Model没睡
B-->>M:吃宵夜吗
end
%% 并行发送
par Controller to Model
C-->>+M:hello?
and Controller to View
C-->>+V:hello?
end
%% 并行接收
par Model to Controller
M-->>-C:hi!
and Model to Controller
V-->>-C:hi!
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
sequenceDiagram
title: hello
autonumber
participant B as Browser
participant C as Controller
participant M as Model
participant V as View
note left of C: 左note
note right of C: 右note
note over B, C: 共note
B -> C: 实线
activate C
C ->> B: 箭头实线
deactivate C
%%加号等价于activate M,减号等价于deactivate M
C -->+ M: 虚线
M -x+ V: 打叉箭头实线
V --x- M: 打叉箭头虚线
M -->>- C: 箭头虚线
%% 循环
loop 每5分钟
%% Highlight background
rect rgba(0, 0, 255, 0.1)
V ->> V: 自环
end
end
loop 每5分钟
B-->>C:汇报
end
%% 可选条件
opt 心情好
M-->>V:唱歌
end
%% 条件判断
alt Controller没睡
B-->>C:吃宵夜吗
else Model没睡
B-->>M:吃宵夜吗
end
%% 并行发送
par Controller to Model
C-->>+M:hello?
and Controller to View
C-->>+V:hello?
end
%% 并行接收
par Model to Controller
M-->>-C:hi!
and Model to Controller
V-->>-C:hi!
end

1
2
3
4
5
sequenceDiagram
actor Z as 张三
actor L as 李四
Z ->> L: 实线箭头
Z -) L: 实线开放箭头
1
2
3
4
5
sequenceDiagram
actor Z as 张三
actor L as 李四
Z ->> L: 实线箭头
Z -) L: 实线开放箭头

甘特图(gantt)

1
2
3
4
5
6
7
8
9
gantt
title 研发周期
dateFormat YYYY-MM-DD
section 项目
A 项目: A1, 2022-01-01, 30d
B 项目: after A1 , 20d
section 子任务
子任务1: 2022-01-12 , 12d
子任务2: 24d
1
2
3
4
5
6
7
8
9
gantt
title 研发周期
dateFormat YYYY-MM-DD
section 项目
A 项目: A1, 2022-01-01, 30d
B 项目: after A1 , 20d
section 子任务
子任务1: 2022-01-12 , 12d
子任务2: 24d

类图(classDiagram)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}

状态图(stateDiagram)

1
2
3
4
5
6
7
8
9
10
11
stateDiagram-v2
state "状态1" as State1
State2 : 状态2
[*] --> State1
State1 --> State2: 过渡文本
State2 --> State1
State2 --> State3
state State3 {
[*] --> second
second --> [*]
}
1
2
3
4
5
6
7
8
9
10
11
12
stateDiagram-v2
state "状态1" as State1
State2 : 状态2
[*] --> State1

State1 --> State2: 过渡文本
State2 --> State1
State2 --> State3
state State3 {
[*] --> second
second --> [*]
}

用户旅程图(journey)