Mermaid

2026年7月26日

はじめに

Mermaidは、テキストベースで図を描画するためのオープンソースツールで、Markdownやドキュメント内で簡単にフローチャート、シーケンス図、クラス図などを作成できる。

利用方法

Markdownの一部として用いるなら、Joplinなど、Mermaidに対応したエディタを用いればよい。たとえば、つぎのようにMermaidのコードブロックを書くと、図として認識される。

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

HTMLであれば、以下のようにすれば、Mermaidによる記述を図として埋め込める。

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
    <script>mermaid.initialize({ startOnLoad: true });</script>
</head>
<body>
    <div class="mermaid">
        graph TD;
            A --> B;
            A --> C;
            B --> D;
            C --> D;
    </div>
</body>
</html>

コマンドラインツールとしては、NPMでインストールできる。

$ npm install -g @mermaid-js/mermaid-cli

Mermaidにより記述したファイルを用意して(拡張子は.mmdのようである)、以下のように実行する。

$ mmdc -i input.mmd -o output.svg
$ mmdc -i input.mmd -o output.png -b transparent

基本構文

Mermaidは、テキストベースのシンプルな記法である。図の種類がいくつかあり、それぞれ独自の記法になっていて、字下げに意味があったりなかったりする。

コメントは%%で書ける。

フローチャート

```mermaid
flowchart TD
    A[開始] --> B{条件?}
    B -->|Yes| C[処理1]
    B -->|No| D[処理2]
    C --> E[終了]
    D --> E
```
flowchart TD A[開始] --> B{条件?} B -->|Yes| C[処理1] B -->|No| D[処理2] C --> E[終了] D --> E

flowchartの代わりにgraphと書いても同じである。TDというのはTop-downの意味で、LR(Right to left)だと図が横になる。

flowchart LR A[注文開始] --> B{在庫確認} B -->|在庫あり| C[決済処理] B -->|在庫なし| D[在庫不足通知] C --> E[出荷準備] D --> F[注文キャンセル] E --> G[配送] G --> H[注文完了] F --> H

方向については、以下の種類がある。

  • TB - Top to bottom
  • TD - Top-down/ same as top to bottom
  • BT - Bottom to top
  • RL - Right to left
  • LR - Left to right

A[箱]だと箱型になるが、A(丸箱)だと角が丸くなる。

```mermaid
flowchart TD
    A(スタート)
```
flowchart TD A(スタート)

A[(円筒)]と書くと、円筒になる。

```mermaid
flowchart TD
    A[(データベース)]
```
flowchart TD A[(データベース)]

A((丸))だと丸。

```mermaid
flowchart TD
    A((1))
```
flowchart TD A((1))

点線は-.->など。

```mermaid
flowchart LR
    A[A] <-.-> B[B]
```
flowchart LR A[A] <-.-> B[B]

シーケンス図

```mermaid
sequenceDiagram
    participant ユーザー
    participant サーバー
    ユーザー ->> サーバー: リクエスト
    サーバー -->> ユーザー: レスポンス
    ユーザー ->> サーバー: データ送信
    サーバー -->> ユーザー: 確認
```
sequenceDiagram participant ユーザー participant サーバー ユーザー ->> サーバー: リクエスト サーバー -->> ユーザー: レスポンス ユーザー ->> サーバー: データ送信 サーバー -->> ユーザー: 確認

participantはなくてもよいが、ある場合、この順番で描画される。逆にすると逆になる。

```mermaid
sequenceDiagram
    participant サーバー
    participant ユーザー
    ユーザー ->> サーバー: リクエスト
    サーバー -->> ユーザー: レスポンス
    ユーザー ->> サーバー: データ送信
    サーバー -->> ユーザー: 確認
```
sequenceDiagram participant サーバー participant ユーザー ユーザー ->> サーバー: リクエスト サーバー -->> ユーザー: レスポンス ユーザー ->> サーバー: データ送信 サーバー -->> ユーザー: 確認

エイリアスが使える。

```mermaid
sequenceDiagram
    participant A as ユーザー
    participant B as サーバー
    A ->> B: リクエスト
    B -->> A: レスポンス
    A ->> B: データ送信
    B -->> A: 確認
```
sequenceDiagram participant A as ユーザー participant B as サーバー A ->> B: リクエスト B -->> A: レスポンス A ->> B: データ送信 B -->> A: 確認

