h5 实现甘特图
使用HTML5和JavaScript实现甘特图
HTML5结合JavaScript可以创建交互式甘特图,以下是实现方法:
Canvas绘图基础
<canvas id="ganttChart" width="800" height="400"></canvas>
<script>
const canvas = document.getElementById('ganttChart');
const ctx = canvas.getContext('2d');
// 绘制网格和坐标轴
ctx.strokeStyle = '#ccc';
ctx.lineWidth = 1;
for (let i = 0; i <= 10; i++) {
ctx.beginPath();
ctx.moveTo(50, 50 + i * 30);
ctx.lineTo(750, 50 + i * 30);
ctx.stroke();
}
</script>
动态数据渲染
function drawGantt(tasks) {
tasks.forEach((task, index) => {
const y = 60 + index * 30;
const xStart = 50 + (task.startDay * 20);
const width = (task.duration * 20);
ctx.fillStyle = task.color || '#4CAF50';
ctx.fillRect(xStart, y, width, 20);
ctx.fillStyle = '#000';
ctx.font = '12px Arial';
ctx.fillText(task.name, xStart + 5, y + 15);
});
}
使用现成库简化开发
1. Chart.js甘特图插件
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-gantt"></script>
<canvas id="ganttChart"></canvas>
<script>
new Chart(document.getElementById('ganttChart'), {
type: 'gantt',
data: {
datasets: [{
label: '项目计划',
data: [
{task: '需求分析', start: '2023-01-01', end: '2023-01-07'},
{task: 'UI设计', start: '2023-01-08', end: '2023-01-15'}
]
}]
}
});
</script>
2. D3.js实现高级甘特图
import * as d3 from 'd3';
const svg = d3.select("#gantt-container")
.append("svg")
.attr("width", 800)
.attr("height", 400);
// 创建时间比例尺
const xScale = d3.scaleTime()
.domain([new Date(2023, 0, 1), new Date(2023, 2, 1)])
.range([0, 700]);
// 绘制任务条
svg.selectAll(".task")
.data(tasks)
.enter()
.append("rect")
.attr("class", "task")
.attr("x", d => xScale(d.startDate))
.attr("y", (d, i) => 50 + i * 30)
.attr("width", d => xScale(d.endDate) - xScale(d.startDate))
.attr("height", 20);
响应式设计要点
CSS样式优化
.gantt-container {
overflow-x: auto;
max-width: 100%;
}
@media (max-width: 768px) {
.gantt-task {
height: 15px;
font-size: 0.8em;
}
}
交互功能增强
// 添加工具提示
canvas.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
tasks.forEach(task => {
if (isInsideTask(x, y, task)) {
showTooltip(task);
}
});
});
数据格式建议
标准化任务数据结构
{
"tasks": [
{
"id": 1,
"name": "前端开发",
"start": "2023-06-01",
"end": "2023-06-15",
"progress": 0.7,
"dependencies": [2]
}
]
}
日期处理工具

function parseDate(dateStr) {
const parts = dateStr.split('-');
return new Date(parts[0], parts[1]-1, parts[2]);
}
function getWorkingDays(start, end) {
// 计算工作日逻辑
}






