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

Graphviz 图形可视化教程 / 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 线型 soliddasheddottedboldtapered
color 颜色 "#666666""red"
penwidth 线宽 123
arrowsize 箭头大小 0.81.01.5
arrowhead 头部箭头形状 见 5.2
arrowtail 尾部箭头形状 同上
dir 方向 forwardbackbothnone
decorate 装饰线 truefalse
constraint 是否影响排名 truefalse

边样式示例

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 - 布局引擎 — 了解各布局引擎的原理和选择策略。