Graphviz中的集群不会对称地排列间距

4
我正在尝试在Graphviz中使多个节点集均匀分布。如下图所示,我认为图像最好地解释了我的意图:在第2层和第3层之间存在额外的间距。第2层和第3层之间的间隔应该与第1层和第2层之间的间隔相同。间距还需要随着超过3个层的节点而自适应调整。当我尝试使用超过3个层时,第4层的间距与第3层一样糟糕。以下是我的图形文件:
digraph G {
    nodesep=1.25;
    splines=false;

    node[width=1, shape=circle];
    edge[style=invis];

    subgraph cluster_1 {
        label="Layer 1";
        "1-1" -> "1-2" -> "1-3";
    }

    subgraph cluster_2 {
        label="Layer 2";
        "2-1" -> "2-2" -> "2-3";
    }

    subgraph cluster_3 {
        label="Layer 3";
        "3-1" -> "3-2" -> "3-3";
    }

    edge[style=solid, penwidth=1, constraint=false];

    "1-1" -> "2-1";
    "1-3" -> "2-1";

    "1-1" -> "2-2";
    "1-2" -> "2-2";

    "1-2" -> "2-3";
    "1-3" -> "2-3";

    "2-1" -> "3-1";
    "2-3" -> "3-1";

    "2-1" -> "3-2";
    "2-2" -> "3-2";

    "2-2" -> "3-3";
    "2-3" -> "3-3";

}

我该如何使我的间距对称?非常感谢您的帮助。谢谢。

更新: 我已经成功地使间距变得均匀,但这不是一个完美的解决方案。

通过在图形上方放置一个不可见节点,并将其连接到每层的顶部节点,可以使层次结构间距均匀。然而,这个节点会破坏需要添加到图像上方的内容的间距。所以,有没有更好的方法来解决这个问题呢?


我认为你在布局引擎中发现了一个错误。额外的空间出现在边缘 "x-3" -> "y-1" 与样条曲线环绕节点 "y-2" 的位置。 - stefan
@stefan 如果没有容器,布局引擎就没有理由假设等间距很重要(这并不是说它不应该被编程实现)。将聚类嵌套在另一个聚类中会导致布局引擎将它们等距离排列。请参见我的答案中的代码。 - ben rudgers
@benrudgers:使用或不使用“容器”都是一样的(指在编程中)。相等间距仅仅是巧合,外层集群中的大片白色空间明确显示了在确定内部图表大小方面存在问题。请参见我在下面对你答案的评论。 - stefan
1个回答

2

添加外部集群

正确排列的图像,显示了添加的外部集群的边界框 为了清晰起见,显示了外部集群的边界框

将集群cluster_1cluster_2cluster_3嵌套在另一个集群中会导致布局引擎将它们均匀地分开。

使用布局引擎

然而,从底部到顶部的rankdir将左到右的显示顺序反转为(cluster_3, cluster_2, cluster_1)。在源文件中反转顺序可以修复这个问题。

工作代码

digraph G {
  nodesep=1.25;
  splines=false;
  clusterrank=local;
  node[width=1, shape=circle];
  edge[style=invis];

  subgraph cluster_0 {

    subgraph cluster_3 {
      label="Layer 3";
      "3-1" -> "3-2" -> "3-3";
    }

    subgraph cluster_2 {
      label="Layer 2";
      "2-1" -> "2-2" -> "2-3";
    }

    subgraph cluster_1 {
      label="Layer 1";
      "1-1" -> "1-2" -> "1-3";
    }
  }

 edge[style=solid, penwidth=1, constraint=false];

 "1-1" -> "2-1";
 "1-3" -> "2-1";

 "1-1" -> "2-2";
 "1-2" -> "2-2";

  "1-2" -> "2-3";
  "1-3" -> "2-3";

  "2-1" -> {"3-1" "3-2"};
  "2-3" -> {"3-1" "3-3"};

  "2-2" -> {"3-2" "3-3"};

}

注释

新的外部集群可以进行样式设置,使其边界框不可见。


第一 - 外部集群会拉伸图形大小,这是不希望的行为。第二 - 在一个集群内部,没有任何集群的排序。在我的机器上(win7 64位; gv 2.38.0),你的例子给出了随机顺序的集群结果为123,像你的图片,321有两个大间距甚至是一个丑陋的231。 - stefan
@stefan 就像你的问题中所述,图形的大小是默认的。手册描述了如何控制其行为。这次我会让你自己阅读它。不用谢。 - ben rudgers
我并没有提出任何问题。我只是指出了为什么我认为你的解决方案不是解决方案。首先,你的外部集群会拉伸图形大小。我不是在谈论可见性,而是在谈论像素中的结果图像。如果我忽略了这个问题的解决方案,我会很高兴如果你能指出手册中的相关点,并为OP和所有其他读者发布一个可重现的解决方案。其次,你的“解决方案”表现出随机行为。请检查一下。除非这是特定于我的版本2.38.0的错误,否则我认为你的解决方案是错误的,并要求你重新绘制你的答案。 - stefan
我的解决方案是解决问题的最简单方法。它在Linux Ubuntu 15.04上始终有效。如果在Windows上出现问题,请向开发人员报告。如果问题与像素有关,请尝试输出到SVG。文档可通过Graphviz网站获得。对于我混淆您在问题中提出的问题,我感到抱歉。 - ben rudgers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接