Mermaid 图表语法

Mermaid

通过 mermaid 可以实现以纯文本的方式绘制流程图,序列图,甘特图等。

使用

元数据标识: grammar_mermaid

想要使用该语法,需要在设置>扩展语法 里把mermaid选项打开。或者在每篇文章的元数据里通过 grammar_mermaid 进行控制。系统默认关闭mermaid语法功能

mermaid 提供了流程图,序列图,甘特图等多种图形效果

mermaid的语法为代码块语法的执行功能,语言为 mermaid

```mermaid!
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;

### 流程图

因为 mermaid 支持不同图表,所以所有的流程图需要以 graph 开头

#### 图表方向

 graph 的后方添加流程图的显示方向

TB -从上到下
BT - 从下到上
RL - 从右到左
LR - 从左到右
TD -  TB 一样,从上到下

``` mermaid!
graph LR
    Start --> Stop

``` mermaid!
graph TB
Start --> Stop

#### 节点形状

默认结点
``` mermaid!
graph TB
    id

带文字说明的结点
``` mermaid!
graph LR
id1[This is the text in the box]

带圆角文字说明的结点
``` mermaid!
graph LR
    id1(This is the text in the box)

带文字说明的圆形结点
``` mermaid!
graph LR
id1((This is the text in the circle))

带文字说明的飘带结点
``` mermaid!
graph LR
    id1>This is the text in the box]

带文字说明的菱形结点

``` mermaid!
graph LR
id1{This is the text in the box}

#### 结点间的连线

结点间可以有不同形式的连接,比如实线,虚线,带箭头的线等

带箭头的线
``` mermaid!
graph LR
    A-->B

没有任何修饰的线
``` mermaid!
graph LR
A --- B

在线上有描述文字的线
``` mermaid!
graph LR
    A-- This is the text ---B

或者

``` mermaid!
graph LR
A---|This is the text|B

有箭头同时带上文字描述的线
``` mermaid!
graph LR
    A-->|text|B

或者
``` mermaid!
graph LR
A-- text -->B

点状形式的线
``` mermaid!
graph LR;
   A-.->B;

加粗的线
``` mermaid!
graph LR
A ==> B

带文字加粗的线
``` mermaid!
graph LR
   A == text ==> B

子图表

subgraph 子图表名称
子图表中的描述语句...
end

``` mermaid!
graph TB
c1-->a2
subgraph one
a1-->a2
end
subgraph two
b1-->b2
end
subgraph three
c1-->c2
end

#### 结点样式自定义

``` mermaid!
graph LR
    id1(Start)-->id2(Stop)
    style id1 fill:#f9f,stroke:#333,stroke-width:4px
    style id2 fill:#ccf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5

跟 fontawesome 字体的集成

使用 fa: #图表名称# 的语法添加 fontawesome

``` mermaid!
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?);

### 序列图

因为 mermaid 支持不同图表,所以所有的序列图需要以 sequenceDiagram 开头

sequenceDiagram
    [参与者1][连线][参与者2]:消息文本
    ...

#### 参与者

```mermaid!
sequenceDiagram
    participant John
    participant Alice
    Alice->>John: Hello John, how are you?
    John-->>Alice: Great!

别名

```mermaid!
sequenceDiagram
participant A as Alice
participant J as John
A->>J: Hello John, how are you?
J->>A: Great!

#### 连线

6种不同类型的连线

|Type|Description|
|:--|:--|
|->|不带箭头的实线|
|-->|不带箭头的虚线|
|->>|带箭头的实线|
|-->>|带箭头的虚线|
|-x|末端为叉的实线(表示异步)|
|--x|末端为叉的虚线(表示异步)|

#### 消息文本

消息显示在连线的上方

[参与者1][连线][参与者2]:消息文本

#### 活动中

在消息线末尾增加 + ,则消息接收者进入当前消息的“活动中”状态;
在消息线末尾增加 - ,则消息接收者离开当前消息的“活动中”状态。

或者使用以下语法直接说明某个参与者进入/离开“活动中”状态:

activate 参与者
deactivate 参与者
``` mermaid!
sequenceDiagram
    Alice->>John: Hello John, how are you?
    activate John
    John-->>Alice: Great!
    deactivate John

``` mermaid!
sequenceDiagram
Alice->>+John: Hello John, how are you?
John-->>-Alice: Great!

在同一个参与者上面可以叠加多个活动中状态

``` mermaid!
sequenceDiagram
    Alice->>+John: Hello John, how are you?
    Alice->>+John: John, can you hear me?
    John-->>-Alice: Hi Alice, I can hear you!
    John-->>-Alice: I feel great!

标注

可以对流程图进行标注,标注位置支持 左侧, 右侧 和 横跨 三种方式

Note 位置表述 参与者: 标注文字

其中位置表述可以为

表述 含义
right of 右侧
left of 左侧
over 在当中,可以横跨多个参与者

``` mermaid!
sequenceDiagram
participant John
Note right of John: Text in note

``` mermaid!
sequenceDiagram
    participant John
    Note left of John: Text in note

``` mermaid!
sequenceDiagram
Alice->John: Hello John, how are you?
Note over Alice,John: A typical interaction

#### 循环

语法如下

loop 循环的条件
    循环体描述语句
end

示例

``` mermaid!
sequenceDiagram
    Alice->John: Hello John, how are you?
    loop Every minute
        John-->Alice: Great!
    end

条件选择
语法如下

alt 条件 1 描述
分支 1 描述语句
else 条件 2 描述 # else 分支可选
分支 2 描述语句
else ...
...
end
如果遇到可选的情况,即没有 else 分支的情况,使用如下语法:

opt 条件描述
分支描述语句
end
示例

``` mermaid!
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
opt Extra response
Bob->>Alice: Thanks for asking
end

#### 自定义样式

mermaid 在生成序列图时,会定义很多 class, 配合上小书匠的自定义 css 样式,用户可以进行更个性化的样式控制

下面列出的是 mermaid 生成的 class

|Class|Description|
|--|:--|
actor|Style for the actor box at the top of the diagram.
text.actor|Styles for text in the actor box at the top of the diagram.
actor-line|The vertical line for an actor.
messageLine0|Styles for the solid message line.
messageLine1|Styles for the dotted message line.
messageText|Defines styles for the text on the message arrows.
labelBox|Defines styles label to left in a loop.
labelText|Styles for the text in label for loops.
loopText|Styles for the text in the loop box.
loopLine|Defines styles for the lines in the loop box.
note|Styles for the note box.
noteText|Styles for the text on in the note boxes.

### 类图

类图用于面向对象对于应用结构概念建模, 也用于把具体的模型翻译成程序代码。类图也可以用于数据建模。

Mermaid 支持类图语法显示

```mermaid!
 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()
      }

语法

类结构
UML 提供一种机制表示类及成员,比如属性,方法和一些其他额外信息。

一个简单的类在图形上主要包含下面三种主要部份:

最顶层为类的名称。显示为粗体,且首字母为大写。同时可以定义一些描述文字。
中间层为类的属性。多个属性之间将进行左对齐排列,属性名称以小写开头。
底层部份为类的一些方法函数。多个方法之间将进行左对齐排列,方法名称也是以小写开头。

```mermaid!
classDiagram
class BankAccount
BankAccount : +String owner
BankAccount : +Bigdecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawl(amount)

#### 定义一个类

两种方法定义一个类:

通过关键字 class , 比如 class Animal, 显示定义一个类
通过两个类之间的关系 relationship 来隐式定义类比如 Vehicle <|-- Car这样就定义了两个类 Vehicle  Car以及他们之间的关系

```mermaid!
classDiagram
    class Animal
    Vehicle <|-- Car

注: 类的名称只能由字母,数字和下划线组成。

定义类的成员

Mermaid 通过括号 () 区分类的属性和方法。带有 () 的内容,将会做为方法进行显示,其他的则做为类的属性。

Mermaid 提供两种方法定义类的成员

类外字义

```mermaid!
classDiagram
class BankAccount
BankAccount : +String owner
BankAccount : +BigDecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawal(amount)

类内部定义

```mermaid!
classDiagram
    class BankAccount{
        +String owner
        +BigDecimal balance
        +deposit(amount)
        +withdrawl(amount)
    }

返回类型

通过在类成员的方法最后,也就是) 添加上一个空格,然后就可以定义该方法的返回类型。

example:

```mermaid!
classDiagram
class BankAccount{
+String owner
+BigDecimal balance
+deposit(amount) bool
+withdrawl(amount) int
}

泛型

在 Mermaid 里,对于泛型,比如 List<int>泛型类型,只要将 <> 用波浪线~代替,生成的图形就可以表示为泛型。

注: 目前 Mermaid 还不支持嵌套泛型定义,比如 List<List<int>>

```mermaid!
classDiagram
class Square~Shape~{
    int id
    List~int~ position
    setPoints(List~int~ points)
    getPoints() List~int~
}

Square : -List~string~ messages
Square : +setMessages(List~string~ messages)
Square : +getMessages() List~string~

可见性

类成员的可见性有四种,在类成员的名称前面添加下面这些符号来进行表示。

+ Public
- Private
# Protected
~ Package/Internal

类成员方法还可以在其结尾处添加下面两种符号来表示方法的类型,比如静态和虚函数。

* Abstract e.g.: someAbstractMethod()*
$ Static e.g.: someStaticMethod()$

定义类之间的关系

主要语法:

[classA][Arrow][ClassB]:LabelText
Mermaid 支持的几种类之间关系
语法 描述
< --
*-- 组合
o-- 聚合
--> 关联
-- 实线连接
..> 依赖
.. >
.. 虚线连接

