GraphViz - 如何连接子图?

Win*_*ith 152 graphics directed-graph dot graphviz subgraph

DOT语言中GraphViz,我试图表示一个依赖关系图.我需要能够在容器内部拥有节点,并且能够使节点和/或容器依赖于其他节点和/或容器.

subgraph用来代表我的容器.节点链接工作正常,但我无法弄清楚如何连接子图.

鉴于下面的程序,我需要能够连接cluster_1cluster_2使用箭头,但我尝试过的任何东西都会创建新节点而不是连接集群:

digraph G {

    graph [fontsize=10 fontname="Verdana"];
    node [shape=record fontsize=10 fontname="Verdana"];

    subgraph cluster_0 {
        node [style=filled];
        "Item 1" "Item 2";
        label = "Container A";
        color=blue;
    }

    subgraph cluster_1 {
        node [style=filled];
        "Item 3" "Item 4";
        label = "Container B";
        color=blue;
    }

    subgraph cluster_2 {
        node [style=filled];
        "Item 5" "Item 6";
        label = "Container C";
        color=blue;
    }

    // Renders fine
    "Item 1" -> "Item 2";
    "Item 2" -> "Item 3";

    // Both of these create new nodes
    cluster_1 -> cluster_2;
    "Container A" -> "Container C";
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Hig*_*ark 169

DOT用户手册给出了以下具有簇之间具有边缘的簇的图的示例

digraph G {
  compound=true;
  subgraph cluster0 {
    a -> b;
    a -> c;
    b -> d;
    c -> d;
  }
  subgraph cluster1 {
    e -> g;
    e -> f;
  }
  b -> f [lhead=cluster1];
  d -> e;
  c -> g [ltail=cluster0,lhead=cluster1];
  c -> e [ltail=cluster0];
  d -> h;
}
Run Code Online (Sandbox Code Playgroud)

节点和集群之间的边缘.

在此输入图像描述

  • @Winston史密斯:老问题,但是我遇到了类似的问题并且每个集群都有一个看不见的虚拟节点解决了它,即使集群是空的也可以链接到它.`DUMMY_0 [shape = point style = invis]` (53认同)
  • 谢谢 - 这是有效的,但它真的感觉像一个丑陋的黑客.我希望**我没有一个我没有节点的容器的场景. (13认同)
  • 如果有人感兴趣,如果你有标签链接(边缘),这可能会导致定位问题.虽然边缘的头部或尾部可能隐藏在群集下方,但标签仍然位于中点,这意味着某些边缘标签看起来漂浮在群集上而不是由边缘本身定位. (5认同)
  • 当使用仅垂直连接的群集时,我发现群集之间的边缘折叠为仅箭头。我用[minlen](http://www.graphviz.org/doc/info/attrs.html#d:minlen)= 1修正了该问题。c-> g [ltail = cluster0,lhead = cluster1,minlen = 1]; (2认同)
  • 以下是带有示例的手册链接:http://graphviz.org/Documentation/dotguide.pdf(第30页)。 (2认同)

Jon*_*ley 85

为便于参考,HighPerformanceMark答案中描述的解决方案直接应用于原始问题,如下所示:

digraph G {

    graph [fontsize=10 fontname="Verdana" compound=true];
    node [shape=record fontsize=10 fontname="Verdana"];

    subgraph cluster_0 {
        node [style=filled];
        "Item 1" "Item 2";
        label = "Container A";
        color=blue;
    }

    subgraph cluster_1 {
        node [style=filled];
        "Item 3" "Item 4";
        label = "Container B";
        color=blue;
    }

    subgraph cluster_2 {
        node [style=filled];
        "Item 5" "Item 6";
        label = "Container C";
        color=blue;
    }

    // Edges between nodes render fine
    "Item 1" -> "Item 2";
    "Item 2" -> "Item 3";

    // Edges that directly connect one cluster to another
    "Item 1" -> "Item 3" [ltail=cluster_0 lhead=cluster_1];
    "Item 1" -> "Item 5" [ltail=cluster_0 lhead=cluster_2];
}
Run Code Online (Sandbox Code Playgroud)

compound=truegraph声明中是至关重要的.这产生了输出:

连接集群的图表

请注意,我将边缘更改为引用群集中的节点,将ltail和lhead属性添加到每个边缘,指定群集名称,并添加图层级属性"compound = true".

关于人们可能想要连接其中没有节点的集群的担心,我的解决方案是始终向每个集群添加一个节点,使用style = plaintext进行渲染.使用此节点标记集群(而不是集群的内置"label"属性,该属性应设置为空字符串(在Python中label='""').这意味着我不再添加直接连接集群的边,但它在我的特殊情况下工作.

  • 注意:'graph [fontsize = 10 fontname ="Verdana"compound = true];' 是必不可少的 - 如果你错过了链接到ltail/lhead不起作用. (23认同)
  • @ s.Daniel这只是复合=真; 这是必需的 (6认同)

mih*_*jlv 10

确保使用fdp文件的布局.我不认为neato支持集群.

  • 我也经验地发现`neato`引擎不支持集群..我不确定这是不是一个bug. (2认同)