跳转到主要内容

Mermaid

mermaid 围栏把文本写成流程图、时序图、甘特图、类图与状态图,本地渲染、跟随深浅色、diff 友好。

mermaid 围栏把一段文本渲染成流程图、时序图、甘特图、类图、ER 图与状态图。图以源码形式存在,可以进 Git、可以 review diff、可以被搜索命中;渲染由主题自带的 Mermaid 在读者浏览器里完成,不请求外部服务。需要像素级控制的示意图画成 SVG,按图片使用。

最简例子

源码
```mermaid
flowchart LR
  内容["content/"] --> Hugo
  配置["hugo.yml"] --> Hugo
  主题["OINK 主题"] --> Hugo
  Hugo --> 站点["public/"]
```
flowchart LR
  内容["content/"] --> Hugo
  配置["hugo.yml"] --> Hugo
  主题["OINK 主题"] --> Hugo
  Hugo --> 站点["public/"]

围栏语言写 mermaid 即可,没有其它开关。主题检测到这个围栏后才把 Mermaid 运行时加入这一页,同一页里画十张图也只加载一次。

时序图

sequenceDiagram 描述参与者之间按时间发生的消息,适合说明请求链路与加载顺序。

源码
```mermaid
sequenceDiagram
  autonumber
  participant 读者 as 读者浏览器
  participant CDN as 静态托管
  participant JS as 页面脚本包
  读者->>CDN: GET /zh/docs/components/mermaid/
  CDN-->>读者: HTML(含 <pre class="mermaid">)
  读者->>CDN: GET 本页的脚本包
  CDN-->>读者: mermaid.min.js
  JS->>JS: 把围栏源码渲染成 SVG
  Note over JS: 未使用的运行时不下载
```
sequenceDiagram
  autonumber
  participant 读者 as 读者浏览器
  participant CDN as 静态托管
  participant JS as 页面脚本包
  读者->>CDN: GET /zh/docs/components/mermaid/
  CDN-->>读者: HTML(含 <pre class="mermaid">)
  读者->>CDN: GET 本页的脚本包
  CDN-->>读者: mermaid.min.js
  JS->>JS: 把围栏源码渲染成 SVG
  Note over JS: 未使用的运行时不下载

甘特图

gantt 画时间区间。下面是 PostgreSQL 各大版本从发布日算起的五年社区支持期,1825d 即五年。

源码
```mermaid
gantt
  title PostgreSQL 大版本的五年社区支持期
  dateFormat YYYY-MM-DD
  axisFormat %Y
  section PG 15
  发布于 2022-10-13 :2022-10-13, 1825d
  section PG 16
  发布于 2023-09-14 :2023-09-14, 1825d
  section PG 17
  发布于 2024-09-26 :2024-09-26, 1825d
  section PG 18
  发布于 2025-09-25 :active, 2025-09-25, 1825d
```
gantt
  title PostgreSQL 大版本的五年社区支持期
  dateFormat YYYY-MM-DD
  axisFormat %Y
  section PG 15
  发布于 2022-10-13 :2022-10-13, 1825d
  section PG 16
  发布于 2023-09-14 :2023-09-14, 1825d
  section PG 17
  发布于 2024-09-26 :2024-09-26, 1825d
  section PG 18
  发布于 2025-09-25 :active, 2025-09-25, 1825d

类图与 ER 图

classDiagram 画类型与关系,erDiagram 画实体与基数。两者都常用来解释数据模型。

源码
```mermaid
classDiagram
  class Page {
    +string Title
    +string Description
    +int Weight
    +Content()
    +OutputFormats()
  }
  class Resource {
    +string Name
    +string RelPermalink
    +Resize(spec)
  }
  class OutputFormat {
    +string Name
    +string MediaType
  }
  Page "1" --> "0..*" Resource : 页面包资源
  Page "1" --> "1..*" OutputFormat : html / print / markdown / rss
```
classDiagram
  class Page {
    +string Title
    +string Description
    +int Weight
    +Content()
    +OutputFormats()
  }
  class Resource {
    +string Name
    +string RelPermalink
    +Resize(spec)
  }
  class OutputFormat {
    +string Name
    +string MediaType
  }
  Page "1" --> "0..*" Resource : 页面包资源
  Page "1" --> "1..*" OutputFormat : html / print / markdown / rss
