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

在 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>`}

相关文章:

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

一、最终实现的结果gif展示 二、开发步骤简介 1、vue中引用甘特图包dhtmlx-gantt // 可根据项目版本载入适配的版本 npm install dhtmlx-gantt7.1.132、vue文件中引入 <script> import { gantt } from dhtmlx-gantt/codebase/dhtmlxgantt.js import dhtmlx-gantt/code…...

【C++高级主题】命令空间(三):未命名的命名空间

目录 一、未命名的命名空间的基本概念 1.1 定义与特点 1.2 基本语法 1.3 访问方式 1.4 未命名的命名空间的作用 二、未命名的命名空间与静态声明的比较 2.1 静态声明的作用 2.2 未命名的命名空间的优势 2.3 示例代码比较 2.4. 未命名的命名空间的作用域和链接属性 三…...

鸿蒙OSUniApp 开发支持图片和视频的多媒体展示组件#三方框架 #Uniapp

使用 UniApp 开发支持图片和视频的多媒体展示组件 前言 在现代移动应用中&#xff0c;图片和视频已成为内容展示的主流形式。一个优秀的多媒体展示组件不仅能提升用户体验&#xff0c;还能增强产品的互动性和视觉冲击力。随着鸿蒙&#xff08;HarmonyOS&#xff09;生态的不断…...

VoltAgent 是一个开源 TypeScript 框架,用于构建和编排 AI 代理

​一、软件介绍 文末提供程序和源码下载 VoltAgent 是一个开源 TypeScript 框架&#xff0c;用于构建和编排 AI 代理 二、什么是 VoltAgent&#xff1f; AI 代理框架提供了构建由自主代理提供支持的应用程序所需的基础结构和工具。这些代理通常由大型语言模型 &#xff08;&am…...

数据中台(大数据平台)之数据仓库建设

数据中台作为企业数据管理的核心枢纽&#xff0c;应支持并促进企业级数据仓库的建设&#xff0c;确保数据的有效整合、治理和高效应用。在建设数据仓库的过程中&#xff0c;设计和规划显得尤为重要&#xff0c;需要深入理解业务需求&#xff0c;制定合理的技术架构&#xff0c;…...

如何使用DeepSpeed来训练大模型

&#x1f525; DeepSpeed是什么&#xff1f; DeepSpeed 是微软开源的一个 分布式训练加速库。 能帮助我们&#xff1a; 高效训练大模型&#xff08;百亿、千亿参数规模&#xff09; 节省显存、加速训练 支持 ZeRO 优化器、Offload、混合精度&#xff08;FP16/BF16&#xff0…...

道可云人工智能每日资讯|《北京市人工智能赋能新型工业化行动方案(2025年)》发布

道可云人工智能&元宇宙每日简报&#xff08;2025年5月28日&#xff09;讯&#xff0c;今日人工智能&元宇宙新鲜事有&#xff1a; 河南&#xff1a;打造“AI智慧文旅”沉浸式体验新空间&#xff0c;推动5GAR/VR在文旅消费场景应用 近日&#xff0c;河南省人民政府办公…...

Unity 中实现首尾无限循环的 ListView

之前已经实现过&#xff1a; Unity 中实现可复用的 ListView-CSDN博客文章浏览阅读5.6k次&#xff0c;点赞2次&#xff0c;收藏27次。源码已放入我的 github&#xff0c;地址&#xff1a;Unity-ListView前言实现一个列表组件&#xff0c;表现方面最核心的部分就是重写布局&…...

mongodb集群之副本集

目录 1. 适用场景备份高可用性 2. 集群搭建如何搭建资源规划根据资源完成各节点conf文件的配置启动各个mongodb节点初始化集群信息 搭建实例Linux搭建实例&#xff08;待定&#xff09;Windows搭建实例 3. 副本集基础操作4.集群平滑升级 1. 适用场景 备份 1&#xff09;服务器…...

基于微服务架构的社交学习平台WEB系统的设计与实现

设计&#xff08;论文&#xff09;题目 基于微服务架构的社交学习平台WEB系统的设计与实现 摘 要 社交学习平台 web 系统要为学习者打造一个开放、互动且社交性强的在线教育环境&#xff0c;打算采用微服务架构来设计并实现一个社交学习平台 web 系统&#xff0c;以此适应学…...

window10下docker方式安装dify步骤

window10下docker方式安装dify步骤&#xff08;稳定后考虑部署至linux中&#xff09; 教程&#xff1a;https://blog.csdn.net/qq_49035156/article/details/143264534 教程&#xff1a;https://blog.csdn.net/m0_51171437/article/details/146069890 0、资源要求 ---windows…...

Spark SQL进阶:解锁大数据处理的新姿势

目录 一、Spark SQL&#xff0c;为何进阶&#xff1f; 二、进阶特性深剖析 2.1 窗口函数&#xff1a;数据洞察的新视角 2.2 高级聚合&#xff1a;挖掘数据深度价值 2.3 自定义函数&#xff08;UDF 和 UDTF&#xff09;&#xff1a;拓展功能边界 三、性能优化实战 3.1 数…...

放假带出门的充电宝买哪种好用耐用?倍思超能充35W了解一下!

端午节的到来和毕业季的临近&#xff0c;让很多人开始计划出游或长途旅行。而在旅途中&#xff0c;一款好用耐用的充电宝可以省不少事。今天&#xff0c;我们就来聊聊放假带出门的充电宝买哪种好用耐用&#xff0c;看看为什么倍思超能充35W更适合带出门~ 一、为什么需要一款好用…...

云原生DMZ架构实战:基于AWS CloudFormation的安全隔离区设计

在云时代,传统的DMZ(隔离区)概念已经演变为更加灵活和动态的架构。本文通过解析一个实际的AWS CloudFormation模板,展示如何在云原生环境中构建现代化的DMZ安全架构。 1. 云原生DMZ的核心理念 传统DMZ是网络中的"缓冲区",位于企业内网和外部网络之间。而在云环境…...

小工具合集

Freetool.tools - Overview Freetool.tools is a 100% free online utility website offering a wide range of handy tools for everyday tasks. It focuses on simplicity, instant access, and zero cost—no signup, ads, or paywalls. ✅ Key Features & Strengths …...

AI智能体策略FunctionCalling和ReAct有什么区别?

Dify 内置了两种 Agent 策略&#xff1a;Function Calling 和 ReAct&#xff0c;但二者有什么区别呢&#xff1f;在使用时又该如何选择呢&#xff1f;接下来我们一起来看。 1.Function Calling Function Call 会通过将用户指令映射到预定义函数或工具&#xff0c;LLM 先识别用…...

改进自己的图片 app

1. 起因&#xff0c; 目的: 前面我写过一个图片 app &#xff0c; 最新做了些改动。 把原来的一列&#xff0c;改为3列&#xff0c; 继续使用瀑布流手机上使用&#xff0c;更流畅&#xff0c;横屏显示为2列。 2. 先看效果 3. 过程: 过程太细碎了&#xff0c;这里只是做一下…...

docker不用dockerfile

好的&#xff01;既然你不想使用 Dockerfile&#xff0c;我们就完全不写 Dockerfile&#xff0c;改用你 Leader 提到的思路&#xff1a; 用基础镜像启动一个容器 → 手动在容器里安装依赖和复制项目 → 保存为新镜像 这个方式更直观&#xff0c;就像“你进入容器自己配置环境&a…...

Uniapp+UView+Uni-star打包小程序极简方案

一、减少主包体积 主包污染源&#xff08;全局文件依赖&#xff09;劲量独立导入 componentsstaticmain.jsApp.vueuni.css 分包配置缺陷&#xff0c;未配置manifest.json中mp-weixin节点 "usingComponents" : true,"lazyCodeLoading" : "requiredC…...

深度学习篇---Pytorch框架下OC-SORT实现

下面将详细介绍如何基于 PyTorch 框架实现 OC-SORT&#xff08;Observation-Centric SORT&#xff09;算法。OC-SORT 是一种高性能的多目标跟踪算法&#xff0c;特别适用于复杂场景下的目标跟踪。我们将从算法原理到具体实现逐步展开。 1. 算法概述与核心原理 OC-SORT 在传统…...

STM32 HAL库SPI读写W25Q128(软件模拟+硬件spi)

1. 引言 在嵌入式系统开发中&#xff0c;SPI&#xff08;Serial Peripheral Interface&#xff09;总线是一种常用的串行通信协议&#xff0c;用于在微控制器和外部设备之间进行高速数据传输。W25Q128 是一款常见的 SPI Flash 芯片&#xff0c;具有 128Mbit&#xff08;16MB&a…...

算法题(159):快速幂

审题&#xff1a; 本题需要我们计算出(a^b)%c的值&#xff0c;并按照规定格式输出 思路&#xff1a; 方法一&#xff1a;暴力解法 我们直接循环b次计算出a^b,然后再取余c&#xff0c;从而得出最终结果 时间上&#xff1a;会进行2^31次&#xff0c;他的数量级非常大&#xff0c;…...

【新品发布】嵌入式人工智能实验箱EDU-AIoT ELF 2正式发布

在万物互联的智能化时代&#xff0c;将AI算法深度植入硬件终端的技术&#xff0c;正悄然改变着工业物联网、智慧交通、智慧医疗等领域的创新边界。为了助力嵌入式人工智能在教育领域实现高质量发展&#xff0c;飞凌嵌入式旗下教育品牌ElfBoard&#xff0c;特别推出嵌入式人工智…...

基于javaweb的SpringBoot体检管理系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

Mac Python 安装依赖出错 error: externally-managed-environment

Mac Python 使用 ip3 install -r requirements.txt 出错 This environment is externally managed ╰─> To install Python packages system-wide, try brew installxyz, where xyz is the package you are trying toinstall.If you wish to install a Python library th…...

Docker Desktop for Windows 系统设置说明文档

1. 文档概述 本文档旨在详细说明 Docker Desktop for Windows 应用程序中“设置 (Settings)”界面下的所有可配置选项及其子选项。对于每个配置项&#xff0c;我们将提供其功能描述、推荐配置&#xff08;如适用&#xff09;以及相关注意事项&#xff0c;帮助用户更好地理解和…...

C++高级编程深度指南:内存管理、安全函数、递归、错误处理、命令行参数解析、可变参数应用与未定义行为规避

C高级编程深度指南&#xff1a;内存管理、安全函数、递归、错误处理、命令行参数解析、可变参数应用与未定义行为规避 1. 可变参数1.1 可变参数的定义与原理1.2 使用可变参数的场景1.3 可变参数的实现方式1.3.1 省略号方式1.3.2 模板参数包方式 2.2 动态内存分配函数2.3 内存泄…...

【下拉选项数据管理优化实践:从硬编码到高扩展性架构】

下拉选项数据管理优化实践&#xff1a;从硬编码到高扩展性架构 背景 在大型前端项目中&#xff0c;下拉选项数据管理是一个常见但容易被忽视的痛点。我们的项目中存在多种格式的选项标识符&#xff0c;如代码格式&#xff08;OPTION_A1&#xff09;和数字格式&#xff08;100…...

IPD的基础理论与框架——(四)矩阵型组织:打破部门壁垒,构建高效协同的底层

在传统的组织架构中&#xff0c;企业多采用直线职能制&#xff0c;就像一座等级森严的金字塔&#xff0c;信息沿着垂直的层级传递&#xff0c;员工被划分到各个职能部门。这种架构职责清晰、分工明确&#xff0c;在稳定的市场环境中&#xff0c;能让企业高效运作&#xff0c;发…...

深度学习篇---OC-SORT实际应用效果

OC-SORT 算法在实际应用中的效果可从准确性、鲁棒性、效率三个核心维度评估,其表现与传统多目标跟踪算法(如 SORT、DeepSORT)相比有显著提升,尤其在复杂场景中优势突出。以下是具体分析: 一、准确性:目标关联更可靠 1. 遮挡场景下的 ID 保持能力 优势表现: 传统算法(…...