Markdown 画图教程:用 Mermaid 画流程图、时序图、甘特图

Markdown 也能画图?Mermaid 入门

写技术文档的时候,经常会需要配图——流程图、架构图、时序图之类的。传统做法是用 draw.io 或者 Visio 画好再导出图片插入,但这就带来一个问题:图和文字是分离的。文档改了,图也得重新打开工具改,时间一长就容易不同步。

Mermaid 解决的就是这个问题。它让你直接在 Markdown 里用文本写图表定义,渲染器自动帮你画出图来。代码和文档放在一起,版本控制也方便,改个节点就是改行文字的事。

简单说,Mermaid 是一个基于 JavaScript 的图表库,支持用类似 Markdown 的文本语法来定义各种图表。GitHub 从 2022 年开始原生支持 Mermaid,现在 Typora、Obsidian、GitLab、VS Code 这些主流工具也都能渲染 Mermaid 图表了。

基本语法:mermaid 代码块

在 Markdown 中使用 Mermaid 非常简单,就是写一个 mermaid 标记的代码块:

​```mermaid
flowchart TD
    A[开始] --> B{是否继续?}
    B -->|是| C[处理]
    B -->|否| D[结束]
    C --> D
​```

渲染出来就是一个从上到下的流程图,包含一个判断节点和两条分支。核心就三步:

  1. ```mermaid 开头的代码块
  2. 在里面用 Mermaid 语法定义图表
  3. 保存后渲染器自动生成 SVG 图表

对了,Mermaid 用 %% 来写注释,跟很多语言的双斜杠注释类似:

​```mermaid
flowchart TD
    %% 这是一个注释,不会显示在图表中
    A --> B
​```

流程图(Flowchart)——最常用的图表

流程图是 Mermaid 中使用频率最高的图表类型。定义一个流程图,开头的 flowchart 关键字后面跟方向:

方向关键字说明
从上到下TDTBTop-Down / Top-Bottom
从下到上BTBottom-Top
从左到右LRLeft-Right
从右到左RLRight-Left

节点形状

节点的形状由包裹文字的符号决定,这是很多教程没讲清楚的细节:

​```mermaid
flowchart LR
    A[矩形] --> B(圆角矩形)
    B --> C{菱形判断}
    C --> D[(数据库)]
    D --> E[[子程序]]
    E --> F>不对称形状]
​```
  • [] — 标准矩形
  • () — 圆角矩形
  • {} — 菱形(通常用于判断)
  • [()] — 圆柱体(数据库)
  • [[]] — 子程序
  • > — 不对称形状

说实话,实际用得最多的就是 [](){} 这三种,其他的按需选用就行。

连接线

连接线也有好几种写法,对应不同的线型和箭头:

​```mermaid
flowchart LR
    A --> B    %% 实线箭头
    C --- D    %% 实线无箭头
    E -->|文字| F   %% 带标注的实线箭头
    G -.-> H   %% 虚线箭头
    I ==> J    %% 粗线箭头
​```
写法效果
-->实线 + 箭头
---实线,无箭头
-->\|文字\|实线 + 箭头 + 标注文字
-.->虚线 + 箭头
==>粗线 + 箭头

子图(Subgraph)

当流程图比较复杂时,可以用 subgraph 把相关节点分组:

​```mermaid
flowchart TB
    subgraph 用户端
        A[打开页面] --> B[填写表单]
    end
    subgraph 服务端
        C[接收请求] --> D[验证数据]
        D --> E[写入数据库]
    end
    B --> C
    E --> F[返回结果]
