Graphviz 强制子图之间的边向左或向右移动

Graphviz 强制子图之间的边向左或向右移动,graphviz,trie,dot,subgraph,Graphviz,Trie,Dot,Subgraph,我有一个PATRICA trie,我正在为它生成一个GraphViz文件。内部节点为跳过值,边为虚线0和实线1。最好0在1的左边,按字母顺序排列叶子。我重新安排了访问图表的顺序,因此dot给出了这个结果。然而,当我使用子图将它们分组到森林中的树中时,我似乎无法强制dot可靠地遵守子图间边的顺序 digraph { rankdir=TB; node [shape = box, style = filled, fillcolor = lightsteelblue]; // f

我有一个PATRICA trie,我正在为它生成一个GraphViz文件。内部节点为跳过值,边为虚线0和实线1。最好0在1的左边,按字母顺序排列叶子。我重新安排了访问图表的顺序,因此
dot
给出了这个结果。然而,当我使用子图将它们分组到森林中的树中时,我似乎无法强制
dot
可靠地遵守子图间边的顺序

digraph {
    rankdir=TB;
    node [shape = box, style = filled, fillcolor = lightsteelblue];
    // forest size 2.

    subgraph cluster_tree0 {
        style = filled; fillcolor = lightgray; label = "tree 0";
        // branches
        branch0_0 [label = "3", shape = none, fillcolor = none];
        branch0_0 -> branch0_1;
        branch0_1 [label = "0", shape = none, fillcolor = none];
        branch0_1 -> branch0_2 [style = dashed];
        branch0_2 [label = "1", shape = none, fillcolor = none];
        branch0_2 -> leaf0_1 [style = dashed, color = royalblue];
        branch0_2 -> leaf0_2 [color = royalblue];
        branch0_1 -> branch0_3;
        branch0_3 [label = "2", shape = none, fillcolor = none];
        branch0_3 -> leaf0_3 [style = dashed, color = royalblue];
        branch0_3 -> leaf0_4 [color = royalblue];
        // leaves
        leaf0_1 [label = "u"];
        leaf0_2 [label = "v"];
        leaf0_3 [label = "x"];
        leaf0_4 [label = "y"];
    }
    branch0_0 -> branch1_0 [lhead = cluster_tree0, ltail = cluster_tree1, color = firebrick, style = dashed];

    subgraph cluster_tree1 {
        style = filled; fillcolor = lightgray; label = "tree 1";
        // branches
        branch1_0 [label = "0", shape = none, fillcolor = none];
        branch1_0 -> leaf1_0 [style = dashed, color = royalblue];
        branch1_0 -> branch1_1;
        branch1_1 [label = "1", shape = none, fillcolor = none];
        branch1_1 -> leaf1_1 [style = dashed, color = royalblue];
        branch1_1 -> branch1_2;
        branch1_2 [label = "0", shape = none, fillcolor = none];
        branch1_2 -> leaf1_2 [style = dashed, color = royalblue];
        branch1_2 -> leaf1_3 [color = royalblue];
        // leaves
        leaf1_0 [label = "f"];
        leaf1_1 [label = "m"];
        leaf1_2 [label = "n"];
        leaf1_3 [label = "o"];
    }

}
在一个图上,它工作得很好,但它的子图的顺序与我想要的相反

我颠倒了文件中的顺序,但看起来还是一样。我玩过它,我可以通过
rank=same
ordering=out
,以及
invi
来扭转它,但我希望它是编程的。有没有什么简单的方法可以将代表0的红色虚线画在代表1的实线的左边而不是右边?

好吧,完全是胡扯,但可能完全可以编写脚本

首先,您的输入有点重复:

digraph {
    rankdir=TB;
    newrank=true  // helps
    graph [splines=false]
    node [shape = box, style = filled, fillcolor = lightsteelblue];
    // forest size 2.

    subgraph cluster_tree1 {
        style = filled; fillcolor = lightgray; label = "tree 1";
        // branches
        branch1_0 [label = "0", shape = none, fillcolor = none];
        branch1_0 -> leaf1_0 [style = dashed, color = royalblue];
        branch1_0 -> branch1_1;
        branch1_1 [label = "1", shape = none, fillcolor = none];
        branch1_1 -> leaf1_1 [style = dashed, color = royalblue];
        branch1_1 -> branch1_2;
        branch1_2 [label = "0", shape = none, fillcolor = none];
        branch1_2 -> leaf1_2 [style = dashed, color = royalblue];
        branch1_2 -> leaf1_3 [color = royalblue];
        // leaves
        leaf1_0 [label = "f"];
        leaf1_1 [label = "m"];
        leaf1_2 [label = "n"];
        leaf1_3 [label = "o"];
    }
  subgraph cluster_tree0 {
        style = filled; fillcolor = lightgray; label = "tree 0";
        // branches
        branch0_0 [label = "3", shape = none, fillcolor = none];
        branch0_0 -> branch0_1;
        branch0_1 [label = "0", shape = none, fillcolor = none];
        branch0_1 -> branch0_2 [style = dashed];
        branch0_2 [label = "1", shape = none, fillcolor = none];
        branch0_2 -> leaf0_1 [style = dashed, color = royalblue];
        branch0_2 -> leaf0_2 [color = royalblue];
        branch0_1 -> branch0_3;
        branch0_3 [label = "2", shape = none, fillcolor = none];
        branch0_3 -> leaf0_3 [style = dashed, color = royalblue];
        branch0_3 -> leaf0_4 [color = royalblue];
        // leaves
        leaf0_1 [label = "u"];
        leaf0_2 [label = "v"];
        leaf0_3 [label = "x"];
        leaf0_4 [label = "y"];
    }
    // position the clusters (trees)
    {rank=same    branch1_0 ->  branch0_1 [style=invis weight=0]} 
  
     // a kludge, we'll add this edge in later
     graph [comment="branch0_0 -> branch1_0 [color = firebrick, style = dashed  constraint=false weight=0 ];"]
}
“问题”是集群到集群的分支,因此我们将其删除(对于第一次点传递)。然后我们添加不可见边,将簇定位到需要的位置。
将此输入运行到dot-Tdot>myfile.dot中。这将设置所有节点和边的位置。
通过gawk(任何语言)运行该命令,取消对已注释分支的注释,并将其插入到文件中。
最后,neato-n2-tpngfixedfile>fixed.png
(不舒服,但它能工作)

f=4.gv

T=png; F=`basename $f .gv`;dot -Tdot $f >$F.dot;
gawk '
$1~/comment/{
  sub(/[\t ]*comment="/,"")
  sub(/"[\],;]?[\t ]*$/,"")
  add[++a]=$0
  next
}
{oline[++o]=$0}
END{
  for (i=1;i<o;i++)print oline[i]
  for (i=1;i<=a;i++)print add[i]
  print oline[o]
}' $F.dot|
neato -n2 -Tpng >$F.$T
firefox $F.$T 
T=png;F=`basename$F.gv`;dot-Tdot$f>$f.dot;
呆呆的
$1~/评论/{
sub(/[\t]*comment=“/,”)
子(/“[\],;]?[\t]*$/,”)
添加[++a]=$0
下一个
}
{oline[++o]=$0}
结束{

对于(i=1;我问你如何通过编程将“Tree 1”放在“Tree 0”的左边?是的,这就是我想要的。这样字母就按顺序排列。在ASCII中,所有字母中的第四个MSB是0表示树1,1表示树0。你是如何使用rank=same、ordering=out和invi的?我想我可以向后绘制它,“branch1\u 0->branch0\u 0”[lhead=cluster_tree1,ltail=cluster_tree0,color=firebrick,style=虚线,dir=back];”它会以正确的方式排列,但垂直间距错误;这很难预测。我尝试了很多东西。这真是太神奇了。为什么
neato-n2
以及为什么关闭样条线会有帮助?样条线设置没有什么区别,它是一个(失败的)实验遗留下来的。这()解释了
neato-n
(或
neato-n2
)。
-n2
不是必需的,但是当我喜欢点外的边时,为什么要重新计算边呢?最终布局也没有区别。