如何控制graphviz中节点的位置(即避免边交叉)

51

我正在使用graphviz(dot)生成您下面所看到的图形。左下角的节点(红色椭圆形)会导致困扰,因为它的边缘穿过相邻节点的多条边。有没有办法限制节点的放置在某个特定区域内?

交叉多条边的图形

5个回答

64

你可以创建一个不可见的约束条件,使得红色节点似乎位于所有其他节点的左侧。

redNode -> leftmostNode [style=invis];

之前:

before

之后:

after


2
这解决了我的问题。我只想让某些东西出现在另一些东西的另一侧。谢谢。 - Derrick Petzold

34

我喜欢@smokris的" [style=invis] "技巧,可以说服graphviz将节点放置在你想要的位置上,通过添加会影响布局但不可见的边。


另一个技巧是使用constraint属性,它允许您添加可见但不影响布局的边。

如果添加一个新的边会破坏您的图形,请在该边上设置[constraint=false]:现在graphviz将忽略它在放置节点时。

如果 false,则该边不用于排名节点。例如,在图中

digraph G {
    a -> c;
    a -> b;
    b -> c [constraint=false];  
}

边缘 b -> c 在排名分配过程中不会添加约束条件,因此唯一的约束条件是 a 必须在 b 和 c 上方,得出以下图形:


31

实际上有一种方法可以控制单个节点的位置 - 使用“pos”属性:

http://www.graphviz.org/doc/info/attrs.html#d:pos

例如,你可以编写以下内容:

n [pos="3,5!"];

这将会使得节点 n 位于精确的位置 (3,5)

然而,这只适用于布局引擎 "fdp" 和 "neato"。


23
“pin”属性仅适用于“fdp”和“neato”,不支持“dot”。因此,在使用“dot”时,如果不绕过“dot”布局引擎,使用“pos”是毫无意义的。请注意,其中的感叹号表示强调。 - Brent Bradburn
1
@nobar:嗯,再次查看文档,似乎你是对的——我的错,抱歉。 - Stuart Golodetz
1
我注意到感叹号在fdp中也不起作用,尽管它在neato中有效。此外,“-s”参数应该管理“pos”属性中给定的坐标的缩放(默认为72.0),但似乎不起作用(它会导致段错误)。总之:将“pos”属性的所有数字除以72.0并使用“neato”即可解决问题! - peschü

10

我不知道有什么方法可以控制单个节点的位置。这样做没有意义,因为要想这样做,您需要知道最终图形的样子,但是手动放置一个节点会改变其余节点的呈现方式。

我通过更改在.dot文件中定义节点的顺序,并调整图形级别的nodesepranksep属性来解决了这个问题。这是一个精细的过程-一次改变几个东西,直到看起来正确为止。

您还可以将图形渲染为SVG,然后将其导入Visio(或其他编辑器)并手动重新排列不满意的节点。


2
我认为Visio不能编辑通用的SVG,但Inkscape可以。 - Gringo Suave
1
@GringoSuave:Inkscape确实可以,但如果您移动节点,则边缘不会跟随。这使得它除了非常少的节点之外,对其他任何东西都不实用。 - Trygve Flathen
3
这个答案是不正确的,不应该被接受。下面有两个回答分别获得了30和20票,它们都可以成为很好的被接受的答案。 - Noah Sussman

0

如果您使用neato和-n2参数,则可以放置节点:

`dot -T ${format} -n2 -Goverlap-true -Gsplines=false -Kneato -o ${ output } ${ input }`

例如

dot -T png -n2 -Goverlap-true -Gsplines=false -Kneato -o monkey.png monkey.dot

neato 期望以点(即英寸的1/72)为单位,将所有物体从左下角定位。

以下 dot 文件根据指定放置所有物体,但有一个小烦恼,即位置始终是对象的中心。

digraph G {
    overlap=true
    bgcolor="transparent"
    node [

        shape=box   
        width=1.2
        height=1.2
        fillcolor="#e9e9e9"
        fontcolor="#333333"
        fontsize=18
        style="filled"
        color="#aaaaaa"
    ];

    edge [
        penwidth=2  
        fontsize=18
        margin=0.01
        labelfloat=true
        fontcolor="#333333"
        color="#bbbbbb"
    ];

d [pos="864,2016!" ] [label="D" ]  [width=16  height=16]



subgraph x {

    node [color="#886600" fillcolor="#dd9944"]

    A [pos="1440,1440!" ] 

    c [pos="864,2016!" ] [label="C" ] 

        A -> c 

    monkey [pos="1008,1872!" ] [label="HI MONKEY" ] 

    A -> c  [label="THIS WAY" ]  [ pos="s,1440,1483 e,907,2016 1440,1488 1440,1856 1280,2016 912,2016" ][ lp="1360, 1936 " ] 

}

F [pos="576,1440!" ] 

up_left [pos="72,2808!"][label="" height=1 width=1 penwidth=0 color="red"]  down_right [pos="2808,72!"] [label="" height=1 width=1 fillcolor="red" penwidth=0 color="red"]

}


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