Mermaid 甘特图编辑器
甘特图把工作放到日历上:什么时候做什么、哪些会重叠、哪一项必须等另一项做完才能开始。当日期和依赖关系才是重点时用它。如果你只需要先后顺序而不需要具体日期,流程图更轻,而且计划一延期它也不会立刻过期。
带依赖与里程碑的发布计划
`after a1` 才是让这张图成为甘特图、而不只是一堆条形的关键——依赖被显式声明了,所以第一项一挪,后面全都跟着挪。里程碑标记的是不占用时间的固定节点。
gantt
title 2.4 版本发布
dateFormat YYYY-MM-DD
axisFormat %m-%d
section 研发
接口约定 :done, a1, 2026-01-06, 10d
功能实现 :active, a2, after a1, 20d
内部测试 : a3, after a2, 8d
section 发布
预发环境验证 : b1, after a3, 5d
发布评审 :milestone, m1, after b1, 0d
生产环境上线 :crit, b2, after m1, 3d实例讲解
1. 最小的合法甘特图
`dateFormat` 告诉 Mermaid 如何解析你写的日期;`axisFormat` 控制日期如何显示。这是两个不同的设置,混淆它们是甘特图最常见的困扰来源。
gantt
title 第 14 个迭代
dateFormat YYYY-MM-DD
section 开发
实现功能 :2026-03-02, 10d2. 任务 ID 与依赖
给任务一个 ID,后面的任务就能写 `after <id>`。依赖一旦声明,改一处开始日期,其余的会自动跟随。
gantt
title 数据迁移
dateFormat YYYY-MM-DD
section 准备
梳理表结构 :a1, 2026-02-02, 5d
编写映射 :a2, after a1, 8d
section 执行
演练 :a3, after a2, 3d
正式切换 :a4, after a3, 1d3. 状态关键字
`done`、`active`、`crit` 会改变条形的画法。这是最省事的办法,让一张图回答“我们现在到哪了”,而不只是“当初计划是什么”。
gantt
title 第一季度平台工作
dateFormat YYYY-MM-DD
section 基础设施
Terraform 整理 :done, t1, 2026-01-05, 12d
Kubernetes 升级 :active, t2, 2026-01-19, 15d
成本复核 : t3, after t2, 5d
section 安全
依赖项审计 :crit, s1, 2026-01-12, 6d4. 里程碑
里程碑是一个时间点而不是一段时间——给它 `0d`。用它标记那些由外部决定的固定日期:一场展会、一个合同期限、一次封版。
gantt
title 上线计划
dateFormat YYYY-MM-DD
section 研发
功能封版 :milestone, m1, 2026-04-01, 0d
集中修缺陷 : e1, 2026-04-01, 5d
拉发布分支 :milestone, m2, after e1, 0d
section 市场
禁发期结束 :milestone, m3, 2026-04-15, 0d5. 排除周末
`excludes weekends` 让工期不计算周六周日,于是 10 天的任务会跨越两个工作周,而不是在周末中间结束。这往往就是一张有人信、和一张被默默无视的计划之间的差别。
gantt
title 新服务接入
dateFormat YYYY-MM-DD
excludes weekends
section 搭建
准备基础设施 :p1, 2026-05-04, 5d
打通 CI/CD :p2, after p1, 5d
section 交接
手册与培训 :p3, after p2, 4d甘特图语法速查
甘特图只在一个地方语法苛刻——任务行——其余地方都异常宽容。这正是甘特图的错误大多“无声无息”的原因。
| 语法 | 含义 |
|---|---|
| gantt | 开启该图。 |
| title 文字 | 图表标题。 |
| dateFormat YYYY-MM-DD | 如何“解析”你写下的日期。 |
| axisFormat %m-%d | 坐标轴上如何“显示”日期。与 dateFormat 是两回事。 |
| excludes weekends | 计算工期时跳过周六和周日。 |
| section 名称 | 把任务归入一个带标题的分组行。 |
| 任务 :id, 2026-01-01, 10d | 指定开始日期与工期的任务。 |
| 任务 :id, after 其他, 10d | 在“其他”结束时开始的任务。 |
| 任务 :done, id, ... | 已完成——画成灰色。 |
| 任务 :active, id, ... | 进行中——高亮显示。 |
| 任务 :crit, id, ... | 关键路径——用强调色画出。 |
| 名称 :milestone, id, 日期, 0d | 一个时间点,而不是一段区间。 |
| 10d / 3w / 2h | 以天、周、小时表示的工期。单位不能省。 |
甘特图的六个坑——其中只有一个会报错
这正是甘特图与本站其他图类型不同的地方。以 Mermaid 11.12.2 复现:下面六项中,只有一项会让图画不出来。其余五项都会生成一张看上去毫无问题、实际却是错的图——而这危险得多,因为没有人会去复核一张已经成功画出来的图。
你会看到
Parse error,结尾是:Expecting 'taskData', got 'NL'
原因
任务行少了冒号。冒号把任务的显示名和数据分开,没有它就没有可解析的数据。这是本列表中唯一会被 Mermaid 直接拒绝的错误。
解决办法
在名称和 ID 之间加上冒号。
gantt
dateFormat YYYY-MM-DD
section 开发
设计 a1, 2026-01-01, 5dgantt
dateFormat YYYY-MM-DD
section 开发
设计 :a1, 2026-01-01, 5d你会看到
图能渲染,但坐标轴突然横跨好几个月
原因
某个 `after` 指向了并不存在的任务 ID——通常是拼错了,或者 ID 被改过名。Mermaid 不会警告,而是把这个任务放到某个任意位置,坐标轴便被拉长以容纳它。两个各 10 天的任务,可能因此落在一条长达八个月的轴上。
解决办法
检查每个 `after <id>` 是否与已声明的 ID 完全一致。坐标轴刻度突然变化就是信号。
gantt
dateFormat YYYY-MM-DD
section S
设计 :a1, 2026-01-01, 10d
开发 :a2, after sheji, 10dgantt
dateFormat YYYY-MM-DD
section S
设计 :a1, 2026-01-01, 10d
开发 :a2, after a1, 10d你会看到
任务名在第一个冒号处被截断
原因
任务名里含有冒号。第一个冒号就是分隔符,它后面的一切都被当成任务数据——`阶段一: 设计` 会渲染成一个只叫“阶段一”的任务,“设计”两个字凭空消失。
解决办法
任务名里不要用冒号。改用短横线,或把细节放到 section 标题里。
gantt
dateFormat YYYY-MM-DD
section S
阶段一: 设计 :a1, 2026-01-01, 10dgantt
dateFormat YYYY-MM-DD
section S
阶段一 - 设计 :a1, 2026-01-01, 10d你会看到
某个条形塌缩成了一条线
原因
工期没写单位。`5` 并不表示五天——单位是必需的,没有它任务就得不到有意义的长度。图照样能画出来,只是那个任务看起来不占用任何时间。
解决办法
始终写上单位:`5d`、`3w`、`2h`。
gantt
dateFormat YYYY-MM-DD
section S
设计 :a1, 2026-01-01, 5gantt
dateFormat YYYY-MM-DD
section S
设计 :a1, 2026-01-01, 5d你会看到
日期悄无声息地落在了错误的一天
原因
日期与声明的 `dateFormat` 不匹配。在 `dateFormat YYYY-MM-DD` 之下写 `01/03/2026` 并不会失败——Mermaid 会尽力抢救,把任务放到 1 月 3 日。如果你本意是 3 月 1 日,这张图现在错了两个月,而且看上去毫无破绽。
解决办法
严格按你声明的格式写日期。若想用日/月/年输入,就声明 `dateFormat DD/MM/YYYY`。
gantt
dateFormat YYYY-MM-DD
section S
设计 :a1, 01/03/2026, 10dgantt
dateFormat YYYY-MM-DD
section S
设计 :a1, 2026-03-01, 10d你会看到
工期看着没错,但实际的完成日期不对
原因
没有写 `excludes weekends`。默认情况下 10 天就是 10 个自然日、包含周末,所以任何超过一个工作周的任务,在图上的结束时间都会比现实中更早。
解决办法
在靠前的位置加上 `excludes weekends`,除非这项工作确实一周七天都在推进。
gantt
dateFormat YYYY-MM-DD
section S
迁移 :a1, 2026-06-01, 10dgantt
dateFormat YYYY-MM-DD
excludes weekends
section S
迁移 :a1, 2026-06-01, 10d渲染须知
以下均为针对本站所用 Mermaid 11.12.2 的实测结果。甘特图的行为与这里其他所有图类型都不一样。
甘特图是唯一渲染宽度固定的图类型
本站其他所有图都朝着内容增长的方向变大。甘特图的 viewBox 宽度永远是 1264 像素,无论它有 3 个任务还是 40 个——变化的只有高度,从约 172 像素到 1060 像素。坐标轴会被压缩或拉伸以适应这个固定宽度,所以跨越两年的计划和跨越两周的计划看起来一样密。如果你的条形细到看不清,问题出在时间跨度上,而不是任务数量。
中文任务名基本不影响布局
由于宽度本来就是固定的 1264 像素,中文任务名不会像在别的图里那样改变整体尺寸——它只影响左侧标签列能显示多少字。汉字虽然单字更宽,但表达同样内容所需的字数少得多,所以中文任务名通常比英文原文更不容易被截断。这是甘特图对中文最友好的一点。
它曾是 PNG 导出缺陷中受害最深的类型
由于 Mermaid 输出 `width="100%"` 且没有高度,浏览器会以默认的 300×150 方框来解析导出尺寸,而甘特图又宽又扁的比例把这个问题放大到了极致:一张 1280×148 的图会被导成 600×58 的 PNG。现在导出会读取 viewBox,同一张图导出为 2560×296。如果你手上还留着旧的甘特图 PNG,它们是没法靠放大补救的。
这里的 PNG 导出是逐像素精确的
甘特图的标签是纯 SVG 文本而不是内嵌 HTML,所以不像流程图、类图、状态图和 ER 图,它可以被直接光栅化。导出的 PNG 与屏幕完全一致,不需要重新渲染,也没有字体排版偏移。
除了冒号,语法几乎处处宽容
缺少 section、状态关键字写错、日期格式不符、工期没有单位——这些统统能渲染。唯一会被拒绝的是没有冒号的任务行。这种不对称是关于写甘特图最有用的一条认知:图能画出来,几乎说明不了它是对的。
什么时候该换一种图
如果日期本来就是拍脑袋估的,甘特图会用一种它们并不配得上的精确度把它们呈现出来,而且总会有人拿这些日期来要求你。一张只展示先后顺序、不带日期的流程图更诚实,计划变动时也不需要维护。
如果计划每周都在变,把甘特图以文本形式放进版本库确实很好——差异一看便知谁挪了。但一张没人更新的计划图,比没有图更糟。你在做的到底是哪一种,心里要有数。
而任何涉及资源平衡、产能或人员分配的事情,这都是完全错误的工具。Mermaid 只是在日历上画条形;它并不知道谁在做这件事,也不知道那个人是不是已经排满了。
其他图类型
作者 Dominik Malsch · 最后更新: