You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Graphviz中的Cluster子图实现垂直对齐?

Graphviz实现Cluster垂直对齐的方法

我用Graphviz生成包含Cluster的图,采用「前一个子图最后一个节点连接后一个子图第一个节点」的策略时,生成的图向左倾斜,希望让这些Cluster子图实现垂直对齐。以下是相关代码、效果示例及解决方案:


原策略(前子图最后节点连后子图首节点)代码

digraph {
    compound=true
    fontname="Verdana"
    fontsize=12
    nodesep = 1
    ranksep = 1.5
    node[shape=folder, style="filled,solid", color=green4, fontsize=12]
    subgraph "cluster 1" {
        style=filled color=green4 fillcolor=lightgreen
        label = <l1>
        n0 [label=<n0> fillcolor=limegreen]
        n1 [label=<n1> fillcolor=limegreen]
        n2 [label=<n2> fillcolor=limegreen]
        n3 [label=<n3> fillcolor=limegreen]
        n4 [label=<n4> fillcolor=limegreen]
        n5 [label=<n5> fillcolor=limegreen]
        n0 -> n1
        n1 -> n2
        n2 -> n3
        n3 -> n4
        n4 -> n5
    }
    subgraph "cluster c1" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c1>
        n6 [label=<n6> fillcolor=limegreen]
    }
    subgraph "cluster c2" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c2>
        n7 [label=<n7> fillcolor=limegreen]
        n8 [label=<n8> fillcolor=limegreen]
        n9 [label=<n9> fillcolor=limegreen]
        n10 [label=<n10> fillcolor=limegreen]
        n7 -> n8
        n8 -> n9
        n9 -> n10
    }
    subgraph "cluster c3" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c3>
        n11 [label=<n11> fillcolor=limegreen]
        n12 [label=<n12> fillcolor=limegreen]
        n13 [label=<n13> fillcolor=limegreen]
        n14 [label=<n14> fillcolor=limegreen]
        n11 -> n12
        n12 -> n13
        n13 -> n14
    }
    subgraph "cluster c4" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c4>
        n15 [label=<n15> fillcolor=limegreen]
        n16 [label=<n16> fillcolor=limegreen]
    }
    subgraph "cluster c5" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c5>
        n17 [label=<n17> fillcolor=limegreen]
        n18 [label=<n18> fillcolor=limegreen]
        n17 -> n18
    }
    subgraph "cluster c6" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c6>
        n48 [label=<n48> fillcolor=limegreen]
        n49 [label=<n49> fillcolor=limegreen]
        n50 [label=<n50> fillcolor=limegreen]
        n51 [label=<n51> fillcolor=limegreen]
        n48 -> n49
        n49 -> n50
        n50 -> n51
    }
    subgraph "cluster c7" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c7>
        n52 [label=<n52> fillcolor=limegreen]
        n53 [label=<n53> fillcolor=limegreen]
    }
    subgraph "cluster c8" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c8>
        n54 [label=<n54> fillcolor=limegreen]
        n55 [label=<n55> fillcolor=limegreen]
    }
    n6 -> n7 [ltail="cluster c1", lhead="cluster c2"]
    n10 -> n11 [ltail="cluster c2", lhead="cluster c3"]
    n18 -> n15 [ltail="cluster c5", lhead="cluster c4"]
    n14 -> n17 [ltail="cluster c3", lhead="cluster c5"]
    n55 -> n48 [ltail="cluster c8", lhead="cluster c6"]
    n16 -> n52 [ltail="cluster c4", lhead="cluster c7"]
    n53 -> n54 [ltail="cluster c7", lhead="cluster c8"]
}

原策略效果

左倾斜的Cluster图:左倾斜的Cluster图
期望效果:垂直对齐的Cluster图


「最后节点连最后节点」策略代码

