読者です 読者をやめる 読者になる 読者になる

(12日目) blockdiag の class 機能を使ってみる

今日は blockdiag の class 機能を紹介します。

class 機能も最近できたばかりの機能で、シンプルでわかりやすい機能が多い blockdiag の中で
少し変わった位置にある機能です。
blockdiag ではノードやエッジ(矢印)、グループなどを書く際に、
label や color などの属性を設定しながら図を作成しています。

class 機能はあらかじめ属性をクラスとしてまとめておいて、
それを各要素に適用するための仕組みです。
CSS の class 定義と似た考え方を持っています。


例として次のような図を考えてみます。今日はサンプルとして nwdiag を利用しています。
ホスト数が 8台あるネットワークを模した図です。

nwdiag {
  network dmz {
    router [shape = cisco.router];
    server01 [shape = cisco.www_server, textcolor = red, address = 192.168.0.1];
    server02 [shape = cisco.www_server, textcolor = red, address = 192.168.0.2];
    server03 [shape = cisco.www_server, textcolor = red, address = 192.168.0.3];
  }
  network internal {
    router [shape = cisco.router];
    client01 [shape = cisco.pc, textcolor = gray, address = 192.168.1.1];
    client02 [shape = cisco.pc, textcolor = gray, address = 192.168.1.2];
    client03 [shape = cisco.pc, textcolor = gray, address = 192.168.1.3];
    client04 [shape = cisco.pc, textcolor = gray, address = 192.168.1.4];
    client05 [shape = cisco.pc, textcolor = gray, address = 192.168.1.5];
    client06 [shape = cisco.pc, textcolor = gray, address = 192.168.1.6];
    client07 [shape = cisco.pc, textcolor = gray, address = 192.168.1.7];
    client08 [shape = cisco.pc, textcolor = gray, address = 192.168.1.8];
  }
}

サーバーを 3台、クライアントホストを 8台用意しましたが、
それぞれを同じように描画するために定義が少し煩雑になっています。

ここで便利なのが class 機能です。
共通の定義(ここでは shape, textcolor) を抜き出しクラスとして定義すると、
図の定義がかなりシンプルになります。

nwdiag {
  class server [shape = cisco.www_server, textcolor = red];
  class client [shape = cisco.pc, textcolor = gray];

  network dmz {
    router [shape = cisco.router];
    server01 [class = server, address = 192.168.0.1];
    server02 [class = server, address = 192.168.0.2];
    server03 [class = server, address = 192.168.0.3];
  }
  network internal {
    router [shape = cisco.router];
    client01 [class = client, address = 192.168.1.1];
    client02 [class = client, address = 192.168.1.2];
    client03 [class = client, address = 192.168.1.3];
    client04 [class = client, address = 192.168.1.4];
    client05 [class = client, address = 192.168.1.5];
    client06 [class = client, address = 192.168.1.6];
    client07 [class = client, address = 192.168.1.7];
    client08 [class = client, address = 192.168.1.8];
  }
}

どうでしょうか、すこしは図の定義はすっきりしたのではないでしょうか。
class をうまく使うことで、サーバーやクライアントの表現を変更したくなった場合に
一箇所の変更でまとめて変更するようなこともできます。

生成された結果の図は最初と変わりません。

autoclass プラグイン

blockdiag ではもうひとつクラスを適用する仕組みを提供しています。
その仕組みとは autoclass プラグインです。

autoclass プラグインを使うとノード名に応じて自動的にクラスを適用します。
先ほどの例では server と client というふたつのクラスを定義していました。

  class server [shape = cisco.www_server, textcolor = red];
  class client [shape = cisco.pc, textcolor = gray];

autoclass を利用すると 〜_server, 〜_client というノードを定義すると
自動的にこれらのクラスが適用されます。

autoclass を利用して同じ図をもう一度書きなおすと以下のようになります。

nwdiag {
  plugin autoclass;
  class server [shape = cisco.www_server, textcolor = red];
  class client [shape = cisco.pc, textcolor = gray];

  network dmz {
    router [shape = cisco.router];
    s01_server [address = 192.168.0.1];
    s02_server [address = 192.168.0.2];
    s03_server [address = 192.168.0.3];
  }
  network internal {
    router [shape = cisco.router];
    c01_client [address = 192.168.1.1];
    c02_client [address = 192.168.1.2];
    c03_client [address = 192.168.1.3];
    c04_client [address = 192.168.1.4];
    c05_client [address = 192.168.1.5];
    c06_client [address = 192.168.1.6];
    c07_client [address = 192.168.1.7];
    c08_client [address = 192.168.1.8];
  }
}

もちろん出力された図は同じものが出力されます。


class 機能や autoclass プラグインは大きめの図を作る際の手助けとなる機能です。
今回の例では shape, textcolor 属性を例として取り上げましたが、
blockdiag で扱える属性であればすべてをクラスとして定義することができます。

図を書く際に共通なスタイルを見つけたらクラスにして、シンプルに書けないか試してみてください。