Graphviz双Cluster子图与节点对齐配置技术求助
解决Dot图双Cluster布局需求
需求目标
- 两个Cluster在图空间中水平居中对齐;
- Cluster内的节点水平对齐;
- P节点到E节点的边尽可能保持笔直。
现有代码
digraph G { compound=true; rankdir=LR; subgraph cluster_states { style=invis; rank=same P1 P2; P1 [fillcolor="#80B1D3", shape=ellipse, style=filled, group=a]; P2 [fillcolor="#80B1D3", shape=ellipse, style=filled, group=a]; } subgraph cluster_symbols { style=invis; rank=same E1 E2 E3; E1 [fillcolor="#E0E0E0", shape=hexagon, style=filled, group=b]; E2 [fillcolor="#E0E0E0", shape=hexagon, style=filled, group=b]; E3 [fillcolor="#E0E0E0", shape=hexagon, style=filled, group=b]; } P1 -> P1 [color="#8d8d8d", label=" 0.4 ", style=filled, weight=0.4, constraint=true]; P1 -> P2 [color="#5e5e5e", label=" 0.6 ", style=filled, weight=0.6, constraint=true]; P2 -> P1 [color="#464646", label=" 0.7 ", style=filled, weight=0.7, constraint=true]; P2 -> P2 [color="#a5a5a5", label=" 0.3 ", style=filled, weight=0.3, constraint=true]; P1 -> E1 [color="#d4d4d4", label=" 0.1 ", style=dashed, weight=0.1, constraint=false]; P1 -> E2 [color="#757575", label=" 0.5 ", style=dashed, weight=0.5, constraint=false]; P1 -> E3 [color="#8d8d8d", label=" 0.4 ", style=dashed, weight=0.4, constraint=false]; P2 -> E1 [color="#bcbcbc", label=" 0.2 ", style=dashed, weight=0.2, constraint=false]; P2 -> E2 [color="#5e5e5e", label=" 0.6 ", style=dashed, weight=0.6, constraint=false]; P2 -> E3 [color="#bcbcbc", label=" 0.2 ", style=dashed, weight=0.2, constraint=false]; }
当前效果

预期效果

解决方案
要实现预期布局,可通过以下配置调整:
修改后的代码
digraph G { compound=true; rankdir=TB; // 切换为垂直布局,便于水平居中对齐 // 添加辅助居中的不可见节点 center_node [shape=point, style=invis]; subgraph cluster_states { style=invis; rank=same P1 P2; P1 [fillcolor="#80B1D3", shape=ellipse, style=filled]; P2 [fillcolor="#80B1D3", shape=ellipse, style=filled]; // 用不可见边绑定到辅助节点,实现组内居中 center_node -> P1 [style=invis]; center_node -> P2 [style=invis]; } subgraph cluster_symbols { style=invis; rank=same E1 E2 E3; E1 [fillcolor="#E0E0E0", shape=hexagon, style=filled]; E2 [fillcolor="#E0E0E0", shape=hexagon, style=filled]; E3 [fillcolor="#E0E0E0", shape=hexagon, style=filled]; // 用不可见边绑定到辅助节点,实现组内居中 center_node -> E1 [style=invis]; center_node -> E2 [style=invis]; center_node -> E3 [style=invis]; } // 强制两个Cluster和辅助节点处于同一水平层级 {rank=same cluster_states cluster_symbols center_node} // 状态转移边,保留布局约束 P1 -> P1 [color="#8d8d8d", label=" 0.4 ", style=filled, weight=1]; P1 -> P2 [color="#5e5e5e", label=" 0.6 ", style=filled, weight=1]; P2 -> P1 [color="#464646", label=" 0.7 ", style=filled, weight=1]; P2 -> P2 [color="#a5a5a5", label=" 0.3 ", style=filled, weight=1]; // P到E的边,提升权重确保路径笔直,关闭布局约束避免干扰状态节点 P1 -> E1 [color="#d4d4d4", label=" 0.1 ", style=dashed, weight=10, constraint=false]; P1 -> E2 [color="#757575", label=" 0.5 ", style=dashed, weight=10, constraint=false]; P1 -> E3 [color="#8d8d8d", label=" 0.4 ", style=dashed, weight=10, constraint=false]; P2 -> E1 [color="#bcbcbc", label=" 0.2 ", style=dashed, weight=10, constraint=false]; P2 -> E2 [color="#5e5e5e", label=" 0.6 ", style=dashed, weight=10, constraint=false]; P2 -> E3 [color="#bcbcbc", label=" 0.2 ", style=dashed, weight=10, constraint=false]; }
关键配置说明
rankdir=TB:将布局方向从水平改为垂直,让两个Cluster可以水平并列,更容易实现居中对齐;- 不可见
center_node:作为对齐基准,通过不可见边连接两个Cluster内的所有节点,确保整个Cluster组相对于该节点居中; rank=same强制层级:保证两个Cluster和辅助节点处于同一水平高度,实现整体水平对齐;- 提升P到E边的
weight:高权重会让Dot优先选择更短、更笔直的路径绘制这些边; - 状态转移边保留默认约束:确保状态节点的布局符合转移逻辑,不受P-E边的干扰。
内容的提问来源于stack exchange,提问作者Tommaso Belluzzo
相关产品推荐
相关产品推荐

