Skip to content

甘特图

甘特图是一种条形图,最早由卡罗尔·阿达米茨基于1896年开发,后来在1910年代由亨利·甘特独立开发,用于说明项目进度以及完成任何一个项目所需的时间。甘特图展示了项目终端元素和摘要元素的开始和结束日期之间的天数。

给用户的提示

甘特图将每个计划任务记录为一个从左到右延伸的连续条形图。x轴代表时间,y轴记录不同的任务及其完成顺序。

重要的是要记住,当与任务相关的特定日期、天数或日期集合被“排除”时,甘特图将通过向右延长相同数量的天数来适应这些变化,而不是在任务内部创建间隙。如图所示

然而,如果排除的日期位于两个设置为连续开始的任务之间,排除的日期将在图形上被跳过并留空,后续任务将在排除日期结束后开始。如图所示

甘特图对于跟踪项目完成所需的时间非常有用,但通过一些调整,它也可以用于图形化表示“非工作日”。

Mermaid 可以将甘特图渲染为 SVG、PNG 或可以粘贴到文档中的 MarkDown 链接。

语法

任务默认是顺序进行的。任务的开始日期默认为前一个任务的结束日期。

冒号 : 将任务标题与其元数据分隔开。元数据项由逗号 , 分隔。有效的标签包括 activedonecritmilestone。标签是可选的,但如果使用,必须首先指定。处理完标签后,剩余的元数据项将按以下方式解释:

  1. 如果指定了单个项目,它决定了任务何时结束。它可以是特定的日期/时间或持续时间。如果指定了持续时间,则会将其添加到任务的开始日期以确定任务的结束日期,同时考虑任何排除项。
  2. 如果指定了两个项目,最后一个项目将按照前一种情况解释。第一个项目可以指定一个明确的开始日期/时间(格式由dateFormat指定),或者使用after [[otherTaskID2 [otherTaskID3]]...]引用另一个任务。在后一种情况下,任务的开始日期将根据任何引用任务的最晚结束日期设置。
  3. 如果指定了三个项目,最后两个将按照前一种情况解释。第一个项目将表示任务的ID,可以使用later 语法引用。
元数据语法开始日期结束日期ID
, , startdate 使用 dateformat 解释endDate 使用 dateformat 解释taskID
, , startdate 使用 dateformat 解释开始日期 + lengthtaskID
, after , 先前指定任务 otherTaskID 的结束日期使用 dateformat 解释的 endDatetaskID
, after , 之前指定任务 otherTaskID 的结束日期开始日期 + lengthtaskID
, , until startdate 使用 dateformat 解释先前指定任务 otherTaskID 的开始日期taskID
, after , until 之前指定任务otherTaskID的结束日期之前指定任务otherTaskID的开始日期taskID
, startdate 使用 dateformat 解释enddate 使用 dateformat 解释n/a
, startdate 使用 dateformat 解释开始日期 + lengthn/a
after , 先前指定任务 otherTaskID 的结束日期enddate 使用 dateformat 解释n/a
after , 之前指定的任务 otherTaskID 的结束日期开始日期 + lengthn/a
, until startdate 使用 dateformat 解释先前指定任务 otherTaskID 的开始日期n/a
after , until 之前指定任务 otherTaskID 的结束日期之前指定任务 otherTaskID 的开始日期n/a
前一个任务的结束日期使用dateformat解释的enddaten/a
前一个任务的结束日期开始日期 + lengthn/a
until 前一个任务的结束日期之前指定的任务 otherTaskID 的开始日期n/a

信息

支持关键字 until 已在 (v10.9.0+) 中添加。这可以用于定义一个任务,该任务将一直运行,直到某个其他特定任务或里程碑开始。

为了简化,表格没有展示使用after关键字列出的多个任务。以下是一个如何使用它以及如何解释它的示例:

标题

title 是一个可选的字符串,用于在甘特图顶部显示,以描述整个图表。

排除

excludes 是一个可选属性,它接受特定格式的日期(YYYY-MM-DD)、星期几("sunday")或"weekends",但不接受"weekdays"这个词。这些日期将在图表上标记,并从任务的持续时间计算中排除。这意味着如果在任务间隔期间有排除的日期,则这些“跳过”的天数将被添加到任务的末尾,以确保持续时间与代码中指定的相同。

周末 (v\11.0.0+)

在排除周末时,可以配置周末为周五和周六或周六和周日。默认情况下,周末是周六和周日。要定义周末的开始日,有一个可选属性weekend,可以在新行中添加,后跟fridaysaturday

章节声明

您可以将图表划分为不同的部分,例如将项目的不同部分(如开发和文档)分开。

