首页
/ Mermaid Swimlanes(泳道图)语法与实战指南:用 subgraph 表达"谁负责"的流程图

Mermaid Swimlanes(泳道图)语法与实战指南:用 subgraph 表达"谁负责"的流程图

2026-09-06 18:53:47作者:齐添朝

导读

泳道图(Swimlane Diagram)是 Mermaid 自 v11.16.0 起引入的实验性图类型(以 swimlane-beta 为起始关键字,语法仍可能在后续版本演进)。与普通流程图只回答"接下来发生什么"不同,泳道图通过纵向划分的"泳道"额外回答"这一步归谁负责"。本文基于仓库中的官方文档 swimlanes.md(渲染后的用户文档见 docs/syntax/swimlanes.md)并结合源码,完整讲解其声明方式、泳道/节点/连线语法、无障碍声明、专项配置项与布局引擎的实现原理。读完本文,你将能直接写出结构清晰的审批流、工单流转与跨团队交付流程,并了解该图类型背后"复用 flowchart 引擎、仅替换泳道布局"的架构设计。

什么是泳道图:按职责划分的过程图

泳道图把一条流程按"负责人"切开:每条泳道(lane)代表一个参与者(actor)、团队、系统或阶段,泳道内的节点表示发生在该负责人身上的工作,箭头表示工作的先后顺序以及发生在泳道之间的"交接(handoff)"。

当流程中最重要的信息不仅是"下一步是什么",还包括"这一步由谁拥有"时,就该使用泳道图。典型场景包括:

  • 审批流(申请人 / 审核人 / 系统);
  • 支持/工单流程(客户 → 支持 → 工程);
  • 交付与履约工作流(订单 → 仓储 → 物流);
  • 任何需要跨团队、跨系统协作的业务过程。

快速开始:第一个泳道图示例

泳道图以 swimlane-beta 关键字开头,随后可用 subgraph 声明泳道、用 flowchart 风格语法声明节点与连线。下面是一个最基础的客户支持流程:

swimlane-beta LR
  subgraph Customer
    request[Request service]
    receive[Receive update]
  end

  subgraph Support
    triage[Triage request]
    answer[Send answer]
  end

  subgraph Engineering
    investigate[Investigate issue]
    fix[Prepare fix]
  end

  request --> triage
  triage -->|Known issue| answer
  triage -->|Needs code change| investigate
  investigate --> fix --> answer
  answer --> receive

说明:本页示例使用了 Neo 外观与 Redux 主题渲染;开箱即用时,泳道图使用你配置的默认 look 与 theme,无需额外设置。

从渲染结果可以看出:请求先在 Customer 泳道发起,交接给 Support 泳道做分类,遇到"需要改代码"的分支再交接给 Engineering,最终答案又回到 Customer。泳道本身即承担了"归属"这一维度的信息表达。

核心语法:声明关键字与方向

一个泳道图必须从 swimlane-beta 关键字开始,其后可以(可选地)跟一个方向声明:

swimlane-beta
swimlane-beta LR

支持的方向及含义如下:

方向 含义
TB 从上到下(Top to bottom)
TD 自上而下,与 TB 相同
BT 从下到上(Bottom to top)
LR 从左到右(Left to right)
RL 从右到左(Right to left)

若未显式声明方向,默认使用 TB 从源码角度看,swimlane 图对方向的解析完全复用了 flowchart 的语法能力,因为它本质上是一个"复用 flowchart 解析器、数据库与渲染器,仅替换布局引擎"的图类型(详见下文 实现原理)。

Lanes(泳道):用 subgraph 声明

泳道使用 subgraph ... end 块声明。在泳道图中,顶层的 subgraph 会被渲染为泳道

swimlane-beta
  subgraph Sales
    lead[Qualify lead]
    quote[Prepare quote]
  end

为泳道指定内部 id 与显示标签

当标签包含空格,或希望为样式化提供一个稳定 id 时,可以使用 subgraph id [label] 形式,为泳道同时指定内部 id 和展示标签:

swimlane-beta LR
  subgraph sales [Sales team]
    lead[Qualify lead]
    quote[Prepare quote]
  end

  subgraph finance [Finance team]
    review[Review terms]
    approve[Approve quote]
  end

  lead --> quote --> review --> approve

Nodes(节点):flowchart 风格形状

泳道内部的节点使用与 flowchart 相同的"形状"语法:先写节点 id,再在形状符号内写标签。例如下面覆盖了最常见的几种节点形态(起止、普通任务、分支判断):

swimlane-beta LR
  subgraph Intake
    start([Start])
    task[Do work]
    fix[Fix issues]
  end

  subgraph Review
    decision{Ready?}
  end

  subgraph Complete
    done((Done))
  end

  start --> task --> decision
  decision -->|Yes| done
  decision -->|No| fix
  fix --> task

最常见的节点写法与对应形状、用途归纳如下:

语法 形状 常见用途
id[Text] 矩形 任务或活动
id(Text) 圆角矩形 步骤或事件
id([Text]) 体育场形(两端半圆) 开始或结束
id{Text} 菱形(决策) 分支判断问题
id((Text)) 圆形 连接点或标记

更完整的形状目录(图标、图片、Markdown 字符串、类定义与样式化等),请直接参见 Flowchart 语法

Edges(连线):支持同泳道与跨泳道

连线同样沿用 flowchart 语法,既可以连接同一泳道内的节点,也可以跨泳道连接(跨泳道连线即"交接"):

swimlane-beta LR
  subgraph Buyer
    choose[Choose product]
    pay[Pay invoice]
  end

  subgraph Store
    reserve[Reserve stock]
    ship[Ship product]
  end

  choose --> reserve
  reserve -->|Invoice ready| pay
  pay --> ship

常见的连线写法:

语法 含义
A --> B 带箭头的连线
A --- B 无箭头的连线
A -->|Label| B 带标签的箭头连线
A -.-> B 虚线箭头
A ==> B 粗箭头

完整的连线语法(包括多向箭头、最小连线长度等),参见 Flowchart 语法 · Links between nodes

无障碍访问:accTitle 与 accDescr

与 Mermaid 其他图类型一致,泳道图支持使用 accTitleaccDescr 提供无障碍标题与描述,便于屏幕阅读器与辅助技术理解图意:

swimlane-beta LR
  accTitle: Support escalation
  accDescr: A request starts with the customer, is triaged by support, and may be escalated to engineering.

  subgraph Customer
    request[Open request]
  end

  subgraph Support
    triage[Triage]
  end

  subgraph Engineering
    resolve[Resolve]
  end

  request --> triage --> resolve

实现原理:基于 flowchart 的 "layout-variant" 图

理解泳道图最好从源码切入。它是一个相当有代表性的架构示例——没有复制 flowchart 的实现,而是整体复用了 flowchart 的解析器(parser)、数据模型(db)与渲染器(renderer),只替换了默认布局引擎与泳道专用样式

源码 swimlanesDiagram.ts 中的注释清楚地说明了这一点:swimlane 是"布局变体图(layout-variant diagram)",它刻意调用 flowchart 的公开工厂函数 createFlowDiagram 而非重复整个 flowchart 插件,这是跨图隔离规则的唯一特许例外——依赖仅作用于 flowchart 的导出入口,绝不触碰其内部实现:

// packages/mermaid/src/diagrams/swimlanes/swimlanesDiagram.ts
import { createFlowDiagram } from '../flowchart/flowDiagram.js';
import swimlanesStyles from './styles.js';

export const diagram = createFlowDiagram({ defaultLayout: 'swimlane', styles: swimlanesStyles });

与之配套的检测与懒加载逻辑位于 detector.ts:检测器用正则 /^\s*swimlane-beta\b/ 识别文本是否以 swimlane-beta 开头,然后通过异步 loader 在真正需要渲染时才加载该图插件:

const detector: DiagramDetector = (txt) => /^\s*swimlane-beta\b/.test(txt);

该插件随后注册进 Mermaid 的图编排表(见 diagram-orchestration.ts 中对 swimlanes 的引入与注册),与 flowchart、sequence 等图类型一同参与分发。

在样式层面,styles.ts 复用 flowchart 的完整样式函数,再追加泳道专用规则:因为泳道簇(cluster)形状会自行绘制泳道边界,需要把通用的 .cluster rect 边框抑制掉——具体做法是把其描边颜色与簇背景相匹配,并且是主题自适应的(而非写死某种颜色):

const getStyles = (options: FlowChartStyleOptions): string =>
  `${getFlowchartStyles(options)}
  .swimlane.cluster rect {
    stroke: ${options.clusterBorder} !important;
  }
  [data-look="neo"].cluster rect {
    filter: none;
  }
`;

真正产生泳道布局效果的是 defaultLayout: 'swimlane' 所指向的专用布局流水线。在 rendering-util/layout-algorithms/swimlanes 目录下可以看到该布局引擎的完整模块:负责主干流程的 pipeline.ts/layoutCore.ts、方向变换(direction/ 下如 lrTransform.ts 处理 LR/RL 等方向的坐标换算)、泳道内排序(__tests__/laneOrdering.spec.ts)、正交连线路由器(orthogonalRouter/router.ts)等;同时还有大量针对布局质量的端到端用例(如 __tests__/pipeline.lr.e2e.spec.ts15-border-hugging-lr.ddlt.spec.ts)。此外 swimlanesDiagram.spec.ts 验证了图类型本身的行为,而仓库根目录 e2e/diagrams/swimlanes 下的一组 .mmd 样例则用于快照级视觉回归。

泳道图专项配置(SwimlaneDiagramConfig)

