markdownでシーケンス図を書こう

## ちょっとしたシーケンス図をさくっと書きたい

皆さんは設計でシーケンス図を書くときにどのようにしていますか？
astahなどのUMLツールを使って書くのが一般的だと思います。私もそうです。

確かに込み入ったシーケンスを書く場合にはそれがいいのでしょうが、例えば**Wikiの中にちょっとしたシーケンスを書きたい**ときはどうでしょうか？

1. astahでシーケンス図を書く
2. 画像に出力する
3. Wikiに貼る

という工程を踏むのはかなり面倒ですよね？
しかも、しばらく経ってからシーケンスを更新する必要が生じたとき、**「元のastahはどこだ…？」**となるのは火を見るより明らかです。

もっと便利な方法があります。

**markdownでシーケンス図を書くのです。**


## mermaidを使ったシーケンス図の書き方

markdownでシーケンス図を書くときには**mermaid**とういライブラリを使います。

例えば、GitLabでは初めからこのmermaidが組み込まれているようで、特にインストールなどは必要ありません。
Qiitaもmarkdownですが、mermaidはサポートしていないようです。
VSCodeでは拡張機能である「Markdown Preview Enhanced」をインストールすれば使えるようになります。

mermaidを使う場合、以下のようにコードブロックの言語に`mermaid`を指定します。
そして、シーケンス図を書く場合には、次の行に`sequenceDiagram`と宣言して、中身を書き始めます。

    ```mermaid
    sequenceDiagram
        ここにシーケンスを書く

    ```

### 基本の書き方

    ```mermaid
    sequenceDiagram
        コック ->> フライパン: ハンバーグを焼く
        フライパン -->> コック : 焼き上がり

    ```
![mermaid_seq_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/abf949fa-5477-1809-8b62-33cd725b3e73.png)

ただし、この書き方だとライフラインの名前「コック」を「シェフ」に変えたいと思った場合、2箇所直さないといけません。
シーケンス図が複雑になっていくと数十箇所も直す羽目になるかもしれません…。

そこで、ライフラインはエイリアス(別名)をつけておいた方がいいです。

    participant cook as コック

という書き方でcookというライフラインに「コック」という別名(ラベル)を与えることができます。
これで「コック」を「シェフ」や「板前」に変えたいと思ったら、この行を修正するだけで済みます。

ライフラインにはなるべく抽象的な名前をつけておきましょう。

    ```mermaid
    sequenceDiagram
    participant cook as コック
    participant kitchenware1 as フライパン
        cook ->> kitchenware1: ハンバーグを焼く
        kitchenware1 -->> cook : 焼き上がり

    ```

### 実行仕様

ライフライン上に実行仕様をつけたい場合は、開始と終了の矢印の後に+と-をつけます。

    ```mermaid
    sequenceDiagram
    participant cook as コック
    participant kitchenware1 as フライパン
        cook ->>+ kitchenware1: ハンバーグを焼く
        kitchenware1 -->>- cook : 焼き上がり

    ```

![mermaid_seq_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/72ac0736-0231-71cc-3491-061313fa7ed9.png)


実行仕様は入れ子にすることもできます。

    ```mermaid
    sequenceDiagram
    participant cook as コック
    participant kitchenware1 as フライパン
        cook ->>+ kitchenware1: ハンバーグを焼く
        cook ->>+ kitchenware1: 蓋をする
        kitchenware1 -->>- cook: ふっくら
        kitchenware1 -->>- cook : 焼き上がり

    ```

![mermaid_seq_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/30b123c6-e998-4ac1-6a61-01ff81f02223.png)


### ノート

シーケンス図にノート(メモ)をつけることもできます。

ノートをつける位置によって、少し指定の仕方が変わります。

