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
```渲染出來就是一個從上到下的流程圖,包含一個判斷節點和兩條分支。核心就三步:
- 寫
```mermaid開頭的程式碼區塊 - 在裡面用 Mermaid 語法定義圖表
- 儲存後渲染器自動產生 SVG 圖表
對了,Mermaid 用 %% 來寫註解,跟很多語言的雙斜線註解類似:
```mermaid
flowchart TD
%% 這是一個註解,不會顯示在圖表中
A --> B
```流程圖(Flowchart)——最常用的圖表
流程圖是 Mermaid 中使用頻率最高的圖表類型。定義一個流程圖,開頭的 flowchart 關鍵字後面跟方向:
| 方向 | 關鍵字 | 說明 |
|---|---|---|
| 從上到下 | TD 或 TB | Top-Down / Top-Bottom |
| 從下到上 | BT | Bottom-Top |
| 從左到右 | LR | Left-Right |
| 從右到左 | RL | Right-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 分區,不然圖表會很亂,可讀性也差。
flowchart 和 graph 的差別
你可能會在一些舊文章裡看到用 graph 而不是 flowchart。這是因為 Mermaid 早期版本只有 graph 關鍵字,後來新增了 flowchart 作為替代。兩者的主要差別:
flowchart支援更多的連接線類型(比如雙向箭頭<-->)flowchart的子圖之間可以直接連線graph是舊語法,仍然可用但不建議新專案使用
如果你剛開始學,直接用 flowchart 就好,不用糾結。
時序圖(Sequence Diagram)——互動流程
時序圖適合描述多個角色之間的互動順序,比如客戶端和伺服器之間的請求-回應流程,或者使用者和系統之間的操作步驟。
```mermaid
sequenceDiagram
participant 使用者
participant 前端
participant 後端
participant 資料庫
使用者->>前端: 輸入帳號密碼
前端->>後端: 發送登入請求
後端->>資料庫: 查詢使用者資訊
資料庫-->>後端: 回傳使用者資料
後端-->>前端: 回傳登入結果
前端-->>使用者: 顯示登入成功
```時序圖的箭頭類型
| 寫法 | 含義 |
|---|---|
->> | 實線箭頭(請求) |
-->> | 虛線箭頭(回應/回傳) |
--) | 實線開放箭頭 |
--) | 虛線開放箭頭 |
-x | 實線叉號(非同步) |
進階用法:迴圈和條件
時序圖裡可以用 loop、alt、opt 等關鍵字來表示迴圈和條件分支:
```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,非常方便。
常見問題排查
圖表不顯示?
最常見的原因:
- 程式碼區塊標記錯誤 — 確認是
```mermaid不是```markdown或```text - 語法拼寫錯誤 — Mermaid 對關鍵字大小寫不敏感,但拼寫錯誤會直接導致渲染失敗
- 縮排問題 — 雖然 Mermaid 不像 Python 那樣嚴格依賴縮排,但 subgraph 內的節點需要對齊
特殊字元顯示異常?
如果節點文字中包含 ()、{}、[] 這些符號,需要用引號包裹:
```mermaid
flowchart TD
A["處理資料(x, y)"] --> B
```圖表太大或太小?
Mermaid 會自動根據內容調整大小。如果覺得太大,可以精簡節點數量;如果需要精確控制樣式,Mermaid 支援 classDef 來自訂節點樣式,不過這個已經屬於進階用法了。
參考來源
- Mermaid 官方文件 — Introduction:Mermaid 語法參考和入門指南
- GitHub Blog — Include Diagrams in Markdown Files with Mermaid:GitHub 官方 Mermaid 支援公告
- GitHub Docs — Creating Diagrams:GitHub 平台的 Mermaid 使用文件