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. Buy a license.

React Gantt Chart Component

react-gantt-chart-link-dependency.png

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/2019.4.4052.tar.gz --save

The first version of our component is very simple:

src/gantt/GanttChart.js

import React, {Component} from 'react';
import {DayPilotGantt} from "daypilot-pro-react";

class GanttChart extends Component {
  
  render() {
    return (
      <div>
        <DayPilotGantt/>
      </div>
    );
  }
}

export default GanttChart;

This code displays an empty Gantt chart without any configuration. Lets display a task:

import React, {Component} from 'react';
import {DayPilotGantt} from "daypilot-pro-react";

class GanttChart extends Component {

  render() {
    return (
      <div>
        <DayPilotGantt
          startDate={"2019-10-01"}
          days={30}
          tasks={[
            {
              "id": 1,
              "text": "Task 1",
              "start": "2019-10-04T00:00:00",
              "end": "2019-10-16T00:00:00",
            }
          ]}
        />
      </div>
    );
  }
}

export default GanttChart;

Our application now displays a minimal Gantt chart with a single task:

react-gantt-chart-task.png

The tasks are defined using tasks={} property of <DayPilotGantt> component. 

The structure of the data object is defined in the API docs (see DayPilot.Task.data). We define four basic properties: 

  • id - task ID
  • text - task name to be displayed in the Gantt chart
  • start - 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 - they task name (and possibly additional properties) are displayed in the row headers on the right 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 30 days - starting on October 1, 2019.

Let's add another task now and a link that highlights the dependency between them:

import React, {Component} from 'react';
import {DayPilotGantt} from "daypilot-pro-react";

class GanttChart extends Component {

  render() {
    return (
      <div>
        <DayPilotGantt
          startDate={"2019-10-01"}
          days={30}
          tasks={[
            {
              id: 1,
              text: "Task 1",
              start: "2019-10-04T00:00:00",
              end: "2019-10-10T00:00:00",
            },
            {
              id: 2,
              text: "Task 2",
              start: "2019-10-10T00:00:00",
              end: "2019-10-16T00:00:00",
            }
          ]}
          links={[
            {
              from: 1,
              to: 2,
              type: "FinishToStart"
            }
          ]}
        />
      </div>
    );
  }
}

export default GanttChart;

And the result:

react-gantt-chart-link-dependency.png

Gantt Configuration Object

In the previous examples, we have defined the Gantt chart properties directly using the component attributes. That's good for static configuration but we would like to modify the properties on the fly.

In the next step, we will move the configuration to the component state and apply it to the Gantt chart component using spread syntax (...this.state).

We will also add complete property to our task records (it sets the task progress bar value) and add a milestone record (type: "Milestone").

import React, {Component} from 'react';
import {DayPilotGantt} from "daypilot-pro-react";

class GanttChart extends Component {

  constructor(props) {
    super(props);
    this.state = {
      startDate: "2019-10-01",
      days: 30,
      tasks: [
        {
          id: 1,
          text: "Task 1",
          start: "2019-10-04T00:00:00",
          end: "2019-10-10T00:00:00",
          complete: 50
        },
        {
          id: 2,
          text: "Task 2",
          start: "2019-10-10T00:00:00",
          end: "2019-10-16T00:00:00",
          complete: 60
        },
        {
          id: 3,
          text: "Milestone 3",
          start: "2019-10-16T00:00:00",
          end: "2019-10-16T00:00:00",
        }
      ],
      links: [
        {
          from: 1,
          to: 2,
          type: "FinishToStart"
        }
      ]
    };
  }


  render() {
    return (
      <div>
        <DayPilotGantt
          {...this.state}
        />
      </div>
    );
  }
}

export default GanttChart;

Our updated Gantt chart with progress bars and a milestone:

react-gantt-chart-milestone.png

Full Source Code

Here is the full source code of our GanttChart React component:

import React, {Component} from 'react';
import {DayPilot, DayPilotGantt} from "daypilot-pro-react";

class GanttChart extends Component {

  constructor(props) {
    super(props);
    this.state = {
      cellWidth: 40,
      linkBottomMargin: 17,
      taskHtmlRightMargin: 25,
      timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "d"}],
      scale: "Day",
      days: 30,
      startDate: "2019-10-01",
      rowHeaderHideIconEnabled: false,
      rowMoveHandling: "Update",
      onRowMoved: args => {
        this.gantt.message("Row moved");
      },
      onTaskMoved: args => {
        this.gantt.message("Task moved");
      },
      linkCreateHandling: "Update",
      onLinkCreated: args => {
        this.gantt.message("Link created");
      },
      rowCreateHandling: "Enabled",
      onRowCreate: args => {
        this.gantt.tasks.add(new DayPilot.Task({
          id: DayPilot.guid(),
          text: args.text,
          start: new DayPilot.Date().getDatePart(),
          end: new DayPilot.Date().getDatePart().addDays(1)
        }));
      },
    };
  }

  componentDidMount() {

    // load resource and event data
    this.setState({
      tasks: [
        {
          "id": 1,
          "text": "Group 1",
          "complete": 35,
          "start": "2019-10-04T00:00:00",
          "end": "2019-10-16T00:00:00",
          "children": [
            {
              "id": 2,
              "start": "2019-10-04T00:00:00",
              "end": "2019-10-11T00:00:00",
              "text": "Task 1",
              "complete": 60
            },
            {
              "id": 3,
              "start": "2019-10-11T00:00:00",
              "end": "2019-10-16T00:00:00",
              "text": "Task 2",
              "complete": 0
            },
            {
              "id": 4,
              "start": "2019-10-16T00:00:00",
              "type": "Milestone",
              "text": "Milestone 1",
              "end": "2019-10-16T00:00:00"
            }
          ],
        }
      ],
      links: [
        {from: 2, to: 3, type: "FinishToStart"}
      ]
    });

  }

  render() {
    var {...config} = this.state;
    return (
      <div>
        <DayPilotGantt
          {...config}
          ref={component => {
            this.gantt = component && component.control;
          }}
        />
      </div>
    );
  }
}

export default GanttChart;