作図はテキストで！Mermaid, PlantUML and Graphviz

# 本記事のめあて
作図となるとExcelやPowerPoint、あるいは作図ツールを使うことが多いと思う。でも必要以上に凝りすぎて時間を無駄にしてませんか。
グラフ記法というものがあり、QiitaやVS Codeなどではマウスを使ってではなく、コーディング的に図が描けます。何がいいかと言うと、
- VS Codeなどのエディタで全て完結する
- 作図ツールよりは表現力は落ちますが相手に伝える必要以上に時間を使って無駄に凝る危険性が低い
    - 客先に提示ならば見た目重視ですけれど社内共有用ならば早く簡単に内容が共有された方がいいですよね
- ChatGPTなど生成AIとの親和性が高い
    - 自分の描いた図が妥当かどうか確認するとか
        - これなら図自体でも生成AIに投入できるようになってきてますが
    - こういう内容の図が欲しいと描かせるとか
        - 改善案を示して、まで考えるとこういう記法を使った方が効率的です

https://qiita.com/aokikenichi/items/8d2e3fc50a18114b38b3

- サイズ、テーマ、ノードとエッジについて追加の説明を書きました

# 背景
- いやね、こういうのがあると昔から知っていたのですが、いざ調べてみると表現力豊かだし、ChatGPTに尋ねて未知の分野をMindmap描かせて頭の整理するとか超絶便利だったのでご紹介
- QiitaでもMermaidとPlantUMLはそのまま使えるしね

