Available only in PRO Edition
Эта функциональность доступна только в PRO версии
dhtmlxGantt включает встроенные функции для отображения дополнительных элементов, таких как базовые линии, дедлайны и ограничения задач по умолчанию. Если вы хотите изменить или расширить эти функции, вы можете вручную добавить пользовательские элементы на временную шкалу, как описано ниже.
Добавление дополнительных элементов обычно включает создание нового слоя отображения и размещение пользовательских элементов там с использованием абсолютного позиционирования для их выравнивания с соответствующими задачами.
Чтобы добавить новый слой в область временной шкалы, вы можете использовать метод gantt.addTaskLayer
. Этот метод принимает функцию в качестве параметра, которая:
gantt.addTaskLayer(function myNewElement(task) {
var el = document.createElement('div');
// ваш код
return el;
});
Related sample: Displaying deadlines
gantt.addTaskLayer
запускается для каждой задачи, и возвращенный DOM элемент добавляется в контейнер.gantt.getTaskPosition
, который облегчает определение размещения и размеров ваших пользовательских элементов.Советы по улучшению скорости рендеринга пользовательских элементов можно найти в руководстве по умному рендерингу для пользовательских слоев.
Если вы хотите показывать пользовательский контент в каждой ячейке временной шкалы, вы можете непосредственно вставлять HTML в ячейки, используя шаблон gantt.timeline_cell_content_template
. Этот подход проще и работает быстрее.
Вот пример сценария: у вас есть запланированное и фактическое время для задач, и вам нужно, чтобы оба отображались.
Изначально задачи выглядят следующим образом:
Чтобы освободить место для базовых линий под задачами, уменьшите высоту полосы задачи до примерно половины высоты строки:
gantt.config.bar_height = 16;
gantt.config.row_height = 40;
Затем сдвиньте линию задачи в верхнюю часть строки с помощью этого CSS:
.gantt_task_line, .gantt_line_wrapper {
margin-top: -9px;
}
.gantt_side_content {
margin-bottom: 7px;
}
.gantt_task_link .gantt_link_arrow {
margin-top: -12px
}
.gantt_side_content.gantt_right {
bottom: 0;
}
Результат будет выглядеть так:
Далее добавьте дополнительные свойства к объекту задачи. Например, используйте 'planned_start' и 'planned_end':
dhtmlxGantt автоматически разбирает 'start_date' и 'end_date' в объекты Date. Для других свойств даты требуется дополнительная обработка. Чтобы 'planned_start' и 'planned_end' были распознаваемыми, разбирайте их с помощью метода gantt.date.parseDate
внутри обработчика события onTaskLoading
:
gantt.attachEvent("onTaskLoading", function(task){
task.planned_start = gantt.date.parseDate(task.planned_start, "xml_date");
task.planned_end = gantt.date.parseDate(task.planned_end, "xml_date");
return true;
});
Теперь используйте метод gantt.addTaskLayer
, чтобы отобразить запланированное время для задач (на основе 'planned_start' и 'planned_end'):
gantt.addTaskLayer(function draw_planned(task) {
if (task.planned_start && task.planned_end) {
var sizes = gantt.getTaskPosition(task, task.planned_start, task.planned_end);
var el = document.createElement('div');
el.className = 'baseline';
el.style.left = sizes.left + 'px';
el.style.width = sizes.width + 'px';
el.style.top = sizes.top + gantt.config.task_height + 13 + 'px';
return el;
}
return false;
});
Наконец, определите стиль для ваших пользовательских элементов:
.baseline {
position: absolute;
border-radius: 2px;
opacity: 0.6;
margin-top: -7px;
height: 12px;
background: #ffd180;
border: 1px solid rgb(255,153,0);
}
Чтобы разрешить редактирование вновь добавленных свойств непосредственно из пользовательского интерфейса, вы можете переопределить структуру лайтбокса.
gantt.config.lightbox.sections = [
{name: "description", height: 70, map_to: "text", type: "textarea", focus: true},
{name: "time", height: 72, map_to: "auto", type: "duration"},
{name: "baseline", height: 72, map_to: {
start_date: "planned_start", end_date: "planned_end"}, type: "duration"}
];
gantt.locale.labels.section_baseline = "Запланировано";
Полная реализация этого примера доступна в соответствующем примере.
Related sample: Display baselines
Вот несколько примеров, демонстрирующих, как использовать метод addTaskLayer() для улучшения временной шкалы диаграммы Ганта пользовательскими элементами:
Если вам нужна функция перетаскивания для пользовательских элементов, вы можете реализовать ее вручную. Хотя DHTMLX Gantt не предоставляет встроенного решения для этого, его довольно просто настроить, обрабатывая три DOM события: mousedown, mousemove и mouseup. Вам также понадобятся несколько флагов, чтобы отслеживать состояние перетаскивания.
var dndRequested = false;
var dndActivated = false;
var startPosition = null;
var startTimestamp = null
var taskId = null;
var domUtils = gantt.utils.dom;
gantt.event(gantt.$task_data, 'mousedown', function(e) {
var draggableElement = domUtils.closest(e.target, '.baseline');
if (draggableElement) {
dndRequested = true;
startTimestamp = Date.now();
startPosition = domUtils.getRelativeEventPosition(e, gantt.$task_data);
taskId = draggableElement.getAttribute("data-task");
}
});
Использование gantt.event вместо нативных слушателей событий гарантирует, что все обработчики будут автоматически удалены при уничтожении экземпляра Gantt с помощью gantt.destructor.
gantt.event(window, 'mousemove', function(e) {
if (dndRequested && gantt.isTaskExists(taskId)) {
var currentPosition = domUtils.getRelativeEventPosition(e, gantt.$task_data);
if (!dndActivated) {
if(Math.abs(currentPosition.x - startPosition.x) > 5 || (Date.now() - startTimestamp) > 500) {
dndActivated = true;
}
}
if (dndActivated) {
var pointerDate = gantt.dateFromPos(currentPosition.x);
gantt.getTask(taskId).baseline_date = pointerDate;
gantt.refreshTask(taskId);
}
}
});
gantt.event(window, 'mouseup', function(e) {
if (dndActivated) {
var task = gantt.getTask(taskId);
task.baseline_date = gantt.roundDate({
date: task.baseline_date,
unit: "hour",
step: 1
});
gantt.updateTask(taskId);
}
dndRequested = false;
dndActivated = false;
startPosition = null;
startTimestamp = null;
taskId = null;
});
Вы можете добавить пользовательский контент на диаграмму Ганта, используя дополнительный оверлей. Это может быть контейнер div, HTML canvas или аналогичные элементы. Любая сторонняя библиотека может быть использована для рендеринга контента оверлея.
Например, вы можете захотеть включить S-кривую для отслеживания расходов или прогресса проекта. Вот как добавить оверлей:
gantt.plugins({
overlay: true
});
var overlay = gantt.ext.overlay.addOverlay(function(container){
var canvas = document.createElement("canvas");
container.appendChild(canvas);
canvas.style.height = container.offsetHeight + "px";
canvas.style.width = container.offsetWidth + "px";
var ctx = canvas.getContext("2d");
var myChart = new Chart(ctx, {
type: "line",
// полная конфигурация диаграммы
});
});
Метод gantt.ext.overlay.addOverlay() возвращает ID оверлея.
Related sample: Gantt chart with overlay and zoom (S-Curve)
Расширение overlay предоставляет несколько методов для управления оверлеями, доступных через gantt.ext.overlay:
var overlay = gantt.ext.overlay.addOverlay(function(container){});
gantt.ext.overlay.deleteOverlay(id);
var ids = gantt.ext.overlay.getOverlaysIds();
gantt.ext.overlay.refreshOverlay(id);
gantt.ext.overlay.showOverlay(id);
gantt.ext.overlay.hideOverlay(id);
var isVisible = gantt.ext.overlay.isOverlayVisible(id);
К началу