dhtmlxGantt can take data of 2 formats:
To populate a Gantt chart with data, use parse or load method.
gantt.init("gantt_here");
gantt.load("tasks.json");
Related sample: Basic initialization
If you pass incorrect data to the Gantt, its tree-like structure becomes cyclic which causes the cyclic reference error.
To load data from an object, use the parse method:
Loading from an inline data source
var data = {
tasks:[
{id:1, text:"Project #1", start_date:"01-04-2020", duration:18},
{id:2, text:"Task #1", start_date:"02-04-2020", duration:8, parent:1},
{id:3, text:"Task #2", start_date:"11-04-2020", duration:8, parent:1}
]
};
gantt.init("gantt_here");
gantt.parse(data);
Related sample: Basic initialization
If your data objects contain both "start_date" and "end_date" values and date values contain only date part (i.e. 01-12-2021 and not 01-12-2021 00:00) - you may need extra configuration. Be sure to check this article Task end date display & Inclusive end dates.
To load data from a server, use the load method:
gantt.html
gantt.init("gantt_here");
gantt.load("data.json");
The load method will send an AJAX request to the specified url and will expect a response with data in one of the supported formats. For example:
data.json
{
"tasks":[
{"id":1, "text":"Project #1", "start_date":"01-04-2020", "duration":18},
{"id":2, "text":"Task #1", "start_date":"02-04-2020","duration":8, "parent":1},
{"id":3, "text":"Task #2", "start_date":"11-04-2020","duration":8, "parent":1}
],
"links":[
{"id":1, "source":1, "target":2, "type":"1"},
{"id":2, "source":2, "target":3, "type":"0"}
]
}
The format is specified in the second argument of the method: "json", "xml" or "oldxml".
gantt.load("data.xml", "xml");
On the server you can have either a static file with data or a script that will collect data from the data source and write it to the response. The server-side implementation depends on the framework you want to use.
See detailed instructions and code samples for various platforms in the article Server-Side Integration.
For example, in case of Node.js we should add a server route for the URL where Gantt will send an AJAX request for data.
gantt.load("/data");
It will generate a corresponding response in the JSON format.
app.get("/data", function(req, res){
db.query("SELECT * FROM gantt_tasks", function(err, rows){
if (err) console.log(err);
db.query("SELECT * FROM gantt_links", function(err, links){
if (err) console.log(err);
for (var i = 0; i < rows.length; i++){
rows[i].start_date = rows[i].start_date.format("YYYY-MM-DD");
rows[i].open = true;
}
res.send({ tasks:rows, links : links });
});
});
});
See all supported data formats in the article Supported Data Formats.
There are three ways to define a schedule for a task in the data feed:
The property that is not specified will be calculated based on the ones that are defined in the data object.
Related sample: Backward planning
The end_date has a higher priority than the duration parameter. If there are 3 parameters specified in the task object, Gantt will ignore the duration parameter and the task will be loaded with a different duration value. For example:
{
"id":"20", "text":"Project #2",
"start_date":"01-04-2025",
"duration":3,
"end_date":"05-04-2025",
"order":10,"progress":0.4,
"type": "project", "open": true
}
// the task above will be loaded with the duration value calculated in accordance
// with the specified 'start_date' and 'end_date'
{
"id":"20", "text":"Project #2",
"start_date":"01-04-2025",
"duration":4,
"end_date":"05-04-2025",
"order":10,"progress":0.4,
"type": "project", "open": true
}
You can use ISO date format in Gantt. For this, you need to redefine functions that parse and serialize dates in Gantt:
gantt.templates.parse_date = function(date) {
return new Date(date);
};
gantt.templates.format_date = function(date) {
return date.toISOString();
};
If you need to change the date format dynamically, it is necessary to modify the parse_date template in the following way:
var cfg = gantt.config;
var strToDate = gantt.date.str_to_date(cfg.date_format, cfg.server_utc);
gantt.templates.parse_date = function(date){
return strToDate (date);
};
This section will give you an answer to the question: "How to correctly save and display the end date of the task?".
Firstly, let's consider two possible scenarios you may face when working with task dates:
Due to the details of how dhtmlxGantt interprets and stores end dates of tasks, the result dates may have values that are not expected.
Take a look at the following example:
gantt.parse({ tasks: [
{
id: 1,
text: "Task 1",
start_date: "22-12-2021",
end_date: "22-12-2021"
}
]}, links:[]);
console.log(gantt.getTask(1).end_date);
// 22 December 2021 00:00:00
console.log(gantt.getTask(1).duration);
// 0
In this example, both start and end dates will refer to the same point of time and the task duration will be 0.
gantt.config.columns = [
{name: "text", label: "Name", tree: true, width: 200, resize: true},
{name: "duration", label: "Duration", width:80, align: "center", resize: true},
{name: "start_date", label: "Start", width:80, align: "center", resize: true},
{name: "end_date", label: "Finish", width:80, align: "center", resize: true}
];
gantt.init("gantt_here");
gantt.parse({ tasks: [
{
id: 1,
text: "Task 1",
start_date: "02-04-2020",
end_date: "02-04-2020"
}
]}, links:[]);
In this example, the Finish date (end_date of the task) is specified as April 3, while the task itself ends at the end of April 2.
We will explain the details on how Gantt stores end dates below.
Even if you don't specify the hour-minute part for the task date (duration_unit = "day"), dhtmlxGantt always saves it as JS Date, which has the hour-minute-second-millisecond part, on the client side.
The current format of the end dates is the following:
If we show the end date of the task on the screen without setting an hour-minute part, the result may be misleading. In the example from scenario 2, the start and end dates will look like "02-04-2022 - 03-04-2022". This will make you think that the task lasts not 1 day but 2 (from the 2nd to the 3rd of April).
This is the default behavior and it may confuse you but there is the ability to fix it via configuration. In the following part we will show you several ways on how you can deal with it.
1) The first thing you should not do is to change the actual task dates which are stored in the gantt.
You may also want to modify the task dates which are loaded into the gantt, i.e. to specify end dates as 02-04-2022 23:59:59. But you'd better not do this because such decision may conflict with the calculation of the duration of tasks and auto-scheduling.
Instead, we recommend that you use the following methods:
2a) To change the format of the end dates of tasks in the gantt (i.e. to include the end date in the duration of the tasks), you can redefine the task_end_date template.
Let's take a task that starts on April 2nd, 2020 and lasts for one day and consider how the template can change the end date.
By default, the end date of this task should be displayed as April 3rd, 2020 (03-04-2020 00:00:00
):
But if you apply the task_end_date template, the same task will be finished on April 2nd, 2020:
The code looks like:
// override the columns config
gantt.config.columns = [
{name: "wbs", label: "#", width: 60, align: "center", template: gantt.getWBSCode},
{name: "text", label: "Name", tree: true, width: 200, resize: true},
{name: "start_date", label: "Start", width:80, align: "center", resize: true},
{name: "end_date", label: "Finish", width:80, align: "center", resize: true},
{name:"add"}
];
// redefine the template
gantt.templates.task_end_date = function(date){
return gantt.templates.task_date(new Date(date.valueOf() - 1));
};
var gridDateToStr = gantt.date.date_to_str("%Y-%m-%d");
gantt.templates.grid_date_format = function(date, column){
if(column === "end_date"){
return gridDateToStr(new Date(date.valueOf() - 1));
}else{
return gridDateToStr(date);
}
}
gantt.init("gantt_here");
This way lets you change the task end date shown in the grid, header of the lightbox, and any other places where you need to show the end date.
If you are using the format for inclusive end dates of tasks and want to make it work correctly with inline editing in the grid, you have to create a special editor for editing inclusive end dates of tasks, as in:
// inclusive editor for end dates
// use the default editor, but override the set_value/get_value methods
var dateEditor = gantt.config.editor_types.date;
gantt.config.editor_types.end_date = gantt.mixin({
set_value: function(value, id, column, node){
var correctedValue = gantt.date.add(value, -1, "day");
return dateEditor.set_value.apply(this, [correctedValue, id, column, node]);
},
get_value: function(id, column, node) {
var selectedValue = dateEditor.get_value.apply(this, [id, column, node]);
return gantt.date.add(selectedValue, 1, "day");
},
}, dateEditor);
var textEditor = {type: "text", map_to: "text"};
var startDateEditor = {type: "date", map_to: "start_date"};
var endDateEditor = {type: "end_date", map_to: "end_date"};
var durationEditor = {type: "number", map_to: "duration", min:0, max: 100};
gantt.config.columns = [
{name: "text", label: "Name", tree: true, width: 200, editor: textEditor,
resize: true},
{name: "duration", label: "Duration", width:80, align: "center",
editor: durationEditor, resize: true},
{name: "start_date", label: "Start", width:140, align: "center",
editor: startDateEditor, resize: true},
{name: "end_date", label: "Finish", width:140, align: "center",
editor: endDateEditor, resize: true}
];
// change lightbox and grid templates to display dates of tasks in an inclusive format
gantt.templates.task_end_date = function(date){
return gantt.templates.task_date(new Date(date.valueOf() - 1));
};
var gridDateToStr = gantt.date.date_to_str("%Y-%m-%d");
gantt.templates.grid_date_format = function(date, column){
if(column === "end_date"){
return gridDateToStr(new Date(date.valueOf() - 1));
}else{
return gridDateToStr(date);
}
}
Related sample: Inclusive end date editor
2b) If other parts of the application require the end dates to be stored in the "inclusive" format - i.e. a task that starts on April 2nd, 2020 and lasts for one day needs to be stored with the start_date: "02-04-2022", end_date: "02-04-2022" - you have to implement additional processing of the end dates, namely:
A data source for the Gantt chart is an object that stores 2 types of information:
The full list of properties of a task object is given in the Task properties article.
The default date format for JSON and XML data is "%d-%m-%Y %H:%i" (see the date format specification).
To change it, use the date_format configuration option.
gantt.config.date_format="%Y-%m-%d";
gantt.init("gantt_here");
Once loaded into Gantt, the start_date and end_date properties will be parsed into the Date type.
Date formats that are not supported by the date_format config can be parsed manually via the parse_date template.
The full list of properties of a link object is given in the Link properties article.
You are not limited to the mandatory properties listed above and can add any custom ones to data items. Extra data properties will be parsed as strings and loaded to the client side where you can use them according to your needs.
See examples of data with custom properties here.
If you use a database, we recommend to have 2 separate tables to store data: one for tasks and one for links.
The structure of a standard database to load tasks and links to the Gantt chart is:
Use the following SQL statement to create a database with 2 mentioned tables:
CREATE TABLE `gantt_links` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`source` int(11) NOT NULL,
`target` int(11) NOT NULL,
`type` varchar(1) NOT NULL,
PRIMARY KEY (`id`)
)
CREATE TABLE `gantt_tasks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(255) NOT NULL,
`start_date` datetime NOT NULL,
`duration` int(11) NOT NULL,
`progress` float NOT NULL,
`sortorder` int(11) NOT NULL,
`parent` int(11) NOT NULL,
PRIMARY KEY (`id`)
)
Loading-related methods have the following events flow: