2013-04-14 84 views
4

我正在使用Graphviz(即Dot)爲我計劃構建的超媒體API繪製狀態機。在我的圖中,節點代表狀態,邊代表鏈接。我想要做的是有相同的「類型」(即,使用相同的動詞或相同的rel)的邊緣(鏈接)共享像color這樣的屬性。Graphviz共享節點或邊緣之間的屬性

我知道你可以定義適用於所有節點/邊的「全局」屬性,但是我需要一些我可以更一般地應用於幾種不同「類型」的東西。我所能想到的最接近的類比是HTML類。我不需要多個「班級」(儘管那會很好),但是重複像color=red, style=bold這樣的屬性是很麻煩的。

Dot有沒有辦法宣佈這樣的事情?或者至少有一些我不需要經常重複自己的方式?

回答

4

我在兩種不同的方式做到了這一點:

選項(A):寫從另一個腳本dot文件。當我使用腳本(例如Python或Perl)將輸入數據重繪爲dot格式以進行繪製時,這特別有用。在這種情況下,除了使用Python腳本將數據寫入dot格式之外,我還可以讓它將每個節點和邊緣的屬性寫入dot文件。下面顯示了一個例子(不能運行,因爲我已經從解釋輸入數據的較大腳本中提取了它,但是您可以看到Perl如何編寫代碼dot)。

print "graph G {\n graph [overlap = scale, size = \"10,10\"]; node [fontname = \"Helvetica\", fontsize = 9]\n"; 
for ($j = 0; $j <= $#sectionList; $j++) { 
    print "n$j [label = \"$sectionList[$j]\", style = filled, fillcolor = $groupColour{$group{$sectionList[$j]}} ]\n"; 
    } 
for ($j = 0; $j <= $#sectionList; $j++) { 
    for ($i = $j+1; $i <= $#sectionList; $i++) { 
     $wt = ($collab{$sectionList[$j]}{$sectionList[$i]}+0)/ 
     ($collab{$sectionList[$j]}{$sectionList[$j]}+0); 
     if ($wt > 0.01) { 
     print "n$j -- n$i [weight = $wt, "; 
     if ($wt > 0.15) { 
      print "style = bold]\n"; 
     } 
     elsif ($wt > 0.04) { 
      print "]\n"; 
     } else { 
      print "style = dotted]\n"; 
     } 
     } 
    } 
    print "\n"; 
} 

print "}\n"; 

選項(B):如果我手寫的劇本dot,我將使用一個宏處理器來定義的共同要素。例如,給定包含m4define()文件polygon.dot.m4如下:

define(SHAPE1,square) 
define(SHAPE2,triangle) 

digraph G { 
    a -> b -> c; 
    b -> d; 
    a [shape=SHAPE1]; 
    b [shape=SHAPE2]; 
    d [shape=SHAPE1]; 
    e [shape=SHAPE2]; 
    } 

...命令m4 <polygon.dot.m4 | dot -Tjpg -opolygon.jpg生產: enter image description here

在文件的頂端更改SHAPE1和SHAPE2的定義將改變爲每個相關節點繪製的形狀。

+1

謝謝,我以前從未使用過M4。這很容易:) –

+1

我推薦選項(B)。如果從Python/Perl等生成.dot文件,我建議使用模板庫而不是逐個構建字符串。 –