为此,请以section关键字开始一行并为其命名。(请注意,与整个图表的标题不同,此名称是必需的

里程碑

您可以在图表中添加里程碑。里程碑与任务不同,因为它们代表一个单一的时间点,并通过关键字milestone来标识。以下是如何使用里程碑的示例。您可能会注意到,里程碑的确切位置由里程碑的初始日期和任务的“持续时间”决定,具体方式为:初始日期+持续时间/2。

设置日期

dateFormat 定义了甘特图元素的日期输入格式。这些日期在渲染的图表输出中的表示方式由axisFormat定义。

输入日期格式

默认的输入日期格式是 YYYY-MM-DD。您可以定义自定义的 dateFormat

markdown
dateFormat YYYY-MM-DD

支持以下格式化选项:

输入示例描述
YYYY20144位数的年份
YY142位数的年份
Q1..4一年中的季度。将月份设置为季度中的第一个月。
M MM1..12月份数字
MMM MMMM一月..十二月月份名称,由dayjs.locale()设置的区域设置决定
D DD1..31月份中的第几天
Do1st..31st带有序数的月份中的某一天
DDD DDDD1..365一年中的第几天
X1410715640.579Unix时间戳
x1410715640579Unix 毫秒时间戳
H HH0..2324小时制时间
h hh1..12a A一起使用的12小时制时间。
a A上午 下午上午或下午
m mm0..59分钟
s ss0..59
S0..9十分之一秒
SS0..99百分之一秒
SSS0..999千分之一秒
Z ZZ+12:00与UTC的偏移量,格式为+-HH:mm、+-HHmm或Z

更多信息请参见:https://day.js.org/docs/en/parse/string-format/

轴上的输出日期格式

默认的输出日期格式是 YYYY-MM-DD。你可以定义自定义的 axisFormat,例如 2020-Q1 表示2020年的第一季度。

markdown
axisFormat %Y-%m-%d

支持以下格式化字符串:

格式定义
%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]
%p上午或下午
%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"
%%字面量 "%" 字符

更多信息请参见:https://github.com/d3/d3-time-format/tree/v4.0.0#locale_format

轴刻度 (v10.3.0+)

默认的输出刻度是自动的。你可以自定义你的tickInterval,比如1day1week

markdown
tickInterval 1day

模式是:

javascript
/^([1-9][0-9]*)(millisecond|second|minute|hour|day|week|month)$/;

更多信息请参见:https://github.com/d3/d3-time#interval_every

基于周的tickInterval默认从周日开始。如果您希望指定tickInterval应从另一周几开始,请使用weekday选项:

警告

millisecondsecond 支持在 v10.3.0 版本中添加

紧凑模式下的输出

紧凑模式允许您在同一行显示多个任务。可以通过前面的YAML设置来设置甘特图的显示模式,从而启用紧凑模式。

评论

可以在甘特图中输入注释,这些注释将被解析器忽略。注释需要单独成行,并且必须以%%(双百分号)开头。从注释开始到下一个换行符之间的任何文本都将被视为注释,包括任何图表语法。

样式

甘特图的样式是通过定义一系列CSS类来完成的。在渲染过程中,这些类从位于src/diagrams/gantt/styles.js的文件中提取。

使用的类

描述
grid.tick网格线的样式
grid.path网格边框的样式
.taskText任务文本样式
.taskTextOutsideRight任务文本超出活动栏右侧的样式。
.taskTextOutsideLeft任务文本超出活动条并向左延伸的样式。
todayMarker切换和样式化“今日标记”

示例样式表

css
.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;
}

今日标记

你可以为当前日期的标记设置样式或隐藏它。要设置样式,请为todayMarker键添加一个值。

todayMarker stroke-width:5px,stroke:#0f0,opacity:0.5

要隐藏标记,请将todayMarker设置为off

todayMarker off

配置

可以调整渲染甘特图的边距。

这是通过定义配置对象的ganttConfig部分来完成的。如何使用CLI在mermaidCLI页面中有描述。

mermaid.ganttConfig 可以设置为带有配置参数的 JSON 字符串或相应的对象。

javascript
mermaid.ganttConfig = {
  titleTopMargin: 25, // Margin top for the text over the diagram
  barHeight: 20, // The height of the bars in the graph
  barGap: 4, // The margin between the different activities in the gantt diagram
  topPadding: 75, // Margin between title and gantt diagram and between axis and gantt diagram.
  rightPadding: 75, // The space allocated for the section name to the right of the activities
  leftPadding: 75, // The space allocated for the section name to the left of the activities
  gridLineStartPadding: 10, // Vertical starting position of the grid lines
  fontSize: 12, // Font size
  sectionFontSize: 24, // Font size for sections
  numberSectionStyles: 1, // The number of alternating section styles
  axisFormat: '%d/%m', // Date/time format of the axis
  tickInterval: '1 week', // Axis ticks
  topAxis: true, // When this flag is set, date labels will be added to the top of the chart
  displayMode: 'compact', // Turns compact mode on
  weekday: 'sunday', // On which day a week-based interval should start
};

可能的配置参数:

参数描述默认值
mirrorActor开启/关闭图表下方和上方的角色渲染false
bottomMarginAdj调整图表结束的位置。使用CSS的宽边框样式可能会产生不必要的裁剪,这就是为什么存在这个配置参数。1

交互

可以将点击事件绑定到任务上。点击可以触发一个JavaScript回调,或者打开一个在当前浏览器标签页中打开的链接。注意:当使用securityLevel='strict'时,此功能被禁用;当使用securityLevel='loose'时,此功能被启用。

click taskId call callback(arguments)
click taskId href URL
  • taskId 是任务的 id
  • callback 是显示图表的页面上定义的 JavaScript 函数的名称,如果没有指定其他参数,该函数将以 taskId 作为参数被调用。

初学者提示——在HTML上下文中使用交互式链接的完整示例:

html
<body>
  <pre class="mermaid">
    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>

示例

条形图(使用甘特图)