Available only in PRO Edition
Эта функция доступна только в Gantt PRO edition.
Gantt предоставляет встроенные представления ресурсов для визуализации загрузки ресурсов. Также предлагаются инструменты для распределения проектов по ресурсам для балансировки рабочих нагрузок, вместе с календарями рабочего времени, специфичными для задач и ресурсов.
Сам Gantt не рассчитывает загрузку ресурсов и не предоставляет готовых методов для этого. Однако доступен публичный API, который позволяет создавать пользовательский функционал по мере необходимости.
dhtmlxGantt предоставляет два предопределенных вида макета для отображения загрузки ресурсов: диаграмму загрузки ресурсов и ресурсный гистограмму.
Этот вид включает два компонента: "resourceGrid" для грида и "resourceTimeline" для временной шкалы.
Необходимо предоставить отдельную конфигурацию для "resourceGrid" (чтобы отображать столбцы ресурсов вместо столбцов задач) и "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
После настройки resourceGrid ведет себя как стандартный вид грида, но доступен только для чтения. resourceTimeline наследует конфигурацию шкалы от стандартной временной шкалы и имеет два слоя:
task_row_class
и timeline_cell_class
. Эти шаблоны могут быть настроены на уровне макета.resource_cell_class
и resource_cell_value
для определения стиля и содержания блока: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
Этот вид макета использует "resourceGrid" для грида и "resourceHistogram" для временной шкалы для отображения загрузки ресурсов.
Необходимо предоставить отдельную конфигурацию для "resourceGrid" (чтобы отображать столбцы ресурсов вместо столбцов задач) и "resourceHistogram". Также можно использовать шаблоны для настройки отображения назначений ресурсов на панели.
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
Как и в диаграмме загрузки ресурсов, resourceGrid аналогичен стандартному виду грида, но доступен только для чтения. resourceHistogram добавляет несколько дополнительных шаблонов:
gantt.templates.histogram_cell_class=function(start_date,end_date,resource,tasks,
assignments){
return "";
};
gantt.templates.histogram_cell_label=function(start_date,end_date,resource,tasks,
assignments){
return tasks.length * 8;
};
gantt.templates.histogram_cell_allocated=function(start_date,end_date,resource,tasks,
assignments){
return tasks.length * 8;
};
gantt.templates.histogram_cell_capacity=function(start_date,end_date,resource,tasks,
assignments){
return 24;
};
Понимание maxCapacity
В гистограмме maxCapacity представляет высоту Y-шкалы для каждой строки. Например, если maxCapacity установлено на 24, это определяет самую высокую точку строки.
По умолчанию maxCapacity установлено на 24 для всех ресурсов. Если вы вернете значение больше 24 в шаблоне histogram_cell_capacity, расчеты все равно будут работать, но ячейки панели ресурсов могут отображаться не так, как ожидалось.
Вы можете настроить maxCapacity глобально для гистограммы или индивидуально для каждого ресурса. Вот как:
Related sample: Настройка maxCapacity
maxCapacity можно установить на уровне гистограммы:
{ view: "resourceHistogram", capacity:24, scrollX: "scrollHor",
scrollY: "resourceVScroll"}
Или для конкретных ресурсов:
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}
]);
Настройки емкости на уровне ресурсов переопределят глобальную емкость гистограммы для этих конкретных ресурсов.
По умолчанию оба вида ("resourceGrid" и "resourceTimeline" или "resourceGrid" и "resourceHistogram") связаны с хранилищем данных, указанным в опции gantt.config.resource_store.
Начиная с версии 8.0, Gantt автоматически создает хранилище данных для ресурсов при инициализации. Это хранилище будет готово к моменту срабатывания "onGanttReady". Чтобы получить к нему доступ, используйте метод gantt.getDatastore(gantt.config.resource_store).
Если требуется дополнительная настройка хранилища ресурсов, можно использовать опцию gantt.config.resources:
gantt.config.resources = {
resource_store: {
type: "treeDataStore",
fetchTasks: true,
initItem: function(item) {
item.parent = item.parent || gantt.config.root_id;
item[gantt.config.resource_property] = item.parent;
item.open = true;
return item;
}
},
}
Эти настройки будут использоваться для создания хранилища данных ресурсов по умолчанию. Если уже определено пользовательское хранилище, Gantt будет использовать его вместо этого.
Для загрузки ресурсов их можно включить в gantt.parse()/gantt.load(), как объяснено здесь, или заполнить хранилище напрямую, используя datastore.parse():
gantt.attachEvent("onGanttReady", function(){
const store = gantt.getDatastore(gantt.config.resource_store);
store.parse([
{id: 6, text: "John"},
{id: 7, text: "Mike"},
{id: 8, text: "Anna"},
{id: 9, text: "Bill"},
])
});
Контроль ресурсов в лайтбоксе автоматически подключится к списку ресурсов:
gantt.config.lightbox = {
sections: [
...,
{ name: "resources", type: "resources", map_to: "auto", default_value: 8}
]
};
Вы также можете создать хранилище данных вручную, используя метод createDatastore
:
var resourcesStore = gantt.createDatastore({
name: gantt.config.resource_store,
// используйте treeDatastore, если у вас есть иерархические ресурсы (например, работники/отделы),
// пропустите "type", если у вас плоская структура
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;
}
});
Чтобы заполнить хранилище данных, используйте метод datastore.parse:
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}
]);
Для использования ресурсов в лайтбоксе рассмотрите возможность настройки через метод serverList
в событии onParse хранилища данных:
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("resourceOptions", people);
});
Вы можете настроить панель ресурсов для отображения всех задач, связанных с конкретным ресурсом, включив свойство fetchTasks при инициализации хранилища данных:
gantt.config.resources = {
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;
}
},
};
Или:
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
Когда fetchTasks установлено в true, Gantt будет отображать все задачи, связанные с конкретным ресурсом, на панели представления ресурсов. Эта функция работает как с диаграммой загрузки ресурсов, так и с макетами ресурсного гистограммы.
Чтобы быстро получить все задачи, связанные с ресурсом, вы можете использовать следующий сокращенный метод:
gantt.getResourceAssignments("6");
Связь между задачами и ресурсами определяется параметром конфигурации resource_property
:
gantt.config.resource_property = "user_id";
// task.user_id <-> resource.id
Вы можете связать ресурсы с задачами через свойства объекта задачи несколькими способами:
{
id: 1, text: "Задача #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
user_id: 5 // 5 - это ID ресурса
}
{
id: 1, text: "Задача #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
users: [2, 3] // 2 и 3 - это ID ресурсов
}
Этот формат также можно использовать с пользовательским контролом multiselect.
{
id: 1, text: "Задача #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
users: [{resource_id: 2, value: 8}, {resource_id: 3, value: 4}]
}
Здесь Задача #1 назначена ресурсу с ID=2 в количестве 8 единиц и ресурсу с ID=3 в количестве 4 единиц. Этот формат поддерживается лайтбоксом.
Начиная с версии 8.0, назначения ресурсов также могут быть загружены как отдельный список. Gantt автоматически свяжет их с задачами:
gantt.parse({
tasks: [...],
links: [...],
resources: [...],
assignments: [{id: 1, resource_id: 2, task_id: 5, value: 8}, ...]
});
Подробности о форматах данных доступны здесь.
При отправке данных на сервер DataProcessor преобразует значения этих свойств в JSON. Чтобы упростить обработку на стороне сервера, рассмотрите возможность использования режима DataProcessor "REST_JSON".
Если вы предпочитаете сохранять назначения ресурсов отдельно от задач, включите следующие настройки:
gantt.config.resources = {
dataprocessor_assignments: true,
dataprocessor_resources: true,
};
Подробнее об этом можно узнать в посвященной статье.
По умолчанию ресурс назначается на всю продолжительность задачи. Начиная с версии 7.1, в объект назначения ресурса можно добавить дополнительные параметры для определения конкретных дат назначения в пределах задачи.
Дополнительные свойства включают:
Пример:
{
id: 5, text: "Интерьер офиса", 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
Даты начала и окончания назначений ресурсов отображаются в ресурсной гистограмме и диаграмме.
В объект назначения можно добавить необязательное свойство id:
{
id: 1, text: "Задача #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
users: [{
id: 5,
resource_id: 2, value: 8,
delay: 1
}]
}
Этот объект назначения можно получить через его ID с помощью API Gantt:
var assignment = gantt.getDatastore("resourceAssignments").getItem(5);
Хранилище данных "resourceAssignments" доступно только при включенной конфигурации process_resource_assignments.
Если mode не указан или установлен в "default", даты начала и окончания назначения основаны на датах задачи. Можно добавить delay для корректировки даты начала относительно даты начала задачи.
В этом режиме дата окончания назначения рассчитывается на основе его продолжительности, в то время как дата начала по-прежнему привязана к дате начала задачи с возможной задержкой.
Этот режим сохраняет даты начала и окончания назначения, как указано в данных, независимо от любых изменений в задаче.
Чтобы получить все задачи, связанные с конкретным ресурсом, используйте следующий метод:
gantt.getResourceAssignments("6");
Это возвращает массив объектов, содержащих детали о каждой задаче, назначенной ресурсу:
[
{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"}
]
Чтобы получить назначения ресурсов для конкретной задачи, используйте:
gantt.getTaskAssignments(5);
Этот метод возвращает массив объектов, содержащих детали назначений, аналогичных выводу gantt.getResourceAssignments
.
Вы можете назначать ресурсы любому свойству задачи непосредственно из встроенного лайтбокса.
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"}
];
Чтобы узнать больше о настройке контроля ресурсов в лайтбоксе, ознакомьтесь со статьей Контроль ресурсов.
Серверные коллекции могут быть загружены и обновлены даже после инициализации Gantt:
// Инициализация лайтбокса с пустой коллекцией
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"}
];
// Динамическая загрузка опций
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
Если ресурсы определены с использованием коллекции serverList, они могут быть загружены вместе с другими данными. В противном случае их необходимо загружать вручную.
Для получения более подробной информации о настройке контроля ресурсов в лайтбоксе, обратитесь к статье Контроль ресурсов.
Начиная с версии 8.0, ресурсы и их назначения могут быть загружены в Gantt с помощью методов gantt.parse() или gantt.load():
gantt.parse({
tasks: [
...,
{
id: 5,
text: "Интерьер офиса",
type: "task",
start_date: "03-04-2024 00:00",
duration: 7,
parent: "2",
owner: [
{
resource_id: "6",
value: 3,
start_date: "03-04-2024 00:00",
end_date: "05-04-2024 00:00",
}
]
},
...
],
links: [],
resources: [
{id: 6, text: "John", unit: "hours/day" },
{id: 7, text: "Mike", unit: "hours/day" },
{id: 8, text: "Anna", unit: "hours/day" },
{id: 9, text: "Bill", unit: "hours/day" },
{id: 10, text: "Floe", unit: "hours/day" }
]
});
Назначения также могут быть предоставлены отдельно от задач:
gantt.parse({
tasks: [
...,
{
id: 5,
text: "Интерьер офиса",
type: "task",
start_date: "03-04-2024 00:00",
duration: 7,
parent: "2",
priority: 1
},
...
],
links: [],
assignments: [
{
id: 1, task_id: 5, resource_id: 6, value: 3,
start_date: "03-04-2024 00:00",
end_date: "05-04-2024 00:00"
}
],
resources: [
{id: 6, text: "John", unit: "hours/day" },
{id: 7, text: "Mike", unit: "hours/day" },
{id: 8, text: "Anna", unit: "hours/day" },
{id: 9, text: "Bill", unit: "hours/day" },
{id: 10, text: "Floe", unit: "hours/day" }
]
});
Начиная с версии 7.1, назначения ресурсов могут рассматриваться как объекты в хранилище данных. Свойство process_resource_assignments позволяет анализировать свойства ресурсов задачи в внутренние объекты назначения ресурсов, что упрощает их управление через объект DataStore.
Эта функция особенно полезна для установки конкретных продолжительностей и времен для ресурсов, например, при создании диаграммы ресурсов или гистограммы. Однако включение этой функциональности может повлиять на производительность в крупных проектах. Если настройки времени или продолжительности не требуются, вы можете отключить разбор:
gantt.config.process_resource_assignments = false;
Когда отключено, хранилище данных gantt.getDatastore("resourceAssignments")
недоступно, и объекты назначений не имеют динамических свойств. Диаграмма ресурсов и гистограмма будут предполагать, что ресурсы назначены на всю продолжительность задачи.
Назначения ресурсов хранятся в хранилище данных, создаваемом автоматически. По умолчанию изменения в свойстве ресурса задачи (например, task.users
) автоматически отражаются в хранилище данных.
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);
Если назначения обновляются через API хранилища данных, вы можете синхронизировать их обратно с объектом задачи, используя gantt.updateTaskAssignments():
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);
// Синхронизировать изменения обратно с объектом задачи
gantt.updateTaskAssignments(taskId);
Чтобы отобразить имя ресурса как часть описания задачи или метки ячейки грида, можно использовать вспомогательную функцию для сопоставления идентификаторов с метками:
function byId(list, id) {
for (var i = 0; i < list.length; i++) {
if (list[i].key == id)
return list[i].label || "";
}
return "";
}
Эту функцию можно использовать в шаблонах:
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
Чтобы сделать назначения ресурсов редактируемыми в диаграмме ресурсов, включите следующую конфигурацию:
gantt.config.resources = {
editable_resource_diagram: true
};
Related sample: Assign resource values to specific days
Когда включено, Gantt использует встроенные шаблоны для редактируемых диаграмм, которые можно переопределить при необходимости. Шаблоны по умолчанию доступны в объекте gantt.ext.resources.
Для пользовательских стилей можно использовать такие шаблоны, как:
Стили также могут быть динамически загружены с данными ресурсов или предопределены для каждого ресурса. Ознакомьтесь с этим руководством для получения более подробной информации.
Related sample: Assigning owners to tasks
Пользовательские календари рабочего времени могут быть назначены конкретным ресурсам. Эти календари связаны с задачами через однозначное соответствие:
// Назначение календарей ресурсам
gantt.config.resource_property = "resource_id";
gantt.config.resource_calendars = {
"resource1" : "calendarId1",
"resource2" : "calendarId2",
"resource3" : "calendarId3"
};
Если свойство ресурса изменяется, задачи пересчитываются с использованием нового календаря. Для получения более подробной информации обратитесь к статье Рабочее время.
Расширение группировки позволяет разбивать проекты по свойству ресурса, что помогает балансировать загрузку ресурсов.
Related sample: Break down by resources
Для получения дополнительной информации о группировке задач см. связанную статью.
Когда к задаче назначено несколько ресурсов, эти задачи будут сгруппированы по их назначенным ресурсам. Это означает, что задача, связанная с двумя людьми, не будет отображаться дважды для каждого человека. Вместо этого она будет отображаться один раз, показывая обоих назначенных людей. Задачи в этих группах будут расположены в порядке их начала.
Related sample: Group by multiple resources
Имейте в виду, что задачи, сгруппированные по нескольким ресурсам, нельзя перетаскивать.