js实现甘特图
使用开源库实现甘特图
推荐使用 dhtmlxGantt 或 frappe-gantt 这两个成熟的 JavaScript 库来实现甘特图功能。dhtmlxGantt 功能全面但需要商业授权,frappe-gantt 是 MIT 开源项目适合基础需求。
安装 frappe-gantt:
npm install frappe-gantt
基础实现代码:
import Gantt from 'frappe-gantt';
const tasks = [
{
id: 'Task 1',
name: '需求分析',
start: '2023-01-01',
end: '2023-01-05',
progress: 50
},
{
id: 'Task 2',
name: 'UI设计',
start: '2023-01-06',
end: '2023-01-15',
progress: 20,
dependencies: 'Task 1'
}
];
const gantt = new Gantt('#gantt-container', tasks, {
view_mode: 'Week',
date_format: 'YYYY-MM-DD'
});
自定义 SVG 甘特图
通过原生 SVG 和 JavaScript 手动构建甘特图:

function createGantt(containerId, tasks) {
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('width', '100%');
svg.setAttribute('height', tasks.length * 50 + 50);
// 时间轴绘制逻辑
// 任务条绘制逻辑
tasks.forEach((task, i) => {
const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute('x', calculateXPosition(task.start));
rect.setAttribute('y', i * 50 + 30);
rect.setAttribute('width', calculateWidth(task.start, task.end));
rect.setAttribute('height', '30');
svg.appendChild(rect);
});
document.getElementById(containerId).appendChild(svg);
}
使用 Canvas 绘制
通过 Canvas API 实现高性能甘特图渲染:
class GanttChart {
constructor(canvasId, tasks) {
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext('2d');
this.tasks = tasks;
this.render();
}
render() {
this.clearCanvas();
this.drawTimeScale();
this.drawTasks();
}
drawTasks() {
this.tasks.forEach((task, i) => {
const x = this.timeToPixel(task.start);
const width = this.timeToPixel(task.end) - x;
this.ctx.fillStyle = '#4CAF50';
this.ctx.fillRect(x, i * 40 + 30, width, 30);
});
}
}
关键功能实现
时间计算处理

function parseDate(dateStr) {
return new Date(dateStr + 'T00:00:00');
}
function dayDiff(start, end) {
return (parseDate(end) - parseDate(start)) / (1000 * 60 * 60 * 24);
}
依赖关系连线
function drawDependencies() {
tasks.forEach(task => {
if(task.dependencies) {
const fromTask = tasks.find(t => t.id === task.dependencies);
// 绘制连接线逻辑
}
});
}
交互功能增强
添加事件监听实现交互:
ganttChart.canvas.addEventListener('click', (e) => {
const rect = ganttChart.canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 检测点击的任务项
ganttChart.tasks.forEach(task => {
if(isInTaskArea(x, y, task)) {
showTaskDetails(task);
}
});
});
响应式设计
添加窗口大小监听:
window.addEventListener('resize', () => {
ganttChart.adjustSize();
ganttChart.render();
});
以上方案可根据项目需求选择,开源库方案适合快速实现,自定义方案适合需要深度定制的场景。实际开发中建议优先考虑成熟库方案,可节省约70%的开发时间。






