【问题标题】:subgraph cluster ranking in dot点中的子图聚类排名
【发布时间】:2015-03-04 21:50:07
【问题描述】:

我正在尝试将 media wiki 上的 graphviz 用作软件的文档工具。

首先,我记录了一些运行良好的类关系。一切都按预期垂直排列。

但是,我们的一些模块是 dll,我想将它们分成一个盒子。当我将节点添加到集群时,它们变得边缘化,但集群似乎具有 LR 排名规则。或者被添加到集群会破坏节点的 TB 排名,因为集群现在出现在图表的一侧。

此图表示我正在尝试做的事情:目前,cluster1 和 cluster2 出现在 cluster0 的 右侧

我希望/需要它们出现在下方。

<graphviz>
digraph d {
    subgraph cluster0 {
      A -> {B1 B2}
      B2 -> {C1 C2 C3}
      C1 -> D;
    }
    subgraph cluster1 {
      C2 -> dll1_A;
      dll1_A -> B1;
    }
    subgraph cluster2 { 
      C3 -> dll2_A;
    }
    dll1_A -> dll2_A;
}
</graphviz>

【问题讨论】:

    标签: graphviz dot


    【解决方案1】:

    布局是 Dot 尝试最小化整体高度的一种尝试。

    比所需布局更紧凑的一个原因是使用了从 dll1_aB1 的反向边缘。它尝试将集群拉回尽可能靠近目标节点的位置。为了避免这条边影响图形,要么如图所示放松向上边上的约束,或者在向前方向绘制边并使用dir属性来反转箭头.

    这将有助于许多布局,但仅靠它不足以修复给出的示例。为了防止 Dot 保持它喜欢的紧凑布局,您可以将 minlen 属性添加到应保持(接近)垂直的边缘。这通常可能难以计算,但对于手动调整的布局很实用。

    digraph d {
        subgraph cluster0 {
            A -> {B1 B2}    
            B2 -> {C1 C2 C3}
            C1 -> D;
        }
        subgraph cluster1 {
            C2 -> dll1_A [minlen = 2];
            dll1_A -> B1 [constraint = false];
            /* B1 -> dll1_A [dir = back]; */
        }
        subgraph cluster2 {
            C3 -> dll2_A;
        }
        dll1_A -> dll2_A;
    }
    

    【讨论】:

    • 这对我来说效果很好。关于自动化的评论:如果您的问题涉及结构(在我的情况下是控制流图),其中某些边缘可以被识别为“向后”(从循环出口到入口),那么使用constraint = false 自动标记这些边缘可以解决问题。更一般地,可以根据图的 BFS 或 DFS 树计算一组后向边(假设选择了一个根节点)。
    • @johntex 通常constraint = false 按预期工作。但是,有时,如果反向意图dir = back 更清晰,则已经受约束的图会导致布局不那么令人惊讶。当节点有许多边可能会在层次结构中向上或向下拉节点时,这一点尤其明显。
    【解决方案2】:

    我的经验表明constraint=false 通常会产生不必要的复杂边缘。似乎weight=0 给出了更好的结果:

    digraph d {
        subgraph cluster0 {
            A -> {B1 B2}    
            B2 -> {C1 C2 C3}
            C1 -> D;
        }
        subgraph cluster1 {
            C2 -> dll1_A [minlen = 2];
            dll1_A -> B1 [weight = 0];
            /* B1 -> dll1_A [dir = back]; */
        }
        subgraph cluster2 {
            C3 -> dll2_A;
        }
        dll1_A -> dll2_A;
    }
    

    【讨论】:

      【解决方案3】:

      这将产生您正在寻找的图表:

      digraph d {
        subgraph cluster0 {
          A -> {B1 B2}
          B2 -> {C1 C2 C3}
          C1 -> D;
        }
      
        subgraph {
          rankdir="TB"
          subgraph cluster1 {
            C2 -> dll1_A;
            dll1_A -> B1;
          }
      
          subgraph cluster2 {
            C3 -> dll2_A;
          }
        }
        dll1_A -> dll2_A;
      }
      

      这样做是创建一个仅用于布局目的的子图,以提供您想要的从上到下的顺序。

      【讨论】:

      • 抱歉,我误解了作为问题的一部分给出的图表,并认为它是您要寻找的目标,而不是您得到的。
      猜你喜欢
      • 2020-02-14
      • 2021-04-09
      • 1970-01-01
      • 2014-08-24
      • 1970-01-01
      • 1970-01-01
      • 2012-06-01
      • 2017-08-28
      • 2021-05-01
      相关资源
      最近更新 更多