- 首先把 gantt 官网下载的相关文件放入 resource 文件中。
下载地址:https://dhtmlx.com/docs/products/dhtmlxGantt/download.shtml
- 在html文件中引入
- 创建一个gantt components,此框架是vue3 + ts + ant design。
<template>
<div ref="ganttRef"></div>
</template>
<script>
import { defineComponent, ref, computed, unref, toRaw, onMounted, render } from 'vue';
import { useMessage } from '/@/hooks/web/useMessage';
export default defineComponent({
name: 'Gantt',
props: {
tasks: {
type: Object,
default() {
return { data: [], links: [] };
},
},
columns: {
type: Array,
default() {
return [];
},
},
},
emits: [],
setup(props, { attrs, emit, slots }) {
const ganttRef = ref(null);
const { createMessage, notification } = useMessage();
onMounted(() => {
console.log('渲染===================>');
initGanttEvents();
// gantt.config.readonly = true; // 激活甘特图的只读模式
// gantt.config.cascade_delete = false; // 嵌套任务的级联删除
// gantt.config.keep_grid_width = true; // 要在调整列大小期间保留网格的大小,请将keep_grid_width选项设置为true
gantt.config.drag_resize = true; //允许用户通过拖拽任务的条形图的两端来改变工期
gantt.config.drag_move = true; //允许用户拖动条形图来改变位置
gantt.config.drag_progress = true; // 允许用户推拽条形图上用来调整进度百分比的小按钮
gantt.config.xml_date = '%Y-%m-%d';
// gantt.config.columns = props.columns;
// 重绘操作
// gantt.refreshData();
gantt.config.duration_unit = 'day'; //工期计算的基本单位 hour
gantt.config.duration_step = 1; //工期计算的倍数
gantt.config.work_time = true; // 允许在工作时间而不是日历时间计算任务的持续时间
// gantt.config.scale_height = 28 * 3; //设置甘特图的表头高度
// 改变布局
setLayoutConfig('gridAndTimeLine');
// 改变时间
setScaleConfig('day');
gantt.config.row_height = 44;
gantt.config.show_links = true; //允许显示鼠标移动到进度条上时显示前后两个小圆点(是否显示依赖连线)
gantt.i18n.setLocale('cn'); //本地化
gantt.config.redo = true; // 重做功能
gantt.config.undo = true; // 撤销功能
gantt.config.multiselect = true; // 多选
/**
* https://docs.dhtmlx.com/gantt/desktop__undo_redo.html
* 想要撤回在甘特图中做出的修改,调用undo方法即可: gantt.undo();
* 获取储存的undo命令,使用getUndoStack方法即可:var stack = gantt.getUndoStack(); 返回值都是命令对象的数组
*
* 想要重做在甘特图中做出的修改,调用redo方法即可:gantt.redo();
* 获取储存的redo命令,使用getRedoStack方法即可:var stack = gantt.getRedoStack(); 返回值都是命令对象的数组
*/
gantt.plugins({
// 启用全屏插件
fullscreen: true,
// 启用撤销插件
undo: true,
// 启用tooltip
// tooltip: true,
multiselect: true,
// 标记
marker: true,
// 自动调度
// auto_scheduling: true,
});
// gantt.config.auto_scheduling = true;
// gantt.config.auto_scheduling_strict = true;
// gantt.config.auto_scheduling_compatibility = true;
// 允许在出现意外行为时显示错误警报
gantt.config.show_errors = false;
// 自动扩展时间刻度以适应所有显示的任务
gantt.config.fit_tasks = true;
// 双击task时,弹出lightbox弹出框
gantt.config.details_on_dblclick = false;
// 设置工具提示隐藏之前的时间长度,以毫秒为单位
// gantt.config.tooltip_hide_timeout = 5000;
// 指定将应用于时间轴区域行的 CSS 类
gantt.templates.task_row_class = function (start, end, task) {
// console.log('task_row_class', task);
let style = '';
if (task.type == 'project') {
style = 'row_project';
} else {
style = 'row_task';
}
return 'gantt_row_demo ' + style;
};
// 指定将应用于用户拖动链接时出现的弹出窗口的 CSS 类
gantt.templates.drag_link_class = function (from, from_start, to, to_start) {
// console.log(from, from_start, to, to_start);
let add = '';
if (from && to) {
let allowed = gantt.isLinkAllowed(from, to, from_start, to_start);
add = ' ' + (allowed ? 'gantt_link_allow' : 'gantt_link_deny');
}
return 'gantt_link_tooltip' + add;
};
// 指定将应用于链接的 CSS 类
gantt.templates.link_class = function (link) {
// console.log('link_class', link);
return 'line_task_tofflon';
};
// gantt.config.undo_actions = {
// update: 'update',
// remove: 'remove', // remove an item from datastore
// add: 'add',
// };
gantt.config.undo_steps = 10; //要定义可以还原的步骤数
/*gantt.templates.timeline_cell_class = function (item, date) {
if (date.getDay() == 0 || date.getDay() == 6) {
return 'weekend';
}
};*/
// gantt.clearAll(); //清空数据
// gantt.render();
gantt.init(unref(ganttRef));
initDataProcessor();
});
// 动态修改布局
function setLayoutConfig(level) {
console.log(level);
switch (level) {
case 'gridAndTimeLine':
// 布局
//展示配置滚动条
gantt.config.layout = {
css: 'gantt_container',
cols: [
{
width: 720,
rows: [
{
view: 'grid',
scrollX: 'gridScroll',
// scrollable: true,
scrollY: 'scrollVer',
},
{ view: 'scrollbar', id: 'gridScroll', group: 'horizontal' },
],
// gravity: 2
},
{ resizer: true, width: 1 },
{
rows: [
{ view: 'timeline', scrollX: 'scrollHor', scrollY: 'scrollVer' },
{ view: 'scrollbar', id: 'scrollHor', group: 'horizontal' },
],
},
{ view: 'scrollbar', id: 'scrollVer' },
],
};
gantt.resetLayout();
gantt.render();
break;
case 'grid':
// 布局
gantt.config.layout = {
css: 'gantt_container',
rows: [
{
cols: [
{
// 默认任务列表
view: 'grid',
scrollX: 'scrollHor',
scrollY: 'scrollVer',
},
{
view: 'scrollbar',
id: 'scrollVer',
},
],
},
{
view: 'scrollbar',
id: 'scrollHor',
},
],
};
gantt.resetLayout();
gantt.render();
break;
case 'timeLine':
// 布局
gantt.config.layout = {
css: 'gantt_container',
rows: [
{
cols: [
{
// 默认甘特图(时间线)
view: 'timeline',
scrollX: 'scrollHor',
scrollY: 'scrollVer',
},
{
view: 'scrollbar',
id: 'scrollVer',
},
],
},
{
view: 'scrollbar',
id: 'scrollHor',
},
],
};
gantt.resetLayout();
gantt.render();
break;
}
}
// 动态设置Scale
function setScaleConfig(level) {
console.log(level);
const weekScaleTemplate = function (date) {
const dateToStr = gantt.date.date_to_str('%M-%d日');
const weekNum = gantt.date.date_to_str('(%W周)');
const endDate = gantt.date.add(gantt.date.add(date, 1, 'week'), -1, 'day');
return dateToStr(date) + '~' + dateToStr(endDate) + '' + weekNum(date);
};
switch (level) {
case 'day':
gantt.config.scale_height = 28 * 4;
gantt.config.subscales = [
{
unit: 'year',
step: 1,
date: '%Y年',
},
{
unit: 'month',
step: 1,
date: '%F',
},
{
unit: 'week',
step: 1,
template: weekScaleTemplate,
},
];
gantt.config.scale_unit = 'day';
gantt.config.date_scale = '周%D,%d日';
gantt.render();
break;
case 'week':
gantt.config.subscales = [
{
unit: 'year',
step: 1,
date: '%Y年',
},
{
unit: 'week',
step: 1,
template: weekScaleTemplate,
},
];
gantt.config.scale_height = 28 * 3;
gantt.config.scale_unit = 'month';
gantt.config.date_scale = '%F';
gantt.render();
break;
case 'month':
gantt.config.subscales = [
{
unit: 'year',
step: 1,
date: '%Y年',
},
];
gantt.config.scale_unit = 'month';
gantt.config.date_scale = '%F';
gantt.config.scale_height = 28 * 2;
gantt.render();
break;
case 'year':
gantt.config.subscales = [];
gantt.config.scale_unit = 'year';
gantt.config.date_scale = '%Y年';
gantt.config.scale_height = 28 * 2;
gantt.render();
break;
}
}
function initGanttEvents() {
console.log(gantt.$_eventsInitialized);
if (!gantt.$_eventsInitialized) {
// 当用户双击链接时触发
gantt.attachEvent('onLinkDblClick', function (id, e) {
console.log('onLinkDblClick', id, e);
//any custom logic here
return true;
});
// 在用户删除链接前触发
gantt.attachEvent('onBeforeLinkDelete', function (id, item) {
return true;
});
gantt.$_eventsInitialized = true;
}
}
function initDataProcessor() {
if (!gantt.$_dataProcessorInitialized) {
gantt.$_dataProcessorInitialized = true;
}
}
return { ganttRef, gantt, setScaleConfig, setLayoutConfig };
},
});
</script>