2026/9/7 4:09:06

Mermaid Gantt 图实战指南:完整语法、时间轴控制、紧凑模式与渲染配置解析

Mermaid Gantt 图实战指南:完整语法、时间轴控制、紧凑模式与渲染配置解析 Mermaid Gantt 图实战指南完整语法、时间轴控制、紧凑模式与渲染配置解析【免费下载链接】mermaidGeneration of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown项目地址: https://gitcode.com/GitHub_Trending/me/mermaid本文基于 Mermaid 仓库的官方语法文档 docs/syntax/gantt.md其可编辑源文件位于 packages/mermaid/src/docs/syntax/gantt.md展开系统讲解 Gantt甘特图的完整语法规则任务元数据的三种写法、excludes/weekend排除日期机制、dateFormat与axisFormat双格式体系、tickInterval刻度控制、紧凑模式、里程碑与垂直标记线、todayMarker、ganttConfig配置参数与click交互绑定并结合 ganttDb.js、ganttRenderer.js 等源码说明其底层实现原理读完即可独立编写、调参与排错 Gantt 图表。Gantt 图概述甘特图是一种条形图最早由 Karol Adamiecki 于 1896 年提出后由 Henry Gantt 在 20 世纪 10 年代独立发展而来用于展示项目进度以及完成项目各阶段所需的时间。甘特图以横轴表示时间纵轴记录各个任务及其完成顺序直观呈现从开始日期到结束日期之间的天数。Mermaid 可以将 Gantt 图渲染为 SVG、PNG或输出可粘贴进文档的 MarkDown 链接。用户须知排除日期excludes的两种渲染行为理解甘特图渲染行为的关键在于excludes的语义官方文档对此有明确约定排除日期落在某个任务区间内部时甘特图不会在任务内部产生空洞而是将任务向右延展等量的天数保证任务的实际时长与代码中声明一致排除日期落在两个连续开始的相邻任务之间时这些日期会在图形上被跳过并留白下一个任务从排除日期结束之后才开始。从源码看这一行为由 ganttDb.js 中的checkTaskDates与fixTaskDates实现渲染器会逐日检查区间内是否命中排除项isInvalidDate每命中一天就把endTime顺延一天includes中的日期优先级高于excludes命中的日期不会被排除。该循环设有 10,000 次迭代的保护上限超出会抛出错误。渲染层则由 ganttRenderer.js 的drawExcludeDays将连续排除日合并成exclude-range灰色背景块绘制在图上当时间跨度超过 5 年时会跳过绘制以保护性能。最小示例完整语法示例下面这个示例覆盖了title、excludes、多个section、四种任务标签done/active/crit/milestone、小时级时长与until关键字任务默认是顺序执行的未显式指定开始时间时任务的开始时间默认为上一个任务的结束时间。冒号:分隔任务标题与其元数据元数据各项之间用逗号,分隔。任务元数据规则详解标签Tags合法标签为active、done、crit和milestone源码 ganttDb.js 中的tags数组还包含用于垂直标记线的vert。标签是可选的但如果使用必须写在最前面。元数据项数量的三种解释解析完标签后剩余元数据项按数量解释源码对应parseData/compileData的switch (data.length)分支1 项该项决定任务何时结束可以是具体日期时间或时长若是时长则从任务开始日期起算计入排除日期。2 项末项按上述规则处理首项为显式开始日期时间按dateFormat解析或使用after otherTaskID [[otherTaskID2 ...]]引用其他任务——此时任务开始时间取所有被引用任务中最晚的结束时间源码getStartDate中遍历after后的多个 id 并取endTime最大值。3 项末两项按上述规则处理首项是任务ID可被后续任务通过after taskID/until taskID引用。元数据语法开始时间结束时间任务 IDtaskID, startDate, endDate按dateFormat解析的startDate按dateFormat解析的endDatetaskIDtaskID, startDate, length按dateFormat解析的startDate开始时间 lengthtaskIDtaskID, after otherTaskId, endDate前序任务otherTaskID的结束时间按dateFormat解析的endDatetaskIDtaskID, after otherTaskId, length前序任务otherTaskID的结束时间开始时间 lengthtaskIDtaskID, startDate, until otherTaskId按dateFormat解析的startDate前序任务otherTaskID的开始时间taskIDtaskID, after otherTaskId, until otherTaskId前序任务otherTaskID的结束时间前序任务otherTaskID的开始时间taskIDstartDate, endDate按dateFormat解析的startDate按dateFormat解析的endDate无startDate, length按dateFormat解析的startDate开始时间 length无after otherTaskID, endDate前序任务otherTaskID的结束时间按dateFormat解析的endDate无after otherTaskID, length前序任务otherTaskID的结束时间开始时间 length无startDate, until otherTaskId按dateFormat解析的startDate前序任务otherTaskID的开始时间无after otherTaskId, until otherTaskId前序任务otherTaskID的结束时间前序任务otherTaskID的开始时间无endDate前一个任务的结束时间按dateFormat解析的endDate无length前一个任务的结束时间开始时间 length无until otherTaskId前一个任务的结束时间前序任务otherTaskID的开始时间无注意until关键字自 v10.9.0 起支持用于定义运行到另一个特定任务或里程碑开始为止的任务。源码getEndDate中until后的多个 id 会取最早的开始时间。时长Duration格式指定length时由数字加单位后缀组成源码parseDuration的正则/^(\d(?:\.\d)?)([Mdhmswy]|ms)$/支持小数单位后缀示例毫秒ms500ms秒s30s分钟m30m小时h4h天d3d周w2w月M1M年y1y支持小数值如1.5d。无效的时长标记如3dX会被忽略任务时长按零处理。多任务依赖示例上表未展示after引用多个任务的写法示例如下cherry在b与a中最晚结束者之后开始kiwi结束于b、c中最早开始者开始之时。仓库的 e2e 用例 multiple-dependencies-syntax.mmd 与 should-handle-multiple-dependencies-syntax-with-after-and-until.mmd 对此行为有截图回归验证。图级指令Directivestitletitle是可选字符串显示在甘特图顶部用于描述整个图表title Adding GANTT diagram functionality to mermaidexcludes与 includesexcludes是可选属性接受 YYYY-MM-DD 格式的具体日期、星期几如sunday或weekends但不接受weekdays这个词。被排除的日期会在图上标出并从任务时长计算中剔除——若任务区间内存在排除日期相应天数会追加到任务末尾保证任务时长与代码声明一致。支持多行excludes各行 token 会合并源码mergeTokens用Set去重因此可以把很长的排除清单拆到多行并用注释分组gantt dateFormat DD-MM-YYYY excludes weekends %% week 7 is winter break excludes 10-02-2025 11-02-2025 12-02-2025 13-02-2025 14-02-2025 %% workers holiday 1 maj excludes 01-05-2025除excludes外词法层gantt.jison还提供includes指令用于在排除规则之上强制包含特定日期渲染时命中includes的日期不会画排除背景块。weekend 指令v11.0.0排除周末时可以配置周末是周五周六还是周六周日默认为周六周日。通过可选的weekend指令指定周末的起始日为friday或saturday源码中WEEKEND_START_DAY { friday: 5, saturday: 6 }对应 dayjs 的isoWeekday编号isInvalidDate据此判断该日是否为周末。e2e 用例 should-render-a-gantt-diagram-excluding-friday-and-saturday.mmd 与 should-render-a-gantt-diagram-excluding-saturday-and-sunday.mmd 覆盖两种配置。section 指令可用section将图表划分为多个区块例如区分开发与文档等不同工作流section A section Completed task :done, des1, 2014-01-06,2014-01-08与整图的title可选不同section 的名称是必填的。section 名称支持换行e2e 用例 handle-multiline-section-titles-with-different-line-breaks.mmd 验证了多行标题渲染。里程碑Milestones里程碑与任务不同它表示时间轴上的一个瞬时点以milestone关键字识别。里程碑的具体位置由初始日期与任务时长共同决定位置 初始日期 时长 / 2。渲染层ganttRenderer.js中里程碑矩形经过transform: rotate(45deg) scale(0.8,0.8)变换呈菱形垂直标记线Vertical Markersvert关键字可以在甘特图上添加垂直线便于高亮截止日期、事件或检查点等关键时间点。这些标记线贯穿整个图表位置由提供的日期决定。与里程碑不同垂直标记线不占用任务行源码中vert任务的order被设为-1渲染时从行高计算中过滤掉纯粹是视觉参考点帮助分割时间轴、突出重要时刻日期设置dateFormat定义 Gantt 元素日期输入的格式这些日期在渲染输出中如何显示则由axisFormat定义。两者解耦可以各用一套规则。输入日期格式dateFormat默认输入格式为YYYY-MM-DD可自定义dateFormat YYYY-MM-DD支持的格式符由 day.js 解析见 ganttDb.js 中 dayjs 的customParseFormat插件输入示例说明YYYY20144 位年YY142 位年Q1..4季度月份被设为该季度第一个月M MM1..12月份号MMM MMMMJanuary..Dec月名按dayjs.locale()设置的区域语言D DD1..31当月第几日Do1st..31st带序数词的当月第几日DDD DDDD1..365当年第几日X1410715640.579Unix 时间戳秒x1410715640579Unix 毫秒时间戳H HH0..2324 小时制时间h hh1..1212 小时制时间配合a A使用a Aam pm上午/下午m mm0..59分钟s ss0..59秒S0..9秒的十分位SS0..99秒的百分位SSS0..999秒的千分位Z ZZ12:00相对 UTC 的偏移形如 -HH:mm、-HHmm 或 Z当dateFormat为X/x时间戳时纯数字输入直接按new Date(数值)处理e2e 用例 should-handle-numeric-timestamps-with-dateformat-x.mmd 覆盖此路径。轴上输出日期格式axisFormat默认输出格式为YYYY-MM-DD可自定义axisFormat例如2020-Q1表示 2020 年第一季度axisFormat %Y-%m-%d支持的格式串由 d3-time-format 提供格式定义%a星期缩写%A星期全称%b月份缩写%B月份全称%c日期和时间形如%a %b %e %H:%M:%S %Y%d补零的当月日期[01,31]%e空格填充的当月日期[ 1,31]等价于%_d%H小时24 小时制[00,23]%I小时12 小时制[01,12]%j当年第几日[001,366]%m月份[01,12]%M分钟[00,59]%L毫秒[000, 999]%pAM 或 PM%S秒[00,61]%U周年以周日为一周之始[00,53]%w星期几数字[0(周日),6]%W周年以周一为一周之始[00,53]%x日期形如%m/%d/%Y%X时间形如%H:%M:%S%y不含世纪的年[00,99]%Y含世纪的年%Z时区偏移如-0700%%字面量%此外渲染器还有个小优化当dateFormat恰好为D只到天时axisFormat会自动退化为%d只显示日期见 ganttRenderer.jsmakeGrid。轴刻度tickIntervalv10.3.0默认刻度由 D3 自动生成可自定义tickInterval如1day或1weektickInterval 1day合法模式源码中的校验正则/^([1-9][0-9]*)(millisecond|second|minute|hour|day|week|month)$/匹配失败如1decade会被静默忽略回退到自动刻度。渲染前还会估算刻度总数超过 10,000MAX_TICK_COUNT时会跳过自定义刻度并给出警告防止极端时间域卡死渲染。周刻度的tickInterval默认以周日为一周起点。若想从其他星期开始使用weekday指令weekday可取mondaysunday词法层对每个星期几定义了独立 token见 gantt.jison渲染层通过mapWeekdayToTimeFunction映射到 d3 的timeMonday…timeSunday区间函数。注意millisecond与second的支持自 v10.3.0 加入。e2e 目录 e2e/diagrams/gantt/ 下有should-render-a-gantt-diagram-with-tick-is-2-milliseconds.mmd、should-render-a-gantt-diagram-with-tick-is-2-seconds.mmd、should-render-a-gantt-diagram-with-tick-is-15-minutes.mmd等大量刻度场景的回归用例。紧凑模式Compact Mode紧凑模式允许多个时间重叠的任务共享同一行通过 YAML frontmatter 中的displayMode: compact启用从源码结构看紧凑模式的行数由 ganttRenderer.js 中的getMaxIntersections决定把任务按开始时间排序后做区间着色式扫描同一 section 内最多重叠深度即为该 section 所需行数各 section 行高累加形成图表总高。e2e 用例 should-render-when-compact-is-true.mmd 验证了该行为。注释CommentsGantt 图支持注释注释会被解析器忽略。注释必须独占一行且以%%双百分号开头从注释开始到下一换行之间的所有文本包括图表语法都视为注释样式StylingGantt 图的样式通过一组 CSS 类定义。渲染时这些类名从 styles.js 中提取并注入 SVG主题变量颜色、字体由配置主题提供。主要类类说明grid.tick网格线样式grid.path网格边框样式.taskText任务文本样式.taskTextOutsideRight任务文本超出活动条向右延伸时的样式.taskTextOutsideLeft任务文本超出活动条向左延伸时的样式todayMarker今天标记线的开关与样式除了上表渲染器还会为任务动态追加状态类task/active/done/crit及其组合activeCrit、doneCrit、milestone、vert以及按 section 交替的编号后缀taskText0…taskText3等数量由numberSectionStyles控制。文本超出条形时的左右落位逻辑在 ganttRenderer.jsdrawRects中先比较文本getBBox()宽度与条形宽度若放不下则优先放到条形右侧右侧空间不足再放左侧。示例样式表.grid .tick { stroke: lightgrey; opacity: 0.3; shape-rendering: crispEdges; } .grid path { stroke-width: 0; } #tag { color: white; background: #fa283d; width: 150px; position: absolute; display: none; padding: 3px 6px; margin-left: -80px; font-size: 11px; } #tag:before { border: solid transparent; content: ; height: 0; left: 50%; margin-left: -5px; position: absolute; width: 0; border-width: 10px; border-bottom-color: #fa283d; top: -20px; } .taskText { fill: white; text-anchor: middle; } .taskTextOutsideRight { fill: black; text-anchor: start; } .taskTextOutsideLeft { fill: black; text-anchor: end; }今天标记线Today Marker可以自定义或隐藏当前日期标记线。给它设置一段 CSS 声明即可改变样式todayMarker stroke-width:5px,stroke:#0f0,opacity:0.5设置todayMarker off则完全隐藏标记线渲染层drawToday中todayMarker off时直接返回e2e/diagrams/gantt/should-hide-today-marker.mmd、should-style-today-marker.mmd有对应回归用例。配置Configuration通过配置对象中的gantt部分可以调整渲染边距等参数CLI 用法见 mermaidCLI。mermaid.ganttConfig可设为 JSON 字符串或对应对象mermaid.ganttConfig { titleTopMargin: 25, // 图上方标题文字的顶部边距 barHeight: 20, // 条形高度 barGap: 4, // 不同活动条之间的间距 topPadding: 75, // 标题与图之间、轴与图之间的边距 rightPadding: 75, // 右侧预留给 section 名称的空间 leftPadding: 75, // 左侧预留给 section 名称的空间 gridLineStartPadding: 10, // 网格线的垂直起始位置 fontSize: 12, // 字体大小 sectionFontSize: 24, // section 字体大小 numberSectionStyles: 1, // 交替 section 样式的数量 axisFormat: %d/%m, // 轴上日期/时间格式 tickInterval: 1week, // 轴刻度 topAxis: true, // 设置后在图表顶部额外增加一行日期标签 displayMode: compact, // 开启紧凑模式 weekday: sunday, // 周刻度的起始星期 };其他可选配置参数参数说明默认值mirrorActor打开/关闭在图下方与上方一样渲染 actorfalsebottomMarginAdj调整图表结束位置向下延伸多少。CSS 宽边框可能导致意外裁切此参数即为此而设1完整配置项定义可参考 config.schema.yaml 中的GanttDiagramConfig。另外词法层还支持inclusiveEndDates结束日期含当日结束时间 1 天与topAxis顶部轴指令可在图内直接声明。交互Interaction可以为任务绑定点击事件跳转到 JavaScript 回调或在当前浏览器标签打开链接。注意securityLevelstrict时该功能被禁用securityLevelloose时启用源码 ganttDb.jssetClickFun中非loose级别直接返回。click taskId call callback(arguments) click taskId href URLtaskId是任务 idcallback是页面中定义的 JavaScript 函数名若未指定参数则默认以taskId作为参数调用。完整的 HTML 上下文示例body pre classmermaid gantt dateFormat YYYY-MM-DD section Clickable Visit mermaidjs :active, cl1, 2014-01-07, 3d Print arguments :cl2, after cl1, 3d Print task :cl3, after cl2, 3d click cl1 href https://mermaidjs.github.io/ click cl2 call printArguments(test1, test2, test3) click cl3 call printTask() /pre script const printArguments function (arg1, arg2, arg3) { alert(printArguments called with arguments: arg1 , arg2 , arg3); }; const printTask function (taskId) { alert(taskId: taskId); }; const config { startOnLoad: true, securityLevel: loose, }; mermaid.initialize(config); /script /body从源码看click声明经词法层click/call/href状态机进入setClickEvent/setLink事件通过pushFun延迟绑定到渲染后 DOM 中[iddiagramId-taskId]与对应的-text文本元素上href链接在securityLevel ! loose时会经过sanitizeUrl消毒。综合示例用 Gantt 图做条形图借助 Unix 时间戳输入dateFormat X与%s轴格式甘特图可以兼职横向条形图时间线frontmatter 配置 CSS 注释的综合示例下面的示例把 YAML frontmatter 配置、行内注释、themeCSS、里程碑与垂直标记线组合在一起注意其中tickInterval 1decade因不匹配合法正则而被静默忽略frontmatter 中的displayMode: compact虽然是 gantt 专属设置但也可以写在图表级配置中生效gantt.useWidth、rightPadding、topAxis、numberSectionStyles等参数直接对应前文ganttConfig中的字段。源码与测试索引解析与数据模型gantt.jison词法/文法、ganttDb.js任务编译、after/until解析、时长解析、排除日期修正渲染ganttRenderer.js紧凑模式行高计算、轴刻度、排除日期背景、今天标记线、styles.jsCSS 类默认配置defaultConfig.ts 中gantt段tickInterval/useWidth默认未设置回退到 schema 默认值回归用例e2e/diagrams/gantt/ 下 40 个.mmd场景毫秒/秒级刻度、X时间戳、多行 excludes、vert标签、今天标记线开/关、topAxis、周一起始刻度等本地演示页demos/gantt.html小结Mermaid 的 Gantt 图以日期指令 section 任务元数据三层结构组织dateFormat/axisFormat分别控制输入与轴输出excludes/weekend让时长计算能贴合真实工作日after/until建立任务依赖milestone与vert提供关键节点标注displayMode: compact压缩重叠任务click与todayMarker增强交互与时效感知。掌握本文的元数据三态表、时长单位表与双日期格式表后配合仓库中 e2e 场景目录里的.mmd样例即可覆盖绝大多数项目排期与时间线可视化需求。【免费下载链接】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),仅供参考