​```

我自己的习惯是,一旦流程图超过 8 个节点,就会考虑用 subgraph 分区,不然图表会很乱,可读性也差。

flowchartgraph 的区别

你可能会在一些老文章里看到用 graph 而不是 flowchart。这是因为 Mermaid 早期版本只有 graph 关键字,后来新增了 flowchart 作为替代。两者的主要区别:

  • flowchart 支持更多的连接线类型(比如双向箭头 <-->
  • flowchart 的子图之间可以直接连线
  • graph 是旧语法,仍然可用但不推荐新项目使用

如果你刚开始学,直接用 flowchart 就好,不用纠结。

时序图(Sequence Diagram)——交互流程

时序图适合描述多个角色之间的交互顺序,比如客户端和服务器之间的请求-响应流程,或者用户和系统之间的操作步骤。

​```mermaid
sequenceDiagram
    participant 用户
    participant 前端
    participant 后端
    participant 数据库

    用户->>前端: 输入用户名密码
    前端->>后端: 发送登录请求
    后端->>数据库: 查询用户信息
    数据库-->>后端: 返回用户数据
    后端-->>前端: 返回登录结果
    前端-->>用户: 显示登录成功
​```

时序图的箭头类型

写法含义
->>实线箭头(请求)
-->>虚线箭头(响应/返回)
--)实线开放箭头
--)虚线开放箭头
-x实线叉号(异步)

高级用法:循环和条件

时序图里可以用 loopaltopt 等关键字来表示循环和条件分支:

​```mermaid
sequenceDiagram
    loop 每隔5秒
        客户端->>服务器: 心跳检测
        服务器-->>客户端: 确认存活
    end

    alt 认证成功
        服务器-->>客户端: 返回 Token
    else 认证失败
        服务器-->>客户端: 返回错误信息
    end
​```

note 可以在时序图中添加注释,放在某个参与者的上方或右侧:

​```mermaid
sequenceDiagram
    participant A as Alice
    participant B as Bob
    Note over A,B: 这是一条跨越两个参与者的备注
    A->>B: 你好
    Note right of B: 这条备注在 Bob 右侧
​```

甘特图(Gantt Chart)——项目排期

甘特图在项目管理和任务排期中非常实用。Mermaid 的甘特图语法也比较直观:

​```mermaid
gantt
    title 项目开发计划
    dateFormat YYYY-MM-DD
    axisFormat %m/%d

    section 需求阶段
    需求调研       :done, req1, 2024-01-01, 10d
    需求评审       :active, req2, after req1, 3d

    section 开发阶段
    前端开发       :dev1, after req2, 15d
    后端开发       :dev2, after req2, 12d

    section 测试上线
    集成测试       :test1, after dev1, 7d
    正式上线       :milestone, launch, after test1, 0d
​```

几个关键语法点:

  • dateFormat — 设置日期格式
  • section — 任务分组
  • done / active — 任务状态(已完成 / 进行中)
  • crit — 关键任务(红色高亮)
  • milestone — 里程碑(菱形标记)
  • after 任务ID — 表示某个任务在另一个之后开始

有个坑我之前踩过:dateFormat 必须和实际填写的日期格式一致。如果你设了 YYYY-MM-DD,但写的日期是 01/15/2024,图表会直接崩掉不显示。这个报错信息还不明显,排查起来挺费劲的。

类图(Class Diagram)——代码结构

类图适合描述面向对象设计中的类关系,如果你写的是 Java、C# 或 TypeScript 项目的技术文档,这个会很有用。

​```mermaid
classDiagram
    class Animal {
        +String name
        +int age
        +makeSound() void
    }
    class Dog {
        +String breed
        +fetch() void
    }
    class Cat {
        +bool isIndoor
        +purr() void
    }

    Animal <|-- Dog
    Animal <|-- Cat
​```

类之间关系的表示方式:

写法关系
<\|--继承
*--组合
o--聚合
-->关联
--\|>实现
..>依赖

类成员的访问修饰符:+ 是 public,- 是 private,# 是 protected。

状态图(State Diagram)

状态图用来描述一个对象在不同状态之间的转换过程,在嵌入式开发、游戏逻辑、工作流设计这些场景很常见。

​```mermaid
stateDiagram-v2
    [*] --> 待提交
    待提交 --> 审核中: 提交申请
    审核中 --> 已通过: 审核通过
    审核中 --> 已驳回: 审核驳回
    已驳回 --> 待提交: 重新编辑
    已通过 --> [*]
​```

[*] 表示起始和终止状态。stateDiagram-v2 是新版关键字,比旧版 stateDiagram 支持更多功能(比如嵌套状态和 note)。

状态图还可以用 note 添加说明文字:

​```mermaid
stateDiagram-v2
    state "加载中" as loading
    [*] --> loading
    loading --> 成功: 请求完成
    loading --> 失败: 请求出错

    note right of loading
        显示 Loading 动画
        等待服务器响应
    end note
​```

饼图(Pie Chart)

饼图是最简单的 Mermaid 图表类型,适合展示比例分布:

​```mermaid
pie title 前端框架使用占比
    "React" : 40
    "Vue" : 30
    "Angular" : 15
    "其他" : 15
​```

语法就这几行,pie 关键字开头,title 后面写标题,然后每行一个 "名称" : 数值。数值可以是百分比也可以是原始数值,Mermaid 会自动算比例。

ER 图(Entity-Relationship Diagram)

ER 图用于描述数据库中实体之间的关系,做后端开发或者数据库设计的时候经常会用到:

​```mermaid
erDiagram
    CUSTOMER ||--o{ ORDER : places
    ORDER ||--|{ LINE-ITEM : contains
    CUSTOMER {
        string name
        string email
        int age
    }
    ORDER {
        int id
        string status
        date created_at
    }
    LINE-ITEM {
        string product_name
        int quantity
        float price
    }
​```

关系符号的写法:

符号含义
\|\|--\|\|一对一(必须)
\|\|--o{一对多(可选)
\|\|--\|{一对多(必须)
}o--o{多对多

该选哪种图表?一个快速决策指南

场景推荐图表关键字
业务流程 / 审批流流程图flowchart
系统间交互 / API 调用时序图sequenceDiagram
项目排期 / 任务规划甘特图gantt
代码架构 / 继承关系类图classDiagram
状态机 / 工作流状态图stateDiagram-v2
比例分布饼图pie
数据库设计ER 图erDiagram

如果你不确定用哪种,大多数情况下流程图(flowchart)都能满足需求。时序图则是第二常用的,特别是做 Web 开发或者微服务相关文档的时候。

各平台对 Mermaid 的支持情况

Mermaid 的渲染效果取决于你用的工具,不同平台的支持程度差异还挺大的:

平台支持方式备注
GitHub原生支持README、Issue、PR 中自动渲染
GitLab原生支持与 GitHub 类似
Typora原生支持实时预览,效果最好
Obsidian原生支持需确认设置中开启了 Mermaid
VS Code需装插件推荐 "Markdown Preview Mermaid Support" 插件
Notion有限支持需通过代码块嵌入
飞书文档不支持需导出图片后插入

我在实际使用中遇到过一个问题:同一段 Mermaid 代码在 Typora 里渲染正常,但推到 GitHub 上某个子图之间的连线就消失了。排查后发现是 GitHub 的 Mermaid 版本比 Typora 低,某些新语法还不支持。所以如果你的文档要跨平台使用,建议先在目标平台上预览确认一下。

推荐用 Mermaid Live Editor 在线测试语法——左边写代码,右边实时预览,还能导出 SVG 和 PNG,非常方便。

常见问题排查

图表不显示?

最常见的原因:

  1. 代码块标记错误 — 确认是 ```mermaid 不是 ```markdown```text
  2. 语法拼写错误 — Mermaid 对关键字大小写不敏感,但拼写错误会直接导致渲染失败
  3. 缩进问题 — 虽然 Mermaid 不像 Python 那样严格依赖缩进,但 subgraph 内的节点需要对齐

特殊字符显示异常?

如果节点文字中包含 (){}[] 这些符号,需要用引号包裹:

​```mermaid
flowchart TD
    A["处理数据(x, y)"] --> B
​```

图表太大或太小?

Mermaid 会自动根据内容调整大小。如果觉得太大,可以精简节点数量;如果需要精确控制样式,Mermaid 支持 classDef 来自定义节点样式,不过这个已经属于进阶用法了。

参考来源