9

DOT 言語でエンコードされたダイグラフのコレクションがあります。スーパーグラフの各ノードがこれらのダイグラフの1つであるようなグラフのグラフを作成したいと思います。GraphViz フレームワーク内でこれを行う方法はありますか?

gvpackこれにより、複数のグラフを 1 つの .dot ファイルにまとめることができるようになります。しかし、それらのグラフ間のエッジを宣言できるかどうかはわかりません。

4

2 に答える 2

10

簡単な答えは、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から抽出できます。スクリプトは、接続する必要があるクラスターに関する情報がどこかで入手できる場合、クラスターをリンクするエッジを挿入することもできます。.dotsedawkperlpythonhdr.dot

于 2013-05-12T09:58:07.967 に答える