如何让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图:
期望效果:
「最后节点连最后节点」策略代码
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的基准节点处于同一水平rank,具体操作如下:
- 给每个Cluster添加隐藏锚点节点:在每个Cluster内部新增一个不可见的节点(设置
style=invis),作为对齐基准。 - 设置锚点节点同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
相关产品推荐
相关产品推荐

