05 - 边详解
第 05 章 · 边详解
5.1 边的基本语法
digraph EdgeBasics {
// 有向边
A -> B
// 无向边(graph 中使用 --)
// A -- B
// 链式边
A -> B -> C -> D
// 多目标边
A -> {B C D}
// 带属性的边
A -> B [label="连接" color=red style=dashed]
}
5.2 箭头类型 (Arrow Shape)
arrowhead 属性值
Graphviz 提供 15 种箭头样式,通过 arrowhead 设置头部、arrowtail 设置尾部。
| 箭头名 | 形状 | 说明 |
|---|---|---|
normal | ▶ | 默认三角箭头 |
box | ■ | 实心方块 |
crow | ◁ | 乌鸦尾(反向) |
curve | 〰️ | 曲线箭头 |
diamond | ◆ | 菱形 |
dot | ● | 实心圆 |
inv | ◀ | 反三角 |
invdot | ◉ | 反三角+圆 |
invodot | ◎ | 空心反三角+圆 |
none | — | 无箭头 |
normal | ▶ | 标准三角 |
obox | □ | 空心方块 |
odiamond | ◇ | 空心菱形 |
odot | ○ | 空心圆 |
oinv | ▷ | 空心反三角 |
open | ▷ | 空心箭头 |
tee | ⊢ | T 形 |
vee | ⩔ | V 形(常用) |
halfopen | ⊣ | 半开箭头 |
箭头展示
digraph ArrowShapes {
rankdir=LR
node [shape=plaintext fontname="Microsoft YaHei"]
edge [fontname="Microsoft YaHei" fontsize=9]
n0 [label="normal ▶"]
n1 [label="vee ⩔"]
n2 [label="diamond ◆"]
n3 [label="dot ●"]
n4 [label="box ■"]
n5 [label="crow ◁"]
n6 [label="tee ⊢"]
n7 [label="inv ◀"]
n8 [label="open ▷"]
n9 [label="none —"]
target [label="目标" shape=box style=rounded]
n0 -> target [arrowhead=normal]
n1 -> target [arrowhead=vee]
n2 -> target [arrowhead=diamond]
n3 -> target [arrowhead=dot]
n4 -> target [arrowhead=box]
n5 -> target [arrowhead=crow]
n6 -> target [arrowhead=tee]
n7 -> target [arrowhead=inv]
n8 -> target [arrowhead=open]
n9 -> target [arrowhead=none]
}
边方向 (dir 属性)
digraph EdgeDir {
node [fontname="Microsoft YaHei"]
A -> B [label="forward(默认)" dir=forward]
C -> D [label="back(反向箭头)" dir=back]
E -> F [label="both(双向箭头)" dir=both]
G -> H [label="none(无箭头)" dir=none]
}
5.3 边标签 (Label)
标签位置
digraph EdgeLabels {
node [fontname="Microsoft YaHei" shape=box style=rounded]
A -> B [
label="headlabel" // 边中间标签
headlabel="头部标签" // 箭头端标签
taillabel="尾部标签" // 起始端标签
labeldistance=1.5 // 标签距节点距离
labelangle=45 // 标签角度
]
}
标签属性
| 属性 | 说明 | 默认值 |
|---|---|---|
label | 边中间标签 | — |
headlabel | 箭头端标签 | — |
taillabel | 起始端标签 | — |
labeldistance | 标签距节点距离 | 1.0 |
labelangle | 标签角度 | -25.0 |
labelfontcolor | 标签字体颜色 | 边颜色 |
labelfontname | 标签字体 | 全局字体 |
labelfontsize | 标签字号 | 14 |
labeltooltip | 标签鼠标提示 | — |
多标签边
digraph MultiLabels {
node [fontname="Microsoft YaHei"]
A -> B [
label="边中部"
headlabel="目标端"
taillabel="源端"
fontcolor="#1976D2"
labelfontcolor="#F44336"
]
}
5.4 边样式 (Style)
样式属性
| 属性 | 说明 | 常用值 |
|---|---|---|
style | 线型 | solid、dashed、dotted、bold、tapered |
color | 颜色 | "#666666"、"red" |
penwidth | 线宽 | 1、2、3 |
arrowsize | 箭头大小 | 0.8、1.0、1.5 |
arrowhead | 头部箭头形状 | 见 5.2 |
arrowtail | 尾部箭头形状 | 同上 |
dir | 方向 | forward、back、both、none |
decorate | 装饰线 | true、false |
constraint | 是否影响排名 | true、false |
边样式示例
digraph EdgeStyles {
node [fontname="Microsoft YaHei" shape=box]
A -> B [label="solid 实线" style=solid]
A -> C [label="dashed 虚线" style=dashed]
A -> D [label="dotted 点线" style=dotted]
B -> E [label="bold 粗线" style=bold penwidth=3]
C -> F [label="tapered 渐细" style=tapered penwidth=4]
}
渐变色边
digraph GradientEdge {
node [fontname="Microsoft YaHei"]
A -> B [
color="#1976D2:#388E3C" // 渐变色(支持多色)
penwidth=3
style=bold
label="渐变边"
]
}
5.5 端口连接
位置端口
digraph PortEdge {
node [fontname="Microsoft YaHei" shape=box style=filled fillcolor="#E3F2FD"]
A [label="节点 A"]
B [label="节点 B"]
C [label="节点 C"]
D [label="节点 D"]
// 从 A 的东边出发,到 B 的西边
A:e -> B:w [label="东→西"]
// 从 A 的南边出发,到 C 的北边
A:s -> C:n [label="南→北"]
// 从 B 的东南出发,到 D 的西北
B:se -> D:nw [label="东南→西北"]
}
Record 端口
digraph RecordPortEdge {
node [shape=record fontname="Microsoft YaHei"]
server [label="{<req> 请求处理|<resp> 响应生成|<log> 日志记录}"]
client [label="{<send> 发送请求|<recv> 接收响应}"]
logger [label="日志系统"]
client:send -> server:req [label="HTTP"]
server:resp -> client:recv [label="JSON"]
server:log -> logger [label="写入" style=dashed]
}
5.6 约束 (Constraint)
constraint 属性控制边是否影响布局中的节点排名(层级)。
digraph ConstraintDemo {
rankdir=TB
node [fontname="Microsoft YaHei" shape=box style=filled fillcolor="#E3F2FD" color="#1976D2"]
A -> B [label="正常约束\n影响排名" constraint=true]
A -> C [label="无约束\n不影响排名" constraint=false style=dashed color="#F44336"]
B -> D
C -> D
// B 和 C 在同一层(因为 A->C 不约束 C 的排名)
}
业务场景:隐藏的布局影响
digraph HiddenConstraint {
node [fontname="Microsoft YaHei"]
// 主流程(实线,有约束)
Start -> Step1 -> Step2 -> End [constraint=true]
// 辅助连线(虚线,无约束)
Start -> End [label="快捷路径" style=dashed constraint=false color="#999999"]
}
5.7 权重 (Weight)
weight 属性控制边在布局中的优先级。权重越高,边越直、越短。
digraph WeightDemo {
node [fontname="Microsoft YaHei" shape=box]
A -> B [label="weight=1" weight=1]
A -> C [label="weight=10\n优先拉直" weight=10 penwidth=2 color="#F44336"]
B -> D
C -> D
}
5.8 边的装饰
装饰线 (Decorate)
digraph DecorateDemo {
node [fontname="Microsoft YaHei"]
A -> B [label="decorate=true\n标签有连接线" decorate=true]
C -> D [label="decorate=false\n默认" decorate=false]
}
边的最小长度 (minlen)
digraph MinlenDemo {
node [fontname="Microsoft YaHei"]
A -> B [label="minlen=1\n默认" minlen=1]
A -> C [label="minlen=3\n强制间隔3层" minlen=3 style=dashed color="#F44336"]
B -> D
C -> D
}
5.9 自环与多边
自环 (Self Loop)
digraph SelfLoop {
node [fontname="Microsoft YaHei" shape=circle]
A -> A [label="自环" color="#F44336"]
B -> B [label="带端口" headport=n taillabel=e style=dashed]
}
多边 (Multi-Edge)
同一对节点之间可以有多条边:
digraph MultiEdge {
node [fontname="Microsoft YaHei"]
A -> B [label="边1" color="#1976D2"]
A -> B [label="边2" color="#388E3C" style=dashed]
A -> B [label="边3" color="#F44336" dir=both]
// 合并多边(可选)
// concentrate=true 在图属性中设置会合并平行边
}
5.10 业务场景:状态机
digraph StateMachine {
rankdir=LR
bgcolor="#FAFAFA"
node [fontname="Microsoft YaHei" fontsize=11]
edge [fontname="Microsoft YaHei" fontsize=9]
// 状态节点
Idle [shape=circle style=filled fillcolor="#E8F5E9" color="#388E3C" label="空闲"]
Running [shape=doublecircle style=filled fillcolor="#E3F2FD" color="#1976D2" label="运行中"]
Paused [shape=circle style=filled fillcolor="#FFF3E0" color="#FF9800" label="暂停"]
Error [shape=doublecircle style=filled fillcolor="#FFEBEE" color="#C62828" label="错误"]
Stopped [shape=doublecircle style=filled fillcolor="#ECEFF1" color="#546E7A" label="已停止"]
// 初始状态
Start [shape=point width=0.2]
// 转换
Start -> Idle [label="初始化"]
Idle -> Running [label="启动" color="#388E3C"]
Running -> Paused [label="暂停" color="#FF9800"]
Paused -> Running [label="恢复" color="#1976D2"]
Running -> Error [label="异常" color="#C62828"]
Error -> Idle [label="重置" color="#546E7A" style=dashed]
Running -> Stopped [label="停止" color="#546E7A"]
Stopped -> Idle [label="重新启动" color="#388E3C" style=dashed]
Idle -> Stopped [label="关闭" color="#546E7A"]
}
注意事项
⚠️
-和->:在有向图中使用->,用-会报错;无向图中使用--。
⚠️ label 距离:
labeldistance的值是节点半径的倍数,不是绝对像素。
⚠️ constraint=false 的副作用:可能导致节点出现在意外的位置层级。
⚠️ 端口语法:
node:port中的 port 名在 Record 中是f0/f1等,在位置端口中是n/s/e/w。
⚠️ 多边重叠:同一对节点的多条边可能重叠,可通过调整
label和颜色区分。
扩展阅读
下一章:06 - 布局引擎 — 了解各布局引擎的原理和选择策略。