6

您好我想要一个带有点语言的 uml 序列图,现在我有以下问题我想要布局如下,a、b、c 和 d 在顶部呈一条直线,但线条直接指向底部。我怎样才能做到这一点?

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

也许我可以实现 a、b、c 和 d 及其所属边缘是集群,我为集群设置了不同的 rankdir?

编辑刚刚通过在 a、b、c 和 d 之间添加不可见边缘找到了解决方案,但还有其他解决方案吗?

4

4 回答 4

11

有志者,事竟成!

这是一个关于如何使用 dot 执行此操作的示例:

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]; }
}

渲染后,这将产生这个图像:

序列图

关于这是如何实现的,有一些重要的提示:

  • 每个组件都有一个没有形状、没有高度和没有宽度的节点列表。
  • 每条线必须处于相同的排名,否则 DOT 将根据其自动排名对其进行定位。
  • 为了使事情变得直截了当,所有方向都是相同的:从a到b到c。如果你颠倒其中一些,DOT 会弄得一团糟。在箭头上实现正确方向的技巧是使用 dir edge 属性。
  • 边缘的权重属性对于保持垂直线笔直非常重要。他们的人数必须超过最大的等级。如果您需要创建一个等级高达 100 的图表,您的体重必须至少为 101,否则不可能有一条直的垂直虚线。
  • 为了获得一条直的水平线,您必须将每个节点连接在同一等级上。否则,DOT 将弯曲线。例如,将 a1 连接到 c1 是通过将 a1 连接到 b1 并将 b1 连接到 c1 来实现的。
于 2019-12-16T20:36:31.243 回答
8

您所描述的似乎是dot默认情况下所做的。

例如,这个图表:

digraph SO {
  a -> a1 -> a2
  b -> b1 -> b2
  c -> c1 -> c2
  d -> d1 -> d2
} 

出来是这样的:

在此处输入图像描述

如果您有一个更复杂的图表,您可以使用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
}

出来是这样的:

在此处输入图像描述

但是,如果您希望a, b,cd以特定顺序排列,我认为您将不得不像您建议的那样使用不可见的边缘。该dot指南甚至建议这样做:

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

于 2009-09-29T08:53:16.230 回答
7

你可以试试 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

于 2011-01-09T15:11:39.440 回答
1

建议 #1 - PlantUML

PlantUML 使用 Graphviz,因此一种选择是简单地使用 PlantUML。例如,在 PlantUML 中,这...

@startuml
Bob -> Alice : hello
@enduml

...呈现为这样...

PlantUML 渲染序列图示例

上图呈现在http://plantuml.com/plantuml/...,您可以阅读文档中的PlantUML 序列图。此外,PlantUML 也可以从命令行使用,PlantUML插件可用于许多流行的 IDE

建议 #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" ]
}

并从命令行通过 NEATO(随 Graphviz 一起安装)渲染它......

...呈现为这样...

NEATO 渲染序列图示例

要使用 NEATO 渲染上图,请执行以下操作:

  1. 安装 Graphviz 附带的 NEATO(至少在 Mac 上使用时$ brew install graphviz # requires Homebrew
  2. digraph sequenceDiagramExample {...}上面的代码放在一个名为的文本文件中sequenceDiagramExample.dot
  3. 在命令行中,运行$ neato -Tpng sequenceDiagramExample.dot -o sequenceDiagramExample.png,这将生成一个名为的 PNG 文件sequenceDiagramExample.png
  4. 查看PNG :)

专业提示 - 不要将neatodot可执行文件混淆

  • neato当您想要精细控制元素的定位方式时,可能是您想要使用的(欢迎评论中的其他观点!)
  • 不要将渲染neato与渲染混淆dot(Graphviz 也包含)
  • 例如,使用dot(例如$ dot -Tpng sequenceDiagramExample.dot -o sequenceDiagramExample.png)从 Suggestion #2 渲染有向图将产生这个......

在此处输入图像描述

于 2018-11-25T18:15:35.143 回答