0%

Hexo 插入 Mermaid 图表

Mermaid 是一个用于画流程图、状态图、时序图、甘特图的库,使用 JS 进行本地渲染,广泛集成于许多 Markdown 编辑器中。本文介绍了在 Hexo 中集成 Mermaid图表的过程,并展示了 Mermaid的使用方法。

环境配置

NexT 主题已经支持了 mermaid 功能,我们只需要在主题配置文件中打开即可

next/_config.yaml
1
2
3
4
5
# Mermaid tag
mermaid:
enable: true
# Available themes: default | dark | forest | neutral
theme: forest

同时,在本地 typora 编辑器也原生支持了 mermaid的功能,二者可无缝切换。

在 NexT 的说明文档中使用 mermaid 应该用下面这种语法

1
2
{% mermaid type %}
{% endmermaid %}

但是,typora 编辑器本地是使用 mermaid 语法,也即是我们常见的三个反引号插入代码的语法。

经过测试,发现即使写成mermaid语法,NexT 也是能够解析的,棒!

按照 NexT 的说明文档,我们只需要修改主题配置文件,但是最开始的时候并不 work,尝试后发现安装好 hexo-filter-mermaid-diagrams插件就好了,疑惑。

流程图

流程图语法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
graph LR
单独节点
开始 -- 带注释写法1 --> 结束
开始 -->|带注释写法2| 结束
实线开始 --- 实线结束
实线开始 --> 实线结束
实线开始 -->|带注释| 实线结束
虚线开始 -.- 虚线结束
虚线开始 -.-> 虚线结束
虚线开始 -.->|带注释| 虚线结束
粗线开始 === 粗线结束
粗线开始 ==> 粗线结束
粗线开始 ==>|带注释| 粗线结束
subgraph 子图标题
子图开始 --> 子图结束
end
节点1[方形文本框] --> 节点2{菱形文本框}
节点3(括号文本框) --> 节点4((圆形文本框))

效果如下:

graph LR
  单独节点
  开始 -- 带注释写法1 --> 结束
  开始 -->|带注释写法2| 结束
  实线开始 --- 实线结束
  实线开始 --> 实线结束
  实线开始 -->|带注释| 实线结束
  虚线开始 -.- 虚线结束
  虚线开始 -.-> 虚线结束
  虚线开始 -.->|带注释| 虚线结束
  粗线开始 === 粗线结束
  粗线开始 ==> 粗线结束
  粗线开始 ==>|带注释| 粗线结束
  subgraph 子图标题
    子图开始 --> 子图结束
  end
  节点1[方形文本框] --> 节点2{菱形文本框}
  节点3(括号文本框) --> 节点4((圆形文本框))
  • 图的方向支持一下几种方式:
1
2
3
4
5
6
7
graph LR

TB - 从上到下(top buttom)
BT - 从下到上(buttom top)
LR - 从左到右(left right)
RL - 从右到左(right left)
TD - 跟 TB 相同
  • 三种线类型
1
2
3
--- : 实线
-.- : 虚线
=== : 粗线
  • 虚线带箭头的话加 > ,实线和粗线则最后一个字符替换成 >
  • 注释的两种写法(中间加注释,后边加注释)
1
2
-- 中间加注释写法 -->
-->|后边加注释写法|
  • 文本框类型
1
2
3
4
[] - 方形文本框
{} - 菱形文本框
() - 边角圆滑文本框
(()) - 圆形文本框
  • 子图
1
2
3
subgraph 子图标题
子图开始 --> 子图结束
end
  • 基础fontawesome支持

如果想加入来自frontawesome的图表字体,需要像frontawesome网站上那样引用的那样,详情请点击:fontawdsome

引用的语法为:++fa:#icon class name#++

1
2
3
4
5
graph TD
B["fa:fa-twitter for peace"]
B-->C[fa:fa-ban forbidden]
B-->D(fa:fa-spinner);
B-->E(A fa:fa-camerra-retro perhaps?);

渲染图如下:

graph TD
      B["fa:fa-twitter for peace"]
      B-->C[fa:fa-ban forbidden]
      B-->D(fa:fa-spinner);
      B-->E(A fa:fa-camera-retro perhaps?);

