如何影响图形项目的布局?

时间:2012-07-21 00:59:57

标签: graph graphviz

我正在尝试使用Graphviz可视化一个简单的有限状态机图。 Graphviz创建的布局并不完全符合我的喜好。我期待更短的边缘更紧凑的结果。

到目前为止,我已尝试使用群组并更改边缘的权重,但运气不足。我不清楚为什么Graphviz以它的方式绘制图形以及如何根据自己的喜好调整算法。我可以设置任何参数来实现吗?或者我应该使用除dot之外的其他命令吗?我试过了neato,但结果看起来完全搞砸了,我真的不明白我在做什么......

到目前为止,这是我最好的结果:

Finite State Machine, best result so far

试图想象一个比这更好的布局,我认为如果红色框对齐不同,图形会更好看,更紧凑,例如图中箭头所示:

Finite State Machine, imagined better result

我使用dot创建图表,源代码如下:

  1 digraph JobStateDiagram
  2 {
  3   rankdir=LR;
  4   size="8,5";
  5 
  6   node  [style="rounded,filled,bold", shape=box, fixedsize=true, width=1.3, fontname="Arial"];
  7   Created   [fillcolor=black, shape=circle, label="", width=0.25];
  8   Destroyed [fillcolor=black, shape=doublecircle, label="", width=0.3];
  9   Empty     [fillcolor="#a0ffa0"];
 10   Announced [fillcolor="#a0ffa0"];
 11   Assigned  [fillcolor="#a0ffa0"];
 12   Working   [fillcolor="#a0ffa0"];
 13   Ready     [fillcolor="#a0ffa0"];
 14   TimedOut  [fillcolor="#ffa0a0"];
 15   Failed    [fillcolor="#ffa0a0"];
 16 
 17   {
 18     rank=source; Created Destroyed;
 19   }
 20 
 21   edge  [style=bold, fontname="Arial" weight=2]
 22   Empty     -> Announced [ label="announce"   ];
 23   Announced -> Assigned  [ label="assign"     ];
 24   Assigned  -> Working   [ label="start"      ];
 25   Working   -> Ready     [ label="finish"     ];
 26   Ready     -> Empty     [ label="revoke"     ];
 27 
 28   edge  [fontname="Arial" color="#aaaaaa" weight=1]
 29   Announced -> TimedOut  [ label="timeout"    ];
 30   Assigned  -> TimedOut  [ label="timeout"    ];
 31   Working   -> TimedOut  [ label="timeout"    ];
 32   Working   -> Failed    [ label="error"      ];
 33   TimedOut  -> Announced [ label="announce"   ];
 34   TimedOut  -> Empty     [ label="revoke"     ];
 35   Failed    -> Announced [ label="announce"   ];
 36   Failed    -> Empty     [ label="revoke"     ];
 37 
 38   edge  [style=bold, fontname="Arial" weight=1]
 39   Created   -> Empty     [ label="initialize" ];
 40   Empty     -> Destroyed [ label="finalize"   ];
 41   Announced -> Empty     [ label="revoke"     ];
 42   Assigned  -> Empty     [ label="revoke"     ];
 43   Working   -> Empty     [ label="revoke"     ];
 44 }

另外,如果我在上面的Graphviz文件中做了任何奇怪的事情,请告诉我 - 任何反馈都表示赞赏。


更新

通过用户marapet进行的更多实验和尝试端口等建议增加了我的困惑......例如,在下图中,为什么dot选择为{{1}画出这些奇怪的弯路}和Working->Failed,而不是直线?

Graph with strange long edges

2 个答案:

答案 0 :(得分:13)

对我而言,你的输出看起来没问题。 TimedOutFailed当然是一直到右边,因为从Working到它们的边缘。这是dot最擅长的,虽然您可以进行一些调整以调整graphviz布局,但我认为如果您想创建特定的图形布局并控制所有内容,最好使用其他工具。

话虽如此,我确实用graphviz快速尝试了。我更改了一些线以创建一个包含所有绿色节点的直线,并按照问题中的指示对齐红色节点。我还添加了边缘集中器 - 结果对我来说看起来不太好:

