vue使用甘特图dhtmlxgantt + gantt.addTaskLayer

news2024/11/27 16:51:49

效果图:

甘特图
  • 官网地址

gantt安装与使用

vue版---部分功能收费
  1. 安装gantt  或  引入文件

    npm install dhtmlx-gantt -save
    
    或
    
    import gantt from "/public/static/dhtmlxgantt/dhtmlxgantt.js";
    import "/public/static/dhtmlxgantt/locale/locale_cn.js";
  2. 引入---组件

<template>
#节点高度要给,gantt不根据内容撑开
 <div ref="gantt" class="gantt-container" style="min-height: calc(85vh - 100px); width: 100%; overflow: hidden"></div>
</template>
<script>
 import gantt from "/public/static/dhtmlxgantt/dhtmlxgantt";
 import "/public/static/dhtmlxgantt/locale/locale_cn.js";
</script>

 借鉴

  1. css文件地址 examples/dhtmlx_gantt/dhtmlxgantt.css · 残星落影/博客 - 码云 - 开源中国 (gitee.com)
  2. js文件地址 examples/dhtmlx_gantt/dhtmlx · 残星落影/博客 - 码云 - 开源中国 (gitee.com)

定义渲染数据 

let tasks = ref({
  data: [
    {
      id: 1,
      text: "计划#1",
      start_date: "2023-09-28",
      end_date: "2023-10-28",
      sj_start_date: "2023-09-29",
      sj_end_date: "2023-10-25",
      open: true,
    },
    {
      id: 2,
      text: "已完成",
      start_date: "2023-09-28",
      end_date: "2023-10-28",
      sj_start_date: "2023-09-29",
      sj_end_date: "2023-10-25",
      parent: 1,
    },
    {
      id: 3,
      text: "计划#2",
      start_date: "2023-03-10",
      end_date: "2023-5-20",
      sj_start_date: "2023-03-10",
      sj_end_date: "2023-5-18",
      open: true,
    },
    {
      id: 4,
      text: "已完成",
      start_date: "2023-03-10",
      end_date: "2023-5-20",
      sj_start_date: "2023-03-10",
      sj_end_date: "2023-5-18",
      parent: 3,
    },
  ],
});

 完整代码

<script>
onMounted(() => {
  gantt.config.autosize = true;
  // 只读模式
  gantt.config.readonly = true;
  //是否显示左侧树表格
  gantt.config.show_grid = true;
  //表格列设置
  gantt.config.columns = [
    {
      name: "id",
      label: "编号",
      align: "center",
      tree: false,
      width: "50",
    },
    {
      name: "text",
      label: "计划名称",
      tree: true,
      width: "240",
    },
    {
      name: "start_date",
      label: "计划开始",
      align: "center",
      tree: false,
      width: "100",
    },
    {
      name: "end_date",
      label: "计划完成",
      align: "center",
      tree: false,
      width: "100",
    },
    {
      name: "sj_start_date",
      label: "实际开始",
      align: "center",
      tree: false,
      width: "100",
    },
    {
      name: "sj_end_date",
      label: "实际完成",
      align: "center",
      tree: false,
      width: "100",
    },
  ];
  gantt.config.subscales = [
    {
      unit: "day",
      step: 1,
      format: "%d日",
    },
  ];
  gantt.attachEvent("onGanttReady", function () {
    gantt.templates.tooltip_text = function (start: any, end: any, task: any) {
      return (
        task.toolTipsTxt +
        "<br/>" +
        "阶段:" +
        task.text +
        "<br/>" +
        gantt.templates.tooltip_date_format(start)
      );
    };
  });
  //任务条显示内容
  gantt.templates.task_text = function (start: any, end: any, task: any) {
    return (
      "<div style='text-align:center;color:#fff'>" +
      task.text +
      "(" +
      task.duration +
      "天)" +
      "</div>"
    );
  };
  //任务条上的文字大小 以及取消border自带样式
  gantt.templates.task_class = function (start: any, end: any, item: any) {
    return item.$level == 0 ? "firstLevelTask" : "secondLevelTask";
  };
  gantt.templates.timeline_cell_class = function (item: any, date: any) {
    if (date.getDay() == 0 || date.getDay() == 6) {
      return "weekend";
    }
  };
  gantt.config.layout = {
    //拖拽布局
    css: "gantt_container",
    rows: [
      {
        cols: [
          {
            view: "grid",
            id: "grid",
            scrollX: "scrollHor",
            scrollY: "scrollVer",
          },
          { resizer: true, width: 1 },
          {
            view: "timeline",
            id: "timeline",
            scrollX: "scrollHor",
            scrollY: "scrollVer",
          },
          { view: "scrollbar", scroll: "y", id: "scrollVer" },
        ],
      },
      { view: "scrollbar", scroll: "x", id: "scrollHor", height: 20 },
    ],
  };
  //时间轴图表中,任务条形图的高度
  //   gantt.config.task_height = 28;
  gantt.config.task_height = 16;
  gantt.config.row_height = 40;
  //时间轴图表中,甘特图的高度
  //   gantt.config.row_height = 36;
  //时间轴图表中,如果不设置,只有行边框,区分上下的任务,设置之后带有列的边框,整个时间轴变成格子状。
  gantt.config.show_task_cells = true;
  //当task的长度改变时,自动调整图表坐标轴区间用于适配task的长度
  gantt.config.fit_tasks = true;
  gantt.config.min_column_width = 40;
  gantt.config.auto_types = true;
  gantt.config.xml_date = "%Y-%m-%d";
  gantt.config.scale_unit = "month";
  gantt.config.step = 1;
  gantt.config.date_scale = "%Y年%M";
  gantt.config.start_on_monday = true;
  gantt.config.scale_height = 90;
  gantt.config.autoscroll = true;
  gantt.config.readonly = true;
  // gantt.i18n.setLocale("cn");
  gantt.attachEvent("onTaskLoading", function (task: any) {
    task.sj_start_date = gantt.date.parseDate(task.sj_start_date, "xml_date");
    task.sj_end_date = gantt.date.parseDate(task.sj_end_date, "xml_date");
    return true;
  });
  // 初始化
  gantt.init(proxy.$refs.gantt);
  // 数据解析
  gantt.parse(tasks.value);
  addTaskLayer();
});

// 渲染方法
function addTaskLayer() {
  gantt.addTaskLayer({
    renderer: {
      render: function draw_planned(task: any) {
        // console.log(task);
        if (task.sj_start_date && task.sj_end_date) {
          var sizes = gantt.getTaskPosition(
            task,
            task.sj_start_date,
            task.sj_end_date
          );
          // console.log(sizes);
          var el = document.createElement("div");
          el.className = "baseline";
          el.style.left = sizes.left + "px";
          el.style.width = sizes.width + "px";
          el.style.top = sizes.top + gantt.config.task_height + 17 + "px";
          // console.log(el);
          return el;
        }
        return false;
      },
      getRectangle: function (task: any, view: any) {
        if (task.start_date && task.end_date) {
          return gantt.getTaskPosition(task, task.start_date, task.end_date);
        }
        return null;
      },
    },
  });
}

// 切换日月周季
function setScaleConfig(value: any) {
  dayIndex.value = value;
  if (value == "1") {
    gantt.templates.timeline_cell_class = function (item: any, date: any) {
      if (date.getDay() == 0 || date.getDay() == 6) {
        return "weekend";
      }
    };
  } else {
    gantt.templates.timeline_cell_class = function (item: any, date: any) {
      if (date.getDay() == 0 || date.getDay() == 6) {
        return "";
      }
    };
  }
  switch (value) {
    case "1": //日
      gantt.config.xml_date = "%Y-%m-%d";
      gantt.config.scale_unit = "month";
      gantt.config.step = 1;
      gantt.config.date_scale = "%Y年%M";
      gantt.config.subscales = [
        {
          unit: "day",
          step: 1,
          date: "%d日",
        },
      ];
      gantt.render();
      break;
    case "2": //周
      gantt.config.scale_unit = "week";
      gantt.config.step = 1;
      gantt.config.date_scale = "%Y年%M";
      gantt.templates.date_scale = null;
      gantt.config.subscales = [
        {
          unit: "week",
          step: 1,
          date: "第%W周",
        },
        {
          unit: "day",
          step: 1,
          date: "%d日",
        },
      ];
      gantt.render();
      break;
    case "3": //月
      gantt.config.scale_unit = "month";
      gantt.config.step = 1;
      gantt.config.date_scale = "%Y年";
      gantt.templates.date_scale = null;
      gantt.config.subscales = [
        {
          unit: "month",
          step: 1,
          date: "%M",
        },
      ];
      gantt.render();
      break;
    case "4": //季
      gantt.config.scale_unit = "year";
      gantt.config.step = 1;
      gantt.config.date_scale = "%Y年";
      gantt.config.subscales = [
        {
          unit: "month",
          step: 1,
          date: "%M",
        },
        {
          unit: "quarter",
          step: 1,
          format: function (date: any) {
            var dateToStr = gantt.date.date_to_str("%M");
            var endDate = gantt.date.add(
              gantt.date.add(date, 3, "month"),
              -1,
              "day"
            );
            return dateToStr(date) + " - " + dateToStr(endDate);
          },
        },
      ];
      gantt.render();
      break;
  }
}
</script>

css样式

<style lang="scss" scoped>
@import "/public/static/dhtmlxgantt/dhtmlxgantt.css";

:deep(.gantt_task_line, .gantt_line_wrapper) {
  margin-top: -9px;
}

:deep(.gantt_task_line) {
  background-color: #3b97fe;
  border: #3b97fe;
  height: 15px !important;
  border-radius: 100px;
  border-radius: 100px;
}

:deep(.gantt_task_line) {
  margin-bottom: 10px !important;
}

:deep(.gantt_task_progress) {
  background: #ffd180;
  border-top-right-radius: 100px;
  border-radius: 100px;
}
:deep(.baseline) {
  position: absolute;
  border-radius: 100px;
  margin-top: -12px;
  height: 15px;
  background: #67dd23;
}
:deep(.gantt_grid_scale .gantt_grid_head_cell) {
  color: black !important;
}
:deep(.gantt_task .gantt_task_scale .gantt_scale_cell) {
  color: black !important;
}
:deep(.gantt_layout_cell) {
  ::-webkit-scrollbar {
    height: 8px;
  }
  ::-webkit-scrollbar-track {
    border-radius: 8px;
    background-color: #f5f5f5;
  }

  ::-webkit-scrollbar-thumb {
    border-radius: 8px;
    background-color: #b9b9b9;
  }
}

// 周末 区分
:deep(.weekend) {
  background: #f4f7f4;
}
:deep(.gantt_selected .weekend) {
  background: #f7eb91;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pytest+Yaml+Excel 接口自动化测试框架的实现示例

一、框架架构 二、项目目录结构 三、框架功能说明 解决痛点&#xff1a; 通过session会话方式&#xff0c;解决了登录之后cookie关联处理框架天然支持接口动态传参、关联灵活处理支持Excel、Yaml文件格式编写接口用例&#xff0c;通过简单配置框架自动读取并执行执行环境一键…

python3.5安装教程及环境配置,python3.7.2安装与配置

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python3.5安装教程及环境配置&#xff0c;python3.7.2安装与配置&#xff0c;现在让我们一起来看看吧&#xff01; python 从爬虫开始&#xff08;一&#xff09; Python 简介 首先简介一下Python和爬虫的关系与概念&am…

深度学习实战65-人脸检测模型LFFD的搭建,LFFD模型的架构与原理的详细介绍

大家好,我是微学AI,今天给大家介绍一下深度学习实战65-人脸检测模型LFFD的搭建,LFFD模型的架构与原理的详细介绍。LFFD(Light and Fast Face Detector)模型是一种用于人脸检测的深度学习模型,其设计旨在实现轻量级和快速的人脸检测。本文将详细介绍LFFD模型的定义、优点、原…

类人智能体概念、能力与衍生丨AI Agents闭门研讨观点集锦

导读 在智源社区举办的「青源Workshop第27期&#xff1a;AI Agents 闭门研讨会」上&#xff0c;来自英伟达的高级应用科学家王智琳、CAMEL一作李国豪、AutoAgents一作陈光耀&#xff0c;以及相关技术专家们共同参与交流讨论&#xff0c;分享了最新的研究成果&#xff0c;共同探…

人工麝香市场分析:中国市场年需求量超过15吨

人工麝香作为濒危动物药材麝香的替代品&#xff0c;等同天然麝香配方使用。 是国家重大科研成果和保密品种&#xff0c;用人工麝香生产中成药品种近400种&#xff0c;涵盖中成药常用剂型。 是珍稀动物药材代用品研究的重大突破&#xff0c;为其它珍稀动物药材的应用开辟了一条重…

金融量化交易:使用Python实现遗传算法

大家好&#xff0c;遗传算法是一种受自然选择过程启发的进化算法&#xff0c;用于寻找优化和搜索问题的近似解决方案。本文将使用Python来实现一个用于优化简单交易策略的遗传算法。 1.遗传算法简介 遗传算法是一类基于自然选择和遗传学原理的优化算法&#xff0c;其特别适用…

【方法】Excel表格的“限制保护”不想要了,如何取消?

我们知道&#xff0c;Excel表格可以设置“限制保护”&#xff0c;保护文件不被随意更改&#xff0c;那如果后续不需要保护了&#xff0c;如何取消呢&#xff1f; 下面小编来说说Excel表格常用的三种“保护”&#xff0c;是如何取消的。 第一种&#xff0c;Excel表格的工作表或…

第15章:随堂复习与企业真题(File类与IO流)

第15章&#xff1a;随堂复习与企业真题&#xff08;File类与IO流&#xff09; 一、随堂复习 1. File类的使用 File类的一个实例对应着磁盘上的一个文件或文件目录。 ----> “万事万物皆对象”&#xff08;熟悉&#xff09;File的实例化、常用的方法File类中只有新建、删除…

Unity 自定义窗口

放在Editor文件夹下&#xff1b; #if UNITY_EDITORusing System; using UnityEditor; using UnityEngine;namespace EditorCustumTool {/// <summary>/// 自定义窗口/// </summary>public class CustomWindow : EditorWindow{public enum FlagType{Flag1 101,Fl…

Qt内存管理、UI编辑器、客制化组件、弹出对话框、常用部件类

头文件的小技巧 #include <QtWidgets> // 在自动生成的 .h 里面加上此句 适用条件&#xff1a; QT 的内存管理 当父窗体被关闭时&#xff0c;子部件的内存会自动释放。 对象树是一种管理对象生命周期的机制。当一个对象被添加到另一个对象的子对象列表中时&#xff0…

Springboot+AOP+注解实现字段AES+Base64加解密

AOP实现AESBASE64加解密 场景如下&#xff1a; 需要对数据库存储的字段&#xff0c;进行加解密的处理。如果都直接写代码的话&#xff0c;那么代码回冗余很多&#xff0c;所以使用AOP注解去实现。让代码简洁&#xff0c;方便 具体实现如下&#xff1a; 1、依赖 <depende…

C语言搭建项目-学生管理系统(非链表)

、 目录 搭建offer.h文件 搭建offer.c中的main函数 密码登入系统 搭建my_oferr.c中的接口函数 使用帮助菜单接口函数 增加学生信息接口函数 查询学生信息接口函数 删除学生信息接口函数 保存学生信息接口 打开文件fopen 关闭文件fclose 判断是否保存文件fwrite 退出执行文件…

TCP传输层详解(计算机网络复习)

介绍&#xff1a;TCP/IP包含了一系列的协议&#xff0c;也叫TCP/IP协议族&#xff0c;简称TCP/IP。该协议族提供了点对点的连接机制&#xff0c;并将传输数据帧的封装、寻址、传输、路由以及接收方式都予以标准化 TCP/IP的分层模型 在讲TCP/IP协议之前&#xff0c;首先介绍一…

【MATLAB】tvfEMD信号分解+FFT+HHT组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 TVFEMDFFTHHT组合算法是一种结合了总体变分模态分解&#xff08;TVFEMD&#xff09;、傅里叶变换&#xff08;FFT&#xff09;和希尔伯特-黄变换&#xff08;HHT&#xff09;的信号分解方…

配置Smart Link负载分担示例

Smart Link和Monitor Link简介 定义 Smart Link&#xff0c;又叫做备份链路。一个Smart Link由两个接口组成&#xff0c;其中一个接口作为另一个的备份。Smart Link常用于双上行组网&#xff0c;提供可靠高效的备份和快速的切换机制。 Monitor Link是一种接口联动方案&#…

<习题集><LeetCode><链表><2/19/21/23/24>

目录 2. 两数相加 19. 删除链表的倒数第 N 个结点 21. 合并两个有序链表 23. 合并 K 个升序链表 24. 两两交换链表中的节点 2. 两数相加 https://leetcode.cn/problems/add-two-numbers/ public ListNode addTwoNumbers(ListNode l1, ListNode l2) {//head是cur链表头节点…

拼多多选品大作战:通过热词选利润赛道

相信很多人都听过一句话&#xff1a;找对了风口&#xff0c;猪都能飞起来。 我们电商人也应如此&#xff0c;从行业分析到选品都应快速跟上市场节奏。 今天就给大家分享一下如何通过热词来进行一个行业类目的分析与选择。 01 热词是什么 热词通常指的是热搜词和飙升词&#…

大华DSS S2-045 OGNL表达式注入漏洞复现

0x01 产品简介 大华DSS安防监控系统平台是一款集视频、报警、存储、管理于一体的综合安防解决方案。该平台支持多种接入方式,包括网络视频、模拟视频、数字视频、IP电话、对讲机等。此外,该平台还支持多种报警方式,包括移动侦测、区域入侵、越线报警、人员聚集等。 0x02 漏…

天津大数据培训机构品牌 数据分析师的发展方向

大数据专业还是有一定难度的&#xff0c;毕竟大数据开发技术所包含的编程技术知识是比较杂且多的如果是计算机专业的学生或者自身有一定基础的人学&#xff0c;相对来说会比较容易&#xff0c;但对于零基础小伙伴学习来说&#xff0c;想要学习大数据&#xff0c;难度还是很高的…

C# 编程新手必看,一站式学习网站,让你轻松掌握 C# 技能!

介绍&#xff1a;实际上&#xff0c;您可能弄错了&#xff0c;C#并不是一种独立的编程语言&#xff0c;而是一种由微软公司开发的面向对象的、运行于.NET Framework之上的高级程序设计语言。C#看起来与Java十分相似&#xff0c;但两者并不兼容。 C#的设计目标是简单、强大、类型…