如何调整Graphviz绘图 生成更高更窄的近正方形图形
Graphviz窄高布局调整方案
你当前生成图形过宽的核心原因是:dot类布局引擎默认会将互不连通的子图沿横向并排摆放,原有代码没有对两个连通分量(A-E子树、F-G-H子树)的纵向层级做约束,才会导致整体扁宽。size、ratio属于渲染阶段的缩放参数,不会改变布局阶段的节点相对位置,单独调整group参数也仅能控制同组节点的竖向对齐,无法约束不同连通分量的排布方向,因此达不到预期效果。
方案1:自动排布调整(推荐,无需手动指定坐标)
使用默认dot引擎即可实现,不需要切换到fdp等力导向引擎,调整步骤如下:
- 显式设置全局布局参数,控制节点间距:开启从上到下的排布方向,通过
nodesep控制同层节点横向间距、ranksep控制层间纵向间距,数值越小布局越紧凑。 - 明确同层节点约束:用
rank=same显式指定A-E为同一顶层,F-G-H为同一层,避免引擎自动打乱层级。 - 加不可见约束边强制纵向排布:在两个连通分量之间添加一条无显示效果的边,权值设高强制引擎按上下顺序摆放两个子树,从根源上避免横向并排。
- 修复原有代码问题:原有代码中两个子图重名都叫
s6,会被Graphviz自动合并,需要将第二个重名子图改名为s7避免逻辑错误。
调整完成的可直接运行代码如下:
digraph { layout=dot rankdir=TB nodesep=0.35 ranksep=0.7 node [shape=square] edge [color=black] // 约束A-E为顶层同层节点 { rank=same A B C D E } C -> c F -> f subgraph s1 { edge [color=red] A -> a B -> b1 D -> d1 E -> e1 G -> g1 H -> h1 } subgraph s2 { edge [color=blue] A -> b1 B -> a D -> d2 E -> e2 G -> g2 H -> h2 } subgraph s3 { edge [color=green] A -> a B -> b1 D -> d2 E -> e3 G -> g3 H -> h1 } subgraph s4 { edge [color=purple] A -> b1 B -> a D -> e1 E -> e2 G -> g4 H -> h1 } subgraph s5 { edge [ color=orange] A -> b1 B -> a D -> d5 E -> e1 G -> g5 H -> h1 } subgraph s6 { edge [ color=brown] A -> a B -> b1 D -> d1 E -> e6 G -> g6 H -> h1 } // 修复原代码重名子图问题 subgraph s7 { edge [ color=tan] A -> a B -> b2 D -> d2 E -> e6 G -> g6 H -> h1 } // 不可见约束边,强制F所在子树放在c节点下方 c -> F [style=invis, weight=10] // 约束F/G/H为同层节点 { rank=same F G H } }
运行后F/G/H子树会自动排布在A-E子树的下方,整体比例接近正方形,可根据实际显示效果微调nodesep和ranksep的数值。
方案2:手动固定节点位置(需精确控制布局时使用)
如果需要完全自定义每个节点的位置,可切换到neato引擎,通过pos属性给每个节点指定固定坐标,坐标后必须加!标识强制引擎不做自动调整,示例配置如下:
digraph { layout=neato overlap=false // 顶层A-E固定在y=5的高度,横向均匀排布 A [pos="1,5!", shape=square] B [pos="2,5!", shape=square] C [pos="3,5!", shape=square] D [pos="4,5!", shape=square] E [pos="5,5!", shape=square] // F/G/H固定在A-E下方y=2的高度 F [pos="1.5,2!", shape=square] G [pos="3,2!", shape=square] H [pos="4.5,2!", shape=square] // 其余子节点可按需求自行设置坐标,原有边的定义全部保留即可 }
内容的提问来源于stack exchange,提问作者Troy Daniels
相关产品推荐
相关产品推荐

