🧜‍♀️

【地上の】mermaid でちょっと大きめの図を描く【星】

2023/03/10に公開

はじめに

細かいところに PlantUML ほど融通が利かないと言われる mermaid.js ですが、逆に言えばそこまで複雑なフローでなければそこそこ描けるやんけ!ということで mermaid.js で中規模以上のフロー図を描くときに使えそうな記法などについて書いてきます。

題材

良い感じの題材が思いつかなかったので、今回は地上の星の歌詞のフロー図を mermaid.js で描いていきます。
参考↓
https://twitter.com/Tatawidepine/status/648419121965633536

準備

まずは mermaid.js でフロー図を描く際の基本です。

記載規模やお好みでどうぞ

  1. VSCode
    みんな大好き VSCode。拡張機能を入れることで、描きながらプレビューできたり画像出力ができます。Markdown を普段から VSCode で描いている方は下記の1を。そうでない方は2を使うと良いかと思います。
    1 https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced
    2 https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid
  2. Mermaid Live Editor
    https://mermaid.live/
    ブラウザで動作する公式のエディターです。
    GUI でテーマ選択できたり画像出力もできるので何かと便利です。

基本の書き方

よく紹介されている Mermaid の記載方法です。
だいたいどの記事もこのぐらいしか描かれてないから少し大きめのフロー図を分かりやすく描きたい時に困る

図のタイプを宣言

flowchart TD

mermaid の図のタイプでフローチャートを指定します。ここの宣言によって図のタイプが変わり、記法も変わるので ER 図など他のタイプの図を描きたい場合などは注意しましょう。
また、TD か TB を指定すれば上から下に(Top->Down/Top-Bottom)、LR を指定すれば左から右に(Left->Right)フロー図が描かれます。

要素(ノード)

S(Start)

要素のエイリアスと名前を書きます。括弧内の文字が表示される内容で、先頭の文字がエイリアスになるのでなるべく先頭の方を短めにかくと良いでしょう。また、括弧の種類でノードの形は変わります。

矢印

A --> B

今の時点で特に言うことはないです。

フロー図を描く

とりあえず位置などをあまり気にしなければとりあえず要素と矢印でフロー図が描けます。
いったん地上の星のフローを描くと以下のようになります。

flowchart TD
    S(Start)
    kaze(風の中のすばる)
    ginga(砂の中の銀河)
    where(みんなどこへ行った)
    mio(見送られる)
    mim(見守られる)
    naku(こともなく)
    pegasus(草原のペガサス)
    vinus(街角のヴィーナス)
    sirius(水底のシリウス)
    jupiter(崖の上のジュピター)
    tijou(地上にある星)
    nadataru(名だたる)
    wo(を)
    mono(もの)
    kagayaku(輝く)
    forget(誰も覚えていない)
    otte(追って)
    hito(人は)
    sky(空)
    ice(氷)
    bakari(ばかり)
    miteru(見てる)
    tukamu(掴む)
    swallow(つばめよ)
    sorakara(高い空から教えてよ)
    hosi(地上の星)
    ha(は)
    wo2(を)
    nowhere(今どこにあるのだろう)
    E(End)

    S --> kaze
    kaze --> ginga
    ginga --> where
    where --> mim
    where --> mio
    where --> mio
    mim --> naku
    mio --> naku
    mio --> naku
    naku --> pegasus
    pegasus --> vinus
    vinus --> where
    naku --> tijou
    naku --> nadataru
    tijou --> wo
    nadataru --> mono
    mono --> wo
    wo --> forget
    wo --> otte
    otte --> kagayaku
    kagayaku --> mono
    forget --> hito
    otte --> hito
    hito --> sky
    hito --> ice
    sky --> bakari
    ice --> bakari
    bakari --> miteru
    bakari --> tukamu
    tukamu --> kaze
    miteru --> swallow
    tukamu --> swallow

    swallow --> sorakara
    sorakara --> hosi
    hosi --> wo2
    wo2 --> swallow
    hosi --> ha
    ha --> nowhere

    nowhere --> E
    nowhere --> jupiter
    nowhere --> nadataru
    jupiter --> sirius
    sirius --> where
    naku --> swallow


思っていたよりだいぶ長いコードになってしまいました。フロー図としては流れと相対位置が合っていればいいですが、少しずつ加工していきましょう。

加工していく

少しずつ見やすくなるよう努力していきます。
※あくまで図の話です。コードの見やすさは諦めましょう。

ノードと矢印を加工する

図やチーム内ルールによってお作法はあるかと思いますが、まずは参考資料のように点線を使って一番と二番のフローがある程度分かれて見えるようにしましょう。
点線にする方法は --> を -.-> に変えるだけです。簡単ですね!。

kagayaku -.-> mono

次はノードの加工です。宣言時の括弧の形に応じて形が変わるのでよしなに変えましょう。

  • 角が丸い四角
(Start)

((Start))

  • 四角
[Start]

  • 両サイド余白付き四角
[[Start]]

特定の範囲を色付きで囲む(subgraph)

subgraph を使って特定の範囲を囲って分かりやすくしましょう。
end の記載をお忘れなく。

subgraph Start
swallow --> sorakara
sorakara --> hosi
hosi --> wo2
wo2 --> swallow
hosi -.-> ha
ha --> nowhere
end


(なぜかやたら縦長になってしまったので図は一部のみ

途中経過

ここまでで、以下のようなフロー図ができあがりました。

さらに加工していきましょう。

ノードや矢印・文字の色を変える

参考: https://zenn.dev/junkawa/articles/zenn-mermaidjs-theme-config#classdef-を使う

あまり使っている人を見たことがないですが、 mermaid で描画される図には
SVG で使用できる属性が指定可能です。

では、classDef / lnkStyle を使って色指定してみます。

classDef yellow fill:yellow,color:red
class S,E yellow

Start, End の塗りつぶし色と文字色を変更しました。
構文は若干分かりづらいですが

  • 定義部分: classDef {変数名} {属性と色指定}
  • 適用部分: class {ノード(カンマ区切り)} {変数名}}
    といった感じになります。カンマや半角スペースを間違えるだけでも構文エラーになるので注意してください。

同様に、矢印も linkStyle で色指定していきます。
参考資料のように特殊な遷移っぽいところは赤矢印にします。

linkStyle 29 stroke:red,stroke-width:5px

ここがちょっと厄介なのですが、先ほどのノードでは変数名(id) が使えるのですが link に関しては固有の id が振れないらしく、コード上で何番目に書かれているか を指定することになります。それが linkStyle 直後の番号です(0始まり)。

位置を揃える

基本的に結合が多いものを近くに配置されたりと、自動で描かれます。しかしどうしても思った通りの位置に描画されない時は見えないノードやラインを使って位置調整ができます。
参考:https://ja.stackoverflow.com/questions/66091/mermaidのフローチャートrlでsubgraphの配置を上下から左右に変えたい

    1 --- S
    ... 省略
    E --- 0
classDef white fill:white,color:white,stroke:white
class 1,0 white %% 描画されないようにする
linkStyle 45 stroke-width:0px %% 見えないリンク(1-S)
linkStyle 0 stroke-width:0px,stroke:white %% 見えないリンク(E-0)

こういう感じの↑修正で先ほどまでStartやEnd の位置が微妙だったのをやや調整できます。

あとがき

若干無理やり感はありますが mermaid も意外とやれるなぁと思いました。
ただリンクの採番だけは保守性が最悪なのでなんとかしてほしいです。

Discussion