源码
```mermaid
erDiagram
  pg_database ||--o{ pg_namespace : "包含模式"
  pg_namespace ||--o{ pg_class : "包含关系"
  pg_class ||--o{ pg_attribute : "包含列"
  pg_class ||--o{ pg_index : "被索引"
  pg_class {
    oid oid PK
    name relname
    char relkind
  }
  pg_attribute {
    oid attrelid FK
    name attname
    smallint attnum
  }
```
erDiagram
  pg_database ||--o{ pg_namespace : "包含模式"
  pg_namespace ||--o{ pg_class : "包含关系"
  pg_class ||--o{ pg_attribute : "包含列"
  pg_class ||--o{ pg_index : "被索引"
  pg_class {
    oid oid PK
    name relname
    char relkind
  }
  pg_attribute {
    oid attrelid FK
    name attname
    smallint attnum
  }

状态图

stateDiagram-v2 画状态与迁移条件。下面是 OINK 主题一次发布依次经过的五个状态。这五个状态互不等价,本地构建通过不属于其中任何一个。

源码
```mermaid
stateDiagram-v2
  [*] --> 源码完成
  源码完成 --> 已验证 : 主题检查脚本 + 站点测试套件全绿
  已验证 --> 已发布 : 推送不可变的签名 vX.Y.Z 标签
  已发布 --> 已文档化 : 站点 go.mod 钉住该标签
  已文档化 --> 已部署 : 生产构建上线
  已部署 --> [*]
  已发布 --> 源码完成 : 发现问题只能出新补丁版本,标签不移动
```
stateDiagram-v2
  [*] --> 源码完成
  源码完成 --> 已验证 : 主题检查脚本 + 站点测试套件全绿
  已验证 --> 已发布 : 推送不可变的签名 vX.Y.Z 标签
  已发布 --> 已文档化 : 站点 go.mod 钉住该标签
  已文档化 --> 已部署 : 生产构建上线
  已部署 --> [*]
  已发布 --> 源码完成 : 发现问题只能出新补丁版本,标签不移动

单张图的标题与配置

围栏正文最前面可以写 Mermaid 自己的 YAML 头,它不是 Hugo front matter。title 给图加标题,config 覆盖这一张图的 Mermaid 配置。写死 config.theme 的图不再跟随站点深浅色。

源码
```mermaid
---
title: 只有用到的运行时才会进包
config:
  flowchart:
    curve: linear
---
flowchart TD
  页面 --> 判断{用了什么组件?}
  判断 -->|Mermaid 围栏| M[mermaid.min.js]
  判断 -->|ECharts 围栏| E[echarts.min.js]
  判断 -->|都没用| B[只有基础包]
```
---
title: 只有用到的运行时才会进包
config:
  flowchart:
    curve: linear
---
flowchart TD
  页面 --> 判断{用了什么组件?}
  判断 -->|Mermaid 围栏| M[mermaid.min.js]
  判断 -->|ECharts 围栏| E[echarts.min.js]
  判断 -->|都没用| B[只有基础包]

深浅色

页面初始化时主题读取当前配色模式:深色模式下用 Mermaid 的 dark 主题,浅色模式下用站点配置的主题。Mermaid 不支持重新初始化,读者切换配色时会 重载整个页面,图的配色随之更新。

因此不要把 Mermaid 图放进需要保留输入状态的页面,例如带表单的页面。

站点级默认写在 hugo.yml 里,键名小写,主题按 Mermaid 的默认配置匹配回正确的大小写:

hugo.yml
params:
  mermaid:
    theme: neutral
    flowchart:
      diagrampadding: 6

完整键表见配置总览,可用值以 Mermaid 配置文档为准。

放进标签页与步骤

mermaid 围栏没有 tab 属性,相邻围栏标签页只对普通代码围栏生效。并排比较两张图用 tabs shortcode。

源码
{{< tabs >}}
{{< tab label="按数据流看" >}}
```mermaid
flowchart LR
  Markdown --> Goldmark --> 渲染钩子 --> HTML
```
{{< /tab >}}
{{< tab label="按输出形态看" >}}
```mermaid
flowchart LR
  页面 --> HTML
  页面 --> 打印
  页面 --> Markdown
  页面 --> RSS
```
{{< /tab >}}
{{< /tabs >}}
flowchart LR
  Markdown --> Goldmark --> 渲染钩子 --> HTML
flowchart LR
  页面 --> HTML
  页面 --> 打印
  页面 --> Markdown
  页面 --> RSS

{{% steps %}} 里的每一步是页面级 Markdown,其中可以写 mermaid 围栏,用法见步骤

输出形态

输出 呈现
HTML <pre class="mermaid"> + 本地 Mermaid 运行时,浏览器画成 SVG
打印 与 HTML 相同:打印视图同样加载运行时,图会画出来
Markdown 原样保留 mermaid 围栏与它的源码
RSS 输出 <pre class="mermaid"> 包着的图表源码,订阅端看到的是文本

参数参考

围栏属性:没有。mermaid 围栏不读属性行,写 {height=…}{class=…} 之类既不生效也不报错;尺寸由图自身与容器宽度决定。

站点参数(hugo.yml):

params.mermaid , map , default未设置
整个映射按 Mermaid 的 initialize() 配置传入;键名写小写,主题按 Mermaid 默认配置匹配回正确大小写
params.mermaid.theme , string , defaultMermaid 默认
浅色模式下的主题;深色模式下被强制为 dark

单张图的配置写在围栏正文最前面的 YAML 头里(titleconfig),属于 Mermaid 语法,不是主题参数。

限制与常见问题

  • 切换深浅色会重载页面:Mermaid 不支持重新初始化,主题在渲染正确与不刷新之间选择了前者。
  • 图不能编号、不能缩放:Mermaid 输出的是内联 SVG,不是 <img>{#id num=} 编号与图片缩放都不适用;需要编号时导出成图片,按图片的编号写法使用。
  • 围栏属性无效:宽度在图里控制(flowchart 的方向、classDiagram 的布局),或者用 CSS。
  • 语法错误只在浏览器里可见:Hugo 不解析 Mermaid 语法,写错的图在页面上显示 Mermaid 的报错框,构建照样通过,发布前要在浏览器里确认。
  • RSS 订阅者只能看到源码:结论要写在正文里,不要只画在图上。
  • PlantUML — UML 更全,但需要一个渲染服务
  • 思维导图 — 大纲式的层级图
  • ECharts — 有数值的统计图
  • 图片 — 手绘 SVG、需要编号与缩放的图