digraph {
    compound=true
    fontname="Verdana"
    fontsize=12
    nodesep = 1
    ranksep = 1.5
    node[shape=folder, style="filled,solid", color=green4, fontsize=12]
    subgraph "cluster c0" {
        style=filled color=green4 fillcolor=lightgreen
        label = <l1>
        n0 [label=<n0> fillcolor=limegreen]
        n1 [label=<n1> fillcolor=limegreen]
        n2 [label=<n2> fillcolor=limegreen]
        n3 [label=<n3> fillcolor=limegreen]
        n4 [label=<n4> fillcolor=limegreen]
        n5 [label=<n5> fillcolor=limegreen]
        n0 -> n1
        n1 -> n2
        n2 -> n3
        n3 -> n4
        n4 -> n5
    }
    subgraph "cluster c1" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c1>
        n6 [label=<n6> fillcolor=limegreen]
    }
    subgraph "cluster c2" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c2>
        n7 [label=<n7> fillcolor=limegreen]
        n8 [label=<n8> fillcolor=limegreen]
        n9 [label=<n9> fillcolor=limegreen]
        n10 [label=<n10> fillcolor=limegreen]
        n7 -> n8
        n8 -> n9
        n9 -> n10
    }
    subgraph "cluster c3" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c3>
        n11 [label=<n11> fillcolor=limegreen]
        n12 [label=<n12> fillcolor=limegreen]
        n13 [label=<n13> fillcolor=limegreen]
        n14 [label=<n14> fillcolor=limegreen]
        n11 -> n12
        n12 -> n13
        n13 -> n14
    }
    subgraph "cluster c4" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c4>
        n15 [label=<n15> fillcolor=limegreen]
        n16 [label=<n16> fillcolor=limegreen]
    }
    subgraph "cluster c5" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c5>
        n17 [label=<n17> fillcolor=limegreen]
        n18 [label=<n18> fillcolor=limegreen]
        n17 -> n18
    }
    subgraph "cluster c6" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c6>
        n48 [label=<n48> fillcolor=limegreen]
        n49 [label=<n49> fillcolor=limegreen]
        n50 [label=<n50> fillcolor=limegreen]
        n51 [label=<n51> fillcolor=limegreen]
        n48 -> n49
        n49 -> n50
        n50 -> n51
    }
    subgraph "cluster c7" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c7>
        n52 [label=<n52> fillcolor=limegreen]
        n53 [label=<n53> fillcolor=limegreen]
    }
    subgraph "cluster c8" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c8>
        n54 [label=<n54> fillcolor=limegreen]
        n55 [label=<n55> fillcolor=limegreen]
    }
    n6 -> n10 [ltail="cluster c1", lhead="cluster c2"]
    n10 -> n14 [ltail="cluster c2", lhead="cluster c3"]
    n18 -> n16 [ltail="cluster c5", lhead="cluster c4"]
    n14 -> n18 [ltail="cluster c3", lhead="cluster c5"]
    n55 -> n51 [ltail="cluster c8", lhead="cluster c6"]
    n16 -> n53 [ltail="cluster c4", lhead="cluster c7"]
    n53 -> n55 [ltail="cluster c7", lhead="cluster c8"]
}

该策略效果

最后节点连最后节点的Cluster图


垂直对齐解决方案

要让Cluster实现垂直对齐,核心是强制所有Cluster的基准节点处于同一水平rank,具体操作如下:

  1. 给每个Cluster添加隐藏锚点节点:在每个Cluster内部新增一个不可见的节点(设置style=invis),作为对齐基准。
  2. 设置锚点节点同rank:在全局添加一个子图,将所有Cluster的锚点节点设置为rank=same,强制它们处于同一水平线上,从而带动整个Cluster垂直对齐。

修改后的代码示例:

