首页 > 解决方案 > fdp/graphviz:即使有强制位置,行开头的垂直错位

问题描述

我正在探索使用 fdp 来做基于网格(行和列)的图表,使用 fdp 和强制位置。但令我惊讶的是,强制的立场有时仍然只是建议,并没有真正强制执行。我想知道如何使用 graphviz、一些布局引擎和一些参数组合来完全强制执行这些位置?

这是我的发现的说明:(我正在使用 emacs/org-mode/graphviz 代码块来生成图表)

案例1:单列,完美对齐:

#+begin_src dot :file ./column1.png :cmdline -Kfdp -Tpng
graph dfd {
node[shape=box]
"(0.0, 0.0)" [pos="0.0, 0.0!"]
"(0.0, 0.1)" [pos="0.0, 0.1!"]
"(0.0, 0.2)" [pos="0.0, 0.2!"]
"(0.0, 0.3)" [pos="0.0, 0.3!"]
}
#+end_src

结果: 在此处输入图像描述

案例2:2列:甚至第一列也不再对齐

#+begin_src dot :file ./column2.png :cmdline -Kfdp -Tpng
graph dfd {
node[shape=box]
"(0.0, 0.0)" [pos="0.0, 0.0!"]; "(0.1, 0.0)" [pos="0.1, 0.0!"]
"(0.0, 0.1)" [pos="0.0, 0.1!"]; "(0.1, 0.1)" [pos="0.1, 0.1!"]
"(0.0, 0.2)" [pos="0.0, 0.2!"]; "(0.1, 0.2)" [pos="0.1, 0.2!"]
"(0.0, 0.3)" [pos="0.0, 0.3!"]; "(0.1, 0.3)" [pos="0.1, 0.3!"]
}
#+end_src

结果: 在此处输入图像描述

我还发现列越多,错位越严重。我发现 fdp 的布局算法在某种程度上具有弹性以避免重叠,但我仍然不明白第一列,应该没有任何重叠。

标签: graphviz

解决方案


好吧,我不确定是否graphviz真的是您想要实现的目标的首选工具。但是由于我不知道,这里有一些可以帮助您前进的信息:

dot以分层方式排列您定义的节点,这取决于它们的定义顺序、边的方向以及rank = same同一分层级别上节点的特定指令。dot根据标签自动设置节点的宽度和高度,所以如果你的标签有不同的长度,你需要考虑到这一点。

一个非常基本的示例:

digraph so 
{
    // default/initial node style
    node[ shape = box, width = 2, height = 1.5 ];
    // default/initial edge style
    edge[ style = invis ];

    {rank = same; a1 -> a2 -> a3 -> a4 }
    {rank = same; b1 -> b2 -> b3 -> b4 }
    {rank = same; c1 -> c2 -> c3 -> c4 }
    {rank = same; d1 -> d2 -> d3 -> d4 }
    a1 -> b1 -> c1 -> d1;  

    a1[ label = "bla" ];
    c1[ label = "long label\nwith new line" ];

}

这给了你

在此处输入图像描述

在这个简单的例子中,rank = same指令并不是真正需要的,你可以用

a1 -> b1 -> c1 -> d1;
a2 -> b2 -> c2 -> d2;
a3 -> b3 -> c3 -> d3;
a4 -> b4 -> c4 -> d4;

但是你的结构越精细,明确的排名就越有帮助。


推荐阅读