【问题标题】:Problems with designing UML - like diagrams in graphviz设计 UML 的问题 - 类似于 graphviz 中的图表
【发布时间】:2012-02-12 18:45:14
【问题描述】:

我目前在 graphiz 上设计类似 UML 的图表时遇到问题。问题的原因是它们不完全是 UML 图。主要区别在于我使用缩进将层次结构添加到对象的属性中。实现这些特质对我来说有点困难。我想要实现的是:

我通常使用名为record 的节点形状来设计这些图表。当我必须像 UML 中的关系(即聚合、关联、组合等)一样链接这些类似 UML 的图表中的两个时,就会出现问题。

当我有图表时,我无法与箭头建立关系,因为箭头只从一个节点的随机部分到另一个节点的另一个随机部分。 我拥有类似 UML 的图表的方式很好,但是关系箭头导致它不是我想要的,因为我希望箭头从一个节点的 特定 点到另一个特定点另一个节点。

我用来创建这个图表的 DOT 代码是这样的:

digraph G {

    fontname = "Bitstream Vera Sans"
    fontsize = 8

    node [
        fontname = "Bitstream Vera Sans"
        fontsize = 8
        shape = "record"
    ]

    edge [
        fontname = "Bitstream Vera Sans"
        fontsize = 8    
    ]

    Person [
        label = "{Person \l\l \ age : int\l \ livesIn : City \l \  \ \ sinceYear : int}"
    ] // \l -new line, \ -indentation

    City [
        label = "{City \l \ \ name : string}"
    ]

    Person -> City
}

我尝试通过在节点内使用水平线划分来解决这个问题,即使我不想要这些线。水平线的划分使我可以通过使用ports 使这种特定的关系成为可能,但它们也产生了自己的新问题。他们创造的问题是他们摆脱了我想要的并且在上图中有的缩进。我试图解决箭头问题的方法有效,但产生了新问题 - 缩进消失了,水平线分割无法隐藏

我用来创建这个图表的代码是:

digraph G {

    fontname = "Bitstream Vera Sans"
    fontsize = 8

    node [
        fontname = "Bitstream Vera Sans"
        fontsize = 8
        shape = "record"
        penwidth = 0.5 
    ]

    edge [
        fontname = "Bitstream Vera Sans"
        fontsize = 8    
    ]

    Person [
        label = "{<g0> Person | <g1> age : int | <g2> livesIn : City | <g3> sinceYear : int}"
    ] // \l -new line, \ -indentation

    City [
        label = "{<f0> City | <f1> name : string}"
    ]

    Person:<g2> -> City:<f1> [arrowhead = "empty", headlabel = "*"]
}

这些缩进是关系的重要组成部分,所以我想知道是否有人知道我可以做些什么来让这些缩进回到图表中,以及我可以做些什么来使水平线分割不可见?

如果有人有更好的方法/想法,这也与我在图 2 和图 3 中所做的完全不同,我将不胜感激,这将帮助我实现图 1。

【问题讨论】:

  • 由于您的声誉现在 >10,您应该添加图像并提供您的 graphviz 输入(或至少相关部分)。
  • 我冒昧地发布了原始海报在此问题中创建的重复问题中的图像。这应该会让事情变得更清楚很多

标签: graphviz image-graphviz


【解决方案1】:

您最初的尝试还不错。我会说使用端口绝对是要走的路。 如果您将节点放在集群中,您可以使用集群的边框并隐藏记录节点的边框,从而摆脱那些分隔线。

如您所述,使用反斜杠 \ 不再适用于转义空格。解决方法是改用&amp;#92;,这将转义空格。作为替代方案,您也可以用&amp;nnbsp; 替换每个空格。任何一种都能达到所需的效果。

我做了一些小改动以使内容更具可读性,例如将 Graph 属性放在 graph 块中而不是图的根中,并将端口名称重命名为更合理的名称。我还删除了所有未使用的端口。

我想出的最终结果是这样的:

...这是我使用的 DOT 代码:

digraph G {

    graph [
        compound = true     // To clip the head at the cluster border
        penwidth = 2        // Make the cluster's borders a bit thicker
        rankdir = "LR"      // Make the arrow and nodes go from Left to Right
        ranksep = 1         // Add a bit more space inbetween nodes
    ]

    node [
        color = none        // Hide the node's border
        fontname = "Bitstream Vera Sans"
        height = 0          // Make the node as small as possible (it will grow if it needs more space)
        margin = 0          // Remove unneeded whitespace
        shape = "record"    // So we can use ports
    ]

    edge [
        arrowhead = "open"
        labelangle = -5     // Place the asteriks closer to the line
        labeldistance = 2.5 // Place the asteriks further away from the arrow head
        penwidth = 2        // Make the line a bit thicker
    ]

    /* @NOTE: escaping spaces in the label using '\' doesn't work so use '&nbsp' or '&#92' instead. */
    subgraph cluster_Person {
        Person [
            label = "\N\l | &#92; &#92; &#92;  age : int\l | <livesIn> &#92; &#92; &#92;  livesIn : City\l | &#92; &#92; &#92; &#92; &#92; &#92;  sinceYear : int\l"
        ]
    }

    subgraph cluster_City {
        City [
            label = "<city> \N\l | &#92; &#92; &#92;  name : string\l"
        ]
    }

    Person:livesIn -> City:city [headlabel = "*", lhead = "cluster_City"] // lhead allows us to point to the cluster's border instead of the node, as long as we add `compound = true` to the graph
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    • 1970-01-01
    相关资源
    最近更新 更多