|ノートの位置|コード|
|---|---|
|ライフラインの上|`Note over ライフライン: ノートの内容`|
|ライフラインの右|`Note right of ライフライン: ノートの内容`|
|ライフラインの左|`Note left of ライフライン: ノートの内容`|

    ```mermaid
    sequenceDiagram
        participant cook as コック
        participant kitchenware1 as フライパン

        cook ->>+ kitchenware1: ハンバーグを焼く
        Note over kitchenware1: 8分ほど待つ
        kitchenware1 -->>- cook: 焼き上がり
        Note right of kitchenware1: 竹串を刺して透明な汁が出たら完成
    ```

![mermaid_seq_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/d3f51a2f-da1e-48cd-1553-95dfe31977c5.png)


ライフラインを,(コンマ)でつなげて指定すれば、複数のライフライン上にまたがったノートを書くこともできます。

    ```mermaid
    sequenceDiagram
        participant cook as コック
        participant kitchenware1 as フライパン

        cook ->>+ kitchenware1: ハンバーグを焼く
        Note over cook, kitchenware1: 8分ほど待つ
        kitchenware1 -->>- cook: 焼き上がり

    ```

![mermaid_seq_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/902dc081-7d6b-58a5-7e38-b748742701ee.png)


### 複合フラグメント

シーケンスにはループや条件分岐がつきものです。
もちろんmermaidでも表現することができます。

#### 条件分岐(alt)

下記のようにalt～else～endを使って書きます。

```
alt 条件1
    処理1
else 条件2
    処理2
end
```

    ```mermaid
    sequenceDiagram
        participant cook as シェフ
        participant kitchenware1 as 鍋

        alt ビーフカレー
            cook ->> kitchenware1:牛肉を入れる
        else チキンカレー
            cook ->> kitchenware1:鶏肉を入れる
        end

    ```

![mermaid_seq_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/d78bf92e-75ce-5bd2-70b2-6a87e5c1eb18.png)


#### 条件指定(opt)

下記のようにopt～endを使って書きます。

```
opt 条件
    処理
end
```


    ```mermaid
    sequenceDiagram
        participant cook as シェフ
        participant kitchenware1 as 鍋

        opt 辛いもの好き
            cook ->> kitchenware1: チリペッパーを入れる
        end

    ```

![mermaid_seq_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/4f92bf5f-aa19-7961-530d-1fd35dec969b.png)


#### ループ(loop)

下記のようにloop～endを使って書きます。

```
loop 条件
    処理
end
```

    ```mermaid
    sequenceDiagram
        participant cook as シェフ
        participant kitchenware1 as 鍋

        cook ->> kitchenware1: カレーを煮込む
        loop ときどき
            cook ->> kitchenware1: 混ぜる
        end

    ```

![mermaid_seq_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/03dc32b0-22e7-fd74-4e0d-e6119367a2fe.png)

### 背景色

背景色をつけることもできます。

    rect rgba(r, g, b, a)
        ....
    end

背景色をつけたい部分をrect rgba()～endでくくります。
rgba()で「赤(red)」「緑(green)」「青(blue)」「透過度(alpha)」をそれぞれ指定します。

    ```mermaid
    sequenceDiagram
        participant cook as コック
        participant kitchenware1 as 鍋

        cook ->> kitchenware1: ひき肉を炒める

        rect rgba(255, 0, 255, 0.2)
        opt 辛いもの好き
            cook ->> kitchenware1: 豆板醤を入れる
        end
        end

    ```
![mermaid_seq_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/47096ac5-340f-580c-8cba-a2561388d86e.png)


### コメント

mermaidブロックの中にコメント文を書きたいときは`%% これはコメントです`のようにします。

    ```mermaid
    sequenceDiagram
        コック ->> フライパン: ハンバーグを焼く
        フライパン -->> コック : 焼き上がり
        %% これはコメントなので表示されません

    ```
![mermaid_seq_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/cf5fdd36-ae27-8f82-d903-db5d56f99b7e.png)

## 最後に

いかがでしたか？
markdownでシーケンス図を直接書く方法を知っておくと、より表現の幅が広がり便利になりますね。

本記事ではmermaidの基本部分を紹介しました。もっと詳しい情報を知りたい場合は下記の公式ページを参照してみてください。

[mermaid公式ページ](https://mermaid-js.github.io/mermaid/#/)