Available only in PRO Edition

Resource Management

This functionality is available in the Gantt PRO edition only.

Gantt provides predefined resource views for highlighting resource load, methods for breaking project down by a resource for load balancing, task and resource-specific work-time calendars.

Although Gantt itself does not calculate the resource load, and does not have any methods that can be used out of the box, Gantt provides you with public API for implementing any custom behavior.

Assigning resources

Connecting resources to tasks

The resource relation is defined by the resource_property configuration option:

gantt.config.resource_property = "user_id";
// task.user_id <-> resource.id

Resources can be connected to tasks via the properties of the task object in one of the following ways:

  • assigning one resource to one task
{
    id: 1, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6, 
    user_id: 5 // 5 is the id of the resource 
}
  • assigning multiple resources to one task
{
    id: 1, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6, 
    users: [2, 3] // 2 and 3 are the ids of resources
}

You can use this format with the custom multiselect control.

  • assigning multiple resources and specifying their quantity
{
    id: 1, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
    users: [{resource_id:2, value:8}, {resource_id:3, value:4}]  
}

The resources are assigned to the Task1 as follows: the resource with id=2 - in the quantity of 8 units, while the resource with the id=3 - in the quantity of 4 units. This format is supported by the Resources Control of the lightbox.

When sending data to the server, DataProcessor serializes the values of the described properies into JSON. To process such records on the server with ease, make use of the "REST_JSON" dataprocessor mode.

Setting the time of the resource assignments

By default, the resource is considered to be assigned for the whole duration of a task.
Starting from v7.1, the object of the resource assignment can accept additional optional parameters that allow specifying the dates of the assignment within the task.

The additional properties are:

  • id - (string|number) the id of the assignment
  • start_date - (Date|string) the date the assignment is scheduled to start
  • end_date - (Date|string) the date the assignment is scheduled to be completed
  • delay - (number) the difference between the assignment start date and the task start date
  • duration - (number) the duration of the assignment
  • mode - (string) the calculation mode of the time of the resource assignment: "default"|"fixedDates"|"fixedDuration"
{
    id: 5, text: "Interior office", type: "task", start_date: "03-04-2019 00:00",
    duration: 7, parent: "2", progress: 0.6, priority: 1,
    users: [{
        resource_id: "3",
        value: 8,
        delay: 1     },{
        resource_id: "6",
        value: 3,
        start_date: "03-04-2019 00:00",         end_date: "05-04-2019 00:00",         mode: "fixedDates"     },{
        resource_id: "7",
        value: 3,
        delay: 1,         duration: 2,         mode: "fixedDuration"     }
    ]
}

Related sample:  Assign resource values to specific days

1. The start and end dates of the resource assignment will be reflected in the resource histogram and diagram.

2. The optional id property of the assignment can be added to the resource assignment object:

{
    id: 1, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
    users: [{
        id: 5, 
        resource_id: 2, value: 8, 
        delay: 1
    }]
}

The assignment object will be accessible for the gantt API via this id:

var assignment = gantt.getDatastore("resourceAssignments").getItem(5);

The "resourceAssignments" datastore is only available when the process_resource_assignments config is enabled.


3. The work of the rest properties is defined by the value of the mode property:

  • the "default" mode
{
    id: 1, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
    users: [
        { resource_id: 2, value: 8, delay: 1},
        { resource_id: 3, value: 6},
    ]
}

If the mode is not specified or is set to the "default" value, the start_date and end_date of the assignment are calculated from the dates of the task. By default, the start date of the assignment matches the start date of the task. The same approach is applied to the end date.

The delay property works similarly to the Delay property of MS Project.

If the delay is specified, the start_date of the assignment is calculated as
gantt.calculateEndDate({start_date:task.start_date, duration:assignment.delay, task:task}).

The resource assignment will start with the specified delay from the start of the task. The end date of the assignment will match the end date of the task.
Whenever the task object is updated, the start/end dates of the assignment will be updated accordingly.

  • the "fixedDuration" mode
{
    id: 1, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
    users: [
        {resource_id:2, value:8, duration: 1, delay:0, mode: "fixedDuration"},
        {resource_id:2, value:2, duration: 1, delay:1, mode: "fixedDuration"},
        {resource_id:2, value:3, delay:2, mode: "default"}
    ]
}

