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

「实战应用」如何用DHTMLX将上下文菜单集成到JavaScript甘特图中(四)
DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的所有需求是最完善的甘特图图表库。DHTMLX Gantt是一个高度可定制的工具可以与项目管理应用程序所需的其他功能相补充。在本文中您将学习如何使用自定义上下文菜单来补充基于DHTMLX的JavaScript甘特图来提高用户在任务管理中的效率。考虑到DHTMLX产品的良好互兼容性DHTMLX Suite的Menu小部件是实现本教程目标的甘特图组件的完美补充。在上文中为大家介绍了如何完成更改Tree等级、更改任务类型等操作本文继续介绍如何完成标记完成、拆分任务等操作希望对大家有所帮助~标记完成有了这个上下文菜单项最终用户可以显示给定的任务已经完成。在代码中任务进度参数的值应该设置为1(即100%)。case complete: task.progress 1; gantt.updateTask(task.id); break;拆分任务当您需要将大型任务划分为几个更易于管理的部分时此功能会派上用场。当点击此选项时所选任务似乎在点击位置被分成2部分。实际上一个原始任务有两个副本您可以在其中更改它们的id和start_date或end_date参数原始任务变成以拆分模式显示的项目。case split: gantt.batchUpdate(function () { if (gantt.hasChild(task.id)) { gantt.message(The task already has children, so, it wont 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”类型的任务中调用。此选项仅在网格中可用但如果任务展开它将不再显示在拆分模式中然后该选项将在时间轴中可用。case unsplit: unsplit(task) break;unsplit函数在父任务中也用于相同的目的。case unsplit_parent: const parent gantt.getTask(task.parent); unsplit(parent) break;该函数删除任务的所有后代任务本身接收任务类型。任务的开始和结束日期不会更改并且它不再出现在拆分模式中。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包含任务的真实值则该任务将被隐藏。let hiddenTasks {}; gantt.attachEvent(onBeforeTaskDisplay, function (id, task) { return !hiddenTasks[task.id] });现在让我们继续研究pasteTasks函数。首先迭代tasksToCopy数组。在此数组中按ID获取任务对象执行任务的深度拷贝更改其ID并将任务添加到甘特图。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()方法将任务移动到不同的父任务和新位置。tasksToCut.forEach(function (id) { gantt.moveTask(id, index, parentId); });如果复制或移动任务的任务成为父任务请打开它然后需要清空tasksToCopy和tasksToCut数组。gantt.open(parentId); tasksToCopy []; tasksToCut [];在grid_row_class和task_class模板中如果任务ID在tasksToCopy数组中则返回类名task_to_copy如果任务ID在tasksToCut数组中则返回task_to_cut。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. 不透明度.task_to_cut.gantt_row, .task_to_cut.gantt_row.odd, .task_to_cut.gantt_task_line { opacity: 0.5; }2. 边界.task_to_copy.gantt_row, .task_to_copy.gantt_row.odd, .task_to_copy.gantt_task_line { border: 2px dotted LightSkyBlue; }此外禁用round_dnd_dates配置以便任务可以移动到任何位置并且甘特图不会将它们捕捉到时间轴单元格。gantt.config.round_dnd_dates false;划分任务后其持续时间可能大于或小于1天。任务移动到新位置后甘特图将重新计算任务持续时间该持续时间将四舍五入到最接近的整数。然后甘特图根据任务持续时间重新计算结束日期。当任务持续时间变为0时任务会缩小不方便拖动因此有必要将duration参数修改为大于0。gantt.attachEvent(onTaskDrag, function (id, mode, task, original) { task.duration task.duration || 1 });事实上可以用其他单位计算任务持续时间并以不同的方式显示此参数(例如以小数单位)。结论如你所见使用上下文菜单可以显著增强甘特图应用程序的功能和用户体验。如果您决定在项目管理中使用​DHTMLX Gantt​不需要任何第三方工具来实现自定义上下文菜单​HTMLX Suite​库中的Menu小部件是实现此目的的理想工具。