「实战应用」如何用DHTMLX构建自定义JavaScript甘特图(二)

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的所有需求,是最完善的甘特图图表库。

当您声称您的产品具有高级定制功能时,客户一定会对产品进行严格测试,这个规则当然适用于DHTMLX Gantt,官方技术团队收到了很多关于如何在JavaScript甘特图组件中实现某些外观定制的请求,结合实际的案例,我们将在本文中为您展示如何在实践中实现这些定制。在上文中(点击这里回顾>>),我们主要介绍了JavaScript甘特图用例以及如何可是构建一个JS甘特图,本文将继续介绍如何构建JS甘特图。

DHTMLX Gantt v8.0正式版下载

为任务分配资源

下一个特性是将资源(在我们的例子中是员工)分配给任务的能力,DHTMLX Gantt以广泛的资源管理能力而闻名,包括一个单独的资源面板。

但是如果您需要对单个元素进行更简单的配置,则可以使用简化形式的资源。

在我们的演示中,有一个数组其中指定了员工的姓名和照片,这意味着这些数据可以从服务器加载。

javascript 复制代码
const resourceData = [
{ "key": "1", "label": "John" },
{ "key": "2", "label": "Mike" },
{ "key": "3", "label": "Anna" },
{ "key": "4", "label": "Bill" },
{ "key": "5", "label": "Floe" },
]

DHTMLX Gantt有一个lightbox部分,使您能够为一个任务分配多个资源并指定资源值(小时,天,材料等)。为了使其正常工作,您需要在options参数中指定一个带有资源的数组。

javascript 复制代码
{ name: "resources", type: "resources", map_to: "owners", options: resourceData, default_value: 8 },

如果使用简单的甘特配置(gantt.config.resources) 并且使用load()或parse()方法从服务器加载资源,Gantt将自动向lightbox部分添加必要的参数。

当使用自定义配置时,数组必须包含带有key和label参数的对象。

在我们的演示中,还显示了网格部分中分配给任务的资源(员工照片)。为此需要使用列配置的模板函数,其中将返回getOwnerPics函数的值。

javascript 复制代码
name: "owners", label: "Owners", resize: true, width: 75, template: function (task) {
return getOwnerPics(task);
}

在这个函数中,有必要使用owner任务属性,其中指定了分配的资源。如果存在分配,则应该将资源ID添加到单独的所有者数组中。

下一步是用资源数据遍历数组,如果资源ID在所有者数组中,则获取带有照片的属性并将其添加到images变量中,之后返回这个包含所有员工照片的变量。

javascript 复制代码
function getOwnerPics(task) {
let images = "";

const owners = [];
(task.owners || []).forEach(function (el) {
owners.push(el.resource_id);
})

resourceData.forEach(function (resource) {
if (owners.indexOf(resource.key) > -1) {
images += " " + resource.img || "";
}
})

return images;
}
任务栏中的任务名称和资源

如果您看了Gantt演示,可以看到一些任务栏中显示了任务名称和资源图像。如果它们不适合,这些元素将显示在任务栏的右侧。

要确定任务名称和员工图像是否可以放置在任务栏中,需要应用detectOverflow函数。在这个函数中,首先使用getTaskPosition()方法来获取任务栏的坐标。因为您只需要任务栏的宽度,所以从getTaskPosition()方法返回的对象中获取宽度参数。

javascript 复制代码
const taskWidth = gantt.getTaskPosition(task, task.start_date, task.end_date).width;

然后需要创建canvas元素,使用getComputedStyle()方法查找通常在任务栏中显示的文本字体样式和字体大小。之后在context元素中指定这些参数,并使用measureText()方法来确定文本宽度。

javascript 复制代码
const canvas = document.createElement('canvas');
const context = canvas.getContext("2d");

const bar = document.querySelector(".gantt_task_content")
if (bar) {
const fontFamily = getComputedStyle(bar)['font-family'];
const fontSize = getComputedStyle(bar)['font-size'];
context.font = fontSize + ' ' + fontFamily;
}
const textWidth = context.measureText(task.text).width;

现在是时候将照片添加到任务栏了,您需要指定这些照片的宽度。在我们的演示中,图像的宽度被调整为任务栏的高度,因此您可以使用gantt.config.row_height配置的值。但如果元素的宽度不同,则需要设置一个新值,宽度值必须乘以分配给给定任务的资源数量。

javascript 复制代码
const ownersWidth = (task.owners || []).length * gantt.config.row_height;

现在有必要对文本和图像的宽度值进行总结,如果结果值大于任务栏的宽度,则返回true,这意味着内容(文本+照片)不会包含在任务栏中。

javascript 复制代码
if (textWidth + ownersWidth > taskWidth) {
return true;
}

如果detectOverflow返回false,则task_text模板包含以下条件。如果任务类型是项目,则只需返回任务文本。如果它是一个常规任务,则返回一个HTML元素,其中包含任务文本和可以从getOwnerPics函数获得的员工照片。

javascript 复制代码
gantt.templates.task_text = function (start, end, task) {
if (detectOverflow(task)) {
return ""
}
else {
if (task.type == gantt.config.types.project) {
return task.text;
}
else {
return `<span style="vertical-align: top" >${task.text}</span>${getOwnerPics(task)}`;
}
}
};

在rightside_text模板中,对"task"类型的任务使用detectOverflow函数。如果此函数返回true,则应该返回一个HTML元素,其中包含来自getOwnerPics函数的任务文本和员工图像。

在DHTMLX Gantt中可以只使用一个模板,您不能多次指定不同的模板并期望它们正常工作,所以必须在一个模板中添加所有的代码:

javascript 复制代码
gantt.templates.rightside_text = function (start, end, task) {
if (task.type == gantt.config.types.project) {
return `<div class='project-right' style="${getTriangleStyles(task, "right")}"></div>`
}


if (detectOverflow(task)) {
return `<span style="vertical-align: top" >${task.text}</span>${getOwnerPics(task)}`;
}
return "";
};

由于篇幅有限,下期继续讲解,请持续关注查看最新产品资讯哦~

相关推荐
白远山1 小时前
家政服务家政社区派单实战:调度系统架构设计与实现指南
java·开发语言·小程序·架构·需求分析
DevRay2 小时前
Java 21虚拟线程深度实战:告别线程池焦虑,百万并发吞吐量直接翻倍(原理+代码+避坑)
java·开发语言
李明卫杭州2 小时前
React 复合事件系统对比解析
前端·javascript·react.js
free-elcmacom2 小时前
C++学习<1>程序分区
开发语言·c++
醉颜凉2 小时前
Java 必看:如何彻底避免 HashMap 多线程死循环问题?
java·开发语言
默 语2 小时前
Java新手入门:从零开始安装JDK并配置环境变量
java·开发语言·python·mysql·group by·1024程序员节·数据去重
Brilliantwxx3 小时前
【STM32】 I2C_EEPROM_test 工程(实战篇)
开发语言·stm32·单片机·嵌入式硬件·ecmascript
清水白石0083 小时前
Python 异步编程深度解析:Cancellation 到底是异常还是控制信号?从 asyncio 取消机制到企业级事务设计最佳实践
开发语言·python
kolyle3 小时前
万级 QPS 下的 Token 分发系统架构:从 0 到 1 跑通 AI 时代的“水电煤“
开发语言·人工智能·系统架构·token·qps·极智词元·大模型私有化部署
caoerzhong3 小时前
JeeWMS 开源仓库管理系统 GPL-3.0 合规指南:Java WMS 二次开发前必须弄清的授权边界
java·开发语言·开源·vue