ササっとフローが書きたいときはmermaidが良さげ

# mermaidらくちん!
Qiitaで記事を書いていると「あー、スクショ撮るのめんどい」とか「あー、これフロー図書いたほうがわかり良いわ」とか出てきます。スクショはクリップボードから直接貼り付けができるのでとても楽になりました。で、図形描画、特に「なんとかとなんとかを矢印で結んで～」といったものは今まで結構とっつきづらいイメージがあったのですが、[mermaid(https://mermaid.js.org/)](https://mermaid.js.org/) のmermaid記法が使えるとのことで、使ってみました。
めっちゃらくちん!
というわけで、基本的なコマンドとかを本家からピックアップしてまとめようというのが本記事の主旨です。

# 各ダイアグラムについて
mermaidが対応しているダイアグラムを表にしてみました(リンク先は本家ドキュメント(英語))。

|ダイアグラムの名前|日本語名称|主な用途|対応状況|
|:-:|:-:|:-:|:-:|
|[Flowchart](https://mermaid.js.org/syntax/flowchart.html)|フローチャート|流れ図<br>有向・無向グラフ|正式対応|
|[Sequence Diagram](https://mermaid.js.org/syntax/sequenceDiagram.html)|シーケンス図|UML|正式対応|
|[Class Diagram](https://mermaid.js.org/syntax/classDiagram.html)|クラス図|UML|正式対応|
|[State Diagram](https://mermaid.js.org/syntax/stateDiagram.html)|状態遷移図|UML|正式対応|
|[Entity Relationship Diagram](https://mermaid.js.org/syntax/entityRelationshipDiagram.html)|ER図|データベース設計|正式対応|
|[User Journey](https://mermaid.js.org/syntax/userJourney.html)|ユーザーエクスペリエンス図(?)|(これなんだろ)|正式対応|
|[Gantt](https://mermaid.js.org/syntax/gantt.html)|ガントチャート|タスク管理|正式対応|
|[Pie Chart](https://mermaid.js.org/syntax/pie.html)|円グラフ|数値グラフ|正式対応|
|[Quandrant Chart](https://mermaid.js.org/syntax/quadrantChart.html)|4象限マトリクス|分析図|正式対応|
|[Requirement Diagram](https://mermaid.js.org/syntax/requirementDiagram.html)|要求図|SysML|正式対応|
|[Gitgraph (Git) Diagram](https://mermaid.js.org/syntax/gitgraph.html)|Gitグラフ|コミットグラフ|正式対応|
|[C4C Diagram (Context Diagram)](https://mermaid.js.org/syntax/c4c.html)|C4モデルのコンテキスト図|C4モデル|Experimental|
|[Mindmaps](https://mermaid.js.org/syntax/mindmap.html)|マインドマップ|分析図|Experimental|
|[Timeline](https://mermaid.js.org/syntax/timeline.html)|タイムライン|時間変化表現|Experimental|
|[ZenUML](https://mermaid.js.org/syntax/zenuml.html)|ZenUML|UML|Experimental|

User Journey いったい何者なの……?

## コメントとオプションについて
mermaidにはコメント機能があります
コメント自体は```%%```から始まる行がコメントになるみたいです。
例えば、下のコードをmermaidにすると
```
%% これはコメントです。
flowchart TB
    %% ノードの設定
    root(hoge)
    A[piyo]
    B[fuga]
    %% 枝の設定
    root-->A
    root-->B
```
ばっちり図だけになってますね。
```mermaid
%% これはコメントです。
flowchart TB
    root(hoge)
    A[piyo]
    B[fuga]

    root-->A
    root-->B
```

また、Qiitaでは有効にならないようですが[オプションの命令セット](https://mermaid.js.org/config/directives.html)があります。

## mermaid.jsのDirective
Directiveについてざざっと斜めに見ていきましょう。

### Directiveの宣言
Directiveはmermaidグラフの宣言の直前に表記します。
```%%{directive_text}%%```というようにパーセント記号2つを重ねた中に命令文を書いていきます。
```directive_text```の部分はJSONになります。キーワード```init```または```initialize```から始まります。
例えば次のように、```init```および```initialize```から始まる2つのdirective_textが指定された場合は
```text: directiveの例
%%{init: { 'logLevel': 'debug', 'theme': 'forest' } }%%
%%{initialize: { 'logLevel': 'fatal', "theme":'dark', 'startOnLoad': true } }%%
```
これらは統合されて1つのDirectiveとなります。
```json: initとinitializeを統合した結果
{
    "logLevel": "fatal",
    "theme": "dark",
    "startOnLload": true
}
```
上の例では統合の結果、```"logLevel"```が```"fatal"```に設定されました。

### Directiveを適用した例
次のDirectiveを適用して[A]-->[B]のグラフを書いてみます。
```text:適用するDirective
%%{
  init: {
    "theme": "dark",
    "fontFamily": "monospace",
    "logLevel": "info",
    "flowchart": {
      "htmlLabels": true,
      "curve": "linear"
    },
    "sequence": {
      "mirrorActors": true
    }
  }
}%%
```
オプション設定なしだとこうですが
```mermaid
flowchart LR
    A["A"]
    B["B"]
    A-->B
```
```mermaid
%%{
  init: {
    "theme": "dark",
    "fontFamily": "monospace",
    "logLevel": "info",
    "flowchart": {
      "htmlLabels": true,
      "curve": "linear"
    },
    "sequence": {
      "mirrorActors": true
    }
  }
}%%
flowchart LR
    A["A"]
    B["B"]
    A-->B
```
オプション設定を入れると、ダークモードになりました。フォントも等幅フォントになってますね。
Qiitaで使っているmermaidは(2023年06月10日現在)Version8.14.0のようですので、最新版(10.2.3)とはオプションが違う所もあるかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352775/3b958566-a55a-57ae-969c-44643ff18910.png)

### Directiveの使いどころ
「別に色が変わってもうれしくない」というお話はあるでしょう。でも、特に複雑なグラフ(点と点を線でつないだやつね)を定義すると、しばしば線が暴れる(というかなんでこんなに線がとっ散らかってんだ?)となることがあります。
そういう時にはレンダラーを[dagre](https://github.com/dagrejs/dagre-d3)ベースのものから[elk](https://www.eclipse.org/elk/)ベースのもの([elkjs](https://github.com/kieler/elkjs))に変更してやると解決することがあります(ただしVersion9.4以上)。

標準の設定だと、
```text:レンダラーがdagre
%%{
    init:
    "flowchart": {
        "defaultRenderer": "dagre",
        "curve": "basis"
    }
}%%
```
これをelkjsに変更すると
```text:レンダラーをelkjsに設定
%%{
    init:
    "flowchart": {
        "defaultRenderer": "elk",
        "curve": "basis"
    }
}%%
```
あとは"curve"を[d3.jsのcurveオプション](https://github.com/d3/d3-shape/blob/main/README.md#curves)から設定してやればそれなりにいい具合になることがあります[^1]。
curvesのオプションは
* basis
* bumpX
* bumpY
* cardinal
* catmullRom
* linear
* monotoneX
* monotoneY
* natural
* step
* stepAfter
* StepBefore

が指定できるということです。
その他カスタムカーブの設定は[d3-shapeプロジェクト](https://github.com/d3/d3-shape/)の[shapesのページ](https://github.com/d3/d3-shape/blob/main/README.md#curves)からどうぞ。

[^1]:内部的に使っているのはd3.jsなんですって。やっぱすげぇなあのプロジェクト。


## mermaid.jsを使える環境
Qiita以外でもmermaidは使えます。Visual Studio Codeの拡張機能なんかを入れると手元のmarkdownでお絵描きができてとても良いです(PlantUMLとどっちがいいかはわかんない)。
ここではmermaid.js公式で「ここで使えるよ」というサイトやサービスを一覧で紹介……しようかと思ったけれども数が多くて挫折した……
なお[公式のページはこちら](https://mermaid.js.org/ecosystem/integrations.html)。

Qiitaのユーザーだと[Editor Plugins](https://mermaid.js.org/ecosystem/integrations.html#editor-plugins)あたりをみるとありがたいのではと思います。あとは[sphynx拡張](https://github.com/mgaitan/sphinxcontrib-mermaid)とかもあるんですね。

### Visual Studio Code拡張
とりあえず

https://github.com/mgaitan/sphinxcontrib-mermaid

https://marketplace.visualstudio.com/items?itemName=bpruitt-goddard.mermaid-markdown-syntax-highlighting

入れれば幸せになれると思います。
あとは
```mermaid
%%{
    init:
    "flowchart":{
        "curve": "stepAfter"
    }
}%%
flowchart LR
    item1[hoge]
    item2[fuga]
    item3[piyo]
    item4[foo]
    item5[bar]

    item1 & item2 & item3 ---> item4 & item5
```
みたいな図がもっとバシッとかけるようになってくれればいいなぁ(願望)。