DOT 言語でエンコードされたダイグラフのコレクションがあります。スーパーグラフの各ノードがこれらのダイグラフの1つであるようなグラフのグラフを作成したいと思います。GraphViz フレームワーク内でこれを行う方法はありますか?
gvpack
これにより、複数のグラフを 1 つの .dot ファイルにまとめることができるようになります。しかし、それらのグラフ間のエッジを宣言できるかどうかはわかりません。
簡単な答えは、gvpack
サブグラフ間のエッジを宣言しないことです。実際、サブグラフ間に共通のノード名がある場合、gvpack
衝突を避けるためにそれらの名前を変更します。ただし、それは修正可能です。
たとえば、次の 3 つの.dot
ファイルがあるとします1.dot
。
digraph {
A -> B
A -> C
}
2.dot
:
digraph {
D -> E
E -> F
}
...そして3.dot
:
digraph {
D -> G
G -> A
}
...実行gvpack -u 1.dot 2.dot 3.dot | dot -Tjpg -ogvp1.jpg
すると、次のグラフが得られますgvp1.jpg
:
ご覧のとおりgvpack
、重複するノード名のラベルが変更されました。ただし、 を使用して再ラベル付けを簡単に元に戻すことができますgvpack -u 1.dot 2.dot 3.dot | sed 's/_gv[0-9]\+//g' | dot -Tjpg -ogvsub.jpg
。これにより、次のグラフが生成されますgvsub.jpg
。
このアプローチは、共通のノード名を持つサブグラフに依存しているため、これを実現するには、サブグラフ.dot
ファイルに追加のノードを挿入する必要がある場合があります。
(編集:上記のソリューションは、ノードがマージされたグラフを示しましたが、クラスター内のサブグラフではありませんでした。次のソリューションは、クラスター内のサブグラフを示しています。)
与えられた.dot
ファイル1.dot
(各ダイグラフに名前を付けたことを除いて、これらは上記のファイルと同じです):
digraph g1 {
A -> B
A -> C
}
2.dot
:
digraph g2 {
D -> E
E -> F
}
...そして3.dot
:
digraph g3 {
D -> G
G -> A
}
...とともにhdr.dot
:
digraph GMaster {
compound = true;
g1 [style=invisible, height = 0, width = 0, label=""];
g2 [style=invisible, height = 0, width = 0, label=""];
g3 [style=invisible, height = 0, width = 0, label=""];
g1 -> g2 [lhead=clusterg2, ltail=clusterg1];
g1 -> g3 [lhead=clusterg3, ltail=clusterg1]
...そしてtail.dot
:
}
...実行cat 1.dot 2.dot 3.dot | sed 's/digraph \(\w*\) *{/subgraph cluster\1 { \1/' | cat hdr.dot - tail.dot | dot -Tjpg -oclust1.jpg
してファイルを取得できますclust1.jpg
:
compound=true
したがって、ヘッダー ファイルでは、クラスター間のエッジを許可するために使用される、サブグラフと同じ名前の非表示ノードを各サブグラフに追加しました。クラスター間に描画するエッジを指定し、非表示ノード間の各エッジに対してlhead
とを設定ltail
して、正しいクラスターがこれらのエッジのそれぞれの頭と尾として使用されるようにしました。を使用して各サブグラフをクラスターに変換するプロセスで、各サブグラフに適切な非表示ノードも追加しましたsed
。
ノード D、G、および A 間のエッジが表示されているのは、これらのノードがクラスター間で共通であるためです。また、それぞれが 1 つのクラスターでのみ表示されます。ノードがクラスターに固有である場合、クラスター間に表示される唯一のエッジは、非表示のノード間のエッジになります。これは、次のグラフで確認できます。ここでは、 のノードの名前を変更しました3.dot
。
私が完全に修正できなかった残りの欠陥が 1 つあります。非表示のノードはまだ少しスペースを占有しているため、非表示のノードが表示されているノードの横にあるため、クラスタ ボックスが偏って見えます。これは、クラスター間のエッジの頭が、クラスター ボックスの中央ではなく片側を指していることも意味します。現時点では、各サブグラフを見て、そのサブグラフ/クラスターに既にあるノードを見つけて、そのサブグラフ/クラスターの代表ノードとして機能する準備ができていない限り、それについて何ができるかわかりません(つまり、そのクラスターのエッジを描画する元または元のエッジ)。これは、いくつかのサブグラフについては手作業で簡単に実行できますが、サブグラフが多数ある場合は面倒です。
対照的に、上記で使用したアプローチでは、クラスターの名前を知っていて、それをhdr.dot
ファイルに挿入できることだけが必要です。
hdr.dot
この場合のために手動でファイルを作成しましたが、ファイルの内容は、必要に応じて、、またはを使用して他のファイルhdr.dot
から抽出できます。スクリプトは、接続する必要があるクラスターに関する情報がどこかで入手できる場合、クラスターをリンクするエッジを挿入することもできます。.dot
sed
awk
perl
python
hdr.dot