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

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空心箭头
teeT 形
veeV 形(常用)
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 - 布局引擎 — 了解各布局引擎的原理和选择策略。