(23日目) blockdiag の便利な使い方(サンプル集)

いま現在、blockdiag.com には使い方の例は書いてありますが、
どんな図が書けるのかというサンプルがほとんどありません。
これは単に僕の努力不足なのですが、たまには書きこまれた図をお見せしてみたいと思います。

画面遷移図

最初にご紹介するのは画面遷移図です。
もともと blockdiag を作り始めるきっかけは画面遷移図を書くことだったので、
blockdiag と画面遷移図は非常に相性がいいです。
どの画面からどの画面に遷移するのかを矢印(->)で書くだけで図が出来上がります。

ちょっとしたマスタ管理であれば、遷移だけを書いていけば図が出来上がります。
もちろん、途中で画面を追加したくなっても、画面が廃止になっても定義を書き換えるだけです。

blockdiag {
   トップページ -> メニューA, メニューB, メニューC;

   メニューA -> ○○一覧 -> ○○追加, ○○編集, "○○削除(確認)";
      ○○追加 -> "○○追加(確認)" -> ○○一覧;
      ○○編集 -> "○○編集(確認)" -> ○○一覧;
      "○○削除(確認)" -> ○○一覧;

   メニューB -> △△一覧 -> △△設定;
   メニューC -> □□一覧 -> □□設定;
}

Web でありがちなフローも同じように書くことができます。
例えば会員登録は次のように書きます。

blockdiag {
   各画面 [stacked];
   DB [shape = flowchart.database];
   メール [shape = mail];

   各画面 -> メールアドレス入力 -> アドレス確認画面 -> メール送信完了画面 -> DB, メール;
   メール -> 会員登録フォーム [folded];
   会員登録フォーム -> 会員登録確認画面 -> 登録完了画面;
}

機能構成図

blockdiag では機能構成図のような幾つかのアイテムの関係を書くこともできます。
すべての図に使えるわけではないですが、シンプルなものは大抵かけるのではないかと思います。

少し前はこんな図を書いてメンバーと共有していました。

blockdiag {
  Webブラウザ [stacked];
  MySQL [shape = "flowchart.database"];

  Webブラウザ -> Webアプリ -> MySQL, RabbitMQ;
  RabbitMQ -> バッチ処理A, バッチ処理B, バッチ処理C;

  group {
    Webアプリ; MySQL; RabbitMQ;
  }
}

図によっては blockdiag のレイアウトエンジンと相性が悪いものがあるかもしれません。
僕がいままで書いた中では次のような図は blockdiag で書くには工夫が必要でした。
自分のシステムを中心においた放射状の図は苦手な部類に入ります。

自分の書きたい図に blockdiag が合うようであれば使ってみてもいいかもしれません。

ちなみに定義はこういうものです。

blockdiag {
  group system_A {
    orientation = portrait;
    color = none;

    none01 [shape = none];
    none02 [shape = none];
    A_API;
  }

  group system_B {
    color = none;
    B_API -- DB [folded];
  }
  A_API -- A連携機能 [folded];
  B_API -- B連携機能

  group MySystem {
    管理機能 -> ○○管理機能, △△管理機能, ××管理機能;
    ○○管理機能 -> A連携機能;
    ××管理機能 -> B連携機能 [folded];
    △△管理機能 -> C連携機能, D連携機能;
  }
  C連携機能 -- C_API;
  D連携機能 -- D_API [folded];

  group system_C {
    color = none;
    C_API;
  }

  group system_D {
    orientation = portrait;
    color = none;

    none04 [shape = none];
    none05 [shape = none];
    D_API;
  }
}

それぞれのノードの宣言順序が並び方に強く影響しているので、書き換えるとレイアウトが壊れることがあります。

フローチャート

次の図はフローチャートです。
blockdiag はフローチャート用のノードレンダラーを持っているように、
フローチャートを書くことを得意としています。

例えばよくある携帯アプリの認証ロジックは次のようなフローチャートになります。

blockdiag {
   orientation = portrait;
   plugin autoclass;
   class if [shape = diamond];
   class state [color = pink];

   携帯認証モード -> UA取得 -> キャリア判定_if -> au, Docomo, SoftBank, その他;
      Docomo -> uid取得 -> ログイン判定_if;
      au -> EZ番号取得 -> ログイン判定_if;
      SoftBank -> Cookie取得 -> ログイン判定_if;
      その他 -> エラー終了_state;

   ログイン判定_if -> ログイン状態_state, 非ログイン状態_state;
}

組織図

blockdiag のおもしろい利用方法のひとつが組織図です。
blockdiag を作る際にまったく想定していなかった図なのですが、
ユーザーの方で実際にこんな風に使っている方がいらっしゃいます。

