Half a decade ago I worked in the project management software industry and spent a lot of time building custom controls to render Gantt charts. Nowadays, I can create a simple functional Gantt chart in under a minute — for free — using markdown and Mermaid.js.
In this article I’m going to walk you through what a Gantt chart is, why you might want to use one, and how you can use Mermaid.js to render a simple Gantt chart for inclusion in a report or presentation.
What are Gantt Charts?
Gantt charts are a project management chart named after their creator, Henry Gantt in the early 1900's.
Gantt charts can be used to document key dates and phases in projects by rendering boxes starting at a task’s start date and ending at that task’s end date.
This can help highlight tasks that are behind schedule or tasks that can be considered to be on the critical path that would cause the project to end later if the tasks fell behind schedule.
Nowadays Gantt charts are not as popular in the software engineering world since agile project management is far more effective for software projects, but Gantt charts remain appropriate for key scenarios where:
- Tasks can be accurately identified at the beginning of a project
- Uncertainty and change are rare
- Careful resource scheduling is important
Simple Gantt Charts with Mermaid.js
Mermaid.js allows you to render a Gantt chart by defining its tasks in markdown using the following format:
task name : start-date, end-date
Instead of an end date, task durations can be used instead as shown below:
gantt
title Write about Mermaid.js Gantt Charts
Create code for Gantt chart : 2023-04-11, 2d
Outline article on Gantt charts : 2023-04-12, 2d
Write article on Gantt charts : 2023-04-13, 1d
Publish article on Gantt charts : 2023-04-14, 1d
This Mermaid.js markdown is effective in any environment that supports Mermaid.js. This is a surprisingly large number of places including GitHub markdown, Polyglot Notebooks, and the online Mermaid.js editor.
For more on running Mermaid.js, take a look at my article on creating entity relationship diagrams.
Active, Done, and Critical Tasks
In a Gantt chart you often want to style tasks differently by their status.
For example, it is conventional to style completed tasks differently than other tasks. Additionally, tasks on the critical path are frequently styled red to highlight that the project will end later should these tasks slip.
In Mermaid.js, you can style tasks on a Gantt chart differently by adding their status names after the colon.
The supported custom statuses are:
-
done
for completed tasks -
active
for tasks currently in progress -
crit
for tasks on the critical path -
milestone
for milestones (see next section)
gantt
title Write about Mermaid.js Gantt Charts
Create code for Gantt chart :done, crit, 2023-04-11, 2d
Outline article on Gantt charts :done, 2023-04-12, 2d
A Standard Task : 2023-04-12, 2d
Write article on Gantt charts :active, crit, 2023-04-13, 1d
Publish article on Gantt charts :crit, 2023-04-14, 1d
Note that it is possible for a task to have multiple styles associated with it, such as a completed critical path task.
Together, these styles help direct the viewer’s attention to key areas of the Gantt chart.
Sections and Milestones
For more complex project plans you might want to partition the Gantt chart into multiple sections to indicate key phases of the project or work done by different departments.
Mermaid.js allows you to segment your charts using the section
keyword:
gantt
title Preparing Polyglot Notebooks Talk for Stir Trek 2023
section Proposal and Evaluation
Submit Abstract :done, 2023-01-15, 2023-02-18
Session Evaluation :done, 2023-02-18, 2023-03-05
Talk Accepted :milestone, done, 2023-03-05, 2023-03-05
section Talk Preparation
Research & Outlining :done, 2023-03-12, 9d
Create Mermaid Examples :done, 2023-03-12, 2023-04-08
Write Mermaid Articles :active, 2023-04-08, 7d
Write Jupyter Articles : 2023-04-15, 2d
Deep Dive into Polyglot :crit, 2023-04-08, 2w
Write Polyglot Articles : 2023-04-18, 7d
section Delivery
Final Notebook :crit, 2023-04-22, 7d
Rehearsal :crit, 2023-04-29, 2023-05-04
Stir Trek 2023 :milestone, crit, 2023-05-05, 1d
This segmentation helps direct the viewer to key sets of related tasks.
Additionally, you may note the diamond “Talk Accepted” marker in the chart above.
This is a milestone which represents a significant marker in a project’s lifetime. Milestones are typically not tasks in their own right, but the culmination of the completion of many tasks or a specific fixed-date event of interest.
Milestones are denoted in Mermaid.js by the milestone status in the status list.
Relative Scheduling of Tasks
Mermaid.js lets you specify either the end date of a task or its duration. In a similar way, it will allow you to schedule tasks as starting immediately after another task completes, simulating a predecessor relationship.
To set up predecessor relationships in Mermaid.js, you need to give the predecessor task a unique identifier in its list of statuses. To help differentiate between valid statuses such as done and active, I like to use uppercase identifiers like OUTLINE.
Once you have a predecessor task marked with an ID, you can state that the dependent task starts after that task by stating its start date is after OTHER_TASK_ID as shown below:
gantt
title Preparing Polyglot Notebooks Talk for Stir Trek 2023
section Proposal and Evaluation
Submit Abstract :done, 2023-01-15, 2023-02-18
Session Evaluation :done, EVAL 2023-02-18, 2023-03-05
Talk Accepted :milestone, done, after EVAL
section Talk Preparation
Research & Outlining :done, OUTLINE, 2023-03-12, 9d
Create Mermaid Examples :done, MER_EXAMPLE, after OUTLINE, 5d
Write Mermaid Articles :active, MER_ART, after MER_EXAMPLE, 7d
Write Jupyter Articles : after MER_ART, 3d
Deep Dive into Polyglot :crit, 2023-04-05, 2w
Write Polyglot Articles : 2023-04-12, 10d
section Delivery
Final Notebook :crit, NOTEBOOK, 2023-04-19, 7d
Rehearsal :crit, after NOTEBOOK, 2023-05-04
Stir Trek 2023 :milestone, crit, 2023-05-05, 1d
This allows you to change dates in your project and have the edits also affect dependent tasks. The alternative to this would be to make many edits to the dates of other tasks when a single date changes.
Note however that no predecessor relationship lines are drawn on the Gantt chart and customizing the lag between tasks is not possible with Mermaid.js
Finally, Mermaid.js gives us a few ways of making Gantt charts more suitable for presentations.
Mermaid.js Gantt charts display a red “today line” at the current date on the chart.
This line can be handy when you are trying to determine where the project should be given the current date and schedule. However, it is often more of a distraction if you are creating visuals to be included in a presentation that will be delivered later in time.
To address this, you can state todayMarker off
to disable the today line.
Secondly, complex plans can get very complicated and require a lot of vertical scrolling to see all relevant tasks. This can hinder presentations of tasks.
To address this, Mermaid.js allows you to set the displayMode
to compact
which puts tasks on the same row of the chart when there is no overlap.
Here’s an example that removes the today marker and flattens the Gantt chart down into as few lines as possible:
---
displayMode: compact
---
gantt
title Write about Mermaid.js Gantt Charts
todayMarker off
Create code for Gantt chart :done, crit, 2023-04-11, 2d
Outline article on Gantt charts :done, 2023-04-12, 2d
Write article on Gantt charts :active, crit, 2023-04-13, 1d
Publish article on Gantt charts :crit, 2023-04-14, 1d
Closing Thoughts
Mermaid.js Gantt charts are not Microsoft Project or any other professional project management tool. There are reams of features they don’t support including:
- Parent Tasks
- Progress lines
- Relationship lines
- Slack / lead time markers
- Baselines
- Resource names
- Split-duration tasks
However, Mermaid.js Gantt charts are quite suitable for one thing: creating simple visuals to communicate the high-level task structure of a project.
Using Mermaid.js you can create a simplified view of a project’s task structure and feature that on a status page or internal presentation. And you can do all of that using open markdown and without any commercial tooling.
Mermaid.js Gantt charts won’t be for everyone, but sometimes a high-level project timeline can be really helpful and that’s what Mermaid.js is here to help with.
Top comments (3)
These charts look fantastic. Are they limited to static data, or can they be data driven some how?
I've been thinking about this myself. If you generated valid markdown for the dynamic content you're working with, Mermaid.js would then take that markdown and convert it into a visual built off of your data source. I think you could do this using something like Vue.js or Angular to add the markdown to the page based on dynamic data and then apply an on mounted step to make Mermaid.js transform it to a visual, but I've not tried it yet.
Additionally, once Polyglot Notebooks supports variable sharing for Mermaid, we'd be able to do about the same thing in less complex steps.
Either way, it's still pretty cool.
Definitely very cool. I'd imagine the amount of code that would be required to create an equivalent graph without Mermaid.js would be huge.