vue3+DHTMLX实现项目计划甘特图展示
·
由于在做公司项目时,车间要对生产的项目计划进行编制,根据自身需求我了解相关技术和自身业务需求,最终选择DHTMLX的gantt组件来实现计划的编排和修改等。
我们公司项目采用VUE3技术,前端实现计划的编排,修改等功能;创建计划节点可以上移、下移、复制、前进、后退等操作;最后效果

1、DHTMLX相关资料学习
1.1 api学习,里面api挺多的,支持搜索大家可以根据自己的需求进行学习
1.2 官方给的一些demo,大家可以学习参考
2、具体实现逻辑
首先根据api配置gantt图展示的属性,下面主要是我用到的配置项:
const getGanttInfo = () => {
// 清空之前的配置
gantt.clearAll();
// 配置基本属性
gantt.config.readonly = true// 是否只读
gantt.attachEvent("onTaskDblClick", function (id, e) { return false }); // 禁止点击进行弹窗
gantt.templates.grid_row_class = function (start, end, task) {
return gantt.hasChild(task.id) ? "gantt_parent_row" : "";
};
gantt.attachEvent("onGanttScroll", function (left, top) {
if (top === 0) {
return false
} else {
scrollTop.value = top
}
});
gantt.attachEvent("onTaskOpened", function (id) {
openTasks.value.push(id)
});
gantt.attachEvent("onTaskClosed", function (id) {
openTasks.value.map((item, index) => {
if (item == id) {
openTasks.value.splice(index, 1)
}
})
});
gantt.i18n.setLocale('cn'); // 设置 Gantt 图的界面语言为中文
gantt.config.show_grid = true; // 显示 Gantt 图中的网格线
gantt.config.grid_width = 900;
gantt.config.show_unscheduled = false;
gantt.config.grid_elastic_columns = true;
gantt.config.details_on_create = false; // 点击+时关闭灯箱弹窗
gantt.config.fit_tasks = true; // 自动延长时间刻度
// 配置外部渲染,使用onrender时的渲染方式
gantt.config.external_render = {
isElement: (element) => {
return isValidVNode(element);
},
renderElement: (element, container) => {
render(element, container);
},
};
// 配置刻度单位
setUnit(props.editType); // 甘特图刻度配置
gantt.config.duration_unit = props.editType;
if (props.editType === 'day') {
gantt.config.time_step = 10; // 时间轴上的每个刻度间隔为 10 天
}
gantt.config.step = 1; // 设置步长为 1
gantt.config.scale_height = 28 * 3; // 甘特图的时间刻度高度
gantt.config.min_column_width = 16;
gantt.config.duration_step = 1; // 任务持续时间步长
gantt.config.redo = true; // 重做功能
gantt.config.undo = true; // 启用撤销功能
gantt.config.order_branch = 'marker'; // 左侧树型结构调整时,只允许将任务拖放到某个父节点下
gantt.config.order_branch_free = true; // 左侧树型结构调整时,可以任意拖动任务到任意节点下
gantt.config.auto_scheduling = true; // 控制任务是否自动重新安排
gantt.config.show_errors = false; // 发生异常时,不允许弹出警告到 UI 界面
// 初始化扩展设置
setGanttColumn() // 配置甘特图右侧表格
addTaskType(); // 添加任务类型
// 插件配置
gantt.plugins({
tooltip: true, // 设置工具提示
quick_info: false, // 快速信息框进行隐藏
export_api: true, // 导出 API
undo: true, // 启用撤销功能
marker: true, // 标记
auto_scheduling: true, // 控制任务是否自动重新安排
});
// 添加今天的标记
addTodayMarker();
addProjectStartMarker()
// 展开或折叠树形结构
if (collapse.value) {
expandAll();
} else {
collapseAll();
}
// 初始化甘特图
gantt.init(ganttRef.value);
gantt.parse(props.taskData);
};
2、左侧表格配置像设置,我的需求是表格里的名称、开始时间、结束时间、工期等都可以编辑
// 甘特图列配置
const setGanttColumn = () => {
customEditor()
const textEditor = { type: 'text', map_to: 'text' }
const startDateEditor = { type: 'date', map_to: 'start_date' }
const endDateEditor = { type: 'date', map_to: 'end_date' }
const adjustFinishTimeEditor = { type: 'date', map_to: 'adjustFinishTime' }
const numberEditor = { type: 'number', map_to: 'progress', min: 0, max: 100 }
const durationEditor = { type: 'number', map_to: 'duration', min: 1 }
const predecessorEditor = { type: "predecessor", map_to: "auto" }
const statueEditor = { type: "status_editor", map_to: "status" }
gantt.config.columns = [ // 配置表头
{ align: 'center', name: 'add', label: '', width: 30 },
{
align: 'center',
name: 'buttons',
label: '选择',
width: 35,
onrender: (task: any, node: HTMLInputElement) => {
let input = document.createElement('INPUT');
input.setAttribute('type', 'checkbox');
input.setAttribute('style', 'height:35px;width: 20px');
input.setAttribute('id', 'checkbox' + (task.type !== undefined ? task.type : '') + task.id);
const findIndex = checkList.value.findIndex((c: String) => c + '' === task.id + '');
if (findIndex > -1) {
input.checked = true
}
node.firstElementChild?.appendChild(input);
input.onclick = handleCheckboxChange;
return node;
},
},
{
align: 'center',
name: 'index',
label: '序号',
width: 45,
// resize: true,
template(task) {
// return gantt.getGlobalTaskIndex(task.id) + 1;
return gantt.getWBSCode(gantt.getTask(task.id))
},
},
{
name: "text", label: "任务名称", align: "left", tree: true, width: 400, editor: textEditor,
// template(task) {
// return "<div :title=" + task.text + "><span title='322323232332'></span>" + task.text !== undefined ? task.text : '新任务' + "</div>"
// },
onrender: (item, node) => {
node.setAttribute("title", item.text);
return node;
}
},
{
name: "start_date", label: "预计开始时间", align: "center", width: 250, editor: startDateEditor
},
{ name: "end_date", label: "预计完成时间", align: "center", width: 250, editor: endDateEditor },
{ name: "adjustFinishTime", label: "调整完成时间", align: "center", width: 250, editor: adjustFinishTimeEditor },
{
align: 'center',
name: 'duration',
label: '工期',
width: 90,
editor: durationEditor
},
{
align: 'center',
name: 'sno',
label: '前置任务',
width: 90,
editor: predecessorEditor,
template: function (task) {
return getPredecessor(task)
},
},
{
name: "remark", label: "备注", align: "center"
},
{
name: "status", label: `状态`, align: "center", editor:statueEditor
},
];
}
其他具体操作,感兴趣的可以查看项目源码,下面是源码地址
更多推荐


所有评论(0)