The start_date of the assignment is calculated in the same way as it's calculated in the "default" mode.

The end_date is no longer linked to the end date of the task. Instead, it's calculated as
gantt.calculateEndDate({start_date:assignment.start_date, duration:assignment.delay, task:task}).

Whenever the task object is updated, the dates of the assignments are recalculated, and the durations of the assignments remain unchanged.

  • the "fixedDates" mode
{
    id: 1, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
    users: [{
        resource_id:2, value:8, 
        start_date:"03-04-2018", end_date:"11-04-2018", mode: "fixedDates"
    }]
}

In this mode, the dates of the resource assignment have exactly the same values as specified in the data and are not changed when the task is modified.

The delay field doesn't affect the dates of the assignment when the "fixedDates" mode is used.


Here is a short summary of how assignment dates are calculated in each mode:

  • default

    • assignment.start_date = task.start_date + assignment.delay
    • assignment.end_date = task.end_date
  • fixedDuration

    • assignment.start_date = task.start_date + assignment.delay
    • assignment.end_date = assignment.start_date + assignment.duration
  • fixedDates

    • assignment.start_date = assignment.start_date
    • assignment.end_date = assignment.end_date

Getting tasks a resource is assigned to

There is a shorthand for getting all tasks assigned to a resource - getResourceAssignments.

gantt.getResourceAssignments("6");

The method takes as a parameter the id of the resource and returns an array of objects with tasks assigned to the resource:

[ 
    {task_id: 5, resource_id: "6", value: 5, delay: 0, duration: 7, 
        start_date: "03-04-2019 00:00", end_date: "12-04-2019 00:00", 
        id: 1617258553240, mode: "default"},
    {task_id: 18, resource_id: "6", value: 2, delay: 0, duration: 2, 
        start_date: "05-04-2019 00:00", end_date: "09-04-2019 00:00", 
        id: 1617258553250, mode: "default"},
    {task_id: 19, resource_id: "6", value: 3, delay: 0, duration: 4, 
        start_date: "09-04-2019 00:00", end_date: "13-04-2019 00:00", 
        id: 1617258553251, mode: "default"},
    {task_id: 21, resource_id: "6", value: 5, delay: 0, duration: 4, 
        start_date: "03-04-2019 00:00", end_date: "09-04-2019 00:00", 
        id: 1617258553254, mode: "default"}
]

Each object contains the following properties:

  • task_id - the id of the task
  • resource_id - the id of the resource
  • value - the quantity of the resource assigned to a task
  • delay - the difference between the assignment start date and the task start date
  • duration - the duration of the assignment
  • start_date - the date the assignment is scheduled to start
  • end_date - the date the assignment is scheduled to be completed
  • id - the id of the assignment
  • mode - the calculation mode of the time of the resource assignment: "default"|"fixedDates"|"fixedDuration"

Getting resource assignments of a task

The getTaskAssignments method allows getting the parsed resource assignments of a specific task from the datastore:

gantt.getTaskAssignments(5);

The method takes as a parameter the id of the task and returns an array of objects with the resource assignments of the task:

[
    {task_id: 5, id: 1617254693938, delay: 0, duration: 2, 
        start_date: "03-04-2019 00:00", end_date: "05-04-2019 00:00", 
        mode: "fixedDuration", resource_id: 6, value: 3},
    {task_id: 5, id: 1617254693946, delay: 3, duration: 1, 
        start_date: "06-04-2019 00:00", end_date: "07-04-2019 00:00", 
        mode: "fixedDuration", resource_id: 6, value: 6}
]

The return object contains the same list of properties as the return object of the getResourceAssignments method.

Setting connection via lightbox

Resources can be assigned to any property of the task object using the built-in lightbox.

gantt.serverList("people", [
    {key: 1, label: "John"},
    {key: 2, label: "Mike"},
    {key: 3, label: "Anna"},
    {key: 4, label: "Bill"},
    {key: 7, label: "Floe"}
]);
 
gantt.locale.labels.section_owner = "Owner";
 
gantt.config.lightbox.sections = [
  {name:"description", height:38, map_to:"text", type:"textarea", focus:true},
  {name:"owner", map_to:"owner_id", type:"select", options:gantt.serverList("people")},
  {name:"time", type:"duration", map_to: "auto"}
];

Loading collections

Collections specified as server lists can be loaded and updated dynamically, after gantt is initialized:

