在vue中展示自定義列名的甘特圖

輕嘆年華逝,發表於2020-11-16

  • 今天分享一篇關於檢視任務的甘特圖的文章
  • 首先,用的外掛是dhtmlx-gantt,官網地址https://docs.dhtmlx.com/gantt/
    官網的Getting started模組是檢視甘特圖的各種配置

第一步下載

npm install dhtmlx-gantt --save 或者 yarn add dhtmlx-gantt

接下來是具體程式碼詳細說明

一、子元件模板

<template>
  <div ref="gantt" style="width:100%;height:550px"></div>
</template>

二、需要引入的元件

import "dhtmlx-gantt";
import "dhtmlx-gantt/codebase/locale/locale_cn.js";
import "dhtmlx-gantt/codebase/ext/dhtmlxgantt_marker.js";
import "dhtmlx-gantt/codebase/ext/dhtmlxgantt_tooltip.js";

三、需要在mounted定義相關格式

①設定日期格式

gantt.config.date_format = "%Y-%m-%d %H:%i:%s"; //  設定日期格式
gantt.config.readonly = true;   //只讀模式
gantt.config.duration_unit = "day"; // minute, day, month

②顯示操作按鈕

var colHeader = '<div class="gantt_grid_head_cell gantt_grid_head_add" οnclick="gantt.createTask()"></div>'
// 按鈕
var colContent = function (task) {
return  ('<div class="fa gantt_button_grid gantt_grid_edit fa-pencil" οnclick="clickGridButton(' + task.id + ', \'edit\')"></div>' +
	'<div class="fa gantt_button_grid gantt_grid_add fa-plus" οnclick="clickGridButton(' + task.id + ', \'add\')"></div>' +
	'<div class="fa gantt_button_grid gantt_grid_delete fa-times" οnclick="clickGridButton(' + task.id + ', \'delete\')"></div>');
};

③日期列顯示

第一種寫法

gantt.config.min_column_width = 60;
gantt.config.scale_height = 30 * 2;
gantt.config.scales = [
  { unit: "year", step: 1, format: "%Y" },
  { unit: "month", step: 1, format: "%M" },
  {unit:"week",step:1,format:"%W"},
];

第二種寫法

var weekScaleTemplate = function(date){
    var dateToStr = gantt.date.date_to_str("%M %d");
    var weekNum = gantt.date.date_to_str("(%W周)");
    var endDate = gantt.date.add(gantt.date.add(date,1,"week"), - 1,"day");
    return dateToStr(date)+" - "+ dateToStr(endDate)+""+ weekNum(date);
};

gantt.config.subscales = [{
    unit:"month",
    step:1,
    date:"%F,%Y"
},{
    unit:"week",
    step:1,
    template:weekScaleTemplate
}];

如果對週末進行區分

gantt.templates.timeline_cell_class = function(item,date){
    if(date.getDay()== 0 || date.getDay()== 6){
        return 'weekend';
    }
};

④顯示的列配置

name:繫結資料的名稱;align:對齊方式;label:顯示在表頭的名稱

gantt.config.columns = [
    {name: "text", tree: true,align: "left", resize: true,width: 150,label:'任務名稱'},
    {name: "start_date", align: "center", resize: true,width:100,label:'計劃開始時間'},
    {name: "end_date", align: "center", resize: true,width: 100,label:'計劃結束時間'},
    {name: "cap_actl_start", align: "center", resize: true,width:100,label:'實際開始時間'},
    {name: "cap_actl_end", align: "center", resize: true,width: 100,label:'實際結束時間'},
    {name: "schedule_company_duty_name", align: "center", resize: true,width: 100,label:'負責單位'},
    {name: "schedule_user_duty_name", align: "center", resize: true,width: 100,label:'負責人'},
    {name: "schedule_task_deviation_days", align: "center", resize: true,width: 100,label:'偏差天數'},
    {name: "status", align: "center", resize: true,width: 100,label:'任務狀態'},
    {name: "duration", align: "center",width: 100,label:'持續時間'},
];

注:如果不對甘特圖原始碼的配置進行更改,不會顯示這麼多列,如何配置會在下文提及

⑤左右容器分別有滾動條

gantt.config.layout = {
  css: "gantt_container",
  cols: [
    {
      width:400,
      min_width: 300,
      rows:[
        {view: "grid", scrollX: "gridScroll", scrollable: true, scrollY: "scrollVer"},
        {view: "scrollbar", id: "gridScroll", group:"horizontal"}
      ]
    },
    {resizer: true, width: 1},
    {
      rows:[
        {view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
        {view: "scrollbar", id: "scrollHor", group:"horizontal"}
      ]
    },
    {view: "scrollbar", id: "scrollVer"}
  ]
};

⑥task 內容文字

gantt.templates.task_text = function(start, end, task) {
    // console.log(start,"start")
    // console.log(end,"end")
  if (task.start_date != undefined)
    return ("<b>任務名稱:</b> " + task.text + " (" + task.progress + "%)");
  else
    return ("<b>" + task.text + "</b> ");
};

⑦task 文字懸浮顯示

const that = this
gantt.templates.tooltip_text = function(start, end, task) {
   if (task.start_date != undefined){
     return (
       "<b>任務名稱:</b> " + task.text + 
       "<br/><b>計劃開始時間:</b> " + (task.start_date?that.$moment(task.start_date).format('YYYY-MM-DD'):'無') + 
       "<br/><b>計劃結束時間:</b> " + (task.end_date?that.$moment(task.end_date).format('YYYY-MM-DD'):'無') + 
       "<br/><b>進度:</b> " + task.progress + "%" +
       "<br/><b>實際開始時間:</b> " + (task.cap_actl_start?that.$moment(task.cap_actl_start).format('YYYY-MM-DD'):'無') + 
       "<br/><b>實際結束時間:</b> " + (task.cap_actl_end?that.$moment(task.cap_actl_end).format('YYYY-MM-DD'):'無') +
       "<br/><b>偏差天數:</b> " + (task.schedule_task_deviation_days? task.schedule_task_deviation_days :'無') + 
       "<br/><b>任務狀態:</b> " + task.status
     );
   }
   else {
     return (
       "<b>任務名稱:</b> " + task.text
     );
}

最後初始化甘特圖

 this.addTodayLine();
 gantt.config.fit_tasks = true;   //當task的長度改變時,自動調整圖表座標軸區間用於適配task的長度
 gantt.config.tooltip_hide_timeout = 0;  //設定當滑鼠離開任務後,懸浮框tooltip還會顯示多長時間(ms)才關閉。
 gantt.init(this.$refs.gantt);
 gantt.parse(this.$props.tasks);

四、在methods定義的方法

 // 過載gantt圖
 reload() {
   gantt.clearAll();
   this.addTodayLine();
   gantt.parse(this.$props.tasks);
   gantt.render();
 },

 // 時間線
 addTodayLine() {
   var date_to_str = gantt.date.date_to_str(gantt.config.task_date);
   var today = new Date();
   gantt.addMarker({
     start_date: today,
     css: "today",
     text: "今天",
     title: "今天: " + date_to_str(today)
   });
 }
},

然後是甘特圖的樣式

<style lang="less" scoped>
	@import "~dhtmlx-gantt/codebase/dhtmlxgantt.css";
  	// 操作按鈕樣式
    .fa {
		cursor: pointer;
		font-size: 14px;
		text-align: center;
		opacity: 0.2;
		padding: 5px;
	}
	.fa:hover {
		opacity: 1;
	}
	.fa-pencil {
		color: #ffa011;
	}
	.fa-plus {
		color: #328EA0;
	}
	.fa-times {
     color: red;
   }
   
   // 週末樣式
   .weekend {
       background:#f4f7f4;
   }
   .gantt_selected .weekend {
       background:#f7eb91;
   }
</style>

五、更改dhtmlgantt.js的columns列配置

在下載的dhtml-gantt的包下有codebase的資料夾,這個資料夾下的dhtmlgantt.js是壓縮過得,將其解壓縮之後,大概在14000行左右找到columns列配置,就想如下的程式碼片段

columns: [
    { name: "text", tree: true, width: "*", resize: true },
    { name: "start_date", align: "center", resize: true },
    { name: "duration", align: "center" },
    { name: "add", width: 44 }
],

如果想展示自己所需要的欄位名,只需在這裡新增相應的物件

columns: [{
	name: "text",
	tree: !0,
	width: "*",
	resize: !0
}, {
	name: "start_date",
	align: "center",
	resize: !0
}, {
	name: "duration",
	align: "center"
}, {
	name: "cap_actl_start",
	align: "center"
}, {
	name: "cap_actl_end",
	align: "center"
}, {
	name: "schedule_company_duty_name",
	align: "center"
}, {
	name: "schedule_user_duty_name",
	align: "center"
}, {
	name: "schedule_task_deviation_days",
	align: "center"
}, {
	name: "status",
	align: "center"
}, {
	name: "add",
	width: 44
}],

最後只需要在父元件中獲取到資料之後過載甘特圖即可

if(this.$refs.ganttchart){
    this.$refs.ganttchart.reload(); // 重新重新整理gantt圖
}

最後給大家推薦一篇超詳細的gantt圖配置文章

超詳細的甘特圖配置

相關文章