由于复用了 flowchart 渲染器与配置(如 curve、htmlLabels、间距等共享选项),泳道图的大部分外观由 flowchart 配置控制;只有布局管线专用的"旋钮"集中在 SwimlaneDiagramConfig 配置块中。其类型定义见 config.type.ts

配置项 类型 含义
lineHops boolean | 'arc' | 'gap' 把交叉边渲染成小圆弧("hops")或可见间隙,减少重叠边的阅读困难;设为 false 可关闭。渲染为曲线的边会被跳过,以免破坏几何形状
ignoreCrossLaneEdges boolean 在做泳道分层(layer assignment)时忽略跨越泳道边界的边。对于含大量跨泳道连线的图,可改善层级质量
optimizeRanksByCrossings boolean 为泳道布局启用一次"感知交叉的等级优化(crossing-aware rank optimization)"扫描
automaticLaneOrdering boolean 用确定性加权线性排列启发式自动重排顶层泳道。默认关闭——因为源码中泳道的书写顺序本身可能携带语义

其中尤其值得注意 automaticLaneOrdering:源码注释明确说明它默认不启用,原因是"源码泳道顺序可能承载语义"——即在手工编排的泳道图中,泳道自左(或自上)而下的次序常常对应责任方出场顺序。若交给算法重排,虽然可能减少交叉,却可能改变叙述顺序。

配置方式与其他图类型一致,可通过 initialize 或在文本中通过 %%{ init: ... }%% 指令下发。例如:

mermaid.initialize({
  startOnLoad: true,
  swimlane: {
    lineHops: true,
    automaticLaneOrdering: false,
    optimizeRanksByCrossings: true,
  },
});

最佳实践

让每条泳道只表达一种"归属"

泳道应当回答"这一步由谁负责?"。除非"区分团队/阶段/状态"正是这张图的表达目的,否则不要在同一张图里混用团队、阶段与状态三种维度。

swimlane-beta LR
  subgraph Customer
    submit[Submit order]
    confirm[Confirm delivery]
  end

  subgraph Store
    check[Check order]
    pack[Pack items]
  end

  subgraph Carrier
    collect[Collect package]
    deliver[Deliver package]
  end

  submit --> check --> pack --> collect --> deliver --> confirm

为跨泳道交接连线加标签

跨泳道箭头意味着责任方的变更。当交接依赖某份文档、一次决策、一条消息或某个条件时,请为这条箭头补上标签,读者才能知道"为什么在这里换人":

swimlane-beta LR
  subgraph Applicant
    apply[Submit application]
    sign[Sign agreement]
  end

  subgraph Reviewer
    screen[Screen application]
    decide{Approved?}
  end

  subgraph System
    create[Create account]
    notify[Send welcome email]
  end

  apply -->|Application received| screen
  screen --> decide
  decide -->|Approved| create --> notify --> sign
  decide -->|Needs changes| apply

长流程要"可一眼读通"

当泳道或交接数量多到一屏放不下时,把一个大的过程拆成多张图。一张好用的泳道图通常应该不需要读者反复追线两遍。

swimlane-beta TB
  subgraph Intake
    collect[Collect request]
    validate[Validate details]
  end

  subgraph Review
    review[Review request]
    decide{Ready?}
  end

  subgraph Delivery
    schedule[Schedule work]
    complete[Complete work]
  end

  collect --> validate --> review --> decide
  decide -->|Yes| schedule --> complete
  decide -->|No| collect

使用稳定的 id

为节点和泳道使用简短而有意义的 id。标签可以在不破坏连线、样式或后续引用的前提下随意修改,因此把"引用稳定性"寄托在 id 上。注意泳道也支持与 flowchart 相同的类与样式语句:

swimlane-beta LR
  subgraph ops [Operations]
    intake[Receive request]
    plan[Plan work]
  end

  subgraph legal [Legal]
    review[Review contract]
  end

  intake --> plan --> review

  classDef attention fill:#fff2cc,stroke:#d6a500,color:#111;
  class review attention;

把决策节点放在"做决定的人"所在泳道

决策发生在哪一方,就把菱形节点放在哪一方,然后让不同分支结果路由到实际执行动作的泳道:

swimlane-beta LR
  subgraph Support
    classify{Can support solve it?}
    respond[Respond to customer]
  end

  subgraph Product
    prioritize[Prioritize fix]
  end

  subgraph Engineering
    implement[Implement fix]
  end

  classify -->|Yes| respond
  classify -->|No| prioritize --> implement --> respond

何时改用其他图类型

泳道图并非万能,官方文档给出了清晰的选型边界:

  • 归属不重要、只需要表达顺序或分支时,改用普通的 flowchart
  • 当重点在于参与者之间随时间流动的消息时,改用 sequence 顺序图
  • 当重点是某一个对象如何随事件改变状态时,改用 state 状态图

一句话概括:泳道图的价值在于同时呈现"流程顺序 + 责任归属 + 交接条件"三个维度;如果你只关心其中一维,其他图类型往往更简洁。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.74 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
595
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.63 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
518
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
389