dhtmlxGantt поддерживает два формата данных для загрузки информации:
Для заполнения диаграммы Gantt данными вы можете использовать методы parse или load.
gantt.init("gantt_here");
gantt.load("tasks.json");
Related sample: Basic initialization
Предоставление некорректных данных в Gantt может привести к тому, что его древовидная структура станет циклической, что вызовет ошибку циклической ссылки.
Если вы хотите загрузить данные напрямую из объекта, используйте метод parse:
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
Если ваши объекты данных содержат одновременно "start_date" и "end_date", но значения дат включают только дату (например, 01-12-2021, без времени), может потребоваться дополнительная настройка. Подробнее смотрите в разделе Отображение даты окончания задачи и включительно конец периода.
Для получения данных с сервера используйте метод load:
gantt.html
gantt.init("gantt_here");
gantt.load("data.json");
Метод load отправляет AJAX-запрос по указанному URL и ожидает ответ с данными в одном из поддерживаемых форматов. Например:
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"}
]
}
Вы можете указать формат во втором аргументе метода: "json", "xml" или "oldxml".
gantt.load("data.xml", "xml");
На сервере у вас может быть статический файл с данными или скрипт, который собирает данные из источника и отправляет их в ответе. Настройка на сервере зависит от используемого вами фреймворка.
Подробные инструкции и примеры кода для различных платформ смотрите в Интеграция с серверной стороной.
Например, в Node.js вы настраиваете маршрут сервера, который обрабатывает URL, по которому Gantt отправляет AJAX-запрос за данными.
gantt.load("/data");
Этот маршрут должен возвращать JSON примерно такого вида:
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 });
});
});
});
Все поддерживаемые форматы данных перечислены в Поддерживаемые форматы данных.
Есть три способа задать расписание задачи в данных:
Свойство, которое не указано, будет вычислено на основе двух других.
Related sample: Backward planning
Свойство end_date имеет приоритет над duration. Если указаны все три параметра, Gantt проигнорирует duration и вычислит его на основе дат начала и окончания. Например:
{
"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
}
// На самом деле задача будет загружена с duration, вычисленным по датам начала и окончания:
{
"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
}
Gantt поддерживает ISO-формат даты. Для его использования необходимо переопределить функции парсинга и форматирования дат:
gantt.templates.parse_date = function(date) {
return new Date(date);
};
gantt.templates.format_date = function(date) {
return date.toISOString();
};
Если вы хотите изменить формат даты на лету, обновите шаблон parse_date следующим образом:
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);
};
В этом разделе объясняется, как правильно сохранять и отображать дату окончания задачи.
Сначала рассмотрим два распространённых сценария при работе с датами задач:
Из-за того, как dhtmlxGantt интерпретирует и хранит даты окончания задач, результат может отличаться от ожидаемого.
Пример:
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 декабря 2021 00:00:00
console.log(gantt.getTask(1).duration);
// 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:[]);
Здесь в гриде дата окончания (end_date) отображается как 3 апреля, хотя задача фактически завершается в конце 2 апреля.
Далее объясняется, как Gantt хранит даты окончания.
Даже если часть времени не указана (duration_unit = "day"), dhtmlxGantt всегда хранит даты как объекты JavaScript Date, которые содержат компоненты времени.
Формат хранения дат окончания:
Если дата окончания отображается без времени, это может ввести в заблуждение. В примере из Сценария 2 даты выглядят как "02-04-2022 - 03-04-2022", что можно ошибочно интерпретировать как двухдневную задачу вместо однодневной.
Это стандартное поведение. Хотя оно может сбивать с толку, доступны настройки, позволяющие это изменить, о чём рассказывается в следующих разделах.
1) Первое, чего следует избегать — это изменение фактических дат задач, хранящихся в Gantt.
Возможно, вы захотите изменить даты задач при загрузке в Gantt, например, устанавливая дату окончания как 02-04-2022 23:59:59. Тем не менее, лучше не использовать этот подход, так как это может привести к конфликтам в расчетах длительности задач и авто-планировании.
Вместо этого рекомендуем использовать следующие методы:
2a) Чтобы изменить формат отображения дат окончания задач в Gantt (например, чтобы включить дату окончания в длительность задачи), вы можете переопределить шаблон task_end_date.
Рассмотрим задачу, начинающуюся 2 апреля 2020 года, с длительностью один день, и посмотрим, как шаблон влияет на дату окончания.
По умолчанию дата окончания задачи отображается как 3 апреля 2020 года (03-04-2020 00:00:00
):
Но если использовать шаблон task_end_date, та же задача будет отображаться как завершающаяся 2 апреля 2020 года:
Пример кода:
// переопределяем конфигурацию колонок
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"}
];
// переопределяем шаблон
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");
Этот способ меняет отображение даты окончания задачи в гриде, заголовке lightbox и других местах, где отображается дата окончания.
Если вы используете формат включающей даты окончания и хотите, чтобы он корректно работал с inline editing в гриде, потребуется создать собственный редактор для редактирования включающих дат окончания, например:
// редактор для включающих дат окончания
// используем стандартный редактор, но переопределяем методы set_value/get_value
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}
];
// изменяем шаблоны lightbox и грида для отображения дат задач во включающем формате
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: Редактор включающей даты окончания
2b) Если другим частям вашего приложения нужны даты окончания, сохранённые во "включающем" формате (т.е. задача, начинающаяся 2 апреля 2020 года и длящаяся один день, хранится с start_date: "02-04-2022", end_date: "02-04-2022"), потребуется дополнительная обработка дат окончания:
Источник данных для диаграммы Gantt — это объект, содержащий два основных типа информации:
Полный список свойств объекта задачи приведён в статье Task properties.
Формат дат по умолчанию для JSON и XML данных — "%d-%m-%Y %H:%i" (см. спецификацию формата даты).
Чтобы изменить его, используйте опцию конфигурации date_format.
gantt.config.date_format="%Y-%m-%d";
gantt.init("gantt_here");
После загрузки в Gantt свойства start_date и end_date преобразуются в объекты Date.
Если ваши форматы дат не поддерживаются конфигом date_format, вы можете выполнить парсинг вручную с помощью шаблона parse_date.
Полный список свойств объекта связи доступен в статье Link properties.
Вы не ограничены обязательными свойствами и можете добавлять любые пользовательские свойства в ваши элементы данных. Дополнительные свойства будут распознаны как строки и отправлены на клиентскую сторону, где вы сможете использовать их по своему усмотрению.
Примеры данных с пользовательскими свойствами смотрите здесь.
Для работы с базой данных рекомендуется использовать две отдельные таблицы: одну для задач, другую — для связей.
Типичная структура базы данных для загрузки задач и связей в диаграмму Gantt выглядит так:
Для создания этих двух таблиц используйте следующий SQL:
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`)
)
Ниже представлен поток событий, связанных с методами загрузки: