01 - Graphviz 概述
第 01 章 · Graphviz 概述
1.1 什么是 Graphviz
Graphviz(Graph Visualization Software)是由 AT&T 实验室开发的开源图形可视化软件包。它的核心理念是:
用声明式语言描述图形的拓扑结构,让算法自动计算最优布局。
与手动拖拽绘图工具(如 Visio、draw.io)不同,Graphviz 让你专注于**“画什么”而非“怎么画”**。
核心优势
| 特性 | 说明 |
|---|---|
| 声明式 | 用文本描述结构,而非像素坐标 |
| 自动布局 | 多种引擎自动计算节点位置 |
| 版本友好 | 纯文本可 diff、可 merge |
| 格式丰富 | 输出 PNG/SVG/PDF/PS 等多种格式 |
| 可编程 | 可通过脚本动态生成图形 |
| 开源免费 | Eclipse Public License |
1.2 DOT 语言简介
DOT 是 Graphviz 使用的图形描述语言,语法极其简洁:
digraph G {
A -> B -> C
A -> C
}
这段代码描述了一个有向图:A 指向 B,B 指向 C,同时 A 也直接指向 C。
DOT 语言的三个核心元素
// 1. 图声明
digraph G { ... } // 有向图
graph G { ... } // 无向图
// 2. 节点声明与属性
A [label="节点A" shape=box]
// 3. 边声明与属性
A -> B [label="连接" color=red]
DOT 语法速查
| 语法 | 含义 | 示例 |
|---|---|---|
digraph { ... } | 有向图 | digraph G { A -> B } |
graph { ... } | 无向图 | graph G { A -- B } |
-> | 有向边 | A -> B |
-- | 无向边 | A -- B |
[key=value] | 属性 | A [shape=box] |
subgraph { ... } | 子图 | subgraph cluster_0 { ... } |
// 或 /* */ | 注释 | // 这是注释 |
1.3 布局引擎概览
Graphviz 提供多种布局引擎,适用于不同类型的图形结构:
| 引擎 | 算法类型 | 适用场景 | 特点 |
|---|---|---|---|
| dot | 层次布局 | 流程图、DAG、层次结构 | 自上而下/自左而右分层 |
| neato | 力导向布局 | 小型无向图、网络拓扑 | 弹簧模型,物理模拟 |
| fdp | 力导向布局 | 大型无向图 | neato 的改进版,性能更好 |
| sfdp | 多尺度力导向 | 超大型图 | 分层力导向,处理数万节点 |
| twopi | 放射布局 | 树形结构、辐射关系 | 根节点居中,向外辐射 |
| circo | 圆形布局 | 循环结构、环形拓扑 | 节点沿圆弧排列 |
| osage | 矩形布局 | 层次分组 | 矩形嵌套分组 |
| patchwork | 矩形树图 | 层次数据可视化 | 面积编码层次关系 |
引擎选择流程图
digraph EngineGuide {
rankdir=TB
node [shape=box style=rounded fillcolor="#FFF3E0" color="#FF9800" fontname="Microsoft YaHei"]
edge [color="#666666"]
start [label="你的图形类型?" shape=diamond fillcolor="#E3F2FD" color="#1976D2"]
directed [label="有向图/DAG\n流程图"]
undirected [label="无向图"]
tree [label="树形/层次"]
circular [label="环形/循环"]
large [label="节点数 > 1000?"]
start -> directed [label="有向边"]
start -> undirected [label="无向边"]
start -> tree [label="树结构"]
start -> circular [label="环形结构"]
directed -> dot [label="推荐"]
undirected -> large
large -> fdp [label="是"]
large -> neato [label="否"]
tree -> twopi
circular -> circo
dot [fillcolor="#C8E6C9" color="#388E3C"]
neato [fillcolor="#C8E6C9" color="#388E3C"]
fdp [fillcolor="#C8E6C9" color="#388E3C"]
twopi [fillcolor="#C8E6C9" color="#388E3C"]
circo [fillcolor="#C8E6C9" color="#388E3C"]
}
1.4 适用场景
✅ 典型应用场景
| 场景 | 说明 | 推荐引擎 |
|---|---|---|
| 软件架构图 | 模块依赖、微服务拓扑 | dot |
| 流程图 | 业务流程、审批链 | dot |
| 状态机 | 有限状态自动机(FSM) | dot |
| 网络拓扑 | 服务器连接、网络设备 | neato/fdp |
| 类图/ER图 | UML 类关系、数据库 ER | dot |
| 目录树 | 文件系统、组织架构 | twopi |
| 调用链 | 函数调用关系、API 依赖 | dot |
| 知识图谱 | 实体关系网络 | fdp/sfdp |
| CI/CD 流水线 | 构建阶段、依赖关系 | dot |
| 决策树 | 机器学习决策路径 | twopi |
❌ 不适合的场景
| 场景 | 原因 | 替代方案 |
|---|---|---|
| 精确像素级排版 | 自动布局无法精确控制 | Mermaid、draw.io |
| 实时交互式图形 | Graphviz 是静态渲染 | D3.js、Cytoscape.js |
| 3D 可视化 | 仅支持 2D | Gephi、Three.js |
| 超大图(>10万节点) | 布局算法性能瓶颈 | Gephi、Sigma.js |
1.5 发展历史
| 时间 | 事件 |
|---|---|
| 1991 年 | AT&T 实验室的 Stephen North 等人开始开发 |
| 1996 年 | DOT 语言规范首次公开发布 |
| 2000 年 | 开始支持多种布局引擎(neato、twopi 等) |
| 2004 年 | 成为开源项目,采用 EPL 许可证 |
| 2007 年 | 引入 HTML-like 标签(<TABLE> 等) |
| 2013 年 | 布局引擎 osage 和 patchwork 加入 |
| 2019 年 | Graphviz 2.42 发布,大规模代码重构 |
| 2021 年 | 迁移至 GitHub,社区贡献活跃 |
| 2024 年 | 持续维护,支持更多输出格式 |
设计哲学
Graphviz 遵循 Unix 哲学:
- 单一职责 — 每个布局引擎只做一件事
- 文本流 — 输入/输出均为文本,便于管道组合
- 可组合 — 可与
awk、sed、脚本语言无缝集成
# Unix 管道风格使用 Graphviz
echo 'digraph { A -> B -> C }' | dot -Tsvg > output.svg
1.6 第一个完整示例
让我们绘制一个简单的微服务架构图:
digraph Microservices {
// 全局设置
rankdir=TB
bgcolor="#FAFAFA"
fontname="Microsoft YaHei"
node [fontname="Microsoft YaHei" fontsize=11]
edge [fontname="Microsoft YaHei" fontsize=9]
// 客户端
subgraph cluster_clients {
label="客户端"
style=dashed
color="#9E9E9E"
WebApp [shape=box style=filled fillcolor="#E3F2FD" color="#1976D2" label="Web 应用"]
MobileApp [shape=box style=filled fillcolor="#E3F2FD" color="#1976D2" label="移动 App"]
}
// 网关
Gateway [shape=box3d style=filled fillcolor="#FFF3E0" color="#FF9800" label="API 网关"]
// 服务
subgraph cluster_services {
label="微服务层"
style=dashed
color="#4CAF50"
UserService [shape=component style=filled fillcolor="#E8F5E9" color="#388E3C" label="用户服务"]
OrderService [shape=component style=filled fillcolor="#E8F5E9" color="#388E3C" label="订单服务"]
PayService [shape=component style=filled fillcolor="#E8F5E9" color="#388E3C" label="支付服务"]
}
// 数据层
subgraph cluster_data {
label="数据层"
style=dashed
color="#9C27B0"
MySQL [shape=cylinder style=filled fillcolor="#F3E5F5" color="#7B1FA2" label="MySQL"]
Redis [shape=cylinder style=filled fillcolor="#F3E5F5" color="#7B1FA2" label="Redis"]
}
// 连接关系
WebApp -> Gateway [label="HTTP"]
MobileApp -> Gateway [label="HTTP"]
Gateway -> UserService [label="gRPC"]
Gateway -> OrderService [label="gRPC"]
OrderService -> PayService [label="调用"]
UserService -> MySQL [label="读写"]
OrderService -> MySQL [label="读写"]
UserService -> Redis [label="缓存"]
}
将以上代码保存为 microservices.dot,执行:
dot -Tpng microservices.dot -o microservices.png -Gdpi=150
dot -Tsvg microservices.dot -o microservices.svg
1.7 与其他工具对比
| 工具 | 类型 | 优点 | 缺点 |
|---|---|---|---|
| Graphviz | 声明式/自动布局 | 版本控制友好、布局算法强 | 精确排版困难 |
| Mermaid | 声明式/自动布局 | Markdown 集成好 | 图形类型有限 |
| draw.io | 所见即所得 | 直观、易上手 | 不易版本控制 |
| PlantUML | 声明式 | UML 支持全面 | 依赖 Java |
| D3.js | 编程式 | 高度可定制 | 学习曲线陡 |
| yEd | 桌面工具 | 丰富的自动布局 | 非文本格式 |
注意事项
⚠️ 编码问题:DOT 文件必须使用 UTF-8 编码,否则中文标签可能乱码。
⚠️ 特殊字符:节点标签中的
<、>、{、}、|需要转义或使用 HTML 标签。
⚠️ 布局引擎差异:同一份 DOT 代码在不同引擎下效果完全不同,需根据场景选择。
⚠️ 有向图 vs 无向图:
digraph使用->,graph使用--,混用会报错。
扩展阅读
- Graphviz 官方文档
- DOT 语言规范
- Graphviz Gallery — 官方示例集
- Graphviz 在学术论文中的应用
- 书籍:《Drawing Graphs with Dot》— Graphviz 官方指南
下一章:02 - 安装与环境配置 — 在各平台安装 Graphviz 并配置开发环境。