如何在Graphviz中将绿色节点排列到红色节点右侧?
问题描述
我想把图中所有绿色节点放在红色节点的右侧,用一条虚拟竖线分隔开。原本以为添加cluster能实现,但结果布局混乱了。以下是我的两个Graphviz输入文件,求可行的实现方法?
当前输入文件
rankdir="LR" subgraph cluster_2 { "astn-serialize-string-res" [ color="green" ] } subgraph cluster_4 { "pareto-lang-lib" [ color="red", penwidth=3 ] } subgraph cluster_5 { graph[color="red"] "astn-unmarshall-lib" [ color="red", penwidth=3 ] } subgraph cluster_6 { graph[color="red"] "astn-typedhandlers-lib" [ color="red", penwidth=3 ] } subgraph cluster_7 { graph[color="red"] "astn-tokenizer-lib" [ color="red", penwidth=3 ] } subgraph cluster_8 { "astn-serializer-lib" [ color="red", penwidth=3 ] } subgraph cluster_9 { graph[color="red"] "astn-parser-lib" [ color="red", penwidth=3 ] } subgraph cluster_10 { graph[color="red"] "astn-mrshlschema-lib" [ color="red", penwidth=3 ] } subgraph cluster_11 { graph[color="red"] "astn-marshall-lib" [ color="red", penwidth=3 ] } subgraph cluster_12 { graph[color="red"] "astn-loader-lib" [ color="red", penwidth=3 ] } subgraph cluster_13 { graph[color="red"] "astn-ide-lib" [ color="red", penwidth=3 ] } subgraph cluster_14 { graph[color="red"] "astn-expect-lib" [ color="red", penwidth=3 ] } subgraph cluster_16 { "astn-typedhandlers-api" [ color="green" ] } subgraph cluster_17 { "astn-tokenconsumer-api" [ color="green" ] } subgraph cluster_18 { "astn-serialize-string-api" [ color="green" ] } subgraph cluster_19 { "astn-handlers-api" [ color="green" ] } "pareto-lang-lib--fountain-pen-lib" [label= "fountain-pen-lib"] "pareto-lang-lib" -> "pareto-lang-lib--fountain-pen-lib" "pareto-lang-lib" -> "astn-handlers-api" "pareto-lang-lib" -> "astn-expect-lib" "astn-unmarshall-lib" -> "astn-typedhandlers-api" "astn-unmarshall-lib" -> "astn-handlers-api" "astn-typedhandlers-lib" -> "astn-typedhandlers-api" "astn-typedhandlers-lib" -> "astn-tokenconsumer-api" "astn-typedhandlers-lib" -> "astn-handlers-api" "astn-typedhandlers-lib" -> "astn-expect-lib" "astn-typedhandlers-api" -> "astn-handlers-api" "astn-tokenizer-lib" -> "astn-tokenconsumer-api" "astn-serializer-lib" -> "astn-serialize-string-api" "astn-serializer-lib" -> "astn-handlers-api" "astn-serialize-string-res" -> "astn-serialize-string-api" "astn-parser-lib" -> "astn-tokenconsumer-api" "astn-parser-lib" -> "astn-handlers-api" "astn-mrshlschema-lib" -> "pareto-lang-lib" "astn-mrshlschema-lib" -> "astn-typedhandlers-api" "astn-mrshlschema-lib" -> "astn-handlers-api" "astn-marshall-lib" -> "astn-typedhandlers-api" "astn-marshall-lib" -> "astn-tokenconsumer-api" "astn-marshall-lib" -> "astn-parser-lib" "astn-loader-lib" -> "astn-unmarshall-lib" "astn-loader-lib" -> "astn-tokenizer-lib" "astn-loader-lib" -> "astn-parser-lib" "astn-loader-lib" -> "astn-mrshlschema-lib" "astn-loader-lib" -> "astn-expect-lib" "astn-ide-lib" -> "astn-typedhandlers-api" "astn-expect-lib" -> "astn-handlers-api" }
添加cluster后的输入文件
rankdir="LR" subgraph cluster_0 { } subgraph cluster_1 { subgraph cluster_2 { "astn-serialize-string-res" [ color="green" ] } } subgraph cluster_3 { subgraph cluster_4 { "pareto-lang-lib" [ color="red", penwidth=3 ] } subgraph cluster_5 { graph[color="red"] "astn-unmarshall-lib" [ color="red", penwidth=3 ] } subgraph cluster_6 { graph[color="red"] "astn-typedhandlers-lib" [ color="red", penwidth=3 ] } subgraph cluster_7 { graph[color="red"] "astn-tokenizer-lib" [ color="red", penwidth=3 ] } subgraph cluster_8 { "astn-serializer-lib" [ color="red", penwidth=3 ] } subgraph cluster_9 { graph[color="red"] "astn-parser-lib" [ color="red", penwidth=3 ] } subgraph cluster_10 { graph[color="red"] "astn-mrshlschema-lib" [ color="red", penwidth=3 ] } subgraph cluster_11 { graph[color="red"] "astn-marshall-lib" [ color="red", penwidth=3 ] } subgraph cluster_12 { graph[color="red"] "astn-loader-lib" [ color="red", penwidth=3 ] } subgraph cluster_13 { graph[color="red"] "astn-ide-lib" [ color="red", penwidth=3 ] } subgraph cluster_14 { graph[color="red"] "astn-expect-lib" [ color="red", penwidth=3 ] } } subgraph cluster_15 { subgraph cluster_16 { "astn-typedhandlers-api" [ color="green" ] } subgraph cluster_17 { "astn-tokenconsumer-api" [ color="green" ] } subgraph cluster_18 { "astn-serialize-string-api" [ color="green" ] } subgraph cluster_19 { "astn-handlers-api" [ color="green" ] } } "pareto-lang-lib--fountain-pen-lib" [label= "fountain-pen-lib"] "pareto-lang-lib" -> "pareto-lang-lib--fountain-pen-lib" "pareto-lang-lib" -> "astn-handlers-api" "pareto-lang-lib" -> "astn-expect-lib" "astn-unmarshall-lib" -> "astn-typedhandlers-api" "astn-unmarshall-lib" -> "astn-handlers-api" "astn-typedhandlers-lib" -> "astn-typedhandlers-api" "astn-typedhandlers-lib" -> "astn-tokenconsumer-api" "astn-typedhandlers-lib" -> "astn-handlers-api" "astn-typedhandlers-lib" -> "astn-expect-lib" "astn-typedhandlers-api" -> "astn-handlers-api" "astn-tokenizer-lib" -> "astn-tokenconsumer-api" "astn-serializer-lib" -> "astn-serialize-string-api" "astn-serializer-lib" -> "astn-handlers-api" "astn-serialize-string-res" -> "astn-serialize-string-api" "astn-parser-lib" -> "astn-tokenconsumer-api" "astn-parser-lib" -> "astn-handlers-api" "astn-mrshlschema-lib" -> "pareto-lang-lib" "astn-mrshlschema-lib" -> "astn-typedhandlers-api" "astn-mrshlschema-lib" -> "astn-handlers-api" "astn-marshall-lib" -> "astn-typedhandlers-api" "astn-marshall-lib" -> "astn-tokenconsumer-api" "astn-marshall-lib" -> "astn-parser-lib" "astn-loader-lib" -> "astn-unmarshall-lib" "astn-loader-lib" -> "astn-tokenizer-lib" "astn-loader-lib" -> "astn-parser-lib" "astn-loader-lib" -> "astn-mrshlschema-lib" "astn-loader-lib" -> "astn-expect-lib" "astn-ide-lib" -> "astn-typedhandlers-api" "astn-expect-lib" -> "astn-handlers-api" }
解决方案
方法一:简化Cluster结构实现分组
你之前的Cluster嵌套层级太多,导致Graphviz布局逻辑混乱。直接把红色节点和绿色节点分别放在两个顶级Cluster里,去掉多余的子Cluster,同时隐藏Cluster的边框和标签,就能让Graphviz自动将两组节点左右分隔:
rankdir="LR" // 红色节点的顶级Cluster subgraph cluster_red { label=""; // 隐藏Cluster标签 color=white; // 隐藏Cluster边框 "pareto-lang-lib" [ color="red", penwidth=3 ] "astn-unmarshall-lib" [ color="red", penwidth=3 ] "astn-typedhandlers-lib" [ color="red", penwidth=3 ] "astn-tokenizer-lib" [ color="red", penwidth=3 ] "astn-serializer-lib" [ color="red", penwidth=3 ] "astn-parser-lib" [ color="red", penwidth=3 ] "astn-mrshlschema-lib" [ color="red", penwidth=3 ] "astn-marshall-lib" [ color="red", penwidth=3 ] "astn-loader-lib" [ color="red", penwidth=3 ] "astn-ide-lib" [ color="red", penwidth=3 ] "astn-expect-lib" [ color="red", penwidth=3 ] } // 绿色节点的顶级Cluster subgraph cluster_green { label=""; color=white; "astn-serialize-string-res" [ color="green" ] "astn-typedhandlers-api" [ color="green" ] "astn-tokenconsumer-api" [ color="green" ] "astn-serialize-string-api" [ color="green" ] "astn-handlers-api" [ color="green" ] } // 原有的边定义 "pareto-lang-lib--fountain-pen-lib" [label= "fountain-pen-lib"] "pareto-lang-lib" -> "pareto-lang-lib--fountain-pen-lib" "pareto-lang-lib" -> "astn-handlers-api" "pareto-lang-lib" -> "astn-expect-lib" "astn-unmarshall-lib" -> "astn-typedhandlers-api" "astn-unmarshall-lib" -> "astn-handlers-api" "astn-typedhandlers-lib" -> "astn-typedhandlers-api" "astn-typedhandlers-lib" -> "astn-tokenconsumer-api" "astn-typedhandlers-lib" -> "astn-handlers-api" "astn-typedhandlers-lib" -> "astn-expect-lib" "astn-typedhandlers-api" -> "astn-handlers-api" "astn-tokenizer-lib" -> "astn-tokenconsumer-api" "astn-serializer-lib" -> "astn-serialize-string-api" "astn-serializer-lib" -> "astn-handlers-api" "astn-serialize-string-res" -> "astn-serialize-string-api" "astn-parser-lib" -> "astn-tokenconsumer-api" "astn-parser-lib" -> "astn-handlers-api" "astn-mrshlschema-lib" -> "pareto-lang-lib" "astn-mrshlschema-lib" -> "astn-typedhandlers-api" "astn-mrshlschema-lib" -> "astn-handlers-api" "astn-marshall-lib" -> "astn-typedhandlers-api" "astn-marshall-lib" -> "astn-tokenconsumer-api" "astn-marshall-lib" -> "astn-parser-lib" "astn-loader-lib" -> "astn-unmarshall-lib" "astn-loader-lib" -> "astn-tokenizer-lib" "astn-loader-lib" -> "astn-parser-lib" "astn-loader-lib" -> "astn-mrshlschema-lib" "astn-loader-lib" -> "astn-expect-lib" "astn-ide-lib" -> "astn-typedhandlers-api" "astn-expect-lib" -> "astn-handlers-api" }
方法二:用不可见节点+Rank约束强制分隔
如果需要更精确的位置控制,可以给红色节点和绿色节点分别设置同Rank,再添加不可见的中间节点和边,强制红色在左、绿色在右:
rankdir="LR" // 红色节点组,强制同Rank subgraph red_group { rank=same; "pareto-lang-lib" [ color="red", penwidth=3 ] "astn-unmarshall-lib" [ color="red", penwidth=3 ] "astn-typedhandlers-lib" [ color="red", penwidth=3 ] "astn-tokenizer-lib" [ color="red", penwidth=3 ] "astn-serializer-lib" [ color="red", penwidth=3 ] "astn-parser-lib" [ color="red", penwidth=3 ] "astn-mrshlschema-lib" [ color="red", penwidth=3 ] "astn-marshall-lib" [ color="red", penwidth=3 ] "astn-loader-lib" [ color="red", penwidth=3 ] "astn-ide-lib" [ color="red", penwidth=3 ] "astn-expect-lib" [ color="red", penwidth=3 ] } // 绿色节点组,强制同Rank subgraph green_group { rank=same; "astn-serialize-string-res" [ color="green" ] "astn-typedhandlers-api" [ color="green" ] "astn-tokenconsumer-api" [ color="green" ] "astn-serialize-string-api" [ color="green" ] "astn-handlers-api" [ color="green" ] } // 添加不可见分隔节点,强制分组顺序 separator [style=invisible] "astn-expect-lib" -> separator [style=invisible] separator -> "astn-handlers-api" [style=invisible] // 原有的边定义 "pareto-lang-lib--fountain-pen-lib" [label= "fountain-pen-lib"] "pareto-lang-lib" -> "pareto-lang-lib--fountain-pen-lib" "pareto-lang-lib" -> "astn-handlers-api" "pareto-lang-lib" -> "astn-expect-lib" "astn-unmarshall-lib" -> "astn-typedhandlers-api" "astn-unmarshall-lib" -> "astn-handlers-api" "astn-typedhandlers-lib" -> "astn-typedhandlers-api" "astn-typedhandlers-lib" -> "astn-tokenconsumer-api" "astn-typedhandlers-lib" -> "astn-handlers-api" "astn-typedhandlers-lib" -> "astn-expect-lib" "astn-typedhandlers-api" -> "astn-handlers-api" "astn-tokenizer-lib" -> "astn-tokenconsumer-api" "astn-serializer-lib" -> "astn-serialize-string-api" "astn-serializer-lib" -> "astn-handlers-api"
相关产品推荐
相关产品推荐

