Resources in React Gantt component

3 Jul 202424 minutes to read

In Gantt, the resources are represented by staff, equipment and materials etc. In Gantt component you can show or allocate the resources (human resources) for each task.

To get start quickly with Resource Allocation for each task and to know about Resource view Gantt, you can check on this video

Resource collection

The resource collection contains details about resources that are used in the project. Resources are JSON object that contains id, name, unit and group of the resources and this collection is mapped to the Gantt control using the resources property. These resource fields are mapped to the Gantt control using the resourceFields property.

Resource fields Description
id This field is used to assign resources to the tasks.
name This field is used to map the resource names. These names are displayed as one of Gantt columns and also can display as labels using the labelSettings property.
unit It indicates the amount of work that can be done by a resource for the task in a day.
group This field is used to group the resources and the tasks assigned to that particular resource into category.

The following code snippets shows resource collection and how it assigned to Gantt control.

let projectResources: object[] =  resources: [
    { resourceId: 1, resourceName: 'Martin Tamer', resourceGroup: 'Planning Team', resourceUnit: 50},
    { resourceId: 2, resourceName: 'Rose Fuller', resourceGroup: 'Testing Team', resourceUnit: 70 },
    { resourceId: 3, resourceName: 'Margaret Buchanan', resourceGroup: 'Approval Team' },
    { resourceId: 4, resourceName: 'Fuller King', resourceGroup: 'Development Team' },
    { resourceId: 5, resourceName: 'Davolio Fuller', resourceGroup: 'Approval Team' },
    { resourceId: 6, resourceName: 'Van Jack', resourceGroup: 'Development Team', resourceUnit: 40 },
];

class App extends React.Component<{}, {}>{
    render() {
        return <GanttComponent dataSource={data}
        resourceFields: {
        id: 'resourceId', //resource Id Mapping
        name: 'resourceName', //resource Name mapping
        unit: 'resourceUnit', //resource Unit mapping
        group: 'resourceGroup' //resource Group mapping
    },
    resources: projectResources //resource collection dataSource

        </GanttComponent>
    }
};
ReactDOM.render(<App />, document.getElementById('root'));

Assign resource

We can assign resources for a task at initial load, using the resource id value of the resources as a collection. This collection is mapped from the dataSource to the Gantt control using the resourceInfo property.

Resources are assigned to tasks in following ways.

Assign resource alone

If the unit is not specified for specific resource, the amount of work done will be consider as 100% by default. In such cases, the resource unit will not be displayed in Gantt UI.

    { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 50,resources: [2, 3] }

Assign resources with unit

We can assign the quantity of work done by the resources for the specific task as like below code snippet.

 { TaskID: 3, TaskName: 'Perform soil test', StartDate: new Date('03/29/2019'), Duration: 4,
    resources: [{resourceId: 2, resourceUnit: 70}, {resourceId: 1, resourceUnit: 70}] },

When resource unit is defined in resource collection, the amount of work done by that particular resource will be same for all the tasks.

The following code snippet shows how to assign the resource for each task and map to Gantt control.

export let ProjectResources = [
    { ResourceId: 1, ResourceName: 'Martin Tamer' },
    { ResourceId: 2, ResourceName: 'Rose Fuller' },
    { ResourceId: 3, ResourceName: 'Margaret Buchanan' },
    { ResourceId: 4, ResourceName: 'Fuller King' },
    { ResourceId: 5, ResourceName: 'Davolio Fuller' },
    { ResourceId: 6, ResourceName: 'Van Jack' },
    { ResourceId: 7, ResourceName: 'Fuller Buchanan' },
    { ResourceId: 8, ResourceName: 'Jack Davolio' },
    { ResourceId: 9, ResourceName: 'Tamer Vinet' },
    { ResourceId: 10, ResourceName: 'Vinet Fuller' },
    { ResourceId: 11, ResourceName: 'Bergs Anton' },
    { ResourceId: 12, ResourceName: 'Construction Supervisor' }
];
let data = [
    {
        TaskID: 1, TaskName: 'Project initiation', StartDate: new Date('03/29/2019'), EndDate: new Date('04/21/2019'),
    },
    {
        TaskID: 2, TaskName: 'Identify site location', StartDate: new Date('03/29/2019'), Duration: 2,
        ParentID: 1, Progress: 30, Resources: [{ ResourceId: 1, Unit: 70 }, 6]
    },
    {
        TaskID: 3, TaskName: 'Perform soil test', StartDate: new Date('03/29/2019'), Duration: 4,
        ParentID: 1, Resources: [2, 3, 5]
    },
    {
        TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('03/29/2019'), Duration: 1,
        ParentID: 1, Resources: [8, { ResourceId: 9, Unit: 50 }], Progress: 30
    },
    {
        TaskID: 5,
        TaskName: 'Project estimation', StartDate: new Date('03/29/2019'), EndDate: new Date('04/21/2019'),
    },
    {
        TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('03/29/2019'),
        Duration: 3, ParentID: 5, Progress: 30, Resources: [{ ResourceId: 4, Unit: 50 }]
    },
    {
        TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/01/2019'), Duration: 3,
        ParentID: 5, Resources: [4, 8]
    },
    {
        TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/01/2019'),
        Duration: 2, ParentID: 5, Resources: [12, { ResourceId: 5, Unit: 70 }]
    },
    {
        TaskID: 9, TaskName: 'Sign contract', StartDate: new Date('04/01/2019'), Duration: 1,
        Progress: 30, Resources: [12]
    }
];
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
function App(){
        const taskFields = {
            id: 'TaskID',
            name: 'TaskName',
            startDate: 'StartDate',
            duration: 'Duration',
            progress: 'Progress',
            resourceInfo: 'Resources',
            parentID: 'ParentID'
        };
        const resourceFields = {
            id: 'ResourceId',
            name: 'ResourceName',
            unit: 'Unit'
        };
        const labelSettings = {
            rightLabel: 'Resources'
        };
        return <GanttComponent id='root' dataSource={ data } taskFields = { taskFields } resourceFields={resourceFields} labelSettings = {labelSettings } resources = { ProjectResources } height = '450px' >
            <ColumnsDirective>
            <ColumnDirective field= 'TaskID' visible= 'false' > </ColumnDirective>
            < ColumnDirective field= 'TaskName'  headerText= 'Task Name'  width= '180' > </ColumnDirective>
            < ColumnDirective field= 'Resources'  headerText= 'Resources'  width= '160' > </ColumnDirective>
            < ColumnDirective field= 'Duration'  width= '100' > </ColumnDirective>
            </ColumnsDirective>
        </GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
export let ProjectResources = [
    { ResourceId: 1, ResourceName: 'Martin Tamer' },
    { ResourceId: 2, ResourceName: 'Rose Fuller' },
    { ResourceId: 3, ResourceName: 'Margaret Buchanan' },
    { ResourceId: 4, ResourceName: 'Fuller King' },
    { ResourceId: 5, ResourceName: 'Davolio Fuller' },
    { ResourceId: 6, ResourceName: 'Van Jack' },
    { ResourceId: 7, ResourceName: 'Fuller Buchanan' },
    { ResourceId: 8, ResourceName: 'Jack Davolio' },
    { ResourceId: 9, ResourceName: 'Tamer Vinet' },
    { ResourceId: 10, ResourceName: 'Vinet Fuller' },
    { ResourceId: 11, ResourceName: 'Bergs Anton' },
    { ResourceId: 12, ResourceName: 'Construction Supervisor' }
];
let data =  [
    {
        TaskID: 1, TaskName: 'Project initiation', StartDate: new Date('03/29/2019'), EndDate: new Date('04/21/2019'),
    },
    {
        TaskID: 2, TaskName: 'Identify site location', StartDate: new Date('03/29/2019'), Duration: 2,
        ParentID: 1, Progress: 30, Resources: [{ ResourceId: 1, Unit: 70 }, 6]
    },
    {
        TaskID: 3, TaskName: 'Perform soil test', StartDate: new Date('03/29/2019'), Duration: 4,
        ParentID: 1, Resources: [2, 3, 5]
    },
    {
        TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('03/29/2019'), Duration: 1,
        ParentID: 1, Resources: [8, { ResourceId: 9, Unit: 50 }], Progress: 30
    },
    {
        TaskID: 5,
        TaskName: 'Project estimation', StartDate: new Date('03/29/2019'), EndDate: new Date('04/21/2019'),
    },
    {
        TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('03/29/2019'),
        Duration: 3, ParentID: 5, Progress: 30, Resources: [{ ResourceId: 4, Unit: 50 }]
    },
    {
        TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/01/2019'), Duration: 3,
        ParentID: 5, Resources: [4, 8]
    },
    {
        TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/01/2019'),
        Duration: 2, ParentID: 5, Resources: [12, { ResourceId: 5, Unit: 70 }]
    },
    {
        TaskID: 9, TaskName: 'Sign contract', StartDate: new Date('04/01/2019'), Duration: 1,
        Progress: 30, Resources: [12]
    }
];
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
function App(){
        const taskFields = {
            id: 'TaskID',
            name: 'TaskName',
            startDate: 'StartDate',
            duration: 'Duration',
            progress: 'Progress',
            resourceInfo: 'Resources',
            parentID: 'ParentID'
        };
        const resourceFields = {
            id: 'ResourceId',
            name: 'ResourceName',
            unit: 'Unit'
        };
        const labelSettings = {
            rightLabel: 'Resources'
        };
        return <GanttComponent id='root' dataSource={ data } taskFields = { taskFields } resourceFields={resourceFields} labelSettings = {labelSettings } resources = { ProjectResources } height = '450px' >
            <ColumnsDirective>
            <ColumnDirective field= 'TaskID' visible= 'false' > </ColumnDirective>
            < ColumnDirective field= 'TaskName'  headerText= 'Task Name'  width= '180' > </ColumnDirective>
            < ColumnDirective field= 'Resources'  headerText= 'Resources'  width= '160' > </ColumnDirective>
            < ColumnDirective field= 'Duration'  width= '100' > </ColumnDirective>
            </ColumnsDirective>
        </GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/29.1.33/material.css" rel="stylesheet" type="text/css"/>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
     <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
        <div id='root'>
            <div id='loader'>Loading....</div>
        </div>
</body>

</html>

Add/Edit resource collection

By using cell/ dialog edit option, we can add/remove the multiple resources for a particular task. Resource Unit can be change for a each task on resource tab in edit dialog by double click on the unit cell.

Cell Edit

Dialog Edit

Custom background colors for resource column and taskbar

In the Gantt Component, you can customize the background colors of the resource column and taskbars based on the resources assigned to each task. This customization enhances the readability and usability of the Gantt chart.

To achieve this, utilize the template property for the resource column and the queryTaskbarInfo event. The template property allows you to define a custom template for the resource column, while the queryTaskbarInfo event to modify the taskbar properties, including background colors.

The following code snippet demonstrates how to customize the background colors of the taskbar and resource column according to the assigned resources:

export let ProjectResources = [
    { ResourceId: 1, ResourceName: 'Martin Tamer' },
    { ResourceId: 2, ResourceName: 'Rose Fuller' },
    { ResourceId: 3, ResourceName: 'Margaret Buchanan' },
    { ResourceId: 4, ResourceName: 'Tamer Vinet' }
];
let data = [
  {
    TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
  },
  {
    TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4,
    ParentID: 1, Progress: 30, Resources: [1], info: 'Measure the total property area alloted for construction'
  },
  {
    TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Predecessor: '2',
    Resources: [2], info: 'Obtain an engineered soil test of lot where construction is planned.' +
      'From an engineer or company specializing in soil testing'
  },
  { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Predecessor: '3', Progress: 30, Resources: [3], },
  {
    TaskID: 5,
    TaskName: 'Project Estimation',
    StartDate: new Date('04/02/2019'),
    EndDate: new Date('04/21/2019'),
  },
  {
    TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'),
    Duration: 3, ParentID: 5, Predecessor: '4', Progress: 30, Resources: [4],
    info: 'Develop floor plans and obtain a materials list for estimations'
  },
  {
    TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'),
    Duration: 3, ParentID: 5, Predecessor: '6', Resources: [1], info: ''
  },
  {
    TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'),
    Duration: 4, ParentID: 5, Predecessor: '7', Resources: [2], info: ''
  }
];
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
function App(){
        const taskFields = {
            id: 'TaskID',
            name: 'TaskName',
            resourceInfo: 'Resources',
            startDate: 'StartDate',
            duration: 'Duration',
            progress: 'Progress',
            parentID: 'ParentID'
        };
        function queryTaskbarInfo(args) {
            if(args.data.Resources === 'Martin Tamer'){
                args.taskbarBgColor = '#DFECFF';
                args.progressBarBgColor = '#006AA6'
            }else if(args.data.Resources === 'Rose Fuller'){
                args.taskbarBgColor = '#E4E4E7';
                args.progressBarBgColor = '#766B7C'
            }
            else if(args.data.Resources === 'Margaret Buchanan'){
                args.taskbarBgColor = '#DFFFE2';
                args.progressBarBgColor = '#00A653'
            }
            else if(args.data.Resources === 'Tamer Vinet'){
                args.taskbarBgColor = '#FFEBE9';
                args.progressBarBgColor = '#FF3740'
            }
        };
        const resColumnTemplate = (props) => {
            if (props.ganttProperties.resourceNames) {
              if (props.ganttProperties.resourceNames === 'Martin Tamer') {
                return (
                  <div style=>
                  <span style=>{props.ganttProperties.resourceNames}</span>
                  </div>
                );
              }
        
              if (props.ganttProperties.resourceNames === 'Rose Fuller') {
                return (
                  <div style=>
                  <span style=>{props.ganttProperties.resourceNames}</span>
                  </div>
                );
              }
        
              if (props.ganttProperties.resourceNames === 'Margaret Buchanan') {
                return (
                  <div style=>
                  <span style=>{props.ganttProperties.resourceNames}</span>
                  </div>
                );
              }
        
              if (props.ganttProperties.resourceNames === 'Tamer Vinet') {
                return (
                  <div style=>
                  <span style=>{props.ganttProperties.resourceNames}</span>
                  </div>
                );
              }
        
            } else {
              return <div></div>
            }
          }
        const template = resColumnTemplate.bind(this);
        const resourceFields = {
            id: 'ResourceId',
            name: 'ResourceName'
        };
        const labelSettings = {
            rightLabel: 'Resources'
        };
        const splitterSettings = {
            columnIndex: 2
        };
        return <GanttComponent id='root' queryTaskbarInfo= {queryTaskbarInfo} dataSource= { data } taskFields = { taskFields } resourceFields={resourceFields} labelSettings = { labelSettings } resources = { ProjectResources } height = '380px' splitterSettings = {splitterSettings} >
            <ColumnsDirective>
            < ColumnDirective field= 'TaskName'  headerText= 'Task Name'  width= '270' > </ColumnDirective>
            < ColumnDirective field= 'Resources'  headerText= 'Resources'  width= '175' template= {template} > </ColumnDirective>
            < ColumnDirective field= 'StartDate' headerText='Start Date' width= '150' > </ColumnDirective>
            < ColumnDirective field= 'Duration' width= '150' > </ColumnDirective>
            < ColumnDirective field= 'Progress' width= '150' > </ColumnDirective>
            </ColumnsDirective>
        </GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
export let ProjectResources = [
  { ResourceId: 1, ResourceName: 'Martin Tamer' },
  { ResourceId: 2, ResourceName: 'Rose Fuller' },
  { ResourceId: 3, ResourceName: 'Margaret Buchanan' },
  { ResourceId: 4, ResourceName: 'Tamer Vinet' }
];
let data = [
  {
    TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
  },
  {
    TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4,
    ParentID: 1, Progress: 30, Resources: [1], info: 'Measure the total property area alloted for construction'
  },
  {
    TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Predecessor: '2',
    Resources: [2], info: 'Obtain an engineered soil test of lot where construction is planned.' +
      'From an engineer or company specializing in soil testing'
  },
  { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Predecessor: '3', Progress: 30, Resources: [3], },
  {
    TaskID: 5,
    TaskName: 'Project Estimation',
    StartDate: new Date('04/02/2019'),
    EndDate: new Date('04/21/2019'),
  },
  {
    TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'),
    Duration: 3, ParentID: 5, Predecessor: '4', Progress: 30, Resources: [4],
    info: 'Develop floor plans and obtain a materials list for estimations'
  },
  {
    TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'),
    Duration: 3, ParentID: 5, Predecessor: '6', Resources: [1], info: ''
  },
  {
    TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'),
    Duration: 4, ParentID: 5, Predecessor: '7', Resources: [2], info: ''
  }
];
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
function App(){
        const taskFields = {
          id: 'TaskID',
          name: 'TaskName',
          resourceInfo: 'Resources',
          startDate: 'StartDate',
          duration: 'Duration',
          progress: 'Progress',
          parentID: 'ParentID'
        };
        function queryTaskbarInfo(args: any) {
          if(args.data.Resources === 'Martin Tamer'){
            args.taskbarBgColor = '#DFECFF';
            args.progressBarBgColor = '#006AA6'
        }else if(args.data.Resources === 'Rose Fuller'){
            args.taskbarBgColor = '#E4E4E7';
            args.progressBarBgColor = '#766B7C'
        }
        else if(args.data.Resources === 'Margaret Buchanan'){
            args.taskbarBgColor = '#DFFFE2';
            args.progressBarBgColor = '#00A653'
        }
        else if(args.data.Resources === 'Tamer Vinet'){
            args.taskbarBgColor = '#FFEBE9';
            args.progressBarBgColor = '#FF3740'
        }
        };
        const resColumnTemplate = (props: any) => {
            if (props.ganttProperties.resourceNames) {
              if (props.ganttProperties.resourceNames === 'Martin Tamer') {
                return (
                  <div style=>
                  <span style=>{props.ganttProperties.resourceNames}</span>
                  </div>
                );
              }
        
              if (props.ganttProperties.resourceNames === 'Rose Fuller') {
                return (
                  <div style=>
                  <span style=>{props.ganttProperties.resourceNames}</span>
                  </div>
                );
              }
        
              if (props.ganttProperties.resourceNames === 'Margaret Buchanan') {
                return (
                  <div style=>
                  <span style=>{props.ganttProperties.resourceNames}</span>
                  </div>
                );
              }
        
              if (props.ganttProperties.resourceNames === 'Tamer Vinet') {
                return (
                  <div style=>
                  <span style=>{props.ganttProperties.resourceNames}</span>
                  </div>
                );
              }
        
            } else {
              return <div></div>
            }
          }
        const template: any = resColumnTemplate.bind(this);;
        const resourceFields = {
            id: 'ResourceId',
            name: 'ResourceName'
        };
        const labelSettings = {
            rightLabel: 'Resources'
        };
        const splitterSettings = {
            columnIndex: 2
        };
        return <GanttComponent id='root' queryTaskbarInfo= {queryTaskbarInfo} dataSource={ data } taskFields = { taskFields } resourceFields={resourceFields} labelSettings = {labelSettings } resources = { ProjectResources } height = '380px' splitterSettings = {splitterSettings} >
            <ColumnsDirective>
            < ColumnDirective field= 'TaskName'  headerText= 'Task Name'  width= '270' > </ColumnDirective>
            < ColumnDirective field= 'Resources'  headerText= 'Resources'  width= '175' template= {template} > </ColumnDirective>
            < ColumnDirective field= 'StartDate' headerText='Start Date' width= '150' > </ColumnDirective>
            < ColumnDirective field= 'Duration' width= '150' > </ColumnDirective>
            < ColumnDirective field= 'Progress' width= '150' > </ColumnDirective>
            </ColumnsDirective>
        </GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet" type="text/css"/>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
     <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
        <div id='root'>
            <div id='loader'>Loading....</div>
        </div>
</body>

</html>