最近接到需要在页面中引入甘特图,经过多方对比插件
甘特图1
1.Gantt-elastic:一个基于HTML和CSS的甘特图插件,具有自适应布局和触摸屏支持。
2.jsgantt-improved:一个基于JavaScript的甘特图插件,具有灵活的配置选项,支持任务链和资源分配。
3.dhtmlxGantt:一个功能丰富的甘特图插件,支持任务编辑,资源分配和多种视图模式。
4.jQuery Gantt Chart:一个基于jQuery的甘特图插件,支持日期范围选择和任务进度跟踪。
5.FusionCharts Gantt:一个基于图表库FusionCharts的甘特图插件,支持动态数据更新和多种视图模式。
甘特图2
1.vue-gantt-schedule-timeline:一个基于Vue.js的甘特图插件,支持时间轴和事件编辑。
2.vue-gantt:一个基于Vue.js的甘特图插件,支持动态数据更新和任务进度跟踪。
3.vue-dhtmlx-gantt:一个基于dhtmlxGantt的Vue.js甘特图插件,支持任务编辑,资源分配和多种视图模式。
4.vue-fusioncharts-gantt:一个基于FusionCharts Gantt的Vue.js甘特图插件,支持动态数据更新和多种视图模式。

最后选择了 dhtmlxGantt
效果图如下:
在这里插入图片描述

因为官方文档全部是英文,所以经过多方查证,总结一下文档中API的用法:

一. 在 Vue 中使用 dhtmlxGantt 组件时,gantt.parse中各个参数代表的意思是什么

gantt.parse() 方法是用于将数据解析为 Gantt 图表的方法。它接受一个包含任务和链接数据的对象作为参数。该对象包含以下属性:

data: 任务数据数组,包含每个任务的信息,例如 id、text、start_date、duration 等等。
links: 链接数据数组,包含每个链接的信息,例如 id、source、target 等等。
key: 任务数据对象中唯一标识每个任务的属性名称,默认为 "id"parent: 任务数据对象中用于标识父任务的属性名称,默认为 "parent".
open_tree_initially: 布尔值,如果设置为 true,则所有任务默认展开。
preserve_links: 布尔值,如果设置为 true,则链接信息中的任务不存在时也会保留链接。
preserve_tasks: 布尔值,如果设置为 true,则链接信息中的任务不存在时也会保留任务。

例如,可以使用以下代码将数据解析为 Gantt 图表:

const data = [
  { id: 1, text: "Task 1", start_date: "2023-03-15", duration: 3 },
  { id: 2, text: "Task 2", start_date: "2023-03-18", duration: 2, parent: 1 },
];
/*
gantt.parse 方法中的 data 参数是一个包含任务信息的数组。每个任务都包含多个字段,下面是一些常用的字段及其作用:
id: 任务的唯一标识符。
text: 任务的名称。
start_date: 任务的开始日期,可以是一个字符串或者一个 Date 对象。
end_date: 任务的结束日期,可以是一个字符串或者一个 Date 对象。
duration: 任务的持续时间,以天为单位。如果 end_date 和 duration 都提供了,duration 会被忽略。
progress: 任务的进度,以百分比表示。
parent: 父任务的 id,如果当前任务是顶级任务,则该字段为 0。
open: 是否展开当前任务的子任务。如果不提供,默认为 true。
state: 用于设置任务的状态。状态可以是任何自定义值,例如 "in progress"、"completed"、"cancelled" 等等。在 Gantt 图中,任务的状态可以通过任务条颜色、边框、文本样式等 visulization 属性进行自定义渲染,以便用户更直观地了解任务状态的变化。可以在 Gantt 文档中的 Visualization 属性部分了解有关自定义任务状态可视化的更多信息。
除了上面列出的常用字段之外,还有很多其他可选字段,例如 color、link、type 等,可以根据实际需求来添加。
*/

const links = [
  { id: 1, source: 1, target: 2, type: "0" },
];

gantt.parse({
  data: data,
  links: links,
});
//其中,data 数组包含两个任务,links 数组包含一个链接,最后将这些数据传递给 gantt.parse() 方法进行解析,即可在 Gantt 图表中显示这些任务和链接。

二. 在月刻度下需要从1号开始显示到月底最后一天应该怎么显示,直接上代码

//设置 scale_unit 属性为 month,以显示月刻度
gantt.config.scale_unit = "month";
//设置 step 属性为 1,以每个月显示一个刻度
gantt.config.step = 1;
//设置 date_scale 属性为 %Y-%m-%d,以显示年月日格式的刻度
gantt.config.date_scale = "%Y-%m-%d";
//设置 scale_date 属性为 gantt.date.monthStart,以从每个月的第一天开始显示刻度。
gantt.config.scale_date = gantt.date.monthStart;
//设置 subscale 属性为一个包含两个刻度的对象,分别为 day 和 week。
gantt.config.subscales = [
  { unit: "day", step: 1, date: "%d" },
  { unit: "week", step: 1, date: "#%W" }
];

三. 显示展示今日、项目开始和结束标示线

如果需要使用标示线的功能,需要引入 dhtmlxgantt_marker.js,这样才能通过 gantt.addMarker 方法为一些重要日期的增加标示:
不然会报这个错:
Error in mounted hook: "TypeError: _dhtmlxGantt.default.addMarker is not a function"
完整代码如下:

import 'dhtmlx-gantt/codebase/ext/dhtmlxgantt_marker.js';//标识线
...
 	  //显示当天刻度线
      gantt.addMarker({
        start_date: new Date(),
        css: "today",//today样式class为自带,其他的时间标识线需要自己定义class
        text: "今天",
        title: "今天: "
      });
...

四. 两个都有甘特图的页面相互跳转的时候,因为没有销毁组件,导致甘特图会发生混乱,需要在组建销毁前或者页面跳转前进行数据清除销毁,

可以利用两个函数:beforeDestroy 或者 beforeRouteLeave

需要用到dhtmlx的 API 中的 gantt.clearAll()gantt.destructor()

a. gantt.clearAll()方法用于清空 Gantt 数据以及视图中的所有任务。它没有参数。使用这个方法可以在重新加载新数据时清除所有现有数据和视图。
b. gantt.destructor()方法用于完全销毁 Gantt 实例及其依赖项,释放所有内存。它没有参数。使用此方法会导致 Gantt 实例无法再次使用,需要重新创建一个新的 Gantt 实例。

完整代码如下:

//beforeDestroy写法
 beforeDestroy() {
    gantt.clearAll();
    gantt.destructor();
  },
  ...
  //beforeRouteLeave写法
  beforeRouteLeave(to, from, next) {
  // 销毁 dhtmlxGantt 组件
  if (this.gantt) {
  	this.gantt.clearAll();
    this.gantt.destructor();
    this.gantt = null;
  }
  next();
}

⚠️注意:如果是以子组件的方式引入使用的,在使用 beforeRouteLeave 时发现没有生效,那是因为 vue 生命周期导致的,此时需要使用 beforeDestroy

五、给任务加单击事件的时候会触发多次

这是为什么呢?可能是因为多次挂载了单击事件
最后我是直接在 mounted 里面去挂载

 mounted() {
    if (gantt){
      gantt.attachEvent("onTaskClick", (taskId,event)=>{
        event.stopPropagation(); // 阻止事件冒泡
      }, {once: true});
    }
  },

六、缩小单元格宽度

原来比较宽,会有一个默认值
在这里插入图片描述
后面通过 API 查到有个属性 gantt.config.min_column_width

gantt.config.min_column_width = 30;//单元格宽度设置

七、单元格样式自定义,比如字体颜色或者背景颜色

 // 在时间线上增加一行显示日
      gantt.config.subscales = [
        { unit: 'day', step: 1, format: '%d', css: function(date) {
        	//定义个class类
            return "self-style";
          }}
      ]
 ...
 .self-style{
  background: #0bb051;
  color: #fff !important;
}

效果如下:
在这里插入图片描述

八、默认显示指定月份或者年份

  1. 显示指定月份
 // 只显示当前月份数据
 // const date = new Date();
  this.currentDate = dayjs().format('YYYY-MM')
  let date= this.currentDate.split('-')
  let firstDay,lastDay
  if(this.currentDate){
    // 获取当前月份的第一天和最后一天
     firstDay = dayjs(`${Number(date[0])}-${Number(date[1])}-01`);
     lastDay = firstDay.endOf('month');
  }
  gantt.config.start_date = firstDay.format('YYYY-MM-DD')
  gantt.config.end_date =  lastDay.format('YYYY-MM-DD')
  gantt.render();

补充:通过左右箭头切换上下月份

	prevMonth() {
      // 获取上个月份
      const lastMonth = dayjs(this.currentDate,'YYYY-MM').subtract(1, 'month').format('YYYY-MM')
      this.currentDate = lastMonth
      gantt.clearAll();
      //this.getMonthGanttChartList(),获取数据
    },
    nextMonth() {
      const nextMonth = dayjs(this.currentDate,'YYYY-MM').add(1, 'month').format('YYYY-MM')
      this.currentDate = nextMonth
      gantt.clearAll();
       //this.getMonthGanttChartList(),获取数据
    },
  1. 显示指定年份
// 默认只显示当前年份数据
const date = new Date();
 const startDate = new Date(date.getFullYear(), 0, 1);
 const endDate = new Date(date.getFullYear() + 1, 0, 0);
 gantt.config.start_date = startDate;
 gantt.config.end_date = endDate;
 gantt.render();

九、给任务条添加圆角样式

	gantt.templates.task_class = function (start, end, task) {
        let css = "";
        if (task.$source === "auto") {
          css += "gantt_auto_task ";
        }
        if (task.color) {
          css += "gantt_task_color_" + task.color + " ";
        }
        css += "gantt_task_rounded_corners"; // 添加圆角样式
        return css;
      };
      ...
      //css
      .gantt_task_rounded_corners.gantt_task_line,
		.gantt_task_rounded_corners.gantt_task_content {
		  border-radius: 8px; /* 添加圆角 */
		}

上述问题需要引入的包:

import gantt from 'dhtmlx-gantt'  // 引入模块
import 'dhtmlx-gantt/codebase/ext/dhtmlxgantt_marker.js';//标识线
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'//任务栏悬浮显示

在这里插入图片描述

参考资料:
官方例子
查看官方文档

Logo

前往低代码交流专区

更多推荐