DEV Community

Cover image for Creating Gantt Charts with Markdown and Mermaid.js
Matt Eland
Matt Eland Subscriber

Posted on • Originally published at newdevsguide.com

Creating Gantt Charts with Markdown and Mermaid.js

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.

A Gantt Chart

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
Enter fullscreen mode Exit fullscreen mode

A Gantt Chart

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
Enter fullscreen mode Exit fullscreen mode

A Gantt Chart

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
Enter fullscreen mode Exit fullscreen mode

A Gantt Chart

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
Enter fullscreen mode Exit fullscreen mode

A Gantt Chart

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
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
ant_f_dev profile image
Anthony Fung

These charts look fantastic. Are they limited to static data, or can they be data driven some how?

Collapse
 
integerman profile image
Matt Eland

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.

Collapse
 
ant_f_dev profile image
Anthony Fung

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.