我正在使用graphviz(dot)生成您下面所看到的图形。左下角的节点(红色椭圆形)会导致困扰,因为它的边缘穿过相邻节点的多条边。有没有办法限制节点的放置在某个特定区域内?
我正在使用graphviz(dot)生成您下面所看到的图形。左下角的节点(红色椭圆形)会导致困扰,因为它的边缘穿过相邻节点的多条边。有没有办法限制节点的放置在某个特定区域内?
你可以创建一个不可见的约束条件,使得红色节点似乎位于所有其他节点的左侧。
redNode -> leftmostNode [style=invis];
之前:
之后:
我喜欢@smokris的" [style=invis] "技巧,可以说服graphviz将节点放置在你想要的位置上,通过添加会影响布局但不可见的边。
另一个技巧是使用constraint
属性,它允许您添加可见但不影响布局的边。
如果添加一个新的边会破坏您的图形,请在该边上设置[constraint=false]
:现在graphviz将忽略它在放置节点时。
如果
false
,则该边不用于排名节点。例如,在图中
digraph G { a -> c; a -> b; b -> c [constraint=false]; }
边缘
b -> c
在排名分配过程中不会添加约束条件,因此唯一的约束条件是 a 必须在 b 和 c 上方,得出以下图形:
实际上有一种方法可以控制单个节点的位置 - 使用“pos”属性:
http://www.graphviz.org/doc/info/attrs.html#d:pos
例如,你可以编写以下内容:
n [pos="3,5!"];
这将会使得节点 n
位于精确的位置 (3,5)
。
然而,这只适用于布局引擎 "fdp" 和 "neato"。
我不知道有什么方法可以控制单个节点的位置。这样做没有意义,因为要想这样做,您需要知道最终图形的样子,但是手动放置一个节点会改变其余节点的呈现方式。
我通过更改在.dot
文件中定义节点的顺序,并调整图形级别的nodesep
和ranksep
属性来解决了这个问题。这是一个精细的过程-一次改变几个东西,直到看起来正确为止。
您还可以将图形渲染为SVG
,然后将其导入Visio(或其他编辑器)并手动重新排列不满意的节点。
如果您使用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"]
}