咱们今天不聊虚的,直接上手。作为一名在数据可视化坑里摸爬滚打多年的“老鸟”,我见过太多因为一个stack参数没加、一个颜色选错,导致PPT上数据看起来“增长惊人”,结果老板一问“具体数字是多少”就哑火的情况。ECharts好用吗?好用。但它也是个“老实人”,你给它什么配置,它就给你画什么图,它不会替你检查逻辑漏洞。
这篇文章,我把这30个坑掰开了、揉碎了,结合真实代码和场景,咱们逐个击破。别光看,动手改一遍,下次你就能在同事面前秀一波“这图表我调了三天”的专业感。
一、 被忽视的“堆叠”陷阱:折线图里的数字游戏
1. 堆叠柱状图误用为普通柱状图(第1坑)
这是新手最容易踩的坑。你以为你在展示各部分的绝对值,结果因为没加stack,数据全挤在一起,或者为了堆叠而堆叠,导致读者无法看清总量。
场景:展示A、B两个产品每天的销售额。 错误做法:直接两个series,不设stack,视觉重叠,或者虽然分开但读者难以感知“总销售额”的变化趋势。
// 错误示范:数据互相遮挡,无法看清总量
option = {
xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed'] },
yAxis: { type: 'value' },
series: [
{ name: '产品A', type: 'bar', data: [120, 132, 101] },
{ name: '产品B', type: 'bar', data: [220, 182, 191] } // 这些柱子会叠在A上面,或者并排,取决于设置
]
};
// 正确示范:明确加上 stack: 'total'
option = {
xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed'] },
yAxis: { type: 'value' },
series: [
{ name: '产品A', type: 'bar', stack: 'total', data: [120, 132, 101] },
{ name: '产品B', type: 'bar', stack: 'total', data: [220, 182, 191] }
]
};
避坑指南:如果你的目的是展示“部分与整体”的关系,必须加stack。如果目的是对比各部分的独立表现,不要加stack,并确保图表有清晰的图例和颜色区分。
2. 堆叠折线图的视觉误导(第2坑)
堆叠折线图会让底部的线条看起来波动很小,而顶部的线条波动巨大。这其实只是视觉错觉,因为底部是基准线,顶部是累加值。
场景:展示某网站每日PV(页面浏览量)和UV(独立访客数)。PV远高于UV,如果堆叠,UV的线条会被“压扁”在最底部,几乎看不见波动。
// 错误示范:PV和UV堆叠,UV线条几乎不可见
option = {
xAxis: { type: 'category', data: ['Jan', 'Feb', 'Mar', 'Apr'] },
yAxis: { type: 'value' },
series: [
{ name: 'UV', type: 'line', stack: 'total', data: [100, 110, 105, 120] }, // 在底部,波动被放大倍数小
{ name: 'PV', type: 'line', stack: 'total', data: [500, 550, 520, 600] } // 在顶部,波动被放大
]
};
// 建议:如果两个数据量级差异巨大,考虑双Y轴,或者不堆叠,直接用折线对比趋势
option = {
xAxis: { type: 'category', data: ['Jan', 'Feb', 'Mar', 'Apr'] },
yAxis: [
{ type: 'value', name: 'UV' },
{ type: 'value', name: 'PV' }
],
series: [
{ name: 'UV', type: 'line', yAxisIndex: 0, data: [100, 110, 105, 120] },
{ name: 'PV', type: 'line', yAxisIndex: 1, data: [500, 550, 520, 600] }
]
};
避坑指南:堆叠折线图适合展示总量趋势,不适合展示各分量的独立波动。如果分量波动更重要,请用双Y轴或分离的折线图。
3. 空数据导致折线断开(第3坑)
当数据中有null或undefined时,ECharts默认会在该点断开折线。这在某些场景下是好事(表示无数据),但在展示连续趋势时,可能让读者误以为数据缺失。
// 默认行为:断点
series: [{
data: [10, 20, null, 40, 50],
connectNulls: false // 默认值,断开
}]
// 正确行为:如果希望平滑连接,设置 connectNulls: true
series: [{
data: [10, 20, null, 40, 50],
connectNulls: true // 用直线连接断点两侧的数据
}]
避坑指南:检查你的数据源,确认null是“无数据”还是“数据缺失”。如果是后者,用connectNulls: true;如果是前者,断开是合理的,但最好加个标注说明。
二、 散点图里的“隐形人”:异常点与分布
4. 散点过大掩盖密集区域(第4坑)
散点图的点太大,会导致数据密集区域变成一团模糊的色块,完全看不出分布密度。
// 错误示范:点太大,密集区域糊在一起
series: [{
type: 'scatter',
symbolSize: 50, // 太大了!
data: [[1, 2], [1.1, 2.1], [1.2, 2.05], ...] // 密集点
}]
// 正确示范:点小一点,或者用透明度
series: [{
type: 'scatter',
symbolSize: 5, // 小一点
itemStyle: { opacity: 0.6 }, // 加透明度,重叠区域颜色加深,直观体现密度
data: [...]
}]
避坑指南:数据量大时,务必使用透明度(opacity)或气泡图(symbolSize随数据变化)。透明度的叠加能直观反映数据密度。
5. 坐标轴范围截断异常点(第5坑)
ECharts默认会根据数据自动计算坐标轴范围。如果你的数据中有一个极端异常值(比如9999),它会拉伸坐标轴,导致其他正常数据(0-100)挤在图表底部,几乎看不清。
// 错误示范:异常值9999拉伸了Y轴
option = {
yAxis: { type: 'value' }, // 自动计算,0-100的数据被压缩
series: [{
data: [10, 20, 30, 9999]
}]
};
// 正确示范:手动设置yAxis的min/max,或忽略异常值
option = {
yAxis: {
type: 'value',
min: 0,
max: 100, // 强制固定范围
// 或者使用 splitNumber 控制刻度数量
},
series: [{
data: [10, 20, 30, 9999]
}]
};
避坑指南:在数据处理阶段,就先剔除或单独标注异常值。在ECharts配置中,手动设置yAxis.min/max是避免视觉误导最直接的方法。
6. 混淆散点图与气泡图(第6坑)
散点图是type: 'scatter',气泡图是type: 'scatter'但symbolSize是一个数组。很多人不知道,导致想表达“三个维度”的数据时,用了普通散点图。
// 普通散点图:只展示x, y两个维度
series: [{
type: 'scatter',
data: [[10, 20], [30, 40]]
}]
// 气泡图:展示x, y, size三个维度
series: [{
type: 'scatter',
symbolSize: function (data) {
return data[2] / 5; // 第三个维度决定气泡大小
},
data: [[10, 20, 50], [30, 40, 100]] // 数据格式为 [x, y, size]
}]
避坑指南:想表达三个维度以上?用气泡图,并且明确标注气泡大小代表什么(加个图例或提示框)。
三、 配色:让图表“说人话”
7. 用彩虹色展示连续数据(第7坑)
这是数据可视化的大忌!彩虹色(红橙黄绿青蓝紫)没有内在逻辑,会误导读者认为数据有类别区分。连续数据应该用渐变色或单色系。
// 错误示范:彩虹色
color: ['#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#4B0082', '#9400D3']
// 正确示范:渐变色(从浅蓝到深蓝,代表数值从低到高)
color: ['#e0f7fa', '#80deea', '#26c6da', '#00acc1', '#00838f']
避坑指南:分类数据用区分度高的颜色(如蓝、橙、绿);连续数据用渐变色或单色系;负向数据用红色/暖色,正向数据用蓝色/冷色。
8. 颜色对比度不足(第9坑)
浅色背景上用浅灰色数据,或者深色背景上用深色数据,导致读者根本看不清。
// 错误示范:浅灰线在白色背景上
series: [{
lineStyle: { color: '#cccccc' }, // 几乎看不见
data: [10, 20, 30]
}]
// 正确示范:使用深色,并确保与背景有足够对比
series: [{
lineStyle: { color: '#333333' },
data: [10, 20, 30]
}]
避坑指南:使用WCAG对比度检查工具(如WebAIM Contrast Checker)。确保文字和数据线条与背景的对比度至少达到4.5:1。
9. 忽略色盲友好性(第10坑)
红色和绿色是色盲(红绿色盲)最难区分的颜色。在图表中同时使用红绿表示“涨跌”或“正负”,会让10%的读者抓瞎。
// 错误示范:红绿配色
series: [
{ name: '涨', itemStyle: { color: 'red' } },
{ name: '跌', itemStyle: { color: 'green' } }
]
// 正确示范:红蓝配色,或红绿色+图案区分
series: [
{ name: '涨', itemStyle: { color: '#ff4d4f' } }, // 柔和的红色
{ name: '跌', itemStyle: { color: '#1890ff' } } // 蓝色
]
// 或者在柱状图中,涨用实线,跌用虚线
避坑指南:避免单独使用红绿对比。使用红蓝、橙蓝等对色盲友好的配色。实在要用红绿,必须辅以文字标签或图案区分。
四、 字体与对齐:细节决定成败
10. 字体大小不统一(第11坑)
标题、轴标签、提示框字体大小乱七八糟,读者眼睛会很累。
// 错误示范:字体大小随意
title: { textStyle: { fontSize: 16 } },
axisLabel: { textStyle: { fontSize: 10 } }, // 太小
tooltip: { textStyle: { fontSize: 12 } }
// 正确示范:建立字体层级
title: { textStyle: { fontSize: 18, fontWeight: 'bold' } },
axisLabel: { textStyle: { fontSize: 12 } },
tooltip: { textStyle: { fontSize: 12 } },
legend: { textStyle: { fontSize: 12 } }
避坑指南:确定一个字体基准(如12px),标题用1.5倍(18px),轴标签用1倍,提示框用1倍。保持一致性。
11. 轴标签重叠(第12坑)
当类别太多时,X轴标签会挤在一起,变成一条黑线。
// 错误示范:标签全部显示,重叠
xAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日', '周一', '周二', ...] // 太多
}
// 正确示范:旋转标签,或间隔显示
xAxis: {
type: 'category',
data: [...],
axisLabel: {
rotate: 45, // 旋转45度
interval: 0 // 强制全部显示
}
}
// 或者,间隔显示
axisLabel: {
interval: 2, // 每3个显示1个
rotate: 0
}
避坑指南:优先旋转标签(rotate: 45),如果还是重叠,使用interval间隔显示,或者考虑将图表改为横向柱状图(xAxis和yAxis互换),横向空间更充裕。
12. 对齐方式混乱(第13坑)
Y轴标签左对齐,X轴标签右对齐,提示框位置飘忽不定,读者找不到重点。
// 正确示范:统一对齐
xAxis: {
axisLabel: { align: 'center' } // X轴标签居中对齐刻度
},
yAxis: {
axisLabel: { align: 'right' } // Y轴标签右对齐,方便阅读
},
tooltip: {
trigger: 'axis',
position: function (point, params, dom, rect, size) {
// 固定提示框位置,比如始终在鼠标右侧
return [point[0] + 10, point[1] - 10];
}
}
避坑指南:Y轴标签右对齐(align: 'right'),X轴标签居中对齐(align: 'center')。提示框位置要固定,不要随机飘动。
五、 交互与提示:提升用户体验
13. 提示框信息过载(第14坑)
鼠标悬停时,提示框里塞了十几行数据,读者根本看不完。
// 错误示范:默认提示框,所有系列数据都显示
tooltip: {
trigger: 'axis'
}
// 正确示范:自定义提示框,只显示关键信息
tooltip: {
trigger: 'axis',
formatter: function (params) {
// params 是当前鼠标所在位置的系列数据
let result = params[0].name + '<br/>';
result += params[0].seriesName + ': ' + params[0].value + '<br/>';
if (params[1]) {
result += params[1].seriesName + ': ' + params[1].value;
}
return result;
}
}
避坑指南:精简提示框内容,只显示最重要的1-2个数据。复杂信息放到图表下方的详情面板或表格中。
14. 高亮状态不明显(第15坑)
鼠标悬停时,系列只是颜色变深,没有放大或阴影,读者看不出“这个被选中了”。
// 正确示范:悬停时放大点,并添加阴影
series: [{
type: 'scatter',
symbolSize: 10,
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0,0,0,0.5)'
},
emphasis: {
itemStyle: {
symbolSize: 20, // 悬停时放大
shadowBlur: 20
}
}
}]
避坑指南:利用emphasis配置,在悬停时放大符号、加深颜色或添加阴影,提供明确的视觉反馈。
六、 高级陷阱:性能与布局
15. 大数据量导致卡顿(第16坑)
在页面上渲染超过10,000个散点,浏览器直接卡死