// init lightbox with an empty collection 
gantt.locale.labels.section_owner = "Owner";
 
gantt.config.lightbox.sections = [
  {name:"description", height:38, map_to:"text", type:"textarea", focus:true},
  {name:"owner", map_to:"owner_id", type:"select", options:gantt.serverList("people")},
  {name:"time", type:"duration", map_to: "auto"}
];
 
// once options are loaded 
gantt.updateCollection("people", [
    {key: 1, label: "John"},
    {key: 2, label: "Mike"},
    {key: 3, label: "Anna"},
    {key: 4, label: "Bill"},
    {key: 7, label: "Floe"}
]);

Related sample:  Assigning owners to tasks

If you define resources via the serverList collection, they can be loaded together with the rest of the data, otherwise you'll need to load them manually.

Managing resource assignments

Parsing resource assignments

Starting with v7.1, you can work with the resource assignments as with objects of the data store.

The new process_resource_assignments property enables the process of parsing of the values from the gantt.config.resource_property of tasks into the internal objects of the resource assignments. As a result, you are able to manipulate the resource assignments via the DataStore object. For instance, you can get the necessary assignment object or update it.

Note, that this functionality is required if you want to specify the desired duration and time for the resources when building Resource Diagram and Histogram.

The process may add noticeable performance overhead and large projects may start working slower. Therefore, if you don't need to set time or duration of the assignment, you can disable parsing of the resource assignments using the config:

gantt.config.process_resource_assignments = false;

When the config is disabled, the gantt.getDatastore("resourceAssignments") datastore won't be available and the assignment objects won't have any dynamic properties. The resource diagram and histogram will consider resources to be assigned to the whole duration of the task.

Updating resource assignments

The resource assignments are stored in the data store which is created automatically.

By default, the store of the assignments is populated from the task objects. It means, that if you modify the resource property of the task object (e.g. task.users), the changes will be automatically reflected in the data store.

task[gantt.config.resource_property] = [
    {
        resource_id: "6",
        value: 3,
        start_date: "03-04-2019 00:00",
        end_date: "05-04-2019 00:00",
    }
];
gantt.updateTask(taskId);


But you may need to refresh the data of the assignments in the opposite direction. Namely, you may need to apply the changes to the task object after the resource assignments are modified via the datastore API. In this case, you need to update the resource property of the task object with the values from the datastore by calling the gantt.updateTaskAssignments() method:

var assignmentStore = gantt.getDatastore(gantt.config.resource_assignment_store);
 
assignmentStore.addItem({
    resource_id: 5,
    task_id: 2,
    value: 4
});
assignmentStore.removeItem(assignment.id);
assignmentStore.updateItem(assignment.id);
 
// after the assignments are updated in the datastore, you need 
// to call `updateTaskAssignments` to write the changes to the task object:
gantt.updateTaskAssignments(taskId);

Showing task resource

The resource name can be displayed as a part of task description or a label of one of the grid cells. Gantt doesn't provide a ready method for getting an item specified in the server list by its id, so you'll need to implement a small helper for this:

function byId(list, id) {
    for (var i = 0; i < list.length; i++) {
        if (list[i].key == id)
            return list[i].label || "";
    }
    return "";
}

After that you can use the resource name in templates:

gantt.config.columns = [
    {name: "owner", width: 80, align: "center", template: function (item) {
        return byId(gantt.serverList('people'), item.owner_id)}},
    {name: "text", label: "Task name", tree: true, width: '*'},
    {name: "add", width: 40}
];
 
gantt.templates.rightside_text = function(start, end, task){
    return byId(gantt.serverList('people'), task.owner_id);
};

Related sample:  Assigning owners to tasks

Custom styling of resources

For coloring you'll usually need the following templates:

Depending on your context, you can

Related sample:  Assigning owners to tasks

Resource calendars

Gantt supports the custom work-time calendars feature. Work-time calendars can be associated with specific resources.

They are mapped to tasks via the property value in one-to-one relation:

// a resource value will be taken from the `task.resource_id` property
gantt.config.resource_property = "resource_id";
 
gantt.config.resource_calendars = {
    "resource1" : "calendarId1",
    "resource2" : "calendarId2",
    "resource3" : "calendarId3"
};

