【问题标题】:Force graphviz to preserve node positions强制graphviz保留节点位置
【发布时间】:2013-05-27 15:00:22
【问题描述】:

我有一个随时间变化的图表(通常会添加新节点)。我需要多次重新生成图表,并希望所有节点都保持在原来的位置。这在使用带有fdp-算法的graphviz、设置pin-标志并使用pos-参数指定位置时部分有效。

在大多数情况下,这很有效。但特别是当添加新节点时,布局有时会发生巨大变化——我需要避免这种情况。是否有一个选项可以真正强制这些固定位置?它可能会导致一个丑陋的图表,这没关系 - 但他们只需要坚持。

【问题讨论】:

    标签: nodes graphviz sticky


    【解决方案1】:

    Graphviz 并不容易将 noes 保持在同一位置:

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

    如果在创建图形时所有节点都已知,则以下方法有效:

    • 创建一个包含所有个可能节点的图,然后让 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
      

    例子:

    输入.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"];
    }
    

    input.png 未经修改:

    隐藏节点:

    【讨论】:

    • 非常感谢您的回答!不幸的是,我一开始并不知道所有节点。一些背景信息:我正在可视化一个物理网络,它可以随时更改(添加了新的、以前未知的节点,连接发生了变化……)。而且由于最终用户可以移动节点并创建自己的布局,因此一旦执行更新,它不应该完全改变。所以这不能用graphviz来完成吗?如果没有,是否有替代方案?我一直在寻找年龄......
    • 我也在考虑创建子图或创建单独的图并将它们组合起来。会有这种可能吗?我不要求新节点很好地适应...它们可以放置在所有现有节点之外,并且如果需要,连接可以重叠。
    • 使用pinpos,您可以尝试为新节点添加默认(或随机)pos 值。我想我记得在某处读过,为了有固定的节点位置,所有节点 必须 有一个 pos 属性(不知道边缘)。
    猜你喜欢
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    相关资源
    最近更新 更多