やってみると馴染むものなんですね。ここでは自衛艦隊の組織図を書いてみます。
この図はもともと @99blues さんのところで公開された定義をアレンジしたものです。

blockdiag {
   自衛艦隊 -- 護衛艦隊, 航空集団, 潜水艦隊, "掃海隊群(横須賀)";

   group{
      color=khaki;
      護衛艦隊 -> "第1護衛艦隊(横須賀)", "第2護衛艦隊(佐世保)",
                  "第3護衛艦隊(舞鶴)", "第4護衛艦隊(呉)";
   };
   group{
      color = lightgreen;
      航空集団 -> "第1航空群(鹿屋)", "第2航空群(八戸)",
                  "第4航空群(厚木)", "第4航空群(那覇)";
   };
   group{
      color = aquamarine;
      潜水艦隊 -> "第1潜水隊群(呉)", "第2潜水隊群(横須賀)";
   }
}

座席表

あと最近耳にしたものでは、blockdiag で会社の座席表を書いたそうです。
もちろん好ましいかたちにレイアウトしてくれるわけではないので、
blockdiag の細かいテクニックを駆使して組み上げたそうです。

実物を見ていないのですが、こんな感じの定義で書いたのではないかと思われます。

blockdiag {
   span_width = 0;
   span_height = 0;

   group {
      color = none;
      A01 -- A02 -- A03 -- A04
      A05 -- A06 -- A07 -- A08;
   }
   A04 -- A09;
   A09 [colheight = 2, width = 80];

   spacer_01 [shape = none];

   group {
      color = none;
      B01 -- B02 -- B03 -- B04
      B05 -- B06 -- B07 -- B08;
   }
   B04 -- B09;
   B09 [colheight = 2, width = 80];

   spacer_02 [shape = none];

   group {
      color = none;
      C01 -- C02 -- C03 -- C04
      C05 -- C06 -- C07 -- C08;
   }
   C04 -- C09;
   C09 [colheight = 2, width = 80];
}

ただ、これは blockdiag のレイアウトエンジンを理解した上で、
応用しながら書いている図なので自由度はかなり低いです。
正直なところこれは Visio で書いたほうが幸せになれると思います :-p

シーケンス図

今度は seqdiag の例を紹介します。
seqdiag はシーケンス図というかなり特化した図を対象としているので、
あまりびっくりするような図は出てきません。

ただ、要素を組み合わせていくと結構綺麗な図ができるので個人的には重用しています。
たとえばグループ機能を使うと見栄えがぐっと良くなります。*1

seqdiag {
   PHP => ライブラリ [label = "状態確認", return = "認証状態"] {
      ライブラリ => 認証API [label = "REST Call"] {
         認証API => データベース [label = "ユーザ問い合わせ", return = "ユーザ情報"];
         認証API --> Twitter [label = "ログイン情報"] {
            Twitter -> Twitter [label = "つぶやく"];
         }
      }
   }

   group {
     label = "Webサーバ";
     color = pink;

     PHP; ライブラリ;
   }

   group {
     label = "認証鯖";
     color = lightgreen;

     認証デーモン; データベース;
   }

   group {
     color = lightblue;
     Twitter;
   }
}

他にも最近導入したノート表示もシーケンスの説明を書く上で重要な要素です。
リクエストしてくれたチームではうまく使っておられるそうです。
ここではサンプルとしてメール送信を行う際のやりとり(SMTP)を図示化してみます。

seqdiag {
   activation = none;

   クライアント -> サーバ [label = "HELO", leftnote = "ハンドシェイク\nクライアントから HELO という文字列を送信する"];
   クライアント <- サーバ [label = "250 OK" rightnote = "ok が返ってくる"];
   クライアント -> サーバ [label = "MAIL FROM: ...", leftnote = "送信元アドレスを伝える"];
   クライアント <- サーバ [label = "250 OK" rightnote = "ok が返ってくる"];
   クライアント -> サーバ [label = "RCPT TO: ...", leftnote = "送信先アドレスを伝える"];
   クライアント <- サーバ [label = "250 OK" rightnote = "ok が返ってくる\n(アドレスがなくても ok であることが多い)"];
   ... 以降、本文を送信する ...
}

まとめ

今日は blockdiag シリーズで生成される図の中で、見栄えの良いものをピックアップしてご紹介しました。
Web ではシンプルな例が多いのでどういう図ができるのかイメージしづらいですし、
なかなか人の書いた図を見る機会がないので、もし参考になればうれしいです。

今後、こういうサンプルをまとめて blockdiag.com に掲載しようと思っているので、
こういうのができたよ!もっといい例があるよ!というものがあれば @tk0miya まで教えて下さい。

*1:この機能は珍しく自分のために実装した機能です。僕のケースではグループを使うことで図が格段に見やすくなりまし>た。