マーメイド#21 レンダリングを意識して綺麗な図をかく

**ひとりマーメイド21日目**
**レンダリングを意識して綺麗な図をかく**

## 概要
マーメイドエンジニアのひろきです。こんにちは。
最近流行り（流行らせたい）のマーメイドについて理解を深めていこうと思います。

この記事ではレンダリングを意識して綺麗な図をかく方法を紹介します！

↓↓前回の記事はこちら

https://qiita.com/hirokiwa/items/aecc770eb3c8d4b434f5

## マーメイドあるある

例えば以下のような図を作りたいとします。みなさんならどのように記述しますか？
```mermaid
flowchart LR
    a --- b & d ---c
```

a --> b --> c --> d と時計回りにノードを並べ、これらを線で結び丸く繋ぎます。

真っ先に思いつくのがこのような記述ではないでしょうか。

```:mermaid
flowchart
    a --- b --- c --- d --- a
```
しかしこれをレンタリングすると以下のような図が出来上がります。
```mermaid
flowchart
    a --- b --- c --- d --- a
```
確かに間違ってはいないのですが、なんか変ですね。

なぜこうなってしまうのでしょうか。

## マーメイドの2つの原則
レンダリングを意識することで思い描いた図を記述することができるようになるかもしれません。ここで重要になるのが以下の2つの原則です。

**1. マーメイドのフローは直線的に伸びる**
　マーメイドのフローは指定の方向に直線的に伸びていきます。デフォルトは 上-->下 です。

**2. マーメイドの記述は上から順番にレンダリングされる**
　マーメイドのレンダリングは主要プログラミング言語と同様、上の行から順番に進んでいきます。

## レンダリングを追う
ここでもう一度先ほどの記述を見ます。

フローが伸びる方向は指定がないので、上-->下 です。

`a`-->`b`-->`c`-->`d` の順番で縦に描画が進み、最後に`d`から`a`へとエッジが伸びています。


```:mermaid
flowchart
    a --- b --- c --- d --- a
```
```mermaid
flowchart
    a --- b --- c --- d --- a
```
レンダリングを意識するとこのような出力になることは納得できます。

## 解決策
フローを綺麗に丸く繋ぎたい場合は以下のように記述します。
```:mermaid
flowchart LR
    a --- b & d --- c
```
```mermaid
flowchart LR
    a --- b & d ---c
```
---
こちらも同様にレンダリングを追ってみます。

フローが伸びる方向は`LR`と指定されているため 左-->右 です。

まず`a`が描画され、次に`b`と`c`が同一レベルに描画されます。そして最後に`c`が描画されています。

```:mermaid
flowchart LR
    a --- b & d --- c
```
```mermaid
flowchart LR
    a --- b & d --- c
```

レンダリング順に番号を振ると以下のようになります。記述された順番で指定方向(左-->右)に直線的に描画されていることが分かります。
```mermaid
flowchart LR
    a --- b & d --- c
    subgraph 1
        a
    end
    subgraph 2
        b
        d
    end
    subgraph 3
        c
    end
```
---
ノードを増やしてみます。

指定方向は 上-->下 です。
こちらも同時に定義したノードは同一レベルに描画されていることが分かります。

```:mermaid
flowchart
    a --- b & c --- d & e & f
```
```mermaid
flowchart
    a --- b & c --- d & e & f
```

レンダリング順は以下の通りです。フローが指定方向(上-->下)に直線的に伸びています。
```mermaid
flowchart
    a --- b & c --- d & e & f
subgraph 1
        a
    end
    subgraph 2
        b
        c
    end
    subgraph 3
        d
        e
        f
    end
```

## 応用
以下のような記述を追ってみます。
```:mermaid
flowchart
    a --- b & d --- c
    e --- d & f --- g
    h --- f & i --- j
    k --- i & l --- m
```
```mermaid
flowchart
    a --- b & d --- c
    e --- d & f --- g
    h --- f & i --- j
    k --- i & l --- m
```
---

こちらもレンダリング順に番号を振りました。
```:mermaid
flowchart
    a --- b & d --- c
    e --- d & f --- g
    h --- f & i --- j
    k --- i & l --- m
```

```mermaid
flowchart
    a --- b & d --- c
    e --- d & f --- g
    h --- f & i --- j
    k --- i & l --- m
        subgraph 1
        subgraph 1_1
            a
        end
        subgraph 1_2
            b
            d
        end
        subgraph 1_3
            c
        end
    end
    subgraph 2
        subgraph 2_1
            e
        end
        subgraph 2_2
            f
        end
        subgraph 2_3
            g
        end
    end
    subgraph 3
        subgraph 3_1
            h
        end
        subgraph 3_2
            i
        end
        subgraph 3_3
            j
        end
    end
    subgraph 4
        subgraph 4_1
            k
        end
        subgraph 4_2
            l
        end
        subgraph 4_3
            m
        end
    end
```

まず記述の各行が大枠1~4に当たります。それぞれの大枠の中では指定方向(上-->下)に直線的に描画が進んでいます。

次に1~4の大枠が 左-->右 方向につながっていることが分かります。これは大枠同士が共有しているノード( `d`, `f`, `i` )が隣同士の位置関係を決定しているためです。

例えば、`e --- d & f --- g`の行(大枠2)をレンダリングする際、`d`は既に大枠1の中で位置が決定しているため、これを基準に大枠1,2の位置関係が決まります。

## まとめ
記述したコードが意図しない形でレンダリングされることはよくあります。ぜひレンダリングを意識した記述で、思い通りのダイアグラムを作ってみてください。

↓↓次回の記事はこちら！！

https://qiita.com/hirokiwa/items/7136e5c86fb85814a2a6

## 参考

https://mermaid.js.org