时序图

时序图以 sequenceDiagram 开头声明,语法如下所示

1
2
3
4
5
6
7
8
9
10
11
sequenceDiagram
participant Alice
participant Bob
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts <br/>prevail!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!

显示效果如下:

sequenceDiagram
    participant Alice
    participant Bob
    Alice->>John: Hello John, how are you?
    loop Healthcheck
        John->>John: Fight against hypochondria
    end
    Note right of John: Rational thoughts 
prevail! John-->>Alice: Great! John->>Bob: How about you? Bob-->>John: Jolly good!
  • 参与者(participant)
1
2
3
participant 名称1
participant 名称2
participant A as Alice : 通过 as 定义别名,后续使用 A 比较方便

注:声明的顺序与画图的顺序一致

  • 箭头类型(一个>不带箭头, 两个>带箭头; 一个-实线,两个-虚线)
类型 描述
-> 实线不带箭头
—> 虚线不带箭头
->> 实线带箭头
—>> 虚线带箭头
-x 实线结尾带X
—x 虚线结尾带X
  • 激活参与者
1
2
3
4
5
6
activate John    : 激活参与者
deactivate John : 去激活参与者

也可以通过在 > 后面使用 +/- 符号表示激活和去激活,例如:

Alice->>+John: Hello John, how are you?
  • 注释
1
2
3
4
5
Note [ right of | left of | over ] [Actor]: Text in note content

注: Actor 可以是多个,通过逗号分割,例如:

Note over Alice,John: A typical interaction
  • 循环序列
1
2
3
loop 描述文本
... 时序图语句 ...
end

例子

1
2
3
4
5
sequenceDiagram
Alice->John: Hello John, how are you?
loop Every minute
John-->Alice: Great!
end

显示效果

sequenceDiagram
    Alice->John: Hello John, how are you?
    loop Every minute
        John-->Alice: Great!
    end
  • 条件时序
1
2
3
4
5
alt 描述文本
... statements ...
else
... statements ...
end

例子:

1
2
3
4
5
6
7
sequenceDiagram
Alice->>Bob: Hello Bob, how are you?
alt is sick
Bob->>Alice: Not so good
else is well
Bob->>Alice: Feeling fresh like a daisy
end

显示效果

sequenceDiagram
    Alice->>Bob: Hello Bob, how are you?
    alt is sick
        Bob->>Alice: Not so good
    else is well
        Bob->>Alice: Feeling fresh like a daisy
    end
  • 可选时序
1
2
3
opt 描述文本
... statements ...
end

例子

1
2
3
4
5
sequenceDiagram
Alice->>Bob: Hello Bob, how are you?
opt Extra response
Bob->>Alice: Fine,Thanks
end

显示效果

sequenceDiagram
    Alice->>Bob: Hello Bob, how are you?
    opt Extra response
        Bob->>Alice: Fine,Thanks
    end

甘特图

甘特图以 gantt 开头,用 section划分任务集,语法如下:

1
2
3
4
5
6
7
8
9
gantt
title 甘特图的标题
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d

例子:

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
gantt
dateFormat YYYY-MM-DD
title Adding GANTT diagram functionality to mermaid

section A section
Completed task :done, des1, 2014-01-06,2014-01-08
Active task :active, des2, 2014-01-09, 1d
Future task : des3, after des2, 1d
Future task2 : des4, after des3, 1d

section Critical tasks
Completed task in the critical line :crit, done, 2014-01-06,24h
Implement parser and jison :crit, done, after des1, 1d
Create tests for parser :crit, active, 1d
Future task in critical line :crit, 10h
Create tests for renderer :1d
Add to mermaid :1d

section Documentation
Describe gantt syntax :active, a1, after des1, 1d
Add gantt diagram to demo page :after a1 , 20h
Add another diagram to demo page :doc1, after a1 , 8h

section Last section
Describe gantt syntax :after doc1, 30h
Add gantt diagram to demo page :20h

显示效果:

gantt
       dateFormat  YYYY-MM-DD
       title Adding GANTT diagram functionality to mermaid

       section A section
       Completed task            :done,    des1, 2014-01-06,2014-01-08
       Active task               :active,  des2, 2014-01-09, 1d
       Future task               :         des3, after des2, 1d
       Future task2              :         des4, after des3, 1d

       section Critical tasks
       Completed task in the critical line :crit, done, 2014-01-06,24h
       Implement parser and jison          :crit, done, after des1, 1d
       Create tests for parser             :crit, active, 1d
       Future task in critical line        :crit, 10h
       Create tests for renderer           :1d
       Add to mermaid                      :1d

       section Documentation
       Describe gantt syntax               :active, a1, after des1, 1d
       Add gantt diagram to demo page      :after a1  , 20h
       Add another diagram to demo page    :doc1, after a1  , 8h

       section Last section
       Describe gantt syntax               :after doc1, 30h
       Add gantt diagram to demo page      :20h

饼状图

1
2
3
4
5
6
pie
title Key elements in Product X
"Calcium" : 42.96
"Potassium" : 50.05
"Magnesium" : 10.01
"Iron" : 5
pie
    title Key elements in Product X
    "Calcium" : 42.96
    "Potassium" : 50.05
    "Magnesium" : 10.01
    "Iron" :  5

状态转换图

这个用 mermaid 简单的画了下 TCP 的状态转换图,更多的可以参考Mermaid 文档

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
stateDiagram
CLOSED --> LISTEN: Listen/-

LISTEN --> CLOSED: Close/-
LISTEN --> SYN_RECEIVED: SYN/SYN+ACK
LISTEN --> SYN_SENT: Send/SYN

SYN_RECEIVED --> LISTEN: RST/-
SYN_RECEIVED --> FIN_WAIT1: Close/FIN
SYN_RECEIVED --> ESTABLISED: ACK/-

SYN_SENT --> CLOSED: Close/-
SYN_SENT --> SYN_RECEIVED: SYN/SYN+ACK
SYN_SENT --> ESTABLISED: SYN+ACK/ACK

ESTABLISED --> FIN_WAIT1: Close/FIN
ESTABLISED --> CLOSE_WAIT: FIN/ACK

FIN_WAIT1 --> CLOSING: FIN/ACK
FIN_WAIT1 --> FIN_WAIT2: ACK/-
FIN_WAIT1 --> TIME_WAIT: FIN+ACK/ACK

FIN_WAIT2 --> TIME_WAIT: FIN/ACK

CLOSING --> TIME_WAIT: ACK/-

TIME_WAIT --> CLOSED2: Timeout

CLOSE_WAIT --> LAST_ACK: Close/FIN

LAST_ACK --> CLOSED2: ACK/-
stateDiagram
  CLOSED --> LISTEN: Listen/-

  LISTEN --> CLOSED: Close/-
  LISTEN --> SYN_RECEIVED: SYN/SYN+ACK
  LISTEN --> SYN_SENT: Send/SYN

    SYN_RECEIVED --> LISTEN: RST/-
    SYN_RECEIVED --> FIN_WAIT1: Close/FIN
    SYN_RECEIVED --> ESTABLISED: ACK/-

    SYN_SENT --> CLOSED: Close/-
    SYN_SENT --> SYN_RECEIVED: SYN/SYN+ACK
    SYN_SENT --> ESTABLISED: SYN+ACK/ACK

    ESTABLISED --> FIN_WAIT1: Close/FIN
    ESTABLISED --> CLOSE_WAIT: FIN/ACK

    FIN_WAIT1 --> CLOSING: FIN/ACK
    FIN_WAIT1 --> FIN_WAIT2: ACK/-
    FIN_WAIT1 --> TIME_WAIT: FIN+ACK/ACK

    FIN_WAIT2 --> TIME_WAIT: FIN/ACK

    CLOSING --> TIME_WAIT: ACK/-

    TIME_WAIT --> CLOSED2: Timeout

    CLOSE_WAIT --> LAST_ACK: Close/FIN

    LAST_ACK --> CLOSED2: ACK/-

在线编辑器

这里是 Mermaid 在线编辑器,你可以在这里实验 Mermaid 语法,还可以导出 SVG 或者 PNG 图片。

参考资料