2013-05-27 64 views
8

我有一个随时间变化的图形(通常是添加新节点)。我需要多次重新生成图表,并且希望所有节点都保持在原来的位置。将graphviz与fdp算法一起使用,设置pin -flag并使用pos参数指定位置时,这部分工作。强制graphviz保存节点位置

在大多数情况下,这项工作非常好。但是特别是当添加新节点时,布局有时会发生巨大变化 - 这是我需要避免的。有没有一个选项,实际上这些固定位置?这可能会导致一个丑陋的图表,这将是好的 - 但他们只需要坚持。

回答

14

的Graphviz不会使它容易保持化整为零在相同的位置:

  • 添加/删除节点可能会导致完全不同的布局。
  • 添加/删除节点可以更改边界框的尺寸以进行更改。

如果在创建图形时所有节点都知道以下工作:

  • 创建一个包含所有可能节点的图,让graphviz的摊开来。您可以在图表的开头添加nodes[pin=true];(以后您不必再添加它)。
  • 布局图:

    fdp -Tdot input.gv -o input.pos.gv 
    

    您现在有一个包含所有节点一个点文件。您可以将此用作要创建的所有图形的基本文件:

  • 对于每个图,创建一个input.pos.gv的副本,并通过将style=invis添加到其属性中来隐藏不需要的节点和边。这确保它们不被显示,但是它们在布局中使用的位置将不会被剪掉(例如,如果在图的最上方)。
  • 布置它们使用这样的事情(neato和期权-n2是重要组成部分):

    neato -n2 -Tpng input.pos.v1.gv -o output.v1.png 
    

例子:

input.gv:

digraph g{ 
    node[pin=true]; 
    a -> b; 
    a -> c; 
    b -> d; 
    b -> e; 
    b -> f; 
    c -> g; 
} 

input.pos.modified.gv:

digraph g { 
    node [label="\N", pin=true]; 
    graph [bb="0,0,187,207"]; 
    a [pos="60.846,70.555", width="0.75", height="0.5", style=invis]; 
    b [pos="94.351,128.04", width="0.75", height="0.5"]; 
    c [pos="76.868,18.459", width="0.75", height="0.5"]; 
    d [pos="119.08,188.8", width="0.75", height="0.5",style=invis]; 
    e [pos="157.97,106.75", width="0.75", height="0.5"]; 
    f [pos="27.319,158.05", width="0.75", height="0.5"]; 
    g [pos="160.1,20.585", width="0.75", height="0.5"]; 
    a -> b [pos="e,84.434,111.03 70.717,87.493 73.42,92.13 76.411,97.263 79.332,102.27", style=invis]; 
    a -> c [pos="e,71.34,36.433 66.27,52.918 66.934,50.759 67.624,48.514 68.32,46.252", style=invis]; 
    b -> d [pos="e,111.86,171.05 101.5,145.62 103.54,150.61 105.8,156.17 108.01,161.59", style=invis]; 
    b -> e [pos="e,133.72,114.86 118.76,119.87 120.45,119.31 122.17,118.73 123.89,118.16"]; 
    b -> f [pos="e,49.99,147.9 71.657,138.2 67.726,139.96 63.572,141.82 59.447,143.67"]; 
    c -> g [pos="e,133.07,19.895 104.12,19.155 110.07,19.307 116.47,19.471 122.74,19.631"]; 
} 

输入。PNG无需修改:

output.png

隐藏节点:

output with invisible nodes

+0

非常感谢您的回答!不幸的是,我一开始并不知道所有节点。一些背景信息:我正在形象化一个物理网络,它可以随时改变(新的,以前未知的节点被添加,连接改变,...)。而且由于最终用户可以移动节点并创建自己的布局,所以一旦执行更新,它就不应该完全改变。所以这不能用graphviz来完成?如果没有,是否有其他选择?我一直在寻找年龄...... – Remo

+0

我也在考虑创建子图或创建单独的图并将它们组合在一起。这可能吗?我没有要求新节点很好地适应......它们可以放置在所有现有节点之外,并且连接可以重叠,如果需要的话。 – Remo

+0

使用'pin'和'pos',您可以尝试为新节点添加默认(或随机)的'pos'值。我想我记得在某个地方看过,为了拥有固定的节点位置,所有的节点都必须有'pos'属性(不知道边缘)。 – marapet