在graphviz中设计类UML图的问题

在graphviz中设计类UML图的问题,graphviz,image-graphviz,Graphviz,Image Graphviz,我目前在graphiz上设计类似UML的图表时遇到了问题。问题的原因是它们并不完全是UML图。主要区别在于,我使用缩进将层次结构添加到对象的属性中。实现这些特质对我来说有点困难。我试图实现的是: 我通常使用名为record的节点形状来设计这些图。当我必须像UML中的关系一样链接两个类似UML的图时,问题就出现了,即聚合、关联、组合等 当我有图表时,我无法建立与箭头的关系,因为箭头只从一个节点的随机部分指向另一个节点的随机部分。 我拥有类似UML的图表的方式很好,但是关系箭头导致它不是我想要的,

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

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

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

我用于创建此图形的点代码如下所示:

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
}
我试图通过在节点内使用水平线分割来解决这个问题,尽管我不想要线。水平线划分使我能够通过使用使这种特定关系成为可能,但它们本身也产生了一个新问题。它们产生的问题是,它们去掉了我想要的和在上一张图中出现的缩进。我试图绕过箭头问题的方法是有效的,但是新的问题产生了——缩进消失了,水平线分割无法被隐藏

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

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 = "*"]
}
有向图G{
fontname=“Bitstream Vera Sans”
字体大小=8
节点[
fontname=“Bitstream Vera Sans”
字体大小=8
shape=“记录”
笔宽=0.5
]
边缘[
fontname=“Bitstream Vera Sans”
字体大小=8
]
人[
label=“{Person | age:int | livesIn:City | sinceYear:int}”
]//\l-新行,\-缩进
城市[
label=“{City | name:string}”
]
人员:->城市:[arrowhead=“empty”,headerbel=“*”]
}
这些缩进是关系的重要组成部分,所以我想知道是否有人知道我可以做什么让这些缩进回到图表中,以及我可以做什么使水平线分割不可见


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

您最初的尝试还不错。我想说,使用端口绝对是一种方式。 如果将节点放置在集群中,则可以使用集群的边框并隐藏记录节点的边框,从而去掉那些分隔线

正如您所注意到的,使用反斜杠
\
不再用于转义空格。解决方法是使用
和#92替换每个空格&nnbsp。任何一个都能达到要求的效果

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

我得出的最终结果是:

…这是我使用的点代码:

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
}
有向图G{
图表[
composite=true//在簇边界处剪裁头部
penwidth=2//使簇的边界稍厚一点
rankdir=“LR”//使箭头和节点从左向右移动
ranksep=1//在节点之间添加多一点空间
]
节点[
color=none//隐藏节点的边框
fontname=“Bitstream Vera Sans”
高度=0//使节点尽可能小(如果需要更多空间,它将增长)
margin=0//删除不需要的空白
shape=“record”//这样我们就可以使用端口了
]
边缘[
箭头=“打开”
labelangle=-5//将星号放在离直线较近的位置
labeldistance=2.5//将星号放置在离箭头更远的位置
penwidth=2//将线条加粗一点
]
/*@注意:标签中使用“\”转义空格不起作用,因此请使用“\”或“\”*/
子图簇{
人[
label=“\N\l |和#92;\;\;年龄:国际&\;\;生活地点:城市\;\;\;\;&\;\;\;自年起:国际&”
]
}
子图簇{
城市[
label=“\N\l |\;\;\;名称:string\l”
]
}
Person:livesIn->City:City[headbel=“*”,lhead=“cluster\u City”]//lhead允许我们指向集群的边界而不是节点,只要我们在图中添加'component=true'
}

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