```mermaid!
classDiagram
classA <|-- classB
classC *-- classD
classE o-- classF
classG <-- classH
classI -- classJ
classK <.. classL
classM <|.. classN
classO .. classP

```mermaid!
classDiagram
classA --|> classB : Inheritance
classC --* classD : Composition
classE --o classF : Aggregation
classG --> classH : Association
classI -- classJ : Link(Solid)
classK ..> classL : Dependency
classM ..|> classN : Realization
classO .. classP : Link(Dashed)

基数和多重性在关系上的表示

多种基数表示

1 Only 1
0..1 Zero or One
1..* One or more
* Many
n n {where n>1}
0..n zero to n {where n>1}
1..n one to n {where n>1}

在关系arrow的前面或者后面可以添加用引用 " 包裹的基数内容,用以实现多重性的定义显示效果。实际上,该引号内包裹的内容可以不一定需要上面提到的基数文本,用户自己输入一些描述文字也是可以的。

```mermaid!
[classA] "cardinality1" [Arrow] "cardinality2" [ClassB]:LabelText
classDiagram
Customer "1" --> "" Ticket
Student "1" --> "1..
" Course
Galaxy --> "many" Star : Contains

#### 类的注解

通过特定的文本来注解类的信息

```sh
<<Interface>> 表示接口
<<abstract>> 表示抽像类
<<Service>> 服务类
<<enumeration>> 枚举类

将要注解的信息用 << 和 >> 包裹实现。系统提供两种方式的类注解

单独行注解:

```mermaid!
classDiagram
class Shape
<> Shape

在类内部注解

```mermaid!
classDiagram
class Shape{
    <<interface>>
    noOfVertices
    draw()
}
class Color{
    <<enumeration>>
    RED
    BLUE
    GREEN
    WHITE
    BLACK
}

注释

mermaid注释用%%开头,系统会忽略注释的文本行内容。

```mermaid!
classDiagram
%% This whole line is a comment classDiagram class Shape <>
class Shape{
<>
noOfVertices
draw()
}

#### 设置类图显示布局方向

类图支持四种布局方向,LR,RL,BT和 TB。通过指令 direction 控制。

```mermaid!
classDiagram
  direction RL
  class Student {
    -idCard : IdCard
  }
  class IdCard{
    -id : int
    -name : string
  }
  class Bike{
    -id : int
    -name : string
  }
  Student "1" --o "1" IdCard : carries
  Student "1" --o "1" Bike : rides

状态图

Mermaid 最新版本支持状态图的显示,语法与 plantUml 类似

```mermaid!
stateDiagram-v2
[] --> Still
Still --> [
]

Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
状态
状态可以用多种方式表示。最简单的方式就是定义状态 id 默认为状态的显示

```mermaid!
stateDiagram-v2
    s1

另一种方法使用 state 指令定义一个带描述的状态

```mermaid!
stateDiagram-v2
state "This is a state description" as s2

第三种方法就是通过冒号分格开状态 id 和状态描述

```mermaid!
stateDiagram-v2
    s2 : This is a state description

转换
用-->表示两个状态间的转换,比如: s1 --> s2。代码为:

```mermaid!
stateDiagram-v2
s1 --> s2

也可以用:加上描述符组成转换条件,代码为:

```mermaid!
stateDiagram-v2
    s1 --> s2: A transition

组合状态
组合状态,也可以说成子状态,也就是所谓的一个状态里包含多个状态,他们对于外部的状态,其实是一个黑盒子,但在内部里,却有自己的逻辑关系。

定义一个组合状态,通过 state 指令,指定哪个状态需要变成组合状态,然后再通过 {} 符号,将子状态的状态图包裹在内就可以了。

```mermaid!
stateDiagram-v2
[] --> First
state First {
[
] --> second
second --> [*]
}

Mermaid 支持多层嵌套的组合状态:

```mermaid!
stateDiagram-v2
    [*] --> First

    state First {
        [*] --> Second

        state Second {
            [*] --> second
            second --> Third

            state Third {
                [*] --> third
                third --> [*]
            }
        }
    }

组合状态之间支持状态转换:

```mermaid!
stateDiagram-v2
[*] --> First
First --> Second
First --> Third

state First {
    [*] --> fir
    fir --> [*]
}
state Second {
    [*] --> sec
    sec --> [*]
}
state Third {
    [*] --> thi
    thi --> [*]
}
选择

使用`<<choice>>`,让状态进入选择模式

```mermaid!
stateDiagram-v2
    state if_state <<choice>>
    [*] --> IsPositive
    IsPositive --> if_state
    if_state --> False: if n < 0
    if_state --> True : if n >= 0

分支/汇流
使用 <<fork>>, <<join>>,可以让状态进行分支或者汇流。

```mermaid!
stateDiagram-v2
state fork_state <>
[*] --> fork_state
fork_state --> State3
fork_state --> State3

  state join_state <<join>>
  State2 --> join_state
  State3 --> join_state
  join_state --> State4
  State4 --> [*]

```

参考文献

[^1] https://zhuanlan.zhihu.com/p/17880793496

苏ICP备19018690号-1