Mermaid 流程图连线交叉打结?ELK 算法布局调优完整指南
【免费下载链接】mermaidGeneration of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown项目地址: https://gitcode.com/GitHub_Trending/me/mermaid
用 Mermaid 写流程图,节点一多,渲染出来的布局就容易"翻车":连线互相打结、节点挤成一团。Mermaid 是一个用类 Markdown 文本生成流程图、时序图等图表的工具,而当图变大变复杂时,把底层布局引擎切换到 ELK 算法,往往能一次把可读性救回来。
默认布局何时失守:连线交叉与节点重叠
Mermaid 默认使用 Dagre 来排布节点,白话讲就是"分层布局":它把节点按依赖关系排进若干层,同一层横向并排,然后从上往下连。这种方式对"一条主线加几个分支"的小图非常友好,快且零配置。
但有三类场景它容易失守:
- 分支扇出太多:一个节点向四个方向发散,Dagre 的层内空间不够,边开始绕行穿节点;
- subgraph 嵌套较深:分组框与跨组连线叠加,线直接划过别的组;
- 存在回环:状态会跳回前面的节点,布局引擎为了"断环",可能把真正的入口节点排到图中间,整张图从中间开始读,顺序感全乱。
这三种情况的共同表现就是流程图连线交叉严重、局部重叠,读者被迫沿着线"找路"。
为什么选 ELK:它是一套布局工具箱,而不是另一个 Dagre
先解释一下术语。ELK 全称 Eclipse Layout Kernel,是一个开源的图布局框架,可以理解成"一套统一接口、内置多种布局算法"的工具箱。Mermaid 的 ELK 布局就构建在它之上,相关实现位于仓库的 packages/mermaid-layout-elk/ 目录,底层通过 elkjs 运行。
它和 Dagre 的本质区别在于:Dagre 是单一种算法,而 ELK 让你按场景挑策略。目前 Mermaid 注册的布局名有:
elk(默认,等价于elk.layered):分层布局,也就是常说的 LAYERED——把同层节点排进同一"层"再逐层向下铺开,最适合有明确先后顺序的流程、审批链、部署管线这类图;elk.stress:应力布局,靠"弹簧拉伸"找平衡位置,适合网状、对等结构;elk.force:力导向布局,观感更"有机的",适合没有强层次关系的关系图;elk.mrtree/elk.sporeOverlap:多根树、Spore 布局,面向特定形态的图。
所以官方文档里的定位也很直接:elk 渲染器更适合更大、更复杂的图。它不是要取代 Dagre,而是给复杂场景多一个出口。
flowchart-elk 一步启用:三种方式任选
方式一:改一行图头。在 Markdown 或任何支持 Mermaid 的编辑器里,把flowchart TD换成flowchart-elk TD即可,下面的语法完全不用动:
flowchart-elk TD ORDER[订单创建] --> PAY{支付成功?} PAY -->|是| FULFILL[拣货发货] PAY -->|否| RETRY[推送催付] RETRY --> PAY FULFILL --> DONE((完成))方式二:用 frontmatter 按图配置。不想改图头时,可以在图的配置区声明布局,还能顺带指定非默认算法:
--- config: layout: elk --- flowchart TD ORDER --> PAY把layout改成elk.stress、elk.force等,就能用对应的算法渲染同一张图。
方式三:Web 项目里注册外部布局模块。如果你的站点自己打包 Mermaid,装一个包、注册一次即可:
import mermaid from 'mermaid'; import elkLayouts from '@mermaid-js/layout-elk'; mermaid.registerLayoutLoaders(elkLayouts);注册后,页面上写flowchart-elk就自动生效;ELK 引擎是按需加载的,没用到时不会增加额外体积。可以在 demos/flowchart-elk.html 里直接看到注册后的实际效果。
ELK 布局配置:三个最值得先动的参数
ELK 的参数很多,新手只需先认识这几个(均在config.elk下,默认值可查 packages/mermaid/src/defaultConfig.ts):
- 方向:直接沿用图里的 direction 语句,
TD/TB向下、BT向上、LR向右,按阅读习惯选即可,一般不用单独折腾; mergeEdges(默认关闭):允许多条边共享路径。看起来更整洁,但单条线更难辨认——同一对节点之间连了很多线时再开;nodePlacementStrategy(默认BRANDES_KOEPF):控制同层节点的横向对齐方式,可选SIMPLE、NETWORK_SIMPLEX、LINEAR_SEGMENTS、BRANDES_KOEPF。嫌层内参差,可试换LINEAR_SEGMENTS对比效果;keepEntryNodeOnTop(默认关闭):专门治回环图的"入口跑到中间"问题。开启后,每个循环子流程的入口节点会被固定在首层,保证图从入口读起。上一节示例里RETRY --> PAY的回环就是它的应用场景。
另外一个细节:ELK 渲染包内部的基础间距是主图 40、子图内 30,节点之间默认留白并不小。如果还是显得拥挤,优先考虑把同类节点收进 subgraph 分组,而不是逐个调参。
复杂场景避坑:子图、回环与大图性能
- 先分组,再调参:ELK 会整体排布每个 subgraph 再落位,图乱的根源往往是结构没分层。把"订单域""库存域"这类逻辑单元先框出来,收益通常大于任何参数微调。
- 跨组连线要克制:跨子图跳线会明显拉长路径,写图时就减少跨域依赖,比事后优化更省事。
- 回环图记得开
keepEntryNodeOnTop,避免阅读顺序错乱。 - 大图别硬堆节点:ELK 的分层算法开销随节点数上升,几百节点的大图,正确姿势是把细节折叠进子图、必要时拆图,而不是继续往一张图里塞。
- 一个前提要清楚:ELK 渲染器在官方文档中仍标注为实验特性,且各第三方平台不一定内置——自建站点必须自己安装
@mermaid-js/layout-elk,否则写了flowchart-elk也不会生效。
选型建议与资源入口
一句话选型:十几个节点以内、单向流程为主,留在 Dagre,它最快、零配置,性能优势明显;分支多、有 subgraph 嵌套、存在回环的复杂图,切到flowchart-elk;想要网状、有机观感时再试elk.stress或elk.force。
延伸阅读(均为本仓库内路径):
- 流程图语法与 elk 渲染器说明:docs/syntax/flowchart.md
- ELK 演示页:demos/flowchart-elk.html
- ELK 布局实现源码:packages/mermaid-layout-elk/
- 全局配置默认值(含
elk段):packages/mermaid/src/defaultConfig.ts
图能读通就是好图:小图信任默认,复杂图交给 ELK。
【免费下载链接】mermaidGeneration of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown项目地址: https://gitcode.com/GitHub_Trending/me/mermaid
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考