Overview
This is a simple React project that will let you explore features of the React Gantt Chart component from DayPilot Pro for JavaScript.
The project was generated using DayPilot UI Builder - an online application that lets you configure the Gantt Chart component and generate a new React project.
The Gantt Chart supports tasks, task groups and milestones.
The tasks can be moved using drag and drop.
License
Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript.
React Gantt Chart Component
We will create a new GanttChart
component that will wrap the DayPilotGantt
component and configure its appearance and behavior.
Before we can use the DayPilotGantt
component, we need to install the daypilot-pro-react
package from npm.daypilot.org:
npm install https://npm.daypilot.org/daypilot-pro-react/trial/2024.3.5972.tar.gz --save
The first version of our component is very simple (src/gantt/GanttChart.js
):
import React from 'react';
import {DayPilotGantt} from "daypilot-pro-react";
const GanttChart = () => {
return (
<div>
<DayPilotGantt/>
</div>
);
};
export default GanttChart;
This code displays an empty Gantt chart without any configuration. Let’s display a task:
import React from 'react';
import {DayPilotGantt} from "daypilot-pro-react";
const GanttChart = () => {
return (
<div>
<DayPilotGantt
startDate={"2025-01-01"}
days={30}
tasks={[
{
"id": 1,
"text": "Task 1",
"start": "2025-01-04T00:00:00",
"end": "2025-01-16T00:00:00",
}
]}
/>
</div>
);
};
export default GanttChart;
Our application now displays a minimal Gantt chart with a single task:
The tasks are defined using the tasks={}
attribute of the <DayPilotGantt>
tag.
The structure of the data object is defined in the API docs (see DayPilot.Task.data).
We define four basic properties:
id
- task IDtext
- task name to be displayed in the Gantt chartstart
- task start (DayPilot.Date object or ISO 8601 date/time string)end
- task start (DayPilot.Date object or ISO 8601 date/time string)
These properties define the task identity and position - they are required to display the task in the Gantt chart.
Each task will be displayed in a separate row. The task names (and possibly additional properties) are displayed in the row headers on the left side. The task date/time position is displayed in the time grid as well. If you need to display multiple tasks in the same row, you can check the React Scheduler component, which allows greater flexibility in the task display.
The startDate and days properties define the grid start and end. In our example, we display 31 days - starting on January 1, 2025.
Let's add another task now and a link that highlights the dependency between them:
import React from 'react';
import {DayPilotGantt} from "daypilot-pro-react";
const GanttChart = () => {
return (
<div>
<DayPilotGantt
startDate={"2025-01-01"}
days={30}
tasks={[
{
id: 1,
text: "Task 1",
start: "2025-01-04T00:00:00",
end: "2025-01-10T00:00:00",
},
{
id: 2,
text: "Task 2",
start: "2025-01-10T00:00:00",
end: "2025-01-16T00:00:00",
}
]}
links={[
{
from: 1,
to: 2,
type: "FinishToStart"
}
]}
/>
</div>
);
};
export default GanttChart;
And the result:
Gantt Chart Configuration
In the previous examples, we have defined the Gantt chart properties directly using the component attributes.
In this step, we will move the dynamic properties to state variables:(startDate
, days
, tasks
, and links
).
The static configuration properties will be moved to a special config
object. The properties defined in the config
object will be applied to the Gantt chart component using the spread syntax (...config
).
We will also add a complete
property to our task records (it sets the task progress bar value) and add a milestone record (type: "Milestone"
).
import React, { useState, useEffect } from 'react';
import { DayPilotGantt } from "daypilot-pro-react";
const GanttChart = () => {
const [gantt, setGantt] = useState(null);
const [startDate, setStartDate] = useState("2025-01-01");
const [days, setDays] = useState(30);
const [tasks, setTasks] = useState([]);
const [links, setLinks] = useState([]);
const config = {
timeHeaders: [
{ groupBy: "Month" },
{ groupBy: "Day", format: "d" }
],
scale: "Day"
};
useEffect(() => {
const tasks = [
{
id: 1,
text: "Task 1",
start: "2025-01-04T00:00:00",
end: "2025-01-10T00:00:00",
complete: 50
},
{
id: 2,
text: "Task 2",
start: "2025-01-10T00:00:00",
end: "2025-01-16T00:00:00",
complete: 60
},
{
id: 3,
text: "Milestone 3",
type: "Milestone",
start: "2025-01-16T00:00:00",
end: "2025-01-16T00:00:00"
}
];
setTasks(tasks);
const links = [
{
from: 1,
to: 2,
type: "FinishToStart"
}
];
setLinks(links);
}, [gantt]);
return (
<div>
<DayPilotGantt
{...config}
startDate={startDate}
days={days}
tasks={tasks}
links={links}
controlRef={setGantt}
/>
</div>
);
};
export default GanttChart;
Our updated Gantt chart with progress bars and a milestone:
Row Header Columns with Additional Task Data
In this step, we will customize the row headers of the Gantt chart component to display some more columns in addition to the task name:
Progress
Duration
The row header columns can be defined using the columns property:
const config = {
columns: [
{name: "Name", property: "text"},
{name: "Complete"},
{name: "Duration"},
],
// ...
};
The name
property specifies the column name that will be displayed in the title. The property
value specifies the property of the task that will be used for cell content in each row.
The “Complete” and “Duration” columns will require additional formatting, so we don’t specify the property for them. Instead, we will use the onBeforeRowHeaderRender to define the cell content:
const config = {
// ...
onBeforeRowHeaderRender: (args) => {
if (args.task.type() !== "Milestone") {
args.row.columns[1].html = args.task.data.complete + "%";
args.row.columns[2].html = args.task.duration().totalDays() + " days";
}
},
// ...
};
You can use this feature to display additional task details in the Gantt chart, such as ID, task owner, priority, and so on.
Full Source Code
Here is the full source code of our React Gantt Chart component:
import React, { useEffect, useRef, useState } from 'react';
import { DayPilot, DayPilotGantt } from "daypilot-pro-react";
const Gantt = () => {
const [gantt, setGantt] = useState(null);
const [tasks, setTasks] = useState([]);
const [links, setLinks] = useState([]);
const config = {
timeHeaders: [{groupBy: "Month"},{groupBy: "Day", format:"d"}],
scale: "Day",
days: 90,
startDate: "2025-01-01",
taskHeight: 35,
heightSpec: "Max",
height: 600,
rowHeaderHideIconEnabled: false,
columns: [
{name: "Name", property: "text"},
{name: "Complete"},
{name: "Duration"},
],
onBeforeRowHeaderRender: (args) => {
console.log("onBeforeRowHeaderRender", args);
if (args.task.type() !== "Milestone") {
args.row.columns[1].html = args.task.data.complete + "%";
args.row.columns[2].html = args.task.duration().totalDays() + " days";
}
},
rowMoveHandling: "Update",
onRowMoved: (args) => {
args.control.message("Row moved: " + args.source.text());
},
taskMoveHandling: "Update",
onTaskMoved: (args) => {
args.control.message("Task moved to: " + args.newStart);
},
linkCreateHandling: "Update",
onLinkCreated: (args) => {
args.control.message("Link created, type: " + args.type);
},
rowCreateHandling: "Enabled",
onRowCreate: (args) => {
args.control.tasks.add({
id: DayPilot.guid(),
text: args.text,
start: args.control.startDate,
end: args.control.startDate.addDays(1)
});
},
};
useEffect(() => {
const tasks = [
{
id: 101,
text: "Group 101",
complete: 35,
children: [
{
id: 102,
start: "2025-01-02T00:00:00",
end: "2025-01-04T00:00:00",
text: "Task 1",
complete: 60
},
{
id: 103,
start: "2025-01-05T00:00:00",
end: "2025-01-08T00:00:00",
text: "Task 2",
complete: 0
},
{
id: 104,
start: "2025-01-08T00:00:00",
type: "Milestone",
text: "Milestone 1",
}
],
},
{
id: 201,
text: "Group 201",
complete: 35,
children: [
{
id: 202,
start: "2025-01-08T00:00:00",
end: "2025-01-11T00:00:00",
text: "Task 202",
complete: 60
},
{
id: 203,
start: "2025-01-11T00:00:00",
end: "2025-01-13T00:00:00",
text: "Task 203",
complete: 0
},
{
id: 204,
start: "2025-01-13T00:00:00",
type: "Milestone",
text: "Milestone 204",
}
],
}
];
setTasks(tasks);
const links = [
{ from: 102, to: 103, type: "FinishToStart"},
{ from: 202, to: 203, type: "FinishToStart"},
{ from: 101, to: 201, type: "FinishToStart"},
];
setLinks(links);
}, [gantt]);
return (
<div>
<DayPilotGantt
{...config}
tasks={tasks}
links={links}
controlRef={setGantt}
/>
</div>
);
}
export default Gantt;
History
July 23, 2024: Upgraded to React 18, DayPilot Pro 2024.3.5972, row header columns added.
December 5, 2020: Upgraded to DayPilot Pro for JavaScript 2020.4.4788, React 17.
October 3, 2019: Initial release, React 16.