# 概要
||[Mermaid](https://mermaid.js.org/)|[PlantUML](https://plantuml.com/ja/)|[Graphviz](https://graphviz.org/)|
|:--|:-:|:-:|:-:|
|特徴|汎用性が高く、初心者にも比較的わかりやすい|IT開発支援|グラフ構造のカスタマイズ性が高い|
|グラフ構造（ノードとエッジ）|O|-|◎|
|IT開発支援系_UML|O|◎|-|
|IT開発支援系_インフラ・DB系|O|◎|-|
|発想系_MindMap他|◎|O|O|
|データのグラフ（折れ線、棒、パイ）|O|-|-|
|エディタ対応|Qiita, VS Code|Qiita, VS Code|VS Code|

- 補助機能

||Mermaid|PlantUML|Graphviz|
|:--|:-:|:-:|:-:|
|数式|KaTeX|AsciiMath, JLaTeXMath|-|
|Theme（見た目）|5種類|多数|-|
|Layoutエンジン|-|-|複数|

- Mermaid
    - グラフ構造系
        - ノードとエッジとコメントなど
    - IT開発支援系
        - 一部のUMLやフローチャートなどの開発設計図系
        - C4ダイアグラムなどのインフラ表現系
    - データのグラフ系
        - 折れ線グラフ、棒グラフ、パイチャート
- PlantUML
    - IT開発支援系
        - UMLをほぼ網羅
        - ネットワーク構造やUIモックなど
- Graphviz
    - グラフ構造系
        - ノードとエッジとコメントなど
        - 表現が豊かなので工夫すればマインドマップやクラス図も可

# 作図機能
- グラフ構造以外の作図機能について（なのでGraphvizは略）

||Mermaid|PlantUML|備考|
|:--|:-:|:-:|:-:|
|特徴|多様な図|UMLが充実|-|
||
|UML_シーケンス図|O|O||
|ZenUML|O|-|シーケンス図の別表現|
|UML_クラス図|O|O||
|UML_状態図|O|O||
|UML_ユースケース図|-|O||
|UML_オブジェクト図|-|O||
|UML_コンポーネント図|-|O||
|UML_配置図|-|O||
|UML_タイミング図|-|O||
|UML_アクティビティ図|-|O||
|UML_アクティビティ図(SDL)|-|O|アクティビティ図の別表現|
||
|フローチャート|O|-||
|EBNF 図|-|O||
|正規表現ダイアグラム|-|O||
||
|ER図|O|O||
|ER図(Chen's notation)|-|O|ER図の別表現|
|JSON データ|-|O||
|YAML データ|-|O||
||
|ガントチャート|O|O||
|WBS図|-|O||
|Gitgraph (Git) Diagram|O|-||
||
|アルキメイト図|-|O||
||
|ネットワーク図（nwdiag）|-|O||
||
|UIモックアップ（ソルト）|-|O||
||
|マインドマップ|O|O||
||
|XY Chart|O|-||
|Pie Chart|O|-||
|Quadrant Chart|O|-||
|Sankey|O|-||
||
|User Journey|O|-||
|Requirement Diagram|O|-||
|C4 Diagram|O|?|PlantUMLコンパチブルとあるがPlantUMLのサイトに見たたらず|
|Timeline|O|-||
|Block Diagram|O|-||
|Packet|O|-||
|Architecture|O|-||
||
|DITAA|-|O||



# 補助機能

## 数式

- mermaid

```
graph
    S((S)) --> A
    A["$$F(x)=\int_a^x{f(t)dt}$$"] --> B["$$\frac{d}{dx}F(x)=f(x)$$"]
    B --> A
```

```mermaid
graph
    S((S)) --> A
    A["$$F(x)=\int_a^x{f(t)dt}$$"] --> B["$$\frac{d}{dx}F(x)=f(x)$$"]
    B --> A
```

- PlantUML

```
@startuml
(*) --> "<latex>F(x)=\int_a^xf(t)dt</latex>"
"<latex>F(x)=\int_a^xf(t)dt</latex>" --> "<latex>\frac{d}{dx}F(x)=f(x)</latex>"
"<latex>\frac{d}{dx}F(x)=f(x)</latex>" --> "<latex>F(x)=\int_a^xf(t)dt</latex>"
@enduml
```

```plantuml
@startuml
(*) --> "<latex>F(x)=\int_a^xf(t)dt</latex>"
"<latex>F(x)=\int_a^xf(t)dt</latex>" --> "<latex>\frac{d}{dx}F(x)=f(x)</latex>"
"<latex>\frac{d}{dx}F(x)=f(x)</latex>" --> "<latex>F(x)=\int_a^xf(t)dt</latex>"
@enduml
```

## Theme
- CSSで複雑な指定もできるがデフォルト機能で用意されているテーマは下記
- GraphvizにはThemeに相当するものはない

### Mermaid

```
%%{init: {'theme':'default'}}%%
  graph
    a --> b
```

```mermaid
---
title: default
---
%%{init: {'theme':'default'}}%%
  graph
    a --> b
```

- 以下同様に {'theme':'xxxxx'}} を書き換える

```mermaid
---
title: neutral
---
%%{init: {'theme':'neutral'}}%%
  graph
    a --> b
```

```mermaid
---
title: dark
---
%%{init: {'theme':'dark'}}%%
  graph
    a --> b
```

```mermaid
---
title: forest
---
%%{init: {'theme':'forest'}}%%
  graph
    a --> b
```

```mermaid
---
title: base
---
%%{init: {'theme':'base'}}%%
  graph
    a --> b
```
### PlantUML

```
@startuml
!theme amiga
title amiga
:a;
:b;
@enduml
```
- 以下同様に !theme xxxx; title xxxx を書き換える
```plantuml
@startuml
!theme amiga
title amiga
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme aws-orange
title aws-orange
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme black-knight
title black-knight
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme bluegray
title bluegray
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme blueprint
title blueprint
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme carbon-gray
title carbon-gray
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme cerulean
title cerulean
:a;
:b;
@enduml
```


```plantuml
@startuml
!theme cerulean-outline
title cerulean-outline
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme cloudscape-design
title cloudscape-design
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme crt-amber
title crt-amber
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme crt-green
title crt-green
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme cyborg
title cyborg
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme cyborg-outline
title cyborg-outline
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme hacker
title hacker
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme lightgray
title lightgray
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme mars
title mars
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme materia
title materia
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme materia-outline
title materia-outline
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme metal
title metal
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme mimeograph
title mimeograph
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme minty
title minty
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme mono
title mono
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme plain
title plain
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme reddress-darkblue
title reddress-darkblue
:a;
:b;
@enduml
```

- 同様に下記があるが略
    - reddress-darkgreen
    - reddress-darkorange
    - reddress-darkred
    - reddress-lightblue
    - reddress-lightgreen
    - reddress-lightorange
    - reddress-lightred


```plantuml
@startuml
!theme sandstone
title sandstone
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme silver
title silver
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme sketchy
title sketchy
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme sketchy-outline
title sketchy-outline
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme spacelab
title spacelab
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme spacelab-white
title spacelab-white
:a;
:b;
@enduml
```

- sunlust はQiitaのPlantUMLバージョンでは対応してないみたいでエラー

```plantuml
@startuml
!theme superhero
title superhero
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme superhero-outline
title superhero-outline
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme toy
title toy
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme united
title united
:a;
:b;
@enduml
```

```plantuml
@startuml
!theme vibrant
title vibrant
:a;
:b;
@enduml
```

## Layoutエンジン
- Mermaid, PlantUMLはデフォルトのみ
- GraphvizにはLayoutエンジン指定あり

### Graphviz

- dot(default)
```graphviz
digraph {
    layout="dot"
    subgraph cluster_0 {
        a -> b
        a -> c
        a -> d
    }
    subgraph cluster_1 {
        e -> f
        f -> g
        g -> h
    }
    subgraph cluster_2 {
        i -> j
        j -> l
        l -> m
        m -> i
    }
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116049/0bf33de2-19dc-8c28-c21a-0453fde72c11.png" width=400 />

- fdp
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116049/27c2f334-0947-20ef-63a8-245f8387c893.png" width=400 />

- neato
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116049/9ab8edb7-d294-8e2a-c9c1-490f7da5b04e.png" width=400 />

- circo
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116049/9aa96b3d-10d3-5ea2-6022-c9c103c90412.png" width=400 />




- twopi

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116049/32003172-0b1f-cd1b-3735-3656d94f8383.png" width=250 />

- osage
    - これはグラフではなく、ベン図のような表現
```graphviz
graph {
    layout="osage"

    subgraph cluster_0 {
        label="cls-0"
        a
        b
    }
    
    subgraph cluster_1 {
        label="cls-1"
        subgraph cluster_11 {
            label="cls-1_1"
            c
            d
        }
        subgraph cluster_12 {
            label="cls-1_2"
            e
        }
        f
    }    
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116049/7e58718f-9486-faec-bc80-63bc5afb67f3.png" width=400 />

- patchwork
    - これは量を面積で表したタイル図。

```graphviz
graph {
    layout="patchwork"
        a[area=8]
        b[area=4]
        c[area=2]
        d[area=1]
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116049/65453b92-231e-1713-0dbe-b51c2906936f.png" width=400 />


# その他の表示例
## Mermaid
- こんな棒グラフと折れ線グラフが描ける
- こう言うのを書くならPythonとかExcelの方がいいけれど10件程度のデータがあり、レポートの中でサクッとグラフ表示したい場合には楽だね

```
xychart-beta
    title "Sales Revenue"
    x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
    y-axis "Revenue (in $)" 4000 --> 11000
    bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
    line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
```

```mermaid
xychart-beta
    title "Sales Revenue"
    x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
    y-axis "Revenue (in $)" 4000 --> 11000
    bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
    line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
```

## PlantUML
- GUIのこんなモックアップ的なものが作れる

```
@startsalt
{+
{* File | Edit | Source | Refactor
 Refactor | New | Open File | - | Close | Close All }
{/ General | Fullscreen | Behavior | Saving }
{
{ Open image in: | ^Smart Mode^ }
[X] Smooth images when zoomed
[X] Confirm image deletion
[ ] Show hidden images
}
[Close]
}
@endsalt
```

```plantuml
@startsalt
{+
{* File | Edit | Source | Refactor
 Refactor | New | Open File | - | Close | Close All }
{/ General | Fullscreen | Behavior | Saving }
{
{ Open image in: | ^Smart Mode^ }
[X] Smooth images when zoomed
[X] Confirm image deletion
[ ] Show hidden images
}
[Close]
}
@endsalt
```



## Graphviz

- Graphvizは作図の材料が揃っていると言うよりも、ノードとエッジを描くだけ、それのカスタマイズが豊富ってものなので、とっつきにくいが逆に言うと何でも描ける。Galleryにたくさんの例がある。
    - これらを手で描くのは大変だけれどPythonから呼び出すとか、今なら生成AIもあるしね。

https://graphviz.org/gallery/

## Mindmap比較
- 3記法とも可能なMindmapで比較

### Mermaid
- こう書くのだがQiitaだとTABがうまく入力でいずMermaid/Mindmapは描けず。別のエディタで描いた図を転記。

```
mindmap
日本
    北海道
    東北
    関東
        栃木
        群馬
        茨城
        埼玉
        千葉
        東京
            世田谷
                砧
        神奈川
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116049/18b06c47-474c-2200-ff77-3a67451ef123.png" width=400 />

- ノードとエッジでも描ける
```
graph LR
日本 --- 北海道 & 東北 & 関東
関東 --- 栃木 & 群馬 & 茨城 & 埼玉 & 千葉 & 東京
東京 --- 世田谷 --- 砧
```

```mermaid
graph LR
日本 --- 北海道 & 東北 & 関東
関東 --- 栃木 & 群馬 & 茨城 & 埼玉 & 千葉 & 東京
東京 --- 世田谷 --- 砧
```
## PlantUML
- ノードの表現がデフォルトでも2パターン（矩形囲みと文字のみ）
```
@startmindmap
+ 日本
++ 北海道
++ 東北
++ 関東
+++_ 栃木
+++_ 群馬
+++_ 茨城
+++_ 埼玉
+++_ 千葉
+++_ 東京
++++_ 世田谷
+++++_ 砧
+++_ 神奈川
@endmindmap
```

```plantuml
@startmindmap
+ 日本
++ 北海道
++ 東北
++ 関東
+++_ 栃木
+++_ 群馬
+++_ 茨城
+++_ 埼玉
+++_ 千葉
+++_ 東京
++++_ 世田谷
+++++_ 砧
+++_ 神奈川
@endmindmap
```

- 両サイドでも描ける
```
@startmindmap
+ 日本
-- 北海道
-- 東北
++ 関東
+++_ 栃木
+++_ 群馬
+++_ 茨城
+++_ 埼玉
+++_ 千葉
+++_ 東京
++++_ 世田谷
+++++_ 砧
+++_ 神奈川
@endmindmap
```

```plantuml
@startmindmap
+ 日本
-- 北海道
-- 東北
++ 関東
+++_ 栃木
+++_ 群馬
+++_ 茨城
+++_ 埼玉
+++_ 千葉
+++_ 東京
++++_ 世田谷
+++++_ 砧
+++_ 神奈川
@endmindmap
```

### Graphviz

```graphviz
graph G {
    rankdir="LR"
    日本 -- 北海道
    日本 -- 東北
    日本 -- 関東
    関東 -- 栃木
    関東 -- 群馬
    関東 -- 茨城
    関東 -- 埼玉
    関東 -- 千葉
    関東 -- 東京
    関東 -- 神奈川
    東京 -- 世田谷
    世田谷 -- 砧
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116049/12af8817-b458-2949-03d5-a42da14ce725.png" width=400 />