「实战应用」如何用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 "";
};

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

相关推荐
peak_chan2 分钟前
通过vue-virtual-scroller封装虚拟滚动el-select
前端·javascript·vue.js
小李子呢021112 分钟前
前端八股Vue(7)---computed计算属性和watch侦听器
前端·javascript·vue.js
吴声子夜歌21 分钟前
ES6——对象的扩展详解
开发语言·javascript·es6
aq553560027 分钟前
编程语言对比:从汇编到PHP的四大层级解析
开发语言·汇编·php
kyle~32 分钟前
工程数学---Eigen库(C++唯一标配线性代数库)
开发语言·c++·线性代数
CoderCodingNo35 分钟前
【GESP】C++五、六级练习题 luogu-P1886 【模板】单调队列 / 滑动窗口
开发语言·c++·算法
好家伙VCC41 分钟前
**发散创新:基于Rust的轻量级权限管理库设计与开源许可证实践**在现代分布式系统中,**权限控制(RBAC
java·开发语言·python·rust·开源
xiaoshuaishuai81 小时前
C# 方言识别
开发语言·windows·c#
John.Lewis1 小时前
C++进阶(6)C++11(2)
开发语言·c++·笔记
@atweiwei1 小时前
用 Rust 构建agent的 LLM 应用的高性能框架
开发语言·后端·rust·langchain·eclipse·llm·agent