actorというものもある。

sequenceDiagram actor 飼い主 participant にゃんこ 飼い主 ->> にゃんこ: エサを与える にゃんこ ->> にゃんこ: エサを食べる にゃんこ ->> 飼い主: にゃー

クラス図

```mermaid
classDiagram
    class Animal {
        +String name
        +int age
        +eat()
        +sleep()
    }
    class Cat {
        +String furColor
        +int lives
        +meow()
        +scratch()
    }
    Animal <|-- Cat
```
classDiagram class Animal { +String name +int age +eat() +sleep() } class Cat { +String furColor +meow() +scratch() } Animal <|-- Cat

まあ、そのまんまな気がする。

E-R図

```mermaid
erDiagram
    CAT ||--o{ FOOD : "エサを食べる"
    CAT ||--o{ NAP : "お昼寝をする"
    CAT ||--|| OWNER : "飼い主に属する"
    CAT }o--o{ PLAYGROUND : "遊ぶ"

    CAT {
        string name
        int age
        string fur_color
        int lives
    }

    FOOD {
        string name
        string flavor
        int quantity
    }

    NAP {
        datetime start_time
        datetime end_time
        string location
    }

    OWNER {
        string name
        string contact
        date since
    }

    PLAYGROUND {
        string name
        string location
        string type
    }
```
erDiagram CAT ||--o{ FOOD : "エサを食べる" CAT ||--o{ NAP : "お昼寝をする" CAT ||--|| OWNER : "飼い主に属する" CAT }o--o{ PLAYGROUND : "遊ぶ" CAT { string name int age string fur_color int lives } FOOD { string name string flavor int quantity } NAP { datetime start_time datetime end_time string location } OWNER { string name string contact date since } PLAYGROUND { string name string location string type }

||--o{などで1対多の関係などを表す。

ガントチャート

```mermaid
gantt
    title プロジェクトスケジュール
    axisFormat  %m-%d
    section タスク
    設計        :a1, 2023-10-01, 7d
    開発        :a2, after a1, 14d
    テスト      :a3, after a2, 7d
```
gantt title プロジェクトスケジュール axisFormat %m-%d section タスク 設計 :a1, 2023-10-01, 7d 開発 :a2, after a1, 14d テスト :a3, after a2, 7d

:milestoneでマイルストーンを置くことができる。

```mermaid
gantt
    title プロジェクト計画
    dateFormat  YYYY-MM-DD
    axisFormat  %m-%d
    section プロジェクト
        計画段階        :a1, 2023-10-01, 30d
        設計段階        :a2, after a1, 20d
        開発段階        :a3, after a2, 45d
        テスト段階      :a4, after a3, 15d
        リリース        :milestone, after a4, 0d
    section サブタスク
        UI設計         :b1, 2023-10-15, 10d
        バックエンド設計 :b2, 2023-10-25, 10d
        フロントエンド開発 :b3, after b1, 30d
        バックエンド開発 :b4, after b2, 30d
        統合テスト      :b5, after a3, 10d
```
gantt title プロジェクト計画 dateFormat YYYY-MM-DD axisFormat %m-%d section プロジェクト 計画段階 :a1, 2023-10-01, 30d 設計段階 :a2, after a1, 20d 開発段階 :a3, after a2, 45d テスト段階 :a4, after a3, 15d リリース :milestone, after a4, 0d section サブタスク UI設計 :b1, 2023-10-15, 10d バックエンド設計 :b2, 2023-10-25, 10d フロントエンド開発 :b3, after b1, 30d バックエンド開発 :b4, after b2, 30d 統合テスト :b5, after a3, 10d

マインドマップ

```mermaid
mindmap
  root((Mermaid))
    Mermaidの特徴
      テキストベース
      簡単な構文
    図の種類
      フローチャート
      シーケンス図
      クラス図
      ガントチャート
```
mindmap root((Mermaid)) Mermaidの特徴 テキストベース 簡単な構文 図の種類 フローチャート シーケンス図 クラス図 E-R図 ガントチャート

マインドマップの場合は、インデントに意味がある。

アーキテクチャ図

```mermaid
architecture-beta
    group api(cloud)[API]

    service db(database)[Database] in api
    service disk1(disk)[Storage] in api
    service disk2(disk)[Storage] in api
    service server(server)[Server] in api

    db:L -- R:server
    disk1:T -- B:server
    disk2:T -- B:db
```
architecture-beta group api(cloud)[API] service db(database)[Database] in api service disk1(disk)[Storage] in api service disk2(disk)[Storage] in api service server(server)[Server] in api db:L -- R:server disk1:T -- B:server disk2:T -- B:db

システム構成図(アーキテクチャ図)も描けるらしい。線をつなぐところでLとかRとかあるのは、アイコンから線が出る方向(db:Lならdbの左から出る)。

細かい項目

複雑な図

flowchartにおいて、subgraphで複数の図を組み合わせることができる。

flowchart TD subgraph 顧客 A[顧客] -->|注文情報| B[注文処理] end subgraph システム B -->|在庫確認| C[在庫データベース] B -->|決済情報| D[決済システム] D -->|決済結果| B B -->|出荷指示| E[出荷システム] end subgraph 運送業者 E -->|出荷依頼| F[運送業者] F -->|配送状況| E end

色を変える

色を変えることができる。

```mermaid
flowchart TD
    A[🌸 開始] --> B[🍭 処理1]
    B --> C[🍦 処理2]
    C --> D[🍰 終了]

    style A fill:#ffccff,stroke:#ff99ff,color:#ff66ff
    style B fill:#ffcc99,stroke:#ff9966,color:#ff9966
    style C fill:#ccffff,stroke:#99ffff,color:#66ffff
    style D fill:#ffccff,stroke:#ff99ff,color:#ff66ff

    linkStyle 0 stroke:#ff66ff,stroke-width:2px
    linkStyle 1 stroke:#ff9966,stroke-width:2px
    linkStyle 2 stroke:#66ffff,stroke-width:2px
```
flowchart TD A[🌸 開始] --> B[🍭 処理1] B --> C[🍦 処理2] C --> D[🍰 終了] style A fill:#ffccff,stroke:#ff99ff,color:#ff66ff style B fill:#ffcc99,stroke:#ff9966,color:#ff9966 style C fill:#ccffff,stroke:#99ffff,color:#66ffff style D fill:#ffccff,stroke:#ff99ff,color:#ff66ff linkStyle 0 stroke:#ff66ff,stroke-width:2px linkStyle 1 stroke:#ff9966,stroke-width:2px linkStyle 2 stroke:#66ffff,stroke-width:2px

より複雑な設定

```mermaid
%%{init: {'theme': 'default', 'themeVariables': { 'primaryColor': '#ff99ff', 'primaryBorderColor': '#ff99ff', 'lineColor': '#ff99ff', 'secondaryColor': '#ffccff', 'tertiaryColor': '#ff66ff', 'mainBkg': '#ffffff', 'nodeBkg': '#ffffff', 'clusterBkg': '#ffffff', 'defaultLinkColor': '#ff99ff', 'fontFamily': 'Arial', 'fontSize': '14px'}} }%%
flowchart TD
    A[🌸 開始] --> B[🍭 処理1]
    B --> C[🍦 処理2]
    C --> D[🍰 終了]
```
%%{init: {'theme': 'default', 'themeVariables': { 'primaryColor': '#ff99ff', 'primaryBorderColor': '#ff99ff', 'lineColor': '#ff99ff', 'secondaryColor': '#ffccff', 'tertiaryColor': '#ff66ff', 'mainBkg': '#ffffff', 'nodeBkg': '#ffffff', 'clusterBkg': '#ffffff', 'defaultLinkColor': '#ff99ff', 'fontFamily': 'Arial', 'fontSize': '14px'}} }%% flowchart TD A[🌸 開始] --> B[🍭 処理1] B --> C[🍦 処理2] C --> D[🍰 終了]

Markdownの変換

MarkdownからHTMLへの変換をpandocでやろうとしたとき、Mermaidを適切に処理してくれない。フィルターを使う。

-- mermaid_filter.lua

function CodeBlock(el)
  -- mermaidコードブロックかどうかチェック
  if el.classes[1] == "mermaid" then
    -- テキストからクラス名を取り除く
    local content = el.text
    -- <div class="mermaid">で囲む
    return pandoc.RawBlock('html', '<div class="mermaid">' .. content .. '</div>')
  end
  
  return el
end

変換

$ pandoc mermaid.md -o mermaid.html --mathjax -r markdown-auto_identifiers --lua-filter=mermaid_filter.lua