【问题标题】:Forcing the edge between subgraphs to go left or right强制子图之间的边向左或向右
【发布时间】:2021-06-24 12:07:59
【问题描述】:

我有一个 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=sameordering=outinvis 以某种方式将它转过来,但我希望它是程序化的。有没有什么简单的方法可以把代表0的红色虚线画在代表1的实线的左边而不是右边?

【问题讨论】:

  • 您是在问如何以编程方式将“Tree 1”置于“Tree 0”的左侧?
  • 是的,这就是我想要的。这样字母顺序就可以了。在 ASCII 中,所有字母的第 4 个 MSB 为 0 表示树 1,1 表示树 0。
  • 您是如何使用 rank=same、ordering=out 和 invis 做到这一点的?
  • 我想我可以向后画,“branch1_0 -> branch0_0 [lhead = cluster_tree1, ltail = cluster_tree0, color = firebrick, style = dashed, dir = back];”它会以正确的方式对它们进行排序,但垂直间距错误;很难预测。我尝试了很多东西。

标签: graphviz trie dot subgraph


【解决方案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 -Tpng 固定文件 >fixed.png
(糟糕,但它有效)

f=atrie4.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 

【讨论】:

  • 这真是太棒了。为什么neato -n2 以及为什么关闭样条线会有帮助?
  • 样条设置没有区别,它是从(失败的)实验中遗留下来的。这(graphviz.org/faq/#FaqDotWithNodeCoords)解释了neato -n(或neato -n2)。 -n2 不是必需的,但是当我喜欢边缘不规则时,为什么要重新计算边缘。最终布局再次没有区别。
猜你喜欢
  • 1970-01-01
  • 2016-06-22
  • 2011-03-29
  • 1970-01-01
  • 1970-01-01
  • 2013-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多