Graphvizで凡例付きステートチャート図

Graphvizで凡例付きステートチャート図を書く。凡例に色々入れすぎたな。

Graphvizで凡例付きステートチャート図

digraph sample {
  graph [fontname = "monospace", fontsize = 10, rankdir = TD, compound = true];
  node  [fontname = "monospace", fontsize = 10];
  edge  [fontname = "monospace", fontsize = 10];

  // node
  node  [shape = circle];
  start [height = 0.3, width = 0.3, style = filled, fillcolor = black, label = ""];
  end   [height = 0.3, width = 0.3, style = filled, fillcolor = black, label = "", peripheries = 2];

  node  [shape = record];
  state [label = "{\<\<State\>\>\n状態|}"];

  // edge
  edge [arrowhead = vee];
  start -> state;
  state -> end;

  // rank

  // legend
  subgraph cluster_legend {
    label = "凡例";

    // node
    node   [shape = none];
    level1 [group = 1, label = "スタート"];
    level2 [group = 1, label = "フォーク\n(並列処理)"];
    level3 [group = 1, label = "状態"];
    level4 [group = 1, label = "ジョイン"];
    level5 [group = 1, label = "エンド"];

    node     [shape = circle];
    start_ex [height = 0.3, width = 0.3, style = filled, fillcolor = black, label = ""];
    end_ex   [height = 0.3, width = 0.3, style = filled, fillcolor = black, label = "", peripheries = 2];

    node   [shape = record];
    state1_ex [label = "{\<\<State\>\>\n状態1|entry/入場時アクション\ldo/繰り返しアクション\lexit/退場時アクション\lイベント名/内部遷移アクション\l}"];
    state2_ex [label = "{\<\<State\>\>\n状態2|}"];

    node [shape = box];
    folk_ex [height = 0.01, style = filled, fillcolor = black, label = ""];
    join_ex [height = 0.01, style = filled, fillcolor = black, label = ""];
    
    // edge
    edge [style = invis];
    level1 -> level2 -> level3 -> level4 -> level5;

    edge [arrowhead = vee, style = solid];
    start_ex  -> folk_ex [label = "イベント[ガード条件]/アクション"];
    folk_ex   -> state1_ex;
    folk_ex   -> state2_ex;
    state1_ex -> join_ex;
    state2_ex -> join_ex;
    join_ex   -> end_ex;
  }
}