强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Graphviz 图形可视化教程 / 06 - 布局引擎

第 06 章 · 布局引擎

6.1 引擎概览

Graphviz 提供 7+ 种布局引擎,每种引擎针对不同的图形拓扑结构优化:

引擎 算法类别 方向性支持 推荐节点数 核心原理
dot 层次布局 有向 任意 Sugiyama 分层算法
neato 力导向 无向 < 100 弹簧-质点模型
fdp 力导向 无向 < 1000 Fruchterman-Reingold
sfdp 多尺度力导向 无向 > 1000 多层次力导向
twopi 放射布局 有/无向 < 500 径向树布局
circo 圆形布局 有/无向 < 200 圆弧布局
osage 矩形布局 有/无向 任意 矩形嵌套
patchwork 矩形树图 有/无向 任意 Squarified Treemap

6.2 dot 引擎

dot 是最常用的引擎,适合有向图、层次结构图。使用 Sugiyama 分层算法

工作原理

  1. 拓扑排序:确定节点的层级
  2. 交叉减少:最小化边的交叉
  3. 节点放置:在层级内安排节点位置
  4. 边路由:计算边的路径

布局方向

digraph DotTB {
    // TB — 从上到下(默认)
    rankdir=TB
    node [fontname="Microsoft YaHei" shape=box style=rounded]
    A -> B -> C -> D
    B -> E
}
digraph DotLR {
    // LR — 从左到右
    rankdir=LR
    node [fontname="Microsoft YaHei" shape=box style=rounded]
    A -> B -> C -> D
    B -> E
}
digraph DotBT {
    // BT — 从下到上
    rankdir=BT
    node [fontname="Microsoft YaHei" shape=box style=rounded]
    A -> B -> C -> D
}
digraph DotRL {
    // RL — 从右到左
    rankdir=RL
    node [fontname="Microsoft YaHei" shape=box style=rounded]
    A -> B -> C -> D
}

dot 专属属性

属性 说明 常用值
rankdir 布局方向 TBLRBTRL
rank 强制排名 sameminmaxsourcesink
nodesep 同层节点间距 0.25(默认)
ranksep 层间距离 0.5(默认)
concentrate 合并边 truefalse
mclimit 迭代次数 1.0(默认)

适用场景

digraph DotUseCase {
    rankdir=LR
    node [fontname="Microsoft YaHei" shape=box style="filled,rounded" fillcolor="#E3F2FD" color="#1976D2"]
    edge [fontname="Microsoft YaHei" fontsize=9 color="#666666"]

    "dot 引擎" -> "流程图" [label="✓"]
    "dot 引擎" -> "DAG 依赖图" [label="✓"]
    "dot 引擎" -> "类层次图" [label="✓"]
    "dot 引擎" -> "状态机" [label="✓"]
    "dot 引擎" -> "网络拓扑" [label="✗" color="#F44336"]
    "dot 引擎" -> "社交网络" [label="✗" color="#F44336"]
}

6.3 neato 引擎

neato 使用 弹簧-质点模型(Spring Model),适合小型无向图。

工作原理

  • 每条边是一根弹簧,试图拉近相连的节点
  • 每对节点之间有排斥力,防止重叠
  • 通过迭代计算达到力平衡
graph NeatoExample {
    layout=neato
    overlap=false
    node [fontname="Microsoft YaHei" shape=circle style=filled fillcolor="#E8F5E9" color="#388E3C"]
    edge [color="#9E9E9E"]

    A -- B -- C -- D -- A
    A -- C
    B -- D
    E -- A
    E -- B
    E -- C
    E -- D
}

neato 专属属性

属性 说明 常用值
overlap 重叠处理 falsescaleprism
sep 节点分离 +100.5
maxiter 最大迭代次数 100(默认)
epsilon 收敛阈值 0.0001(默认)
start 随机种子 random、数值

6.4 fdp 引擎

fdp(Force-Directed Placement)是 neato 的改进版,使用 Fruchterman-Reingold 算法,性能更好。

graph FdpExample {
    layout=fdp
    overlap=false
    node [fontname="Microsoft YaHei" shape=box style=rounded]
    edge [color="#9E9E9E"]

    subgraph cluster_group1 {
        label="组 1"
        A -- B -- C
    }
    subgraph cluster_group2 {
        label="组 2"
        D -- E -- F
    }
    A -- D
    C -- F
    B -- E
}

neato vs fdp 对比

特性 neato fdp
算法 弹簧模型 Fruchterman-Reingold
性能 小图优 中大图优
子图感知 较强
重叠处理 需手动设置 自动处理
推荐节点数 < 100 < 1000

6.5 sfdp 引擎

sfdp(Scalable Force-Directed Placement)是多尺度力导向布局,适合大型图。

graph SfdpExample {
    layout=sfdp
    overlap=false
    node [fontname="Microsoft YaHei" shape=point width=0.15]

    // 大型随机图(自动生成)
    A -- B -- C -- D -- E -- F -- G -- H
    A -- E -- I -- J -- K -- L
    B -- F -- J -- M -- N
    C -- G -- K -- N -- O
    D -- H -- L -- O -- P
}

适用场景

  • 社交网络图
  • 知识图谱
  • 依赖关系网络(节点数 > 1000)

6.6 twopi 引擎

twopi 使用 放射状布局,根节点居中,其余节点沿同心圆排列。

graph TwopiExample {
    layout=twopi
    ranksep=1.5
    node [fontname="Microsoft YaHei" shape=box style="filled,rounded" fillcolor="#E3F2FD" color="#1976D2"]
    edge [color="#9E9E9E"]

    // 根节点(默认第一个或 root 属性指定)
    Root [fillcolor="#FFCDD2" color="#C62828" label="根节点"]

    Root -> {A B C D}
    A -> {A1 A2 A3}
    B -> {B1 B2}
    C -> {C1 C2 C3 C4}
    D -> {D1}
}

twopi 专属属性

属性 说明 常用值
root 根节点 节点 ID 或 central
ranksep 圆环间距 1.01.5

适用场景

  • 组织架构图
  • 文件目录结构
  • 辐射状知识图谱

6.7 circo 引擎

circo 使用 圆形布局,适合循环结构。

digraph CircoExample {
    layout=circo
    node [fontname="Microsoft YaHei" shape=circle style=filled fillcolor="#E8F5E9" color="#388E3C"]
    edge [fontname="Microsoft YaHei" fontsize=9 color="#9E9E9E"]

    A -> B -> C -> D -> E -> A

    // 额外的非循环连接
    A -> C [style=dashed color="#F44336"]
    B -> D [style=dashed color="#F44336"]
}

适用场景

  • 循环流水线
  • 环形网络拓扑
  • 周期性流程
  • 有限状态机的环形展示

6.8 osage 引擎

osage 使用 矩形布局,按子图分组进行矩形嵌套。

graph OsageExample {
    layout=osage
    node [fontname="Microsoft YaHei" shape=box style=filled]

    subgraph cluster_前端 {
        label="前端"
        style=filled
        fillcolor="#E3F2FD"
        color="#1976D2"
        React [fillcolor="#BBDEFB"]
        Vue [fillcolor="#BBDEFB"]
    }

    subgraph cluster_后端 {
        label="后端"
        style=filled
        fillcolor="#E8F5E9"
        color="#388E3C"
        Go [fillcolor="#C8E6C9"]
        Java [fillcolor="#C8E6C9"]
        Python [fillcolor="#C8E6C9"]
    }

    subgraph cluster_数据 {
        label="数据"
        style=filled
        fillcolor="#F3E5F5"
        color="#7B1FA2"
        MySQL [fillcolor="#E1BEE7"]
        Redis [fillcolor="#E1BEE7"]
        Mongo [fillcolor="#E1BEE7"]
    }
}

6.9 patchwork 引擎

patchwork 生成 矩形树图(Treemap),面积表示层次权重。

