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

JavaScript甘特图 dhtmlx-gantt

背景

需求是在后台中,需要用甘特图去展示管理任务相关视图,并且不用依赖vue,兼容JavaScript原生开发。最终使用dhtmlx-gantt,一个半开源的库,基础功能免费,更多功能付费。
甘特图需求如图:
在这里插入图片描述

调研对比不同的库可参考:https://juejin.cn/post/7337114587122597900?searchId=20241220110156B288C2A4E8F21C0FB170

功能分析

  1. 基础元素:左侧任务树 & 右侧图例任务 Progress
  2. 新增任务
  3. 删除任务
  4. 编辑任务

Gantt 的 NPM地址 docs.dhtmlx.com

官网 Gannt

优点: 功能丰富,支持多种视图和自定义样式,适合构建复杂的项目甘特图。

缺点: 库比较重,半开源,不支持后续定制开发

开发 Demo

1. 安装

npm i dhtmlx-gantt

2. 组件导入
<script lang="ts">
import { defineComponent, onMounted, ref } from 'vue';
import { gantt } from 'dhtmlx-gantt'; // 核心模块
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'; // 样式模块
....
</script>
3. 准备引入DOM
<template><div class="gantt-no" ref="ganttRef"></div>
</template>
<script>setup() {const ganttRef = ref<HTMLElement | null>(null);...return {ganttRef}}
</script>
4. 准备 MOCK 数据
const tasks = {data: [{ id: 1, text: '任务 1', start_date: '2021-10-17', duration: 3, progress: 0.6 },{ id: 2, text: '任务 2', start_date: '2021-10-20', duration: 10, progress: 0.4 }],links: []
}

参数简析:

整体数据是以对象的形式存放,其中的data是一个 Task[],links是任务连线,其结构是 Link[]

单个 Task 可能包含以下的字段:

  • id: 任务唯一标识
  • text: 任务名称
  • start_date: 任务开始时间
  • duration: 任务时长
  • progress: 任务进度
  • parent: 父级的ID(树结构关系)
  • … 其他参数要查阅其官方文档

单个 Link 可能包含:

  • id: 连线的唯一标识
  • source: 源节点
  • target: 目标节点
  • type: 连线类型(0|1|2)标识是否有箭头
5. 初始化以及传入 tasks
onMounted((0 => {if (ganttRef.value) {gantt.init(ganttRef.value); // 初始化 DOMgantt.parse(tasks); // 传入 tasks}
}) 
6. 配置图例参数
  • 禁用连线 (本需求是不需要连线功能的)
gantt.config.show_links = false;
  • 禁用工作进度拖拽 (必须通过界面弹窗的方式进行修改信息)
gantt.config.drag_progress = false;
  • 设置任务分段参数以及单位
gantt.config.duration_unit = 'day';
gantt.config.duration_step = 1;
  • 配置左侧表格栏目
    gantt.config.columns = [{name: 'text',label: '任务名称',tree: true,width: '*',align: 'left',template: function (obj: any) {return obj.text;}},{name: 'start_date',label: '时间',width: '*',align: 'center',template: function (obj: any) {return obj.start_date;}},{name: 'progress',label: '进度',width: '*',align: 'center',template: function (obj: any) {return `${obj.progress * 100}%`;}}];参数简析: **ColumsItem[]**1. name: 'text' [String] , 索取的 tasks 里 **Task[]** 的 Task 的属性2. label: 'xxx' [String], 当前栏显示的文本3. tree: true [Boolean],当前的任务是否为树结构这样4. align: [String: left|right|center],label文本位置属性5. template: [Function],函数类型,入参是 obj,即为当前的 Task 对象6. ... 其他参数要查阅文档
  • 配置右侧表头日期栏
    gantt.config.xml_date = '%Y-%m-%d'; // 日期格式化的匹配格式gantt.config.scale_height = 90; // 日期栏的高度 const weekScaleTemplate = function (date: any) {const mouthMap: { [key: string]: string } = {Jan: '一月',Feb: '二月',Mar: '三月',Apr: '四月',May: '五月',Jun: '六月',Jul: '七月',Aug: '八月',Sept: '九月',Oct: '十月',Nov: '十一月',Dec: '十二月'};// 可以时使用dayjs 处理返回const dateToStr = gantt.date.date_to_str('%d');const mToStr = gantt.date.date_to_str('%M');const endDate = gantt.date.add(gantt.date.add(date, 1, 'week'), -1, 'day');// 处理一下月份return `${dateToStr(date)} 号 - ${dateToStr(endDate)} 号 (${mouthMap[mToStr(date) as string]})`;};const dayFormat = function (date: any) {const weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];return weeks[Dayjs(date).day()];};gantt.config.scales = [{ unit: 'year', step: 1, format: '%Y' },{ unit: 'week', step: 1, format: weekScaleTemplate },{ unit: 'day', step: 1, format: dayFormat }];
  • 添加今日的 Marker Line
    gantt.plugins({marker: true});gantt.addMarker({start_date: new Date(),text: '今日'});
任务菜单以及事件
  • 右键菜单功能
// menu.vue
<template><div class="menu" :style="{ left: x + 'px', top: y + 'px' }"><el-menu@select="handleSelect"background-color="#545c64"text-color="#fff"active-text-color="#fff"><el-menu-item index="add">新增任务</el-menu-item><el-menu-item index="edit">编辑任务</el-menu-item><el-menu-item index="del">删除任务</el-menu-item></el-menu></div>
</template><script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({props: {x: {type: Number,default: 0},y: {type: Number,default: 0}},emits: ['menu-item'],setup(props, ctx) {const handleSelect = (action: string) => {ctx.emit('menu-item', action);};return {handleSelect};}
});
</script><style lang="less" scoped>
.menu {position: fixed;transition: all 1s ease;::v-deep(.el-menu-item) {height: 40px;line-height: 40px;width: 200px;}
}
</style>
// Gantt.vue
<template><transition name="el-fade-in-linear"><Menu :x="menuX" :y="menuY" v-show="menuVisible" @menu-item="handleItemClick" /></transition>
</template>
<script lang="ts">
const menuVisible = ref<boolean>(false); // 控制菜单显示
const menuX = ref<number>(0); // left
const menuY = ref<number>(0); // top
const handleItemClick = (item: any) => {menuVisible.value = false; // 隐藏菜单dialogVisible.value = true; // 显示编辑弹窗
};
gantt.attachEvent('onContextMenu',function (taskId, linkId, event) {var x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft,y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;// 判断要是在树上的右键菜单才有效果if (taskId && event.target.className === 'gantt_tree_content') {console.log('task ContentMenu', taskId, linkId, event);menuX.value = x;menuY.value = y;menuVisible.value = true;}if (taskId || linkId) {return false;}return true;},{}
);
// 取消菜单显示
gantt.attachEvent('onEmptyClick',function (e) {//any custom logic heremenuVisible.value = false;},{}
);
</script>

效果
在这里插入图片描述

  • 其他事件 (禁用原来自带的弹窗)
gantt.attachEvent('onBeforeLightbox',function (id) {console.log(1);return false; // 返回 false},{}
);
  • 任务双击进入编辑事件
gantt.attachEvent('onTaskDblClick',function (id, e) {console.log('id', id, e);dialogVisible.value = true;return false;},{}
);

在这里插入图片描述

总结
  1. 具体代码,只处于一个 Dome 级别
  2. 至于npm源码方面,开源出来的功能从其官网看还是基本满足需求
  3. 库的稳定和功能升级方面,每周下载还是处于活跃的状态
  4. 官网Base是英文的,然后 Samples 样库例提供了很多功能的案例,需要发掘

相关文章:

JavaScript甘特图 dhtmlx-gantt

背景 需求是在后台中&#xff0c;需要用甘特图去展示管理任务相关视图&#xff0c;并且不用依赖vue&#xff0c;兼容JavaScript原生开发。最终使用dhtmlx-gantt&#xff0c;一个半开源的库&#xff0c;基础功能免费&#xff0c;更多功能付费。 甘特图需求如图&#xff1a; 调…...

阿里云-将旧服务器数据与配置完全迁移至新服务器

文章目录 一&#xff1a;创建镜像二&#xff1a;将创建好的镜像复制到新服务器所在的目标地域&#xff08;如果新服务器与镜像在同一地域就不用进行这一操作&#xff09;三&#xff1a;将镜像配置到新服务器上四&#xff1a;导出安全组&#xff08;如果新服务器与旧服务器使用同…...

以EM算法为例介绍坐标上升(Coordinate Ascent)算法:中英双语

中文版 什么是 Coordinate Ascent 算法&#xff1f; Coordinate Ascent&#xff08;坐标上升&#xff09;是一种优化算法&#xff0c;它通过在每次迭代时优化一个变量&#xff08;或一个坐标&#xff09;&#xff0c;并保持其他变量不变&#xff0c;逐步逼近最优解。与坐标下…...

Spark生态圈

Spark 主要用于替代Hadoop中的 MapReduce 计算模型。存储依然可以使用 HDFS&#xff0c;但是中间结果可以存放在内存中&#xff1b;调度可以使用 Spark 内置的&#xff0c;也可以使用更成熟的调度系统 YARN 等。 Spark有完善的生态圈&#xff1a; Spark Core&#xff1a;实现了…...

CSDN编辑器

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…...

【信息系统项目管理师】高分论文:论信息系统项目的资源管理(智慧储电站系统)

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 论文1、规划资源管理2、估算活动资源3、获取资源4、建设团队5、管理团队6、控制资源论文 根据国家2030年前碳达峰行动方案,提出全面推进风电、太阳能发电大规模开发和高质量发展。XX地国家电网启动了“数字李…...

Web开发:ORM框架之使用Freesql的分表分页写法

一、自动分表&#xff08;高版本可用&#xff09; 特性写法 //假如是按月分表&#xff1a;[Table(Name "log_{yyyyMM}", AsTable "createtime2022-1-1(1 month)")]注意&#xff1a;①需包含log_202201这张表 ②递增规律是一个月一次&#xff0c;确保他们…...

Unity功能模块一对话系统(1)前置准备

也许你也曾被游戏中的对话系统深深吸引&#xff0c;那些精心设计的对白、鲜活的角色配音、甚至是简单的文字对话&#xff0c;往往能让玩家产生强烈的代入感和情感共鸣。如果你正在开发一款游戏&#xff0c;或者计划为你的项目加入一个引人入胜的对话系统&#xff0c;那么 Unity…...

strrchr的概念和使用案例

strrchr 是 C 语言标准库中的一个函数&#xff0c;用于在字符串中查找最后一次出现的字符&#xff0c;并返回指向该字符的指针。 概念&#xff1a; strrchr 函数在给定的字符串中从末尾开始搜索指定的字符&#xff0c;返回一个指向该字符最后一次出现的指针。如果字符在字符串…...

缓存管理自动化:JuiceFS 企业版 Cache Group Operator 新特性发布

近期&#xff0c;JuiceFS 企业版推出了 Cache Group Operator&#xff0c;用于自动化创建和管理缓存组集群。Operator 是一种简化 Kubernetes 应用管理的工具&#xff0c;它能够自动化应用程序的生命周期管理任务&#xff0c;使部署、扩展和运维更加高效。 在推出 Operator 之前…...

C++ 并发专题 - 实现一个线程安全的队列

一&#xff1a;概述 本文利用 C 标准库中的多线程、条件变量、互斥锁等工具来实现一个线程安全的队列&#xff0c;并且使用多个线程来向队列中添加和获取数据。 二&#xff1a;实现过程&#xff1a; #include <iostream> #include <queue> #include <mutex&g…...

SQL 基础教程

SQL 是用于访问和处理数据库的标准的计算机语言。 在本教程中&#xff0c;您将学到如何使用 SQL 访问和处理数据系统中的数据&#xff0c;这类数据库包括&#xff1a;Oracle, Sybase, SQL Server, DB2, Access 等等。 SQL 是用于访问和处理数据库的标准的计算机语言。 什么是…...

【源码】Sharding-JDBC源码分析之SQL中影子库ShadowSQLRouter路由的原理

Sharding-JDBC系列 1、Sharding-JDBC分库分表的基本使用 2、Sharding-JDBC分库分表之SpringBoot分片策略 3、Sharding-JDBC分库分表之SpringBoot主从配置 4、SpringBoot集成Sharding-JDBC-5.3.0分库分表 5、SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表 6、【…...

雷池 WAF 搭配阿里云 CDN 使用教程

雷池 WAF&#xff08;Web Application Firewall&#xff09;是一款强大的网络安全防护产品&#xff0c;通过实时流量分析和精准规则拦截&#xff0c;有效抵御各种网络攻击。在部署雷池 WAF 的同时&#xff0c;结合阿里云 CDN&#xff08;内容分发网络&#xff09;可以显著提升网…...

3.银河麒麟V10 离线安装Nginx

1. 下载nginx离线安装包 前往官网下载离线压缩包 2. 下载3个依赖 openssl依赖&#xff0c;前往 官网下载 pcre2依赖下载&#xff0c;前往Git下载 zlib依赖下载&#xff0c;前往Git下载 下载完成后完整的包如下&#xff1a; 如果网速下载不到请使用网盘下载 通过网盘分享的文件…...

【模块一】kubernetes容器编排进阶实战之kubernetes 资源限制

kubernetes 资源限制 kubernetes中资源限制概括 1.如果运行的容器没有定义资源(memory、CPU)等限制&#xff0c;但是在namespace定义了LimitRange限制&#xff0c;那么该容器会继承LimitRange中的 默认限制。 2.如果namespace没有定义LimitRange限制&#xff0c;那么该容器可…...

【开源】一款基于SpringBoot的智慧小区物业管理系统

一、下载项目文件 项目文件源码链接&#xff1a;https://pan.quark.cn/s/3998d958e182如出现网盘空间不够存的情况&#xff01;&#xff01;&#xff01;解决办法是先用夸克手机app注册&#xff0c;然后保存上方链接&#xff0c;就可以得到1TB空间了&#xff01;&#xff01;&…...

Goland:专为Go语言设计的高效IDE

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;Goland是JetBrains公司开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为Go语言设计&#xff0c;提供了高效的代码编辑、强大的调试工具和丰富的项目管理功能。其智能代码补全、强大的调试与测试支…...

云手机与Temu矩阵:跨境电商运营新引擎

云手机与 Temu 矩阵结合的基础 云手机技术原理 云手机基于先进的 ARM 虚拟化技术&#xff0c;在服务器端运行 APP。通过在服务器上利用容器虚拟化软件技术&#xff0c;能够虚拟出多个独立的手机操作系统实例&#xff0c;每个实例等同于一部单独的手机&#xff0c;可独立运行各…...

仓颉编程笔记1:变量函数定义,常用关键字,实际编写示例

本文就在网页版上体验一下仓颉编程&#xff0c;就先不下载它的SDK了 基本围绕着实际摸索的编程规则来写的 也没心思多看它的文档&#xff0c;写的不太明确&#xff0c;至少我是看的一知半解的 文章提供测试代码讲解、测试效果图&#xff1a; 目录 仓颉编程在线体验网址&…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...