digraph {
    compound=true
    fontname="Verdana"
    fontsize=12
    nodesep = 1
    ranksep = 1.5
    node[shape=folder, style="filled,solid", color=green4, fontsize=12]
    
    // 强制所有锚点节点处于同一rank,实现Cluster垂直对齐
    {
        rank=same;
        cluster1_anchor;
        c1_anchor;
        c2_anchor;
        c3_anchor;
        c4_anchor;
        c5_anchor;
        c6_anchor;
        c7_anchor;
        c8_anchor;
    }

    subgraph "cluster 1" {
        style=filled color=green4 fillcolor=lightgreen
        label = <l1>
        cluster1_anchor [style=invis] // 隐藏锚点
        n0 [label=<n0> fillcolor=limegreen]
        n1 [label=<n1> fillcolor=limegreen]
        n2 [label=<n2> fillcolor=limegreen]
        n3 [label=<n3> fillcolor=limegreen]
        n4 [label=<n4> fillcolor=limegreen]
        n5 [label=<n5> fillcolor=limegreen]
        n0 -> n1
        n1 -> n2
        n2 -> n3
        n3 -> n4
        n4 -> n5
    }
    subgraph "cluster c1" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c1>
        c1_anchor [style=invis] // 隐藏锚点
        n6 [label=<n6> fillcolor=limegreen]
    }
    subgraph "cluster c2" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c2>
        c2_anchor [style=invis] // 隐藏锚点
        n7 [label=<n7> fillcolor=limegreen]
        n8 [label=<n8> fillcolor=limegreen]
        n9 [label=<n9> fillcolor=limegreen]
        n10 [label=<n10> fillcolor=limegreen]
        n7 -> n8
        n8 -> n9
        n9 -> n10
    }
    subgraph "cluster c3" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c3>
        c3_anchor [style=invis] // 隐藏锚点
        n11 [label=<n11> fillcolor=limegreen]
        n12 [label=<n12> fillcolor=limegreen]
        n13 [label=<n13> fillcolor=limegreen]
        n14 [label=<n14> fillcolor=limegreen]
        n11 -> n12
        n12 -> n13
        n13 -> n14
    }
    subgraph "cluster c4" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c4>
        c4_anchor [style=invis] // 隐藏锚点
        n15 [label=<n15> fillcolor=limegreen]
        n16 [label=<n16> fillcolor=limegreen]
    }
    subgraph "cluster c5" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c5>
        c5_anchor [style=invis] // 隐藏锚点
        n17 [label=<n17> fillcolor=limegreen]
        n18 [label=<n18> fillcolor=limegreen]
        n17 -> n18
    }
    subgraph "cluster c6" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c6>
        c6_anchor [style=invis] // 隐藏锚点
        n48 [label=<n48> fillcolor=limegreen]
        n49 [label=<n49> fillcolor=limegreen]
        n50 [label=<n50> fillcolor=limegreen]
        n51 [label=<n51> fillcolor=limegreen]
        n48 -> n49
        n49 -> n50
        n50 -> n51
    }
    subgraph "cluster c7" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c7>
        c7_anchor [style=invis] // 隐藏锚点
        n52 [label=<n52> fillcolor=limegreen]
        n53 [label=<n53> fillcolor=limegreen]
    }
    subgraph "cluster c8" {
        style=filled color=green4 fillcolor=lightgreen
        label = <c8>
        c8_anchor [style=invis] // 隐藏锚点
        n54 [label=<n54> fillcolor=limegreen]
        n55 [label=<n55> fillcolor=limegreen]
    }

    // 保持原有的边连接逻辑
    n6 -> n7 [ltail="cluster c1", lhead="cluster c2"]
    n10 -> n11 [ltail="cluster c2", lhead="cluster c3"]
    n18 -> n15 [ltail="cluster c5", lhead="cluster c4"]
    n14 -> n17 [ltail="cluster c3", lhead="cluster c5"]
    n55 -> n48 [ltail="cluster c8", lhead="cluster c6"]
    n16 -> n52 [ltail="cluster c4", lhead="cluster c7"]
    n53 -> n54 [ltail="cluster c7", lhead="cluster c8"]
}

补充说明

  • 隐藏锚点节点不会影响图的可视化效果,仅作为对齐基准。
  • 若图仍有轻微偏移,可调整nodesep或ranksep参数优化间距。

内容的提问来源于stack exchange,提问作者Artyum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:17:00