Markdownでフローチャート、シーケンス図を描く(VSCode+Markdown Preview Enhanced)

# はじめに
VSCodeと、その拡張機能であるMarkdown Preview Enhancedを使って、フローチャートおよびシーケンス図を描く方法について取り上げます。

Visual Studio Code
https://code.visualstudio.com/
Markdown Preview Enhanced
https://shd101wyy.github.io/markdown-preview-enhanced/#/

テキストベースで作図できることのメリットは、ソースコードと一緒にgitなどで構成管理や差分表示ができる点にあります。
仕様書が実装と乖離していくことはよくあることですが、それに抗うための手段として、Markdownでの仕様書作成をお勧めしたいです。

# フローチャート(flowchart.js)
    ```flow
    開始=>start: はじめ
    終了=>end: おわり
    
    分岐(align-next=no)=>condition: おなかすいた？
    処理1=>operation: おやつを手に取る
    定義済み処理=>subroutine: おいしく食べる
    
    分岐2=>condition: 満足した？
    処理2=>operation: それは残念
    
    開始->分岐
    分岐(yes)->処理1
    分岐(no)->処理2(top)->分岐
    
    処理1->定義済み処理(right)->分岐2
    分岐2(yes)->終了
    分岐2(no, bottom)->処理1
    ```
![フローチャート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497894/4753cde9-4395-83fe-c839-b28dd361b6bd.png)


## 基本のこと
`[名前]=>[種別]: [テキスト]`でパーツを宣言して、`[名前]->[名前]`で結びます。
結ぶパーツはあらかじめ宣言しておく必要があります。
3つ以上のパーツを連続して結ぶ書き方もOKです。

## 矢印の始点を指定する
`[名前](方向)->[名前]`で矢印の始点の位置を指定することができます。
矢印の方向は`top`、`bottom`、`right`で指定します。
上記では`処理2(top)->分岐`で「それは残念」の矢印の始点をパーツの上に、`定義済み処理(right)->分岐2`で「おいしく食べる」の矢印の始点をパーツの右に変更しています。
また、分岐は通常yesが下、noが右になりますが、`分岐2(no, bottom)->処理1`のように変更することもできます。
ただし、yes/noの分岐がバラバラだと、見づらくなることもありますので、濫用は避けるのがいいと思います。

## align-next=no について
`分岐(align-next=no)=>condition: おなかすいた？`としていますが、`align-next=no`を外すと、右に続くパーツ(上記では「それは残念」)の横方向の位置が変わります。(外すと右側に移動しています。)
![フローチャート2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497894/d4ddaff1-a8a9-d712-69cb-961549681a38.png)
通常は、縦方向に複数のラインが重ならないよう、自動的に調整が入っています。
ただ、メインラインから分岐してすぐに戻る、のような処理が多くある場合、右へ右へと延びてしまって見栄えが悪い、という場合に`align-next=no`を使うと収まりがよくなります。

## その他
矢印に色を付けたりもできます。やり方は公式サイトに紹介されています。
ただ、あんまり凝ったことをやろうとすると、メンテナンスが大変になってエクセル勢に押し切られる説が...。
https://flowchart.js.org/

実は後述のmermaidでもフローチャートを描くことができるのですが、オーソドックスなスタイルで出力してくれる点でflowchart.jsの方が見やすいだろうと個人的には考えています。

# シーケンス図(mermaid)
    ```mermaid
    sequenceDiagram
    participant 1 as ねこ
    participant 2 as 飼い主
    participant 3 as お店
    
    Note over 1, 2: ごはんの時間
    
    1->>+2: ごはんちょうだい
    2->>2: ごはん確認
    alt ごはんがある
      2->>1: 今あげるよ
    else ごはんがない
      2->>1: ちょっと待ってね
      2->>+3: ごはんを注文
      3-->>-2: ごはんが届く
    end
    
    Note left of 1: ねこは我慢ができない
    
    loop ごはんが来るまで
      1->>2: ねこパンチ
    end
    
    2-->>-1: ごはんをあげる
    ```
![シーケンス図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497894/f19df45b-f687-0e09-98da-060157699fb1.png)

## 基本のこと
mermaidでは複数の種類の図を作成できるため、初めに'sequenceDiagram'を指定してシーケンス図を作成することを明示します。
必須ではありませんが、`participant [別名] as [表示名]`とすることで、図に表示するオブジェクトの名前が長い場合、別名をつけて以降の記述を簡略化できます。
矢印の引き方は以下の通りです。(`->`が矢印なしなのがちょっとトリッキーですが。)

|書き方||
|:--|:--|
|->|矢印**なし**の実線|
|-->|矢印**なし**の点線|
|->>|矢印付きの実線(同期メッセージ)|
|->>|矢印付きの点線(応答メッセージ)|

また、矢印に`+`を追加すると実行状態の開始、`-`を追加すると実行状態の終了となります。
上記では`1->>+2: ごはんちょうだい`で「飼い主」オブジェクトの実行状態開始、`2-->>-1: ごはんをあげる`で実行状態終了です。

## ループや分岐
ループは`loop [名前]`と`end`で囲みます。
また、分岐は`alt [名前]`と`else [名前]`と`end`からなります。

## コメントを付ける
コメントを付けたい場合は`Note`を使用します。
位置を指定することができて、オブジェクトの右または左の場合は`Note right of [オブジェクト名]: [コメント]`、複数のオブジェクトにまたがって表示する場合には`Note over [オブジェクト名], [オブジェクト名]: [コメント]`となります。

## その他
公式サイトに詳しいサンプルがあります。他の図も描けるので見ると発見があるかも。
https://mermaid-js.github.io/mermaid/#/sequenceDiagram

# おわりに
Excelなどでやった方が、自由に整形できて見栄えが良くなる、という考えもあると思います。
ですが、自由度が少ないということは、やるべきことが絞られるということでもあるので、そのメリットについては一考の価値はあるかと。

Markdown Preview Enhancedはとても多機能で、PlantUMLが使えたり、PDFで出力できたりといろいろなことができるようです。
僕もまだ使いこなせてはいないので、これ便利だよ、なことがあったら教えていただけると幸いです。

それと、実はここに書いたことはTyporaなら標準でできてしまいます。
https://typora.io/
見た目も使い勝手も良いのですが、Typoraは「ベータ版は無料使用OK」なので、いつか有料化する可能性があります。
そうなると、仕事で使うのはちょっと難しくなるかもしれません。
それに、仕事では自由にアプリケーションをインストールできるというところばかりではないでしょうから、VSCodeでソースコードもMarkdownも両方使えるようにしておくのがベターなのかなと思っています。