Adding a Progress Line to DHTMLX JavaScript Gantt Chart

Hello everyone! We hope you had a great holiday and are ready to get back to work with renewed energy. We start 2025 with a tutorial that unveils a new customization option for enhanced user experience with Gantt charts based on DHTMLX.

Today, you will learn how to complement a JavaScript Gantt chart with a progress line to facilitate project progress monitoring.

What is a Progress Line and How It Benefits a Gantt Chart

In complex Gantt chart scenarios, members of the project team or stakeholders may struggle to promptly and accurately estimate the current status of multiple tasks. That’s where a progress line can come in handy. It is a visual indicator in the form of a curved line that displays the current status of tasks relative to their planned timelines. This line stems from the current date and indicates the progress of each task, giving the team a clear visual summary of the project’s status. This feature also helps project teams to quickly understand if any adjustments are required without diving into detailed data.

Overall, end-users can get the following benefits from the implementation of a progress line:

  • at-a-glance understanding of task statuses (on track, ahead, or delayed)
  • decreased risk of missing deadlines and resource misallocation
  • enhanced team coordination
  • better workflow transparency

As a result, this feature helps project teams to maintain clarity and good timing in project management workflows.

Here is a sample of a Gantt chart with a progress line built with DHTMLX:
Gantt chart with a progress lineCheck the sample >

Guide on Complementing DHTMLX Gantt with Progress Line

DHTMLX Gantt does not provide the progress line feature by default, but it can be easily added to the Gantt configuration via the Gantt API.

Prerequisites

We won’t dwell on adding a JavaScript Gantt chart on a web page and configuring it since these aspects are well covered in the documentation. Instead, we would like to focus on important details related to creating progress lines.

From a coding perspective, a progress line is a custom element that can be displayed in the Gantt timeline with the addTasklayer() method. This method is called for each row with the task, meaning you can add the progress line in pieces.

If the task starts before the current date and is completed or the task has a progress status of 0% and starts after the current date, you’ll need to add one straight line. If the task progress is from 0 to 100%, you draw two lines associated with the current date and progress of the task. It can be done with SVG. You’ll need three progress line coordinates:

  • top point related to the task row and the date position in the timeline
  • bend point related to the current task progress (and its date)
  • bottom point related to the task row and the date position in the timeline
Step 1: Positioning of Required Elements

First, you need to use the posFromDate() method to get the positions of the task’s start and end dates in the timeline.

const startPos = gantt.posFromDate(task.start_date);
const endPos = gantt.posFromDate(task.end_date);

After that, you get the position of the current date.

const linePos = gantt.posFromDate(today);

Next, you calculate the difference between the positions of the start and end dates of the task and multiply it by the task progress. As a result, you’ll get the task progress date.

const progressOffset = (endPos - startPos) * task.progress;
const progressPos = startPos + progressOffset;

To get the coordinates of the taskbar, you should use the getTaskPosition() method.

const sizes = gantt.getTaskPosition(task, task.start_date, task.end_date);
Step 2: Creating SVG Element and Adding Attributes

Now you can create an SVG element and add the necessary attributes. The height parameter is taken from the task coordinates (the height of the entire row), while the width parameter is inherited. The position is specified using the top and left styles. The SVG element will occupy the entire task row in the timeline.

const svgNS = "http://www.w3.org/2000/svg";
const svg = document.createElementNS(svgNS, "svg");
svg.classList.add("progress-line");
svg.setAttribute("width", 'inherit');
svg.setAttribute("height", sizes.rowHeight);
svg.setAttribute("style", `top:${sizes.top}px; left:0;`);

After that, you create the path element needed to draw lines and add attributes.

const path = document.createElementNS(svgNS, "path");
path.setAttribute("stroke", "black");
path.setAttribute("stroke-width", "2");
path.setAttribute("fill", "none");
Step 3: Calculating Coordinates for Progress Line

The next step is to calculate coordinates for lines. For those who have never worked with SVG elements, we want to clarify a couple of symbols used in path coordinates:

  • M – moving the initial coordinate, from which the elements will be built (from 0,0 to the specified coordinate).
  • L – drawing a line from the current coordinate to the new one.

Coordinates are specified in the following order:

  • M x,y – the initial coordinate. x is taken from the position of the current date. y is 0 because it is the first coordinate starting from the top.
  • L x,y – the coordinate of the task progress date. x is taken from the position of the progress. y is taken from half the row height.
  • L x,y – the ending coordinates. x is taken from the position of the current date. y is taken from the row height.
const startPoint = `M${linePos},0`;
const middlePoint = `L${progressPos},${sizes.rowHeight / 2}`;
const endPoint = `L${linePos},${sizes.rowHeight}`;
Step 4: Checking Task’s Date and Progress

At this point, you need to check the date and progress of the task. If the task starts before the current date and its progress is 100% (i.e. 1) or it starts after the current date and its progress is greater than 0, the task is still in progress. In this case, it is necessary to draw two lines from the task progress. If the condition above is not met, one line is drawn. i.e. the second coordinate is simply excluded.

const ongoingTask = task.start_date < today && task.progress < 1;
const unfinishedTask = today <= task.start_date && task.progress > 0;

if (ongoingTask || unfinishedTask) {
    pathData = `${startPoint} ${middlePoint} ${endPoint}`;
} else {
    pathData = `${startPoint} ${endPoint}`;
}

After that, you add the path element to the SVG element and return the SVG element.

path.setAttribute("d", pathData);
svg.appendChild(path);

return svg;
Step 5: Adding Styles

And the final touch is to add styles to the progress line.

.progress-line {
    position: absolute;
    pointer-events: none;
    z-index: 10;
}

.progress-line path {
    stroke: rgba(255, 0, 0, 70%)
}

Let us clarify the parameters used in the piece of code above:

  • position: absolute; – ensures that the elements are drawn at their positions in the timeline.
  • pointer-events: none; – disables mouse events for SVG elements, i.e. when you click on an SVG element, the click is triggered on the element below it.
  • z-index: 10; – allows displaying custom elements on top of taskbars and links.
  • stroke – serves to set the color.

That’s it. The instructions above will help you enrich your JavaScript Gantt chart with a custom progress line like our sample.

Wrapping Up

Overall, it is great to have an easy way to add a simple yet useful feature like a progress line to a Gantt chart. This feature enables end-users to see how their work aligns with the project’s timeline and take timely measures when things don’t go according to the plan. With DHTMLX Gantt, you get an extensive API for implementing a progress line and many other custom features. If still in doubt, download a free 30-day trial version of our product and give it a try. Stay tuned for more tutorials on DHTMLX Gantt customization in 2025.

Related Materials

Advance your web development with DHTMLX

Gantt chart
Event calendar
Diagram library
30+ other JS components