vue2项目中使用dhtmlx gantt甘特图插件

官网示例地址:https://docs.dhtmlx.com/gantt/samples/
可以在这里查看绑定数据的格式


安装依赖

npm install dhtmlx-gantt --save 

创建一个甘特图组件

<template>
  <el-scrollbar ref="gantt_scrollbar" class="gantt-box">
    <div ref="gantt" class="gantt-container"></div>
  </el-scrollbar>
</template>

<script>
import { gantt } from 'dhtmlx-gantt';
import "dhtmlx-gantt/codebase/dhtmlxgantt.css"
export default {
	name: "gantt",
	props: {
		ganttTasks: {
			type: Array,
			default () {
				return []
			}
		}
	},
	data() {
		return {
			ganttData: []
		}
	},
	mounted() {
		this.initGantt() // gantt初始化配置
		this.getGanttData() // 数据format以及gantt reload
	},
	methods: {
		initGantt() {
			let _this = this
			// 在初始化前设置配置项

			// 初始化gantt
			gantt.init(this.$refs.gantt);
			// 绑定数据
			gantt.parse({
				data: [], // 时间轴上横条的数据
				link: [] // 连接线的数据
			});
		},
		reload() {
			gantt.clearAll();// 从甘特图中删除所有任务和其他元素(包括标记)
			gantt.parse({
				data: this.ganttData,
				link: []
			}); // 数据解析
			gantt.render(); // 呈现整个甘特图
		},
		getGanttData() {
			let ganttData = []
			// toDo
			// formatGanttData()
			this.ganttData = ganttData
			this.reload()
		}
	}
}
</script>

<style lang="less" scoped>
	/*@import "dhtmlx-gantt/codebase/dhtmlxgantt.css"*/
	.gantt-container {
		width: 10000px;
		height: 400px;
	}

.gantt-box {
	width: calc(100% - 10px);
	overflow-y: scroll;
	overflow-x: scroll;
	height: 400px;
}
</style>

到这里传入数据就可以显示甘特图啦


配置

gantt.init()

以下是需要在gantt.init前配置好的,放在initGantt()方法里

  • 设置甘特图只读
initGantt() {
	let _this = this
	// gantt只读
	gantt.config.readonly = true;
	
	// 初始化gantt
	gantt.init(this.$refs.gantt);
	// 绑定数据
	gantt.parse({
		data: [], // 时间轴上横条的数据
		link: [] // 连接线的数据
	});
},
  • 设置甘特图的row是否可以选中
gantt.config.select_task  = false;
  • 设置表格列宽自适应
gantt.config.autofit = false;
  • 设置日期格式
gantt.config.xml_date = "%Y/%m/%d";
  • 自定义表格列
    表格列的内容可以通过template返回
gantt.config.columns=[
	{
		name:"text", width: 160, label:"标题", align: "left", tree:true,
		template: function (obj) {
			// 通过 template 回调可以指定返回内容值
			return `
                <div class="gantt-span-${obj.taskType}" style="width:130px;text-overflow:ellipsis;overflow: hidden;">${obj.taskNum}  ${obj.text}</div>
              `;
		},
	}
];

这里要注意,数据有一些字段是必须保留的,包括:

id: stage.id, // id-gantt必填字段
text: stage.stageName, // 名称-gantt必填字段
start_date: stage.createDate.substring(0, 10), // 开始时间-gantt必填字段
duration: stage.duration, //工作时长-gantt必填字段

这里duration字段也可以用end_date代替

  • 添加自定义class,可以用来设置一些特定日期的样式
// 今日高亮
// 周末高亮
// 这里在时间轴表头添加class
var daysStyle = function(date){
	let todayDate = new Date().setHours(0,0,0,0)
	let paramsDate = new Date(date).setHours(0,0,0,0)
	if (todayDate === paramsDate) {
		return "today";
	}
	if (date.getDay() === 0 || date.getDay() === 6){
		return "weekend";
	}
	return "";
};
//这里在时间轴表格内的cell上添加class
gantt.templates.timeline_cell_class = function (item, date) {
	if (date.getDay() == 0 || date.getDay() == 6) {
		return "weekend"
	}
};

<style lang="less" scope>
/* 周末高亮 */
/deep/ .weekend {
	background: #F8F8F8;
	color: #999999!important;
	// height: 47px!important;
}
/* 今日高亮 */
/deep/ .gantt_task_scale {
	.gantt_scale_line > .gantt_scale_cell {
		color: #333333;
		&.today {
			background: #0066FF;
			color: #FFFFFF;
		}
	}
}
</style>
  • 设置时间轴多层表头
gantt.config.scales = [
	{unit: "month", step: 1, format: "%Y/%M"},
	{unit: "day", format: "%d", css:daysStyle}
];
  • 设置条形图里要显示的文字和自定义的class,实现文字、颜色等自定义
// 条形图里的文字
gantt.templates.task_text = function (start, end, task) {
	return `<span style='text-align:left;'>${task.text} # ${task.taskHolder}</span>`;
};
// 条形图自定义class
gantt.templates.task_class = function (start, end, task) {
	return `task-${task.taskType}-${task.status}`
};
  • 行高
gantt.config.scale_height = 60;
gantt.config.task_height = 24;
gantt.config.row_height = 48;
gantt.config.min_column_width = 50;
  • 添加今日标线
// 今日标线需要用到插件marker
// gantt需要用到的插件
gantt.plugins({
	marker: true,
});
let today = new Date();
gantt.addMarker({
	start_date: today,
	css: 'today',
	text: '',
});
  • 添加tooltip
gantt.plugins({
	tooltip: true
});
// 自定义tooltip内容
gantt.templates.tooltip_text = function (start, end, task) {
	const t = gantt;
	const output = `<div style="font-size:14px;padding: 0 10px;width:250px;line-height:20px;white-space:normal;">
		<p style="font-weight:bold;margin: 8px 0;">${task.text}</p>
		<p style="margin: 4px 0;">当前进度:${task.progress*100}%</p>
		<p style="margin: 4px 0;">标准工时:${task.standardTime}</p>
		<p style="margin: 4px 0;">实际工时:${task.actualTime}</p>
		<p style="margin: 4px 0;">工作状态:${task.statusText}</p>
	</div>`;
	return output;
}
  • 设置表头显示中文
gantt.i18n.setLocale("cn");
  • 树形是否自动展开
gantt.config.open_tree_initially = false;
  • 自定义的点击事件
gantt.attachEvent("onTaskClick", function(id,e){
	let box = document.querySelector('.gantt_tooltip');
	if (box) {
		box.parentNode.removeChild(box);
	}
	let classList = e.target.className.split(' ')
	// 这里自定义了展开/收起树形的点击事件
	if (classList.includes('gantt_open')) {
		gantt.open(id); // 展开
		return true
	}
	if (classList.includes('gantt_close')) {
		gantt.close(id); // 收起
		return true
	}
	// 这里是其他的点击事件
	let task = _this.ganttData.find(item => {return item.id == id})
	if (task.taskType === 'stage') {
		// toDo()
		return true
	}
});

gantt.render()

这里因为我的数据需要异步请求格式化,这是gantt已经初始化了,所以需要使用gantt.render()重新渲染
在gantt重新render前,要清除缓存
这里会把一些配置项也清掉,比如今日标线

reload() {
	gantt.clearAll();// 从甘特图中删除所有任务和其他元素(包括标记)
	gantt.parse({
		data: this.ganttData,
		link: []
	}); // 数据解析
	// 今日标线
	let today = new Date();
	gantt.addMarker({
		start_date: today,
		css: 'today',
		text: '',
	});
	gantt.render(); // 呈现整个甘特图
},

style

  • 去掉树形的文件夹图标
/* 去掉文件夹图标 */
/deep/ .gantt_tree_icon {
	&.gantt_folder_closed, &.gantt_file, &.gantt_folder_open {
		display:none
	}
}
/* 把展开收起图标替换成element-ui的icon */
/* 这里没有找到在js中配置图标的方法,为省事,使用css */
/* 扒了element-ui的icon样式表 */
/deep/ .gantt_tree_icon.gantt_open {
	background-image: none;
	font-family: element-icons!important;
	speak: none;
	font-style: normal;
	font-weight: 400;
	font-variant: normal;
	text-transform: none;
	vertical-align: baseline;
	display: inline-block;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	&::before {
		content: "\e6df";
	}
}
/deep/ .gantt_tree_icon.gantt_close {
	background-image: none;
	font-family: element-icons!important;
	speak: none;
	font-style: normal;
	font-weight: 400;
	font-variant: normal;
	text-transform: none;
	vertical-align: baseline;
	display: inline-block;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	&::before {
		content: "\e6e1";
	}
}

实现的效果

image

posted @   葱花粉丝  阅读(5530)  评论(5编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
点击右上角即可分享
微信分享提示