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

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

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

DHTMLX Gantt v8.0正式版下载

为任务分配资源

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

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

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

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参数中指定一个带有资源的数组。

{ name: "resources", type: "resources", map_to: "owners", options: resourceData, default_value: 8 },

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

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

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

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

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

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

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()方法返回的对象中获取宽度参数。

const taskWidth = gantt.getTaskPosition(task, task.start_date, task.end_date).width;

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

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配置的值。但如果元素的宽度不同,则需要设置一个新值,宽度值必须乘以分配给给定任务的资源数量。

const ownersWidth = (task.owners || []).length * gantt.config.row_height;

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

if (textWidth + ownersWidth > taskWidth) {
return true;
}

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

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中可以只使用一个模板,您不能多次指定不同的模板并期望它们正常工作,所以必须在一个模板中添加所有的代码:

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 "";
};

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/756662.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

万用表革新升级,WT588F02BP-14S语音芯片助力智能测量新体验v

万能表功能&#xff1a; 万能表是一款集多功能于一体的电子测量工具&#xff0c;能够精准测量电压、电流、电阻等参数&#xff0c;广泛应用于电气、电子、通信等领域。其操作简便、测量准确&#xff0c;是工程师们进行电路调试、故障排查的得力助手&#xff0c;为提升工作效率…

Rust 中Self 关键字的两种不同用法

在 Rust 中&#xff0c;Self 是一个特殊的类型标识符&#xff0c;它代表了当前结构体或枚举类型。在结构体或枚举类型的定义中&#xff0c;Self 可以用于表示该类型的任何地方&#xff0c;包括方法签名、构造函数、类型别名等。 构造函数中的 Self&#xff1a; 在这段代码中&a…

大语言模型数据集alpaca羊驼数据集、Vicuna骆马数据集异同、作用、使用领域

文章目录 大语言模型数据集alpaca羊驼数据集、Vicuna骆马数据集异同、作用、使用领域Alpaca和Vicuna简介AlpacaVicuna相同点不同点 alpaca、vicuna能否用在大语言模型微调中&#xff1f;alpaca、vicuna进行大语言模型微调时&#xff0c;由于其已经是标准化数据集&#xff0c;还…

奥特曼剧透GPT-5,将在高级推理功能上实现重大进步

奥特曼&#xff1a;“GPT-5的能力提升幅度将超乎人们的想象...” 自 Claude 3 发布以来&#xff0c;外界对 GPT-5 的期待越来越强。毕竟Claude 3已经全面超越了 GPT-4&#xff0c;成为迄今为止最强大模型。 而且距离 GPT-4 发布已经过去了整整一年时间&#xff0c;2023年3月1…

2024年区块链、电子信息与计算机工程国际会议(ICBEICE 2024)

2024年区块链、电子信息与计算机工程国际会议&#xff08;ICBEICE 2024&#xff09; 2024 International Conference on Blockchain, Electronic Information and Computer Engineering 会议简介&#xff1a; 2024年区块链、电子信息与计算机工程国际会议&#xff08;ICBEIC…

Android 源码中 内置系统App(整个APP源码方式集成)

1. 如何新建一个系统 App 项目 使用 Android Studio 新建一个空项目 FirstSystemApp&#xff0c;包名设置为 com.yuandaima.firstsystemapp&#xff0c;语言选择 Java。后面为叙述方便称该项目为 as 项目。 接着在 jelly/rice14 目录下创建如下的目录和文件&#xff1a; 接着…

安卓面试题多线程 96-100

96. 简述notify()和notifyAll()有什么区别 ?notify可能会导致死锁,而notifyAll则不会任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码 使用notifyall,可以唤醒 所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一…

播放器视频卡顿,延迟的原因

之前测试过一些参数&#xff0c;也看到了1280x720就不卡&#xff0c;1920x1080明显就卡的多。那么就是说数据量太大了导致的延迟与卡顿&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 有可能是协议&#xff0c;ffmpeg参数的问题。 还有一个问题&#xff0c;播…

node.js 的常用命令

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff0c;它使得 JavaScript 可以脱离浏览器在服务器端运行。在使用 Node.js 进行开发时&#xff0c;有一些常用的命令可以帮助你更高效地进行开发和管理项目。以下是一些基本的 Node.js 命令&#xff1a; 1. node…

金江能源:助力新能源行业发展上市之路逐步迈进

在当今全球节能减排的大背景下,新能源产业成为了社会发展的热门领域。楚雄州金江能源集团有限公司作为新能源产业中的佼佼者,凭借其雄厚的技术实力和前瞻性的发展战略,已经展开了公司上市的蓄势之路。5月15日,金江能源将在港交所上市,为公司的发展注入更多资金和资源。 作为一…

vue axios 缓存 接口请求实现缓存加载

文章写的多了&#xff0c;开头就不知道怎么写了&#xff0c;硬挤一些句子总觉的卖弄。其实更多的想留下各位看官&#xff0c;多多的点赞&#xff0c;多多的关注&#xff0c;多的收藏。为将来的博客化动作做好前期数据粉丝基础。哦哦哦&#xff0c;我在想啥呢。。这大下午的。。…

Three.js简介

Three.js前提须知 讲到 Three.js&#xff0c;就需要先说一下 OpenGL 和 WebGL。 OpenGL 是一个跨平台的3D/2D的绘图标准&#xff08;规范&#xff09;&#xff0c;WebGL&#xff08;Web Graphics Library&#xff09;是一种3D绘图协议。 WebGL允许把JavaScript和OpenGL 结合…

图像处理学习笔记(一)

本文主要介绍&#xff0c;以供读者能够理解该技术的定义、原理、应用。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;ISP处理 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人生秘诀&#xff1a;学习的本质就…

xAI开发的一款巨大型语言模型(HLM)--Grok 1

在xAI发布Grok的权重和架构之后&#xff0c;很明显大型语言模型&#xff08;LLM&#xff09;的时代已经过去&#xff0c;现在是巨大型语言模型&#xff08;HLM&#xff09;的时代。这个混合专家模型发布了3140亿个参数&#xff0c;并且在Apache 2.0许可下发布。这个模型没有针对…

【项目管理后台】Vue3+Ts+Sass实战框架搭建一

项目管理后台 建立项目最好是卸载Vetur 新建.env.d.ts文件安装Eslint安装校验忽略文件添加运行脚本 安装prettier新建.prettierrc.json添加规则新建.prettierignore忽略文件 安装配置stylelint新建.stylelintrc.cjs 添加后的运行脚本配置husky配置commitlint配置husky 强制使用…

安卓面试题多线程 76-80

76. 简述普通线程与守护线程的区别 ?java 中的线程分为两种:守护线程(Daemon)和用户线程(User) 任何线程都可以设置为守护线程和用户线程,通过方法 Thread.setDaemon(boolon);true 则把该线程设置为守护线程,反之则为用户线程。Thread.setDaemon()必须在 Thread.start…

从服务器到云原生:企业IT基础设施的演进之路

随着数字经济的迅猛发展&#xff0c;企业IT数字化转型已成为推动业务创新和提升竞争力的关键。在这一转型过程中&#xff0c;基础设施的建设与升级显得尤为重要。企业需要不断优化和更新他们的基础设施&#xff0c;以适应不断变化的市场需求和技术发展。本文将探讨企业IT数字化…

信息系统项目管理师020:信息安全(2信息技术发展—2.1信息技术及其发展—2.1.4信息安全)

文章目录 2.1.4 信息安全1.信息安全基础2.加密解密3.安全行为分析技术4.网络安全态势感知 2.1.4 信息安全 常见的信息安全问题主要表现为&#xff1a;计算机病毒泛滥、恶意软件的入侵、黑客攻击、利用计算机犯罪、网络有害信息泛滥、个人隐私泄露等。随着物联网、云计算、人工智…

【JVM】如何判断堆上的对象没有被引用?

如何判断堆上的对象没有被引用&#xff1f; 常见的有两种判断方法&#xff1a;引用计数法和可达性分析法。 引用计数法会为每个对象维护一个引用计数器&#xff0c;当对象被引用时加1&#xff0c;取消引用时减1。 引用计数法的缺点-循环引用 引用计数法的优点是实现简单&…

大数据面试题 —— HBase

目录 什么是HBase简述HBase 的数据模型HBase 的读写流程HBase 在写的过程中的region的split的时机HBase 和 HDFS 各自的使用场景HBase 的存储结构HBase 中的热现象&#xff08;数据倾斜&#xff09;是怎么产生的&#xff0c;以及解决办法有哪些HBase rowkey的设计原则HBase 的列…