digraph JobStateDiagram
{
  rankdir=LR;
  size="8,5";
  concentrate=true;

  node  [style="rounded,filled,bold", shape=box, fixedsize=true, width=1.3, fontname="Arial"];
  Created   [fillcolor=black, shape=circle, label="", width=0.25];
  Destroyed [fillcolor=black, shape=doublecircle, label="", width=0.3];
  Empty     [fillcolor="#a0ffa0"];
  Failed    [fillcolor="#ffa0a0"];
  Announced [fillcolor="#a0ffa0"];
  Assigned  [fillcolor="#a0ffa0"];
  Working   [fillcolor="#a0ffa0"];
  Ready     [fillcolor="#a0ffa0"];
  TimedOut  [fillcolor="#ffa0a0"];

  {
    rank=source; Created; Destroyed;
  }
  {
    rank=same;Announced;Failed;
  }
  {
    rank=same;Assigned;TimedOut;
  }

  edge  [style=bold, fontname="Arial", weight=100]
  Empty     -> Announced [ label="announce"   ];
  Announced -> Assigned  [ label="assign"     ];
  Assigned  -> Working   [ label="start"      ];
  Working   -> Ready     [ label="finish"     ];
  Ready     -> Empty     [ label="revoke", weight=1     ];

  edge  [color="#aaaaaa", weight=1]
  Announced -> TimedOut  [ label="timeout"    ];
  Assigned  -> TimedOut  [ label="timeout"    ];
  Working   -> TimedOut  [ label="timeout"    ];
  Working   -> Failed    [ label="error"      ];
  TimedOut  -> Announced [ label="announce"   ];
  TimedOut  -> Empty     [ label="revoke"     ];
  Failed    -> Announced [ label="announce"   ];
  Failed    -> Empty     [ label="revoke"     ];

  Created   -> Empty     [ label="initialize" ];
  Empty     -> Destroyed [ label="finalize"   ];
  Announced -> Empty     [ label="revoke"     ];
  Assigned  -> Empty     [ label="revoke"     ];
  Working   -> Empty     [ label="revoke"     ];
}

graphviz output

您还可以通过使用端口来改进边缘的开始和结束位置。

关于你的点文件中有关奇怪事物的问题:行号除外(这最终允许我将列模式用于我的文本编辑器)并且对齐,您的文件对我来说很好。我尽可能地构建我的点文件(图形属性,节点列表,分组,边)。请注意,节点首次出现的顺序可能会对最终布局产生影响。

答案 1 :(得分:1)

尽管这是一个非常老的问题,但我也遇到了类似的问题,并希望分享我的结果。除了“权重”,“等级=相同”的技巧外,我只是发现这些方法可用于调整布局结果:

  • dir = back
  • 添加更多边缘或节点并设置style = invis

对于问题中的这个特定图形,实际上等级=相同和权重将是主要工作,样式= invis可以进行一些微调。因此,通过添加这些行

 {
  rank=same;Announced;Failed;
 }
 {
  rank=same;Assigned;TimedOut;
 }

添加到文件中,并将weight=1添加到“准备清空”边缘,并添加一些不可见的边缘来微调我得到的空间:

GraphViz layout result

完整的图形点源:

digraph JobStateDiagram
{
  rankdir=LR;
  size="8,5";

  node  [style="rounded,filled,bold", shape=box, fixedsize=true, width=1.3, fontname="Arial"];
  Created   [fillcolor=black, shape=circle, label="", width=0.25];
  Destroyed [fillcolor=black, shape=doublecircle, label="", width=0.3];
  Empty     [fillcolor="#a0ffa0"];
  Announced [fillcolor="#a0ffa0"];
  Assigned  [fillcolor="#a0ffa0"];
  Working   [fillcolor="#a0ffa0"];
  Ready     [fillcolor="#a0ffa0"];
  TimedOut  [fillcolor="#ffa0a0"];
  Failed    [fillcolor="#ffa0a0"];

  {
    rank=source; Created Destroyed;
  }
  {
    rank=same;Announced;Failed; #change here
  }
  {
    rank=same;Assigned;TimedOut; #change here
  }

  edge  [style=bold, fontname="Arial" weight=20] #change here
  Empty     -> Announced [ label="announce"   ];
  Announced -> Assigned  [ label="assign"     ];
  Assigned  -> Working   [ label="start"      ];
  Working   -> Ready     [ label="finish"     ];
  Ready     -> Empty     [ label="revoke" weight=1 ]; #change here

  edge  [fontname="Arial" color="#aaaaaa" weight=2] #change here
  Announced -> TimedOut  [ label="timeout"    ];
  Assigned  -> TimedOut  [ label="timeout" weight=1]; #change here
  Working   -> TimedOut  [ label="timeout"    ];
  Working   -> Failed    [ label="error"      ];
  TimedOut  -> Announced [ label="announce"   ];
  TimedOut  -> Empty     [ label="revoke"     ];
  Failed    -> Announced [ label="announce"   ];
  Failed    -> Empty     [ label="revoke"     ];

  edge  [style=bold, fontname="Arial" weight=1]
  Created   -> Empty     [ label="initialize" ];
  Empty     -> Destroyed [ label="finalize"   ];
  Announced -> Empty     [ label="revoke"     ];
  Assigned  -> Empty     [ label="revoke"     ];
  Working   -> Empty     [ label="revoke"     ];
  
  Assigned  -> Working   [ label="start"  style=invis     ]; #change here 
  Assigned  -> Working   [ label="start"  style=invis     ]; #change here 
}

更新:与其将“ Failed”和“ Announced”置于同一等级,不如将“ Failed”,“ Assigned”和“ TimedOut”置于同一等级可能会产生更好的结果,如下所示,这可以更好地说明IMO失败与超时之间的区别。 (您必须删除invis边缘才能获得下图)

enter image description here