graph PatchworkExample {
    layout=patchwork
    node [fontname="Microsoft YaHei" shape=box style=filled]

    subgraph cluster_root {
        label="市场份额"
        style=filled fillcolor="#FAFAFA"

        subgraph cluster_A {
            label="公司 A"
            style=filled fillcolor="#E3F2FD" color="#1976D2"
            A1 [width=3 height=2 fillcolor="#BBDEFB" label="产品 1"]
            A2 [width=1 height=1 fillcolor="#BBDEFB" label="产品 2"]
        }

        subgraph cluster_B {
            label="公司 B"
            style=filled fillcolor="#E8F5E9" color="#388E3C"
            B1 [width=2 height=2 fillcolor="#C8E6C9" label="产品 3"]
            B2 [width=1.5 height=1 fillcolor="#C8E6C9" label="产品 4"]
        }

        subgraph cluster_C {
            label="公司 C"
            style=filled fillcolor="#FFF3E0" color="#FF9800"
            C1 [width=1 height=1 fillcolor="#FFE0B2" label="产品 5"]
        }
    }
}

6.10 引擎选择指南

决策树

digraph EngineDecision {
    rankdir=TB
    node [fontname="Microsoft YaHei" fontsize=10]
    edge [fontname="Microsoft YaHei" fontsize=8]

    // 决策节点
    Q1 [shape=diamond label="有向边?\n(有层次关系)" style=filled fillcolor="#E3F2FD" color="#1976D2"]
    Q2 [shape=diamond label="环形结构?" style=filled fillcolor="#E3F2FD" color="#1976D2"]
    Q3 [shape=diamond label="节点数 > 1000?" style=filled fillcolor="#E3F2FD" color="#1976D2"]
    Q4 [shape=diamond label="树形/辐射?" style=filled fillcolor="#E3F2FD" color="#1976D2"]
    Q5 [shape=diamond label="需要分组?" style=filled fillcolor="#E3F2FD" color="#1976D2"]

    // 结果节点
    dot [shape=box label="dot ✓" style="filled,rounded" fillcolor="#C8E6C9" color="#388E3C"]
    circo [shape=box label="circo ✓" style="filled,rounded" fillcolor="#C8E6C9" color="#388E3C"]
    twopi [shape=box label="twopi ✓" style="filled,rounded" fillcolor="#C8E6C9" color="#388E3C"]
    sfdp [shape=box label="sfdp ✓" style="filled,rounded" fillcolor="#C8E6C9" color="#388E3C"]
    fdp [shape=box label="fdp ✓" style="filled,rounded" fillcolor="#C8E6C9" color="#388E3C"]
    neato [shape=box label="neato ✓" style="filled,rounded" fillcolor="#C8E6C9" color="#388E3C"]
    osage [shape=box label="osage ✓" style="filled,rounded" fillcolor="#C8E6C9" color="#388E3C"]

    Q1 -> dot [label="是"]
    Q1 -> Q2 [label="否"]
    Q2 -> circo [label="是"]
    Q2 -> Q4 [label="否"]
    Q4 -> twopi [label="是"]
    Q4 -> Q3 [label="否"]
    Q3 -> sfdp [label="是"]
    Q3 -> Q5 [label="否"]
    Q5 -> osage [label="是"]
    Q5 -> fdp [label="否\n(< 1000 节点)"]
    Q3 -> fdp [label="否\n(< 1000 节点)" style=dashed]
}

场景对照表

场景 推荐引擎 备选引擎 理由
流程图 dot 层次结构完美适配
状态机 dot circo 状态转换有层次
类图 dot 继承关系天然层次
网络拓扑 fdp neato 无明显层次
社交网络 sfdp fdp 节点多
组织架构 twopi dot 树形辐射
目录结构 twopi dot 层次树
循环流水线 circo 环形结构
分组展示 osage 矩形分组
面积权重 patchwork Treemap
ER 图 dot 实体关系层次

注意事项

⚠️ 引擎不可混用:一个 DOT 文件只能用一种引擎。切换引擎需用命令行参数 -K-T

⚠️ neato 的 overlap:默认不处理重叠,必须设置 overlap=false

⚠️ dot 的 rankrank=same 只在 dot 引擎中有效。

⚠️ 大图性能sfdp 是处理大图(>1000 节点)的最佳选择。

⚠️ circo 的循环:需要明确的环形结构才能获得好效果。


扩展阅读


下一章07 - 子图与集群 — 使用子图和集群组织复杂图形。