2013-04-14 124 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文件,我建议使用模板库而不是逐个构建字符串。 –