最近在做一个项目管理大屏的需求,客户要求用甘特图直观展示项目进度。我调研了DHTMLX、普加等专业甘特图库,发现要么定制化程度不够,要么体积太大影响性能。最后选择了ECharts这个轻量级可视化库,原因很简单:它既能满足基础功能,又支持深度定制。
ECharts的核心优势在于:
实测下来,用ECharts实现甘特图需要解决三个关键问题:
甘特图的本质是时间跨度可视化,但ECharts的坐标系只认数值。我们需要把开始/结束日期转换为天数差值。这里有个坑:直接使用时间戳相减会得到毫秒数,需要转换单位:
javascript复制function dateToDays(start, end) {
// 86400000 = 24*60*60*1000(毫秒/天)
return Math.round((end.getTime() - start.getTime()) / 86400000)
}
比如2023-04-01到2023-04-15的差值是14天。这个数字将成为柱状图的宽度值。
为了让X轴显示真实日期而非天数,需要玩个"障眼法":
关键配置示例:
javascript复制xAxis: [
{ // 真实坐标轴
type: 'value',
min: 0,
max: totalDays,
show: false // 隐藏但参与计算
},
{ // 视觉坐标轴
type: 'category',
data: ['2023.04', '2023.05'],
axisLine: { show: true }
}
]
当任务未开始时,需要显示空白区域。我的解决方案是用双层柱状图叠加:
javascript复制series: [
{ // 透明部分
type: 'bar',
itemStyle: { color: 'transparent' },
data: [14, 0] // 延迟14天开始的任务
},
{ // 有色部分
type: 'bar',
itemStyle: { color: '#1890FF' },
data: [7, 10] // 持续7天和10天的任务
}
]
javascript复制itemStyle: {
normal: {
borderWidth: 0,
opacity: 0.9
},
emphasis: {
shadowBlur: 10,
shadowColor: 'rgba(0,0,0,0.3)'
}
}
当任务名称较长时,可以采用这些策略:
javascript复制label: {
show: true,
formatter: ({ name }) => {
return name.length > 6 ?
`${name.substr(0,6)}...` : name
},
rich: {
b: { fontWeight: 'bold' }
}
}
大屏项目常需要适配不同分辨率,推荐两种方案:
javascript复制window.addEventListener('resize', () => {
myChart.resize()
})
时区问题:
闰秒误差:
性能优化:
javascript复制dataZoom: [{
type: 'slider',
xAxisIndex: 1, // 控制副X轴
filterMode: 'filter'
}]
在最近一个智慧工地项目里,这套方案成功展示了3年期的施工计划。客户特别满意鼠标悬停时显示的任务详情和预警提示功能。如果你也需要类似效果,不妨按照这个思路试试看。