Vue 和 dhtmlx-gantt 实现图表构建动态多级甘特图效果 ,横坐标为动态刻度不是日期

注意事项:1、横坐标根据日期转换成时间刻度在( gantt.config.scales);2、获取时间刻度的最大值(findMaxRepairTime);3、甘特图多级列表需注意二级三级每个父子id需要唯一(convertData

  1. 安装依赖

    npm install dhtmlx-gantt --save

  2. 在当前页引入和配置 dhtmlx-gantt

    import gantt from "dhtmlx-gantt"; // 引入模块
    // import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
    import "dhtmlx-gantt/codebase/skins/dhtmlxgantt_terrace.css"; //皮肤
    import "dhtmlx-gantt/codebase/locale/locale_cn"; // 本地化
    // import "dhtmlx-gantt/codebase/ext/dhtmlxgantt_tooltip.js"; //任务条悬浮提示
    

     

  3. 创建甘特图容器

    <div ref="gantt" class="left-container" />
    
        
        initMount() {
          let convertedData = this.convertData(this.aircraftData);
          this.tasks.data = convertedData;
          let maxNum = this.findMaxRepairTime(this.aircraftData);
          gantt.config.start_date = new Date(2025, 0, 16, 0, 0, 0);
          gantt.config.end_date = new Date(
            2025,
            0,
            16,
            Math.floor(maxNum / 60),
            maxNum % 60,
            0
          );
    
          gantt.config.autosize = true;
          gantt.config.readonly = true;
          gantt.config.show_grid = true;
          gantt.config.columns = [
            { name: "text", label: "名称", tree: true, width: "260" },
          ];
          gantt.config.show_task_cells = true;
    
          // 设置时间刻度
          gantt.config.scales = [
            {
              unit: "minute",
              step: 10,
              format: function (date) {
                // 提取小时和分钟
                var hours = date.getHours();
                var minutes = date.getMinutes();
    
                // 将小时转换为分钟,并加上额外的分钟数
                var totalMinutes = hours * 60 + minutes + 10;
    
                return totalMinutes;
              },
            },
          ];
    
          // 设置任务条上展示的内容,参数task会返回当前任务的数据
          gantt.templates.task_text = function (start, end, task) {
              return '<div class="gantt-task-content">' + task.text + "-" + task.time + "分钟" + '</div>';
            };
          // gantt.config.xml_date = '%Y-%m-%d %H:%i:%s';
    
          this.initData();
          // 初始化甘特图
          gantt.init(this.$refs.gantt);
          gantt.clearAll();
          //销毁
          // gantt.destructor()
          gantt.parse(this.tasks);
        },
       //初始化甘特图
        initData: function () {
          this.tasks.data.map(function (current, ind, arry) {
            var newObj = {};
            if (current.type) {
              if (current.type == 1) {
                newObj = Object.assign({}, current, { color: "#67c23a" });
              }
              //   } else if (current.type == 2) {
              //     newObj = Object.assign({}, current, { color: "#fec0dc" });
              //   } else if (current.type == 3) {
              //     newObj = Object.assign({}, current, { color: "#62ddd4" });
              //   } else if (current.type == 4) {
              //     newObj = Object.assign({}, current, { color: "#d1a6ff" });
              //   }
            } else {
              newObj = Object.assign({}, current, { color: "#f9d484" });
            }
    
            return newObj;
          });
        },
    
    

  4. 处理后端返回的数据

    
        //处理数组
        convertData(aircraftData) {
          let result = [];
          let nextUniqueId = 0; // 用于生成唯一的ID
          aircraftData.forEach((aircraft) => {
            let aircraftInfo = {
              id: aircraft.taskId,
              text: aircraft.planeNum,
              start_date: new Date(2025, 0, 16, 0, 0),
              end_date: new Date(
                2025,
                0,
                16,
                Math.floor(aircraft.repairTime / 60),
                aircraft.repairTime % 60,
                0
              ),
              duration: aircraft.repairTime,
              open: true,
              time: aircraft.repairTime,
            };
            result.push(aircraftInfo);
    
            aircraft.lruList.forEach((sparePart) => {
              let sparePartId = `sparepart-${nextUniqueId++}`; // 生成唯一的ID
              let sparePartInfo = {
                text: sparePart.lruName,
                start_date: new Date(2025, 0, 16, 0, 0),
                end_date: new Date(
                  2025,
                  0,
                  16,
                  Math.floor(sparePart.repairTime / 60),
                  sparePart.repairTime % 60,
                  0
                ),
                id: sparePartId, // sparePart.lruId,  //随机数这个id与下面的sparePart.lruWorkList的parent一致
                duration: sparePart.repairTime,
                parent: sparePart.taskId,
                type: 1,
                open: true,
                time: sparePart.repairTime,
              };
              result.push(sparePartInfo);
    
              sparePart.lruWorkList.forEach((procedure) => {
                let procedureId = `procedure-${nextUniqueId++}`; // 生成唯一的ID
                let procedureInfo = {
                  text: procedure.taskName,
                  start_date: new Date(2025, 0, 16, 0, 0),
                  end_date: new Date(
                    2025,
                    0,
                    16,
                    Math.floor(procedure.workTime / 60),
                    procedure.workTime % 60,
                    0
                  ),
                  id: procedureId, //procedure.lruWorkId, //这个 id要唯一
                  duration: procedure.workTime,
                  parent: sparePartId, // procedure.lruIdThree, //aircraft.lruList这个id和parent一致
                  type: procedure.isCompleted,
                  time: procedure.workTime,
                };
                result.push(procedureInfo);
              });
            });
          });
    
          return result;
        },
        //取最大的修理时间
        findMaxRepairTime(data) {
          let maxRepairTime = 0;
          data.forEach((aircraft) => {
            if (aircraft.repairTime > maxRepairTime) {
              maxRepairTime = aircraft.repairTime;
            }
          });
          return maxRepairTime;
        },
    

  5. 子组件监听调用

    watch: {
        newData: {
          handler(newVal) {
            if (newVal !== undefined && newVal !== null)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/966226.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux 源码编译安装httpd 2.4,提供系统服务管理脚本并测试

第一种方式 1. 下载 Apache HTTP Server 源代码 首先&#xff0c;从 Apache 官网 下载最新版本的 httpd 2.4 源码&#xff0c;或者直接使用 wget 下载&#xff1a; [rootlocalhost ~]# wget https://downloads.apache.org/httpd/httpd-2.4.36.tar.gz # 解压 [rootlocalhost ~…

ARM嵌入式学习--第十三天(I2C)

I2C --介绍 I2C&#xff08;Inter-intergrated Circuit 集成电路&#xff09;总线是Philips公司在八十年代初推出的一种串行、半双工的总线&#xff0c;主要用于近距离、低速的芯片之间的通信&#xff1b;I2C总线有俩根双向的信号线&#xff0c;一根数据线SDA用于收发数据&…

python爬虫--简单登录

1&#xff0c;使用flask框架搭建一个简易网站 后端代码app.py from flask import Flask, render_template, request, redirect, url_for, sessionapp Flask(__name__) app.secret_key 123456789 # 用于加密会话数据# 模拟用户数据库 users {user1: {password: password1}…

C# 解决“因为算法不同,客户端和服务器无法通信”的问题

目录 故障现象 开发运行环境 解决 实现携带证书的 API URL调用 其它 故障现象 实现微信退款功能&#xff0c;我们需要在微信支付商户后台申请安全证书&#xff0c;并调用退款API URL。在调试过程中为增添返回调试信息属性&#xff0c;重新对.net FrameWorkd 类库进行编译…

【大模型】Ubuntu下安装ollama,DeepSseek-R1:32b的本地部署和运行

1 ollama 的安装与设置 ollama官网链接&#xff1a;https://ollama.com/ 在左上角的【Models】中展示了ollama支持的模型在正中间的【Download】中课可以下载支持平台中的安装包。   其安装和模型路径配置操作流程如下&#xff1a; ollama的安装 这里选择命令安装curl -fsSL …

LLAMA-Factory安装教程(解决报错cannot allocate memory in static TLS block的问题)

步骤一&#xff1a; 下载基础镜像 # 配置docker DNS vi /etc/docker/daemon.json # daemon.json文件中 { "insecure-registries": ["https://swr.cn-east-317.qdrgznjszx.com"], "registry-mirrors": ["https://docker.mirrors.ustc.edu.c…

快速上手——.net封装使用DeekSeek-V3 模型

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,用爱发电,去丈量人心,是否能达到人机合一?开工大吉 新的一年就这么水灵灵的开始了,在这里,祝各位读者新春快乐,万事如意! 新年伊…

高德地图python地理编码和geopandas应用判断坐标点空间位置

在本人另一篇文章&#xff08;高德地图地理编码python&#xff08;版本3.9&#xff09;爬虫&#xff08;含坐标转换及数据表模板&#xff09;-CSDN博客&#xff09;的基础上增加geopandas功能&#xff0c;使脚本能自动根据查找的高德地图坐标与现有的几何范围进行交互&#xff…

Pygame介绍与游戏开发

提供pygame功能介绍的文档&#xff1a;Pygame Front Page — pygame v2.6.0 documentation 基础语法和实现逻辑 与CLI不同&#xff0c;pygame提供了图形化使用界面GUI&#xff08;graphical user interface&#xff09;基于图像的界面可以创建一个有图像和颜色的窗口 要让py…

Unity VideoPlayer播放视屏不清晰的一种情况

VideoPlayer的Rnder Texture可以设置Size,如果你的视屏是1920*1080那么就设置成1920*1080。 如果设置成其他分辨率比如800*600会导致视屏不清晰。

使用PyCharm创建项目以及如何注释代码

创建好项目后会出现如下图所示的画面&#xff0c;我们可以通过在项目文件夹上点击鼠标右键&#xff0c;选择“New”菜单下的“Python File”来创建一个 Python 文件&#xff0c;在给文件命名时建议使用英文字母和下划线的组合&#xff0c;创建好的 Python 文件会自动打开&#…

02.06 网络编程_套接字

思维导图&#xff1a; 网络编程基础&#xff1a;套接字的使用 网络编程是现代软件开发中不可或缺的一部分&#xff0c;而套接字&#xff08;Socket&#xff09;是网络编程中用于实现不同主机间通信的基本工具。本文将详细介绍套接字的概念、创建方法、如何通过套接字发送和接…

< OS 有关 > Ubuntu 版本升级 实践 24.04 -> 24.10, 安装 .NET

原因&#xff1a; 想安装 .NET 9 去编译 GitHut 项目&#xff0c;这回用不熟悉的 Ubuntu来做&#xff0c;不知道怎么拐去给 Ubuntu 升级&#xff0c;看到现在版本是 24.10 但不是 LTS 版本&#xff0c;记录下升级过程。 一、实践过程&#xff1a; 1. 查看当前版本 命令1: l…

VsCode创建VUE项目

1. 首先安装Node.js和npm 通过网盘分享的文件&#xff1a;vsCode和Node&#xff08;本人电脑Win11安装&#xff09; 链接: https://pan.baidu.com/s/151gBWTFZh9qIDS9XWMJVUA 提取码: 1234 它们是运行和构建Vue.js应用程序所必需的。 1.1 Node安装&#xff0c;点击下一步即可 …

音频进阶学习十二——Z变换一(Z变换、收敛域、性质与定理)

文章目录 前言一、Z变换1.Z变换的作用2.Z变换公式3.Z的状态表示1&#xff09; r 1 r1 r12&#xff09; 0 < r < 1 0<r<1 0<r<13&#xff09; r > 1 r>1 r>1 4.关于Z的解释 二、收敛域1.收敛域的定义2.收敛域的表示方式3.ROC的分析1&#xff09;当 …

分布式微服务系统架构第91集:系统性能指标总结

加群联系作者vx&#xff1a;xiaoda0423 仓库地址&#xff1a;https://webvueblog.github.io/JavaPlusDoc/ 系统性能指标总结 系统性能指标包括哪些&#xff1f; 业务指标、资源指标、中间件指标、数据库指标、前端指标、稳定性指标、批量处理指标、可扩展性指标、可靠性指标。 …

【C语言标准库函数】指数与对数函数:exp(), log(), log10()

目录 一、头文件 二、函数简介 2.1. exp(double x) 2.2. log(double x) 2.3. log10(double x) 三、函数实现&#xff08;概念性&#xff09; 3.1. exp(double x) 的模拟实现 3.2. log(double x) 和 log10(double x) 的模拟实现 四、注意事项 4.1. exp(double x) 的注…

CSS Overflow 属性详解:控制内容溢出的利器

在前端开发中&#xff0c;处理内容溢出是一个常见的需求。CSS 提供了 overflow 属性&#xff0c;帮助我们控制当内容超出元素框时的显示方式。本文将详细介绍 overflow 属性的各种取值及其应用场景。 1. 什么是 overflow 属性&#xff1f; overflow 属性用于控制当元素的内容…

go语言中的接口

接口简介 现实生活中的接口 现实生活中手机、相机、U 盘都可以和电脑的 USB 接口建立连接。我们不需要关注 usb 卡槽大小是否一样&#xff0c;因为所有的 USB 接口都是按照统一的标准来设计的。 Golang 中的接口&#xff08;interface&#xff09; Golang 中的接口是一种抽象…

网络安全威胁框架与入侵分析模型概述

引言 “网络安全攻防的本质是人与人之间的对抗&#xff0c;每一次入侵背后都有一个实体&#xff08;个人或组织&#xff09;”。这一经典观点概括了网络攻防的深层本质。无论是APT&#xff08;高级持续性威胁&#xff09;攻击、零日漏洞利用&#xff0c;还是简单的钓鱼攻击&am…