我试图使用Graphviz可视化一个简单的有限状态机图.Graphviz创建的布局并不完全符合我的喜好.我期待更短的边缘更紧凑的结果.
到目前为止,我已尝试使用组并更改边缘的权重,但运气不大.我不清楚为什么Graphviz以它的方式绘制图形以及如何根据自己的喜好调整算法.我可以设置任何参数来实现吗?或者我应该使用另一个命令而不是dot?我试过了neato,结果看起来完全搞砸了,我真的不明白我在做什么......
到目前为止,这是我最好的结果:

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

我曾经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 }
Run Code Online (Sandbox Code Playgroud)
另外,任何人请告诉我,如果我在上面的Graphviz文件中做任何奇怪的事情 - 任何反馈都表示赞赏.
更新:
更多的实验和尝试一些像端口一样的建议,由用户marapet给出,增加了我的困惑......例如,在下面的图片中,为什么dot选择绘制这些奇怪的弯路,Working->Failed而Failed->Announced不是直线?

mar*_*pet 14
对我来说你的输出看起来没问题.TimedOut和Failed当然是一路向右,因为有一个边缘从去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" ];
}
Run Code Online (Sandbox Code Playgroud)

您还可以通过使用端口来改进边缘的开始和结束位置.
关于你的点文件中有关奇怪事物的问题:除了行号(最终允许我使用我的文本编辑器的列模式)和对齐之外,你的文件看起来很好.我尽可能地构建我的点文件(图形属性,节点列表,分组,边).请注意,节点首次出现的顺序可能会对最终布局产生影响.
虽然这是一个很老的问题,但我也遇到了类似的问题,想分享我的结果。除了“weight”、“rank=same”这些技巧之外,我刚刚发现这些方法可以用来调整布局结果:
当涉及到问题中的这个特定图表时,实际上排名=相同和权重将完成主要工作,而样式=隐形可以进行一些微调。所以通过添加这些行
{
rank=same;Announced;Failed;
}
{
rank=same;Assigned;TimedOut;
}
Run Code Online (Sandbox Code Playgroud)
到文件并添加weight=1到“准备清空”边缘,并使用一些不可见的边缘来微调空间,我得到了这个:
完整的图点源:
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
}
Run Code Online (Sandbox Code Playgroud)
更新:不要将“失败”和“已宣布”放在同一排名,而是将“失败”、“已分配”和“超时”放在同一排名可能会产生更好的结果,如下所示,IMO 更好地说明了“失败”之间的相似性和差异和超时。(不过,您必须删除隐形边缘才能得到下图)