当前位置: 首页 > ai >正文

在 Vue 2中使用 dhtmlxGantt 7.1.13组件,并解决使用时遇到的问题汇总.“dhtmlx-gantt“: “^7.1.13“,

一、最终实现的结果gif展示

二、开发步骤简介

1、vue中引用甘特图包dhtmlx-gantt

// 可根据项目版本载入适配的版本
npm install dhtmlx-gantt@7.1.13

2、vue文件中引入

<script>
import { gantt } from 'dhtmlx-gantt/codebase/dhtmlxgantt.js'
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
<script/>

3、html部分

<template><div class="gantt-content"  style="width:100%;height: 100%;"><div ref="ganttContainer" style="width:100%;height: 100%;"></div></div>
</template>

4、js部分

  mounted () {// 初始化甘特图  注意:保证先初始化,在加载数据,以防万一可以在此基础上自行修改为异步this.initGantt()
// 初始化数据this.loadData()},watch: {'$route.query.id': {handler (newId) {if (newId) {this.loadData('clearAll')}},immediate: true // 立即执行以处理初始加载}},methods: {async loadData (type) {this.spinning = trueif (type === 'clearAll') { gantt.clearAll() } // 避免来回切换页面更改数据时甘特图数据展示混乱axiosxxx().then(res => {if (rres.code === 200) {// 处理任务阶段数据,甘特图回显let formattedGanttData = []formattedGanttData = res.data.progressItems.map(task => ({id: task.id,text: task.progressName, // 映射任务名称字段start_date: this.formatDate(task.startTime), // 转换为gantt标准字段parent: task.parentId,open: task.level === 1 ? true : undefined,level: task.level,duration: task.duration,status: task.status}))gantt.parse({ data: formattedGanttData })gantt.render() // 强制重绘} else {this.$message.error(res.msg)}this.spinning = false}).catch(err => {this.$message.error(err.msg)this.spinning = false})},// 处理时间格式formatDate (dateStr) {// 根据你的接口日期格式进行调整-gantt图时间格式要求固定let [year, month, day] = dateStr.split('-')return new Date(year, month - 1, day) // 月份减1,因为月份是从0开始的},initGantt () {// // 初始化容器gantt.init(this.$refs.ganttContainer)// 禁用所有交互gantt.config.editable = falsegantt.config.drag_move = gantt.config.drag_resize = falsegantt.config.select_task = false// 禁用编辑功能gantt.config.readonly = truegantt.config.drag_move = falsegantt.config.drag_resize = falsegantt.config.grid_editable = false// 隐藏操作栏配置gantt.config.tree_actions = true // 隐藏展开/折叠图标gantt.config.tree_line = false // 隐藏层级连线gantt.config.row_height = 30 // 调整行高适应多行内容// gantt.config.min_column_width = 120 // 防止列宽过小// 是否显示左侧树表格gantt.config.show_grid = true// 格式化日期-汉化gantt.locale.date = {month_full: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],month_short: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],day_full: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],day_short: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']}gantt.locale.labels = {dhx_cal_today_button: '今天',day_tab: '日',week_tab: '周',month_tab: '月',new_event: '新建日程',icon_save: '保存',icon_cancel: '关闭',icon_details: '详细',icon_edit: '编辑',icon_delete: '删除',confirm_closing: '请确认是否撤销修改!', // Your changes will be lost, are your sure?confirm_deleting: '是否删除计划?',section_description: '描述:',section_time: '时间范围:',section_type: '类型:',section_text: '计划名称:',section_test: '测试:',section_projectClass: '项目类型:',taskProjectType_0: '项目任务',taskProjectType_1: '普通任务',section_head: '负责人:',section_priority: '优先级:',taskProgress: '任务状态',taskProgress_0: '未开始',taskProgress_1: '进行中',taskProgress_2: '已完成',taskProgress_3: '已延期',taskProgress_4: '搁置中',section_template: 'Details',/* grid columns */column_text: '计划名称',column_start_date: '开始时间',column_duration: '持续时间',column_add: '',column_priority: '难度',/* link confirmation */link: '关联',confirm_link_deleting: '将被删除',message_ok: '确定',message_cancel: '取消',link_start: ' (开始)',link_end: ' (结束)',type_task: '任务',type_project: '项目',type_milestone: '里程碑',minutes: '分钟',hours: '小时',days: '天',weeks: '周',months: '月',years: '年'}// 自定义左侧列配置gantt.config.columns = [{ name: 'text',label: '任务名称',width: '*',tree: true,// 插入template,title解决字段显示不全的问题template: (task) => `<div title="${task.text}">${task.text}</div>`},{ name: 'start_date', label: '开始时间', align: 'center', width: 100 },{ name: 'duration', label: '持续天数', align: 'center', width: 70 }]// 任务条文本模板gantt.templates.task_text = (start, end, task) => {const cleanText = task.text.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')return `<div class="gantt-task-title" title="${cleanText}">${task.text}</div>`}// 自定义行样式(关键修改部分)gantt.templates.task_row_class = function (start, end, task) {if (task.level === 1) {return 'custom-gantt-level_1_row'}return ''}// 自定义任务条颜色模板(关键代码)gantt.templates.task_class = function (start, end, task) {// 调试输出(关键)// console.log(`[DEBUG] Task ${task.id}:`, {//   level: task.level,//   status: task.status,//   hasLevel: task.hasOwnProperty('level'),//   hasStatus: task.hasOwnProperty('status')// })switch (true) {case (task.level === 1):return 'custom-gantt-level_1_bar'case (task.level === 2 && task.status === 3):return 'custom-gantt-task_status_done'default:return ''}}}}

5、css部分

5-1、修改dhtmlxGantt 甘特图任务条的颜色

5-2、修改dhtmlxGantt 甘特图背景色

5-3、dhtmlxGantt 甘特图隐藏左侧侧边栏icon展示

<style>
.custom-gantt-level_1_row {background-color: #e6f3ff !important; /* 浅蓝色背景 */
}/*修改任务条主题色*/
.gantt_task_line {background-color: #1890FF;border: 1px solid #1890FF;
}
.gantt_task_line.custom-gantt-level_1_bar {background: #FA8C16 !important;  /* 阶段任务条主色 */border-color: #FA8C16 !important;  /* 阶段边框颜色 */
}
.custom-gantt-task_status_done {background: #A3B1BF !important;  /* 已完成的任务条主色 */border-color: #A3B1BF !important;  /* 已完成的任务边框颜色 */
}/* 隐藏文件夹图标 */
.gantt_tree_icon.gantt_folder_open,
.gantt_tree_icon.gantt_file,
.gantt_tree_icon.gantt_folder_closed {display: none !important;
}/* 保留展开/收起图标 */
.gantt_grid_icon.gantt_open,
.gantt_tree_icon.gantt_close {display: inline-block !important;background-position: center; /* 修正图标位置 */
}
/* 调整层级缩进 */
.gantt_tree_indent {padding-left: 8px !important; /* 减少缩进间距 */
}
/*修改侧边栏hover颜色*/
.gantt_grid_data .gantt_row.odd:hover,
.gantt_grid_data .gantt_row:hover {background-color: #e6f3ff !important;
}
/* 在全局样式表中添加 */
.gantt_tree_text {display: inline-block;max-width: calc(100% - 24px); /* 为图标留出空间 */overflow: hidden;text-overflow: ellipsis;white-space: nowrap;vertical-align: middle;
}/*任务条显示不全时样式*/
.gantt_task_content {overflow: visible !important; /* 允许溢出显示 */
}
.gantt_task_title {max-width: 100%;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;pointer-events: none; /* 防止干扰拖拽操作 */
}</style>

三、使用过程中问题总结

1、页面来回切换,数据更新后甘特图加载数据混乱的问题

使用gantt.clearAll()解决。但要注意再在初始化加载时不需要gantt.clearAll(),所以在再watch监听和初始化可以通过type却分

  watch: {'$route.query.id': {handler (newId) {if (newId) {this.loadData('clearAll')}},immediate: true // 立即执行以处理初始加载}},mounted () {this.initGantt()this.loadData() // 初始化不需要gantt.clearAll()},
methods: {async loadData (type) {....if (type === 'clearAll') { gantt.clearAll() } // 避免来回切换页面更改数据时甘特图数据展示混乱// 源代码保持不变
.....},
}

2、自定义row背景色,根据状态不同自定义任务条的颜色

gantt.templates.task_class,gantt.templates.task_row_class

// 对应的class见css代码部分
initGantt(){// 自定义行样式(关键修改部分)gantt.templates.task_row_class = function (start, end, task) {if (task.level === 1) {return 'custom-gantt-level_1_row'}return ''}// 自定义任务条颜色模板(关键代码)gantt.templates.task_class = function (start, end, task) {// 调试输出(关键)// console.log(`[DEBUG] Task ${task.id}:`, {//   level: task.level,//   status: task.status,//   hasLevel: task.hasOwnProperty('level'),//   hasStatus: task.hasOwnProperty('status')// })switch (true) {case (task.level === 1):return 'custom-gantt-level_1_bar'case (task.level === 2 && task.status === 3):return 'custom-gantt-task_status_done'default:return ''}}}

3、甘特图文案展示不全问题

甘特图禁止编辑操作后,左侧侧边栏text文案过长时展示不全,可自定义添加title

任务条持续时间短,文案展示不全时,添加title展示

      // 自定义左侧列配置gantt.config.columns = [{ name: 'text',label: '任务名称',width: '*',tree: true,// 插入template,title解决字段显示不全的问题template: (task) => `<div title="${task.text}">${task.text}</div>`},{ name: 'start_date', label: '开始时间', align: 'center', width: 100 },{ name: 'duration', label: '持续天数', align: 'center', width: 70 }]// 任务条文本模板gantt.templates.task_text = (start, end, task) => {const cleanText = task.text.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')return `<div class="gantt-task-title" title="${cleanText}">${task.text}</div>`}

http://www.xdnf.cn/news/9225.html

相关文章:

  • Linux中Java开发、部署和运维常用命令
  • uni-app学习笔记十五-vue3页面生命周期(一)
  • unity实现wasd键控制汽车漫游
  • 国产三维CAD皇冠CAD(CrownCAD)建模教程:汽车电池
  • 洛谷 P3372 【模板】线段树 1
  • android 输入系统
  • 不同电脑同一个网络ip地址一样吗
  • 打卡第38天
  • 数据透视:水安 B 证如何影响水利企业的生存指数?
  • Java爬虫,获取未来40天预测气象并写入Excel
  • 制作一款打飞机游戏58:子弹模式组合
  • 低空经济数据湖架构设计方案
  • 在springboot,禁止查询数据库种的某字段
  • 【linux篇】动静态库和自动化构建的“神之一手”:make、Makefile
  • AtCoder 第407场初级竞赛 A~E题解
  • java helloWord java程序运行机制 用idea创建一个java项目 标识符 关键字 数据类型 字节
  • 服务器中分布式存储数据技术都包含哪些内容?
  • maven 最短路径依赖优先
  • Qt QPaintEvent绘图事件painter使用指南
  • Qt函数setText设置中文导致乱码/程序崩溃/报错:常量中有换行符
  • html css js网页制作成品——HTML+CSS+js醇香咖啡屋网页设计(5页)附源码
  • 大模型应用开发第三讲:大模型是Agent的“大脑”,提供通用推理能力(如GPT-4、Claude 3)
  • inviteflood:基于 UDP 的 SIP/SDP 洪水攻击工具!全参数详细教程!Kali Linux教程!
  • 从零实现本地语音识别(FunASR)
  • 在AIX环境下修改oracle 11g rac的IP地址
  • 使用requestAnimationFrame编写动画效果或者处理大量数据
  • 时序数据库IoTDB安装学习经验分享
  • 第三届全国先进技术成果转化大会成功举办 中科亿海微携品亮相
  • 【premiere教程】【01】【跑个流程】
  • 【android bluetooth 协议分析 02】【bluetooth hal 层详解 6】【高通蓝牙hal主要流程介绍-下】