我有一個以DOT語言編碼的圖形集合。我想要構造一個圖表,使得超圖中的每個節點都是這些圖的其中一個。有沒有辦法在GraphViz框架內做到這一點?Graphviz中的圖形圖形
我知道gvpack
將允許我將多個圖組合成一個.dot文件。但我不知道它是否會允許我在這些圖表之間聲明邊界。
我有一個以DOT語言編碼的圖形集合。我想要構造一個圖表,使得超圖中的每個節點都是這些圖的其中一個。有沒有辦法在GraphViz框架內做到這一點?Graphviz中的圖形圖形
我知道gvpack
將允許我將多個圖組合成一個.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
:
因此,在頭文件,我已經添加了一個invisble節點到每個子圖,具有相同的名稱作爲子圖,用於compound=true
來允許羣集之間的邊緣。我已經指定了在簇之間繪製的邊緣,並且我已經爲不可見節點之間的每條邊設置了lhead
和ltail
,以確保將正確的簇用作每個邊的頭部和尾部。在使用sed
將每個子圖轉換爲集羣的過程中,我還爲每個子圖添加了適當的不可見節點。
顯示節點D,G和A之間的邊緣,因爲這些節點在羣集之間是共同的。而且,它們中的每一個僅顯示在一個羣集中。如果節點對於簇是唯一的,那麼將在簇之間顯示的唯一邊將是不可見節點之間的邊緣。這可以看出,在下面的圖,在那裏我已經在3.dot
改名爲節點:
有一個剩餘的缺陷,我還沒有完全得以解決。不可見節點仍佔用一點點空間,因此集羣框看起來不平衡,因爲不可見節點與可見節點並排放置。這也意味着簇之間邊緣的頭部指向簇框的一側而不是中間。目前,除非我們準備查看每個子圖並找到一個已經在該子圖/集羣中的節點作爲該子圖/集羣的代表節點,否則我不知道可以做些什麼。我們爲該羣集繪製邊緣的一個或者從中)。手工製作幾個子圖可以很容易地完成,但是如果有多個子圖,則會很繁瑣。
相反,我上面使用的方法只需要我們知道羣集的名稱,並且可以將它插入到hdr.dot
文件中。
我已經構建了hdr.dot
文件由專人針對這種情況,但hdr.dot
文件的內容可以從其他.dot
文件,如果有必要提取與sed
,awk
,perl
或python
。如果有關應該連接哪些羣集的信息可用,該腳本還可以插入邊緣以將羣集鏈接到hdr.dot
。
感謝Simon的徹底迴應。在我的情況下,儘管我想把每個子圖作爲超圖中的節點,而不是組件。我想指定1-> 2和1-> 3之間存在一條邊,並將子圖劃分爲不同的部分,並用節點之間的適當邊構成節點。 – MRocklin 2013-05-13 13:49:52
啊,我明白了。我認爲加入子圖可以通過類似於我在答案中採用的方法來實現。我會考慮一下。 – Simon 2013-05-13 20:42:15
我編輯了我的答案,以顯示如何通過邊鏈接羣集。 – Simon 2013-05-14 02:29:00