Graphviz从上到下和从左到右排列

8

你好,我想用dot语言制作一个UML序列图,现在我遇到了以下问题:我想要将a、b、c和d排成一条直线放在顶部,但是连接线应该直接延伸到底部。我该如何实现呢?

a   b   c   d
|   |   |   | 
|   |   |   |

也许我可以实现将a、b、c和d及其相关的边缘作为集群,为这些集群设置不同的rankdir。编辑:刚刚发现通过在a、b、c和d之间添加不可见的边缘可以解决问题,但还有其他的解决方案吗?
4个回答

15

有志者事竟成!

以下是使用点号的示例:

digraph SEQ_DIAGRAM {
    graph [overlap=true, splines=line, nodesep=1.0, ordering=out];
    edge [arrowhead=none];
    node [shape=none, width=0, height=0, label=""];

    {
        rank=same;
        node[shape=rectangle, height=0.7, width=2];
        api_a[label="API A"];
        api_b[label="API B"];
        api_c[label="API C"];
    }
    // Draw vertical lines
    {
        edge [style=dashed, weight=6];
        api_a -> a1 -> a2 -> a3;
        a3 -> a4 [penwidth=5, style=solid];
        a4 -> a5;
    }
    {
        edge [style=dashed, weight=6];
        api_b -> b1 -> b2 -> b3 -> b4;
        b4 -> b5 [penwidth=5; style=solid];
    }
    {
        edge [style=dashed, weight=6];
        api_c -> c1;
        c1-> c2 [penwidth=5, style=solid];
        c2 -> c3 -> c4 -> c5;
    }
    // Draws activations
    { rank=same; a1 -> b1 [label="activate()"]; b1 -> c1 [arrowhead=normal]; }
    { rank=same; a2 -> b2 [style=invis]; b2 -> c2 [label="refund()", arrowhead=normal, dir=back]; }
    { rank=same; a3 -> b3 [arrowhead=normal, dir=back, label="place_order()"]; b3 -> c3; }
    { rank=same; a4 -> b4 [label="distribute()", arrowhead=normal]; }
    { rank=same; a5 -> b5 [style=invis]; b5 -> c5 [label="bill_order()", arrowhead=normal]; }
}

渲染后,将生成此图像:

Sequence Diagram

以下是实现此图像的重要提示:

  • 每个组件都有一个没有形状、高度和宽度的节点列表。
  • 每条线必须在相同的等级上,否则DOT将根据它们的自动排名将它们定位。
  • 为了使事情变得简单明了,所有方向都是相同的:从a到b到c。如果你反转其中一些方向,DOT会搞乱它们。在箭头上实现正确方向的技巧是使用dir edge属性。
  • 边缘上的权重属性非常重要,以保持垂直线条的直线。它们必须超过最大的等级。如果你需要创建一个等级深达100的图表,你的权重必须至少是101,否则就不可能有一条直的虚线竖直线。
  • 为了获得一条直线的水平线,您必须连接同一等级上的每个节点。否则,DOT将弯曲该线。例如,通过将a1连接到b1并将b1连接到c1来实现将a1连接到c1。

9
您所描述的似乎是默认情况下dot所执行的操作。
例如,以下图表:
digraph SO {
  a -> a1 -> a2
  b -> b1 -> b2
  c -> c1 -> c2
  d -> d1 -> d2
} 

翻译如下:

呈现的效果如下所示:

enter image description here

如果您有一个更复杂的图表,可以使用rank=same强制使节点处于相同的高度。例如:

digraph SO {
  { rank = same
    a b c d
  }

  a -> a1 -> a2 
  b -> b1 -> b2 -> b3 -> b4
  c -> c1 
  d -> d1 -> d2 -> d3
  d2 -> a2
}

输出如下:

显示为:

enter image description here

然而,如果您希望abcd按特定顺序排列,我认为您需要使用像您建议的不可见边缘。 dot指南甚至建议这样做:

当节点被限制在同一秩上时,边缘权重也起到作用。这些节点之间具有非零权重的边缘被指向尽可能远的相同方向(从左到右或从上到下在旋转的绘图中)。实际上可以通过在需要的位置放置不可见边缘(style="invis")来调整节点排序。


啊,抱歉,当你现在添加d2 -> a2时,我仍然希望a、b、c和d在上面,但是a1、a2、a3仍然在一行。就像上面的样子。 - Sebastian Müller
1
托管这些图像的服务器现在发送广告。这个问题能修复吗? - Dave

8
您可以尝试使用mscgen(消息序列图生成器)。
一个简单的图表示例是example.msc。
msc {

A,B;

--- [label="Start", ID="1"];

A->B [label="signal"];
A<-B [label="signal"];

}

$: mscgen -T png -o example.png -i example.msc.

这个命令可以生成漂亮的时序图。

谢谢, Srikanth Kyatham


3
建议 #1 - PlantUML
PlantUML使用Graphviz,因此一种选择是直接使用PlantUML。例如,在PlantUML中,可以这样写...
@startuml
Bob -> Alice : hello
@enduml

这被渲染为这个。

PlantUML rendered sequence diagram example

上述图表是在http://plantuml.com/plantuml/...渲染的,您可以在文档中了解PlantUML序列图。此外,PlantUML也可以从命令行使用,并且许多流行的IDE都有可用的PlantUML插件
建议#2 - NEATO
您还可以使用GraphvizNEATO(PDF)。例如,这个有向图...
digraph sequenceDiagramExample {
  bobHead [ label="Bob" pos="0,1.5!" shape="record" ];
  bobPoint0 [ pos="0,0.75!" shape="point" width="0" ]
  bobFoot [ label="Bob" pos="0,0!" shape="record" ];
  aliceHead [ label="Alice" pos="1,1.5!" shape="record" ];
  alicePoint0 [ pos="1,0.75!" shape="point" width="0" ]
  aliceFoot [ label="Alice" pos="1,0!" shape="record" ];
  bobHead -> bobPoint0 -> bobFoot [ dir="none" style="dashed" ]
  aliceHead -> alicePoint0 -> aliceFoot [ dir="none" style="dashed" ]
  bobPoint0 -> alicePoint0 [ label="hello" labelloc="c" style="solid" ]
}

通过命令行使用Graphviz中安装的NEATO进行渲染,结果如下:

NEATO rendered sequence diagram example

使用NEATO来渲染上面的图片,需要按照以下步骤进行操作:
  1. 安装NEATO,它随Graphviz一起提供(至少在Mac上使用$ brew install graphviz # requires Homebrew时是这样的)
  2. 将上面的digraph sequenceDiagramExample {...}代码放入名为sequenceDiagramExample.dot的文本文件中
  3. 从命令行运行$ neato -Tpng sequenceDiagramExample.dot -o sequenceDiagramExample.png,将生成一个名为sequenceDiagramExample.png的PNG文件
  4. 查看PNG :)
专业提示-不要混淆neatodot可执行文件。
  • neato可能是你想要使用的,当你想要对元素的定位有更精细的控制时(欢迎在评论中提供其他观点!)
  • 不要混淆使用neato和使用dot进行渲染(也包含在Graphviz中)
  • 例如,使用dot来渲染建议#2的有向图(例如$ dot -Tpng sequenceDiagramExample.dot -o sequenceDiagramExample.png)将产生以下结果...

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接