You can use any property to assign calendars to resources. If the resource property is changed dynamically, the gantt will automatically recalculate time of tasks using a new calendar.

Related sample:  Resource calendars

If multiple resources can be assigned to a single task, the gantt can automatically generate a common calendar for all assigned resources.

You can get more information in the related article.

Balancing resource load

You can use the grouping extension to break down the whole project by the resource property.

This feature can be used for balancing resource load in the calendar.

Related sample:  Break down by resources

Read more about task grouping in the related article.

Grouping tasks by multiple resources

In case you assign several resources to a task, tasks will be grouped by assigned resources. It means that a task assigned to two persons won't be duplicated for each of them. Instead it will be rendered once with both persons assigned to it. Note that grouped tasks will be sorted by the start date.

Group resources

Related sample:  Group by multiple resources

  • If tasks in the loaded data set have several resources assigned to them, Gantt will create groups for them automatically.
  • For tasks without assigned resources Gantt will create the default group Not assigned. In case there is such a group in the data set that is passed into the groupBy() method, it should have the default:true config specified to prevent automatic creation of a such a group.

Please note that dragging of tasks grouped by multiple resources is impossible.

Resource view panel

dhtmlxGantt has two types of predefined layout view for displaying resource load of gantt: resource load diagram and resource histogram.

Resource load diagram

It includes corresponding views for the grid and timeline: "resourceGrid" and "resourceTimeline".

gantt.config.layout = {
    css: "gantt_container",
    rows: [
      {
        cols: [
          {view: "grid", group:"grids", scrollY: "scrollVer"},
          {resizer: true, width: 1},
          {view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
          {view: "scrollbar", id: "scrollVer", group:"vertical"}
        ],
        gravity:2
      },
      { resizer: true, width: 1},
      {
        config: resourceConfig,
        cols: [
          {view: "resourceGrid", group:"grids", width: 435, scrollY:"resourceVScroll"},
          {resizer: true, width: 1},
          {view: "resourceTimeline", scrollX: "scrollHor", scrollY:"resourceVScroll"},
          {view: "scrollbar", id: "resourceVScroll", group:"vertical"}
        ],
        gravity:1
       },
       {view: "scrollbar", id: "scrollHor"}
    ]
};

Related sample:  Resource load diagram

Once initialized, resourceGrid will work in the same way as the default grid view, but readonly. resourceTimeline will inherit the scale configuration from the default timeline and will have two layers:

  • background rows, which inherit task_row_class and timeline_cell_class. The templates of resourceTimeline can be redefined at the layout level.
  • resource layer - a layer specific for resourceTimeline. It will display blocks in cells where the resource has tasks assigned. The block style and content can be templated with the resource_cell_class and resource_cell_value templates:
gantt.templates.resource_cell_value = function(start_date, end_date, resource, tasks,
    assignments){
    var html = "<div>" +  tasks.length * 8 + "h</div>";
        return html;
};

Related sample:  Templates of the Resource diagram

Resource histogram

This type of the layout view for displaying resource load of gantt includes the "resourceGrid" and "resourceHistogram" views for the grid and timeline correspondingly.

Resource histogram

gantt.config.layout = {
    css: "gantt_container",
    rows: [
        {
            gravity: 2,
            cols: [
                {view: "grid", group:"grids", scrollY: "scrollVer"},
                {resizer: true, width: 1},
                {view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
                {view: "scrollbar", id: "scrollVer", group:"vertical"}
            ]
        },
        { resizer: true, width: 1, next: "resources"},
        {
            gravity:1,
            id: "resources",
            config: resourceConfig,
            templates: resourceTemplates,
            cols: [
                { view: "resourceGrid", group:"grids", scrollY: "resourceVScroll" },
                { resizer: true, width: 1},
                { view: "resourceHistogram", capacity:24, scrollX: "scrollHor", 
                    scrollY: "resourceVScroll"},
                { view: "scrollbar", id: "resourceVScroll", group:"vertical"}
            ]
        },
        {view: "scrollbar", id: "scrollHor"}
    ]
};

Related sample:  Resource histogram

The same as in the resource load diagram, resourceGrid will work in the same way as the default grid view, but readonly. resourceHistogram has the following additional templates:

  • histogram_cell_class - the CSS class which is applied to a cell of the resource panel
gantt.templates.histogram_cell_class=function(start_date,end_date,resource,tasks,
    assignments){
    return "";
};
  • histogram_cell_label - the label inside a cell
gantt.templates.histogram_cell_label=function(start_date,end_date,resource,tasks,
    assignments){
    return tasks.length * 8;
};
  • histogram_cell_allocated - the height of the filled area in the histogram. Its value can be set from 0 to maxCapacity *.
gantt.templates.histogram_cell_allocated=function(start_date,end_date,resource,tasks,
    assignments){
    return tasks.length * 8;
};
  • histogram_cell_capacity - the height of the line that defines the available capacity of the resource. Its value can be set from -1 to maxCapacity *. Values less than 0 won't render the line.
gantt.templates.histogram_cell_capacity=function(start_date,end_date,resource,tasks,
    assignments){
    return 24;
};

What maxCapacity is

If each row of the histogram is considered as a bar chart, maxCapacity is the height of the Y-scale of this chart. In the image below maxCapacity = 24:

maxCapacity

Thus, if the templates histogram_cell_allocated or histogram_cell_capacity are set to value 24, it implies the highest point of the row.

maxCapacity can be defined either at the histogram level:

{ view: "resourceHistogram", capacity:24, scrollX: "scrollHor", 
    scrollY: "resourceVScroll"}

or individually for each resource:

resourcesStore.parse([
    {id: 1, text: "John", capacity:8},
    {id: 2, text: "Mike", capacity:4},
    {id: 3, text: "Anna", capacity:8},
    {id: 4, text: "Bill", capacity:8},
    {id: 5, text: "Floe", capacity:8}
]);

Capacity defined at the resource level overrides the global capacity of histogram for a given resource.

Working with the resource view panel

By default both views (either "resourceGrid" and "resourceTimeline" or "resourceGrid" and "resourceHistogram") will be bound to the data store named as specified in the gantt.config.resource_store configuration option.

This data store has to be initialized manually with the help of the createDatastore method:

var resourcesStore = gantt.createDatastore({
  name: gantt.config.resource_store,
  // use treeDatastore if you have hierarchical resources (e.g. workers/departments), 
  // skip the "type" if you have a flat structure
  type: "treeDatastore", 
  initItem: function (item) {
    item.parent = item.parent || gantt.config.root_id;
    item[gantt.config.resource_property] = item.parent;
    item.open = true;
    return item;
  }
});

In order to populate the data store, use the datastore.parse method:

resourcesStore.parse([
    {id: 1, text: "QA", parent:null},
    {id: 2, text: "Development", parent:null},
    {id: 3, text: "Sales", parent:null},
    {id: 4, text: "Other", parent:null},
    {id: 5, text: "Unassigned", parent:4},
    {id: 6, text: "John", parent:1},
    {id: 7, text: "Mike", parent:2},
    {id: 8, text: "Anna", parent:2},
    {id: 9, text: "Bill", parent:3},
    {id: 10, text: "Floe", parent:3}
]);

If you want to use resources in the lightbox, it might be a good idea to do it via the serverList method from the onParse event of the data store:

resourcesStore.attachEvent("onParse", function(){
  var people = [];
  resourcesStore.eachItem(function(res){
    if(!resourcesStore.hasChild(res.id)){
        var copy = gantt.copy(res);
        copy.key = res.id;
        copy.label = res.text;
        people.push(copy);
    }
  });
  gantt.updateCollection("people", people);
});

Expanding resources panel

It is possible to expand the resources panel to show all the tasks assigned to a particular resource by enabling the fetchTasks property during initialization of the datastore via the createDatastore method:

Expanded resource panel

gantt.$resourcesStore = gantt.createDatastore({
    name: gantt.config.resource_store,
    type: "treeDatastore",
    fetchTasks: true,     initItem: function (item) {
        item.parent = item.parent || gantt.config.root_id;
        item[gantt.config.resource_property] = item.parent;
        if(!item.parent){
            item.open = true;
        }else{
            item.open = false;
        }
        return item;
    }
});

Related sample:  Show all assigned tasks in the resource panel

With the fetchTasks property set to true, Gantt renders all tasks assigned to a certain resource in the resource view panel. This functionality works both for the resource diagram and resource histogram types of layout.

There is a shorthand for getting all tasks assigned to a resource - getResourceAssignments.

gantt.getResourceAssignments("6");
Back to top