無向グラフのDOTにgvprでrank付きサブグラフを加える #1
話題のメインがライフゲームと関係なさそうなのでタイトルを変えた。
ライフゲームの記事の#20ではdotコマンドを使ってレンダリングしようとした。
その時は手書きでDOTファイルを書いたのだが、あのサイズでもそれは面倒だった。
これをメッシュ生成プログラムgen_mesh.gの出力に、
gvprプログラムで自動的にrank属性を加えるようにしてみる。
DOTにおける
...snip { rank = same; "0,3"; "1,3"; "2,3"; } ...snip
のように定義されるrank属性はサブグラフに与える属性である。
subgraph
というキーワードが明示されてはいないが、
{ ... }
で囲まれているものが一つのサブグラフとなる。
したがって#20のようなグラフを作るなら、
各ノードについて"x,y"形式のname属性を見て、
同じyの値を持つノードを同じサブグラフに属させればいい。
insert_rank.g
N { graph_t g = subg($G, yOf(name)); g.rank = 'same'; subnode(g, $); }
サブグラフの名前をyの値そのものにして、その値を名前のyに持つノードをそのサブグラフに含める。
gvpr -f gen_mesh.g -a 3,4 | gvpr -cf insert_rank.g | dot -T png -o 3x4.png
上下がひっくり返ってしまった。insert_rank.gの出力を見ると、
graph { subgraph 0 { graph [rank=same]; "0,0"; "1,0"; "2,0"; } subgraph 1 { ...snip } subgraph 2 { ...snip } subgraph 3 { ...snip } "0,0" -- "1,0"; ...snip
のようにy=0のサブグラフが先に定義されている。定義の順序は重要なので修正しないといけない。
とはいえ、この場合に限れば、
gvpr -f gen_mesh.g -a 3,4 | gvpr -cf insert_rank.g | dot -Grankdir=BT -T png -o 3x4.png
のような解決策もないわけではない。
rankの方向性を-Grankdir=BTにしてアップサイドダウンケーキの焼き上がり。