资源管理
此功能仅包含在 Gantt PRO 版本中。
Gantt 提供了预定义的资源视图,用于可视化资源负载、按资源分解项目以平衡工作量的工具,以及为任务和资源量身定制的日历。

虽然 Gantt 本身不会计算资源负载,也不提供内置方法,但它提供了公共 API,您可以据此实现任何自定义功能。
资源视图面板
dhtmlxGantt 提供了两种预定义布局视图,用于展示资源负载:资源负载图和资源直方图。
资源负载图
该视图包含了网格和时间线的专用视图:"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"}
]
};
设置完成后,resourceGrid 的行为类似于默认的网格视图,但它是只读的。resourceTimeline 使用与默认时间线相同的刻度设置,并包含两个层次:
- 背景行,使用来自 task_row_class 和 timeline_cell_class 的模板。这些可以在布局级别进行自定义。
- 资源层 -- 这是 resourceTimeline 独有的,会在资源被分配了任务的单元格中显示区块。可以通过 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;
};
Templates of the Resource diagram
资源直方图
该资源负载布局视图分别为网格和时间线提供了 "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"}
]
};
与资源负载图类似,resourceGrid 的行为类似于默认网格视图,但为只读。resourceHistogram 提供了多个额外模板:
- histogram_cell_class -- 应用于资源面板单元格的 CSS 类
gantt.templates.histogram_cell_class="function(start_date,end_date,resource,tasks,"
assignments){
return "";
};
- histogram_cell_label -- 显示在单元格中的标签
gantt.templates.histogram_cell_label="function(start_date,end_date,resource,tasks,"
assignments){
return tasks.length * 8;
};
- histogram_cell_allocated -- 直方图中填充区域的高度,范围为 0 到 maxCapacity。
gantt.templates.histogram_cell_allocated="function(start_date,end_date,resource,tasks,"
assignments){
return tasks.length * 8;
};
- histogram_cell_capacity -- 表示资源可用容量的线的高度,范围为 -1 到 maxCapacity。小于 0 的值将隐藏该线。
gantt.templates.histogram_cell_capacity="function(start_date,end_date,resource,tasks,"
assignments){
return 24;
};
理解 maxCapacity
可以将每一行直方图看作柱状图,maxCapacity 表示 Y 轴的刻度高度。如下图所示,maxCapacity 设为 24:

因此,将 histogram_cell_allocated 或 histogram_cell_capacity 设为 24,意味着填充至该行顶端。
默认情况下,maxCapacity 对每个资源都是 24。在 histogram_cell_capacity 返回超过 24 的值时会被正确计算,但资源面板单元格中的填充区域可能不会按预期显示。

您可以为整个直方图全局配置 maxCapacity,也可以为每个资源单独设置。示例:
Related example: 配置 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}
]);
资源级别的 capacity 会覆盖直方图的全局 capacity 设置。
使用资源视图面板
默认情况下,两种视图("resourceGrid" 和 "resourceTimeline" 或 "resourceGrid" 和 "resourceHistogram")都连接到在 gantt.config.resource_store 设置中指定的数据存储。
数据存储的自动创建
从 v8.0 开始,资源数据存储会在 gantt 初始化时自动创建,并在 "onGanttReady" 事件触发时准备就绪。可以使用 getDatastore 方法访问该存储。
如需自定义资源存储,可通过 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;
}
},
}
resource_store 内的设置将用于创建默认资源数据存储。如果代码中已存在资源数据存储,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"},
])
});
Lightbox 的资源控件会自动关联到资源列表:
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}
]);
如果您希望在 lightbox 中使用资源,建议在数据存储的 onParse 事件中通过 serverList 方法实现:
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;
}
});
Show all assigned tasks in the resource panel
将 fetchTasks 设为 true 后,Gantt 会在资源视图面板中显示与资源关联的所有任务,适用于资源图和资源直方图布局。
如需快速获取分配给某一资源的所有任务,请参见 getResourceAssignments。
gantt.getResourceAssignments("6");
资源分配
连接资源到任务
资源与任务之间的关联由 resource_property 设置控制:
gantt.config.resource_property = "user_id";
// task.user_id <-> resource.id
可以通过任务对象属性以几种不同方式将资源关联到任务:
- 为任务分配单个资源
{
id: 1, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
user_id: 5 // 5 是资源 id
}
- 为任务分配多个资源
{
id: 1, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6,
users: [2, 3] // 2 和 3 是资源 id
}
此格式适用于 自定义多选控件。
- 分配多个资源并指定数量
{
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}]
}
在这里,id="2" 的资源分配了 8 个单位,id="3" 的资源分配了 4 个单位。此格式受 리소스 컨트롤 lightbox 支持。
从 v8.0 开始,资源分配也可以作为单独的列表加载,Gantt 会自动将其关联到任务:
gantt.parse({
tasks: [...],
links: [...],
resources: [...],
assignments: [{id:1, resource_id:2, task_id: 5, value: 8}, ...]
});
有关数据格式的更多详细信息请参见 此处。
当将数据发送到服务器时,DataProcessor 会将这些属性序列化为 JSON。为了在服务器端高效处理此类记录,建议使用 "REST_JSON" dataprocessor 模式。
如果希望将资源分配的更改与任务分开保存,请启用以下配置:
gantt.config.resources = {
dataprocessor_assignments: true,
dataprocessor_resources: true,
};
详细了解请参见 专门文章。