「实战应用」如何用DHTMLX将上下文菜单集成到JavaScript甘特图中(四)

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

DHTMLX Gantt是一个高度可定制的工具,可以与项目管理应用程序所需的其他功能相补充。在本文中您将学习如何使用自定义上下文菜单来补充基于DHTMLX的JavaScript甘特图,来提高用户在任务管理中的效率。考虑到DHTMLX产品的良好互兼容性,DHTMLX Suite的Menu小部件是实现本教程目标的甘特图组件的完美补充。

DHTMLX Gantt最新正式版下载

在上文中(点击这里回顾>>)为大家介绍了如何完成更改Tree等级、更改任务类型等操作,本文继续介绍如何完成标记完成、拆分任务等操作,希望对大家有所帮助~

标记完成

有了这个上下文菜单项,最终用户可以显示给定的任务已经完成。

在代码中,任务进度参数的值应该设置为1(即100%)。

javascript 复制代码
case "complete":
task.progress = 1;
gantt.updateTask(task.id);
break;
拆分任务

当您需要将大型任务划分为几个更易于管理的部分时,此功能会派上用场。

当点击此选项时,所选任务似乎在点击位置被分成2部分。实际上,一个原始任务有两个副本,您可以在其中更改它们的id和start_date或end_date参数,原始任务变成以拆分模式显示的项目。

javascript 复制代码
case "split":
gantt.batchUpdate(function () {
if (gantt.hasChild(task.id)) {
gantt.message("The task already has children, so, it won't be split to new sub tasks");
return;
}

const leftChild = gantt.copy(task);
leftChild.id = gantt.uid();
leftChild.end_date = new Date(clickDate);
leftChild.parent = task.id;
leftChild.type = "task";

const rightChild = gantt.copy(task);
rightChild.id = gantt.uid();
rightChild.start_date = new Date(clickDate)
rightChild.parent = task.id;
rightChild.type = "task";

task.render = 'split';
task.type = "project";
gantt.updateTask(task.id);

gantt.close(task.id);

gantt.addTask(leftChild);
gantt.addTask(rightChild);
})
break;

如果一个任务已经被分成两个部分,那么每个部分也可以被分成两个部分。在底层下,树状结构发生了变化。

要把它带回来,必须点击"Unsplit parent"。这里需要调用unsplit函数,它只在"project"类型的任务中调用。此选项仅在网格中可用,但如果任务展开,它将不再显示在拆分模式中,然后该选项将在时间轴中可用。

javascript 复制代码
case "unsplit":
unsplit(task)
break;

unsplit函数在父任务中也用于相同的目的。

javascript 复制代码
case "unsplit_parent":
const parent = gantt.getTask(task.parent);
unsplit(parent)
break;

该函数删除任务的所有后代,任务本身接收任务类型。任务的开始和结束日期不会更改,并且它不再出现在拆分模式中。

javascript 复制代码
function unsplit(task) {
gantt.batchUpdate(function () {
gantt.eachTask(function (child) {
if (gantt.isTaskExists(child.id)) {
gantt.deleteTask(child.id);
}
}, task.id)
delete task.render;
task.type = "task";
gantt.updateTask(task.id);
})
}

这就是关于上下文菜单操作的所有内容,现在我们想向您展示如何实现其他一些功能,例如隐藏任务或标记任务来进行剪切和复制。

要隐藏任务,您需要使用onBeforeTaskDisplay事件处理程序。如果返回false,任务将不会显示在甘特图中,检查任务ID是否在hiddenTasks对象中。如果该ID包含任务的真实值,则该任务将被隐藏。

javascript 复制代码
let hiddenTasks = {};
gantt.attachEvent("onBeforeTaskDisplay", function (id, task) {
return !hiddenTasks[task.id]
});

现在,让我们继续研究pasteTasks函数。

首先,迭代tasksToCopy数组。在此数组中,按ID获取任务对象,执行任务的深度拷贝,更改其ID,并将任务添加到甘特图。

javascript 复制代码
tasksToCopy.forEach(function (id) {
const task = gantt.getTask(id);
const clone = gantt.copy(task);
clone.id = gantt.uid();
gantt.addTask(clone, parentId, index);
});

之后,迭代taskstock数组。在这里,您应该使用moveTask()方法将任务移动到不同的父任务和新位置。

javascript 复制代码
tasksToCut.forEach(function (id) {
gantt.moveTask(id, index, parentId);
});

如果复制或移动任务的任务成为父任务,请打开它,然后需要清空tasksToCopy和tasksToCut数组。

javascript 复制代码
gantt.open(parentId);

tasksToCopy = [];
tasksToCut = [];

在grid_row_class和task_class模板中,如果任务ID在tasksToCopy数组中,则返回类名task_to_copy,如果任务ID在tasksToCut数组中,则返回task_to_cut。

javascript 复制代码
gantt.templates.grid_row_class =
gantt.templates.task_class = function (start, end, task) {
if (tasksToCopy.indexOf(task.id) > -1) {
return "task_to_copy"
}
if (tasksToCut.indexOf(task.id) > -1) {
return "task_to_cut"
}
return "";
};

这些类有两种类型的样式:

  1. 不透明度
javascript 复制代码
.task_to_cut.gantt_row,
.task_to_cut.gantt_row.odd,
.task_to_cut.gantt_task_line {
opacity: 0.5;
}
  1. 边界
css 复制代码
.task_to_copy.gantt_row,
.task_to_copy.gantt_row.odd,
.task_to_copy.gantt_task_line {
border: 2px dotted LightSkyBlue;
}

此外,禁用round_dnd_dates配置,以便任务可以移动到任何位置,并且甘特图不会将它们捕捉到时间轴单元格。

javascript 复制代码
gantt.config.round_dnd_dates = false;

划分任务后,其持续时间可能大于或小于1天。任务移动到新位置后,甘特图将重新计算任务持续时间,该持续时间将四舍五入到最接近的整数。然后,甘特图根据任务持续时间重新计算结束日期。

当任务持续时间变为0时,任务会缩小,不方便拖动,因此有必要将duration参数修改为大于0。

javascript 复制代码
gantt.attachEvent("onTaskDrag", function (id, mode, task, original) {
task.duration = task.duration || 1
});

事实上,可以用其他单位计算任务持续时间,并以不同的方式显示此参数(例如,以小数单位)。

结论

如你所见,使用上下文菜单可以显著增强甘特图应用程序的功能和用户体验。如果您决定在项目管理中使用DHTMLX Gantt,不需要任何第三方工具来实现自定义上下文菜单,HTMLX Suite库中的Menu小部件是实现此目的的理想工具。

相关推荐
青皮桔23 分钟前
CSS实现百分比水柱图
前端·css
失落的多巴胺23 分钟前
使用deepseek制作“喝什么奶茶”随机抽签小网页
javascript·css·css3·html5
DataGear27 分钟前
如何在DataGear 5.4.1 中快速制作SQL服务端分页的数据表格看板
javascript·数据库·sql·信息可视化·数据分析·echarts·数据可视化
影子信息28 分钟前
vue 前端动态导入文件 import.meta.glob
前端·javascript·vue.js
青阳流月30 分钟前
1.vue权衡的艺术
前端·vue.js·开源
样子201834 分钟前
Vue3 之dialog弹框简单制作
前端·javascript·vue.js·前端框架·ecmascript
kevin_水滴石穿35 分钟前
Vue 中报错 TypeError: crypto$2.getRandomValues is not a function
前端·javascript·vue.js
翻滚吧键盘35 分钟前
vue文本插值
javascript·vue.js·ecmascript
孤水寒月2 小时前
给自己网站增加一个免费的AI助手,纯HTML
前端·人工智能·html
CoderLiu2 小时前
用这个MCP,只给大模型一个figma链接就能直接导出图片,还能自动压缩上传?
前端·llm·mcp