Highcharts甘特图懒加载实现求助:父任务展开加载子任务
Highcharts甘特图懒加载子任务实现思路
核心步骤拆解
- 初始仅加载顶级父任务:只请求最上层的WBS节点,给每个父任务标记
hasChildren: true(告诉甘特图该任务有子节点可展开),暂不加载子任务数据。 - 监听展开事件:利用Highcharts甘特图的
expand事件,捕获用户点击父任务展开箭头的动作。 - 按需请求子任务:通过当前展开的父任务ID,调用API获取对应的子任务数据。
- 动态添加子任务到图表:将返回的子任务数据转换为甘特图所需格式,添加到现有系列中,同时更新父任务状态避免重复加载。
具体代码示例
1. 初始化甘特图(仅加载顶级任务)
// 模拟初始顶级任务数据(实际从你的API获取) const initialData = [ { id: 'task-1', name: '项目总任务', start: Date.UTC(2024, 0, 1), end: Date.UTC(2024, 5, 30), hasChildren: true, // 标记该任务有子任务 parent: null }, // 其他顶级任务... ]; // 初始化甘特图 const chart = Highcharts.ganttChart('container', { series: [{ name: 'WBS任务', data: initialData }], chart: { events: { // 监听任务展开事件 expand: function(e) { const currentTask = e.point; // 避免重复加载子任务 if (currentTask.hasChildren && !currentTask.loaded) { loadChildTasks(currentTask.id, currentTask); } } } } });
2. 实现子任务加载函数
function loadChildTasks(parentId, parentTask) { // 替换为你的实际API请求地址 fetch(`/api/wbs/getChildren?parentId=${parentId}`) .then(response => response.json()) .then(childData => { // 将API返回的子任务数据转换为甘特图支持的格式 const formattedChildren = childData.map(child => ({ id: child.id, name: child.name, start: Date.UTC(child.startYear, child.startMonth - 1, child.startDay), end: Date.UTC(child.endYear, child.endMonth - 1, child.endDay), hasChildren: child.hasChildren, // 子任务若有下级节点,继续标记 parent: parentId })); // 批量添加子任务,暂不重绘 formattedChildren.forEach(child => { chart.series[0].addPoint(child, false); }); // 统一重绘图表,更新视图 chart.redraw(); // 标记父任务已加载,防止重复请求 parentTask.loaded = true; }) .catch(error => { console.error('加载子任务失败:', error); // 可在此添加用户端错误提示,比如弹窗提示加载失败 }); }
关键细节说明
hasChildren属性:必须设为true,甘特图才会显示展开箭头。loaded自定义属性:用来标记父任务是否已加载过子任务,避免用户多次点击展开时重复发起API请求。addPoint方法:第二个参数设为false,批量添加完成后再调用redraw(),能减少图表重绘次数,提升性能。- 日期格式转换:API返回的日期需转换为
Date.UTC格式,确保甘特图时间轴渲染正确。
内容的提问来源于stack exchange,提问作者Shadman
相关产品推荐
相关产品推荐

