说实话,写代码十年,跟图表打交道的时间可能比跟对象说话的时间还多。
刚入行那会儿,我也觉得 Echarts 就是个“配置项工具”,把数据丢进去,option 一扔,完事。结果呢?产品来说“这个柱子太细了”,运营来说“颜色太暗了”,老板来说“我要一眼看出问题在哪”。这时候才意识到:图表不只是展示数据,更是在讲述数据背后的故事。
今天我把这些年踩过的坑、调过的颜色、改过的配置,全部揉碎了讲给你听。这不是官方文档的搬运,而是一个老程序员给你的实战避坑指南。
第一章:别急着写代码,先问自己“我想讲什么”
很多新手(包括当年的我)犯的最大错误是:拿到数据,打开文档,直接复制粘贴示例代码。
这是大忌。
在打开编辑器之前,请先问自己三个问题:
- 我的核心目的是什么?(比较大小?看趋势?找占比?分析分布?)
- 谁在看这个图表?(老板要宏观结论,分析师要细节数据,用户要直观反馈?)
- 数据之间是什么关系?(时间序列?分类对比?地理分布?)
1.1 比较类数据:谁高谁低?
场景:销售额对比、用户数量排名、CPU 占用率排行。
推荐图表:
- 柱状图 (Bar):最经典,适合分类少(<10个)、维度明确的情况。
- 条形图 (Horizontal Bar):当类别名称很长,或者类别较多时,横着的条形图阅读体验好十倍。
- 漏斗图 (Funnel):适合展示转化流程,如用户从浏览到下单的流失情况。
避坑指南:
- Y轴别从0开始:这是新手最容易犯的错。如果你把Y轴起点设为非零值,差异会被夸大,看起来很有冲击力,但这是欺骗性的。除非你有极强的理由,否则永远从0开始。
- 排序很有用:柱状图如果按数据大小排序(降序或升序),读者一眼就能找到最大和最小值,而不是在乱序中寻找。
// 示例:一个清爽的排名柱状图
option = {
xAxis: {
type: 'category',
data: ['北京', '上海', '广州', '深圳', '杭州'],
axisLabel: { interval: 0, rotate: 0 } // 标签不倾斜,整齐好看
},
yAxis: {
type: 'value',
axisLine: { show: false }, // 去掉Y轴线,更简洁
splitLine: { lineStyle: { type: 'dashed' } } // 网格线用虚线,不抢眼
},
series: [{
data: [18203, 23489, 29034, 104970, 131744],
type: 'bar',
itemStyle: {
color: '#5470c6' // 单一主色,不要用彩虹色
},
barWidth: '60%' // 柱子不要太粗,留白才有呼吸感
}]
};
1.2 趋势类数据:随时间怎么变?
场景:股价走势、日活用户变化、气温波动。
推荐图表:
- 折线图 (Line):展示连续时间序列上的变化趋势。
- 面积图 (Area):当不仅想看趋势,还想强调“量”的累积感时,用面积图。
- 平滑曲线:Echarts 支持
smooth: true,能让折线看起来更柔和,适合展示平滑的物理现象(如温度)。
避坑指南:
- 多线条别超过 5 条:超过 5 条折线,颜色再不同,人也分不清。如果必须展示多组数据,考虑使用切换组件或分面图表。
- 数据点标记:如果数据点很少(比如只有5个点),记得打开
symbol: 'circle',否则读者不知道具体数值在哪里。
// 示例:带面积效果的趋势图
option = {
xAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value',
min: 0 // 强制从0开始,避免视觉误导
},
series: [{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
smooth: true, // 平滑曲线
areaStyle: {
opacity: 0.3 // 面积填充透明度,不要太高,否则遮挡网格
},
lineStyle: {
width: 3, // 线条稍微粗一点,更清晰
color: '#3ba272'
}
}]
};
1.3 占比类数据:各占多少?
场景:市场份额、预算分配、用户性别比例。
推荐图表:
- 饼图 (Pie):适合分类少(个)、占比差异明显的数据。
- 环形图 (Donut):现代感更强,中间可以放关键指标(如“总销售额”),信息密度更高。
- 堆叠柱状图 (Stacked Bar):当需要比较“总量”和“各部分占比”时,堆叠柱状图比饼图更准确,因为人眼对长度比对角度更敏感。
避坑指南:
- 不要放太多扇区:超过 7 个扇区的饼图,基本没法看。如果分类很多,请把小的合并为“其他”。
- 角度误导:3D 饼图虽然好看,但会产生透视变形,导致某些扇区看起来比实际更大。请尽量使用 2D。
- 百分比标签:务必在图上显示百分比,不要让用户自己心算。
// 示例:现代感环形图
option = {
series: [{
type: 'pie',
radius: ['40%', '70%'], // 内半径和外半径,形成环形
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10, // 圆角扇区,更现代
borderColor: '#fff',
borderWidth: 2
},
label: {
show: true,
formatter: '{b}: {d}%', // 显示类别和百分比
fontSize: 12
},
data: [
{ value: 1048, name: '搜索引擎' },
{ value: 735, name: '直接访问' },
{ value: 580, name: '邮件营销' },
{ value: 484, name: '联盟广告' }
]
}]
};
1.4 分布类数据:数据长什么样?
场景:年龄分布、收入区间、性能测试结果分布。
推荐图表:
- 直方图 (Histogram):展示连续数据的分布情况。
- 箱线图 (BoxPlot):适合展示统计分布,包括中位数、四分位数、异常值。数据分析师最爱。
- 散点图 (Scatter):展示两个变量之间的关系,如身高与体重。
避坑指南:
- 箱线图的异常值:Echarts 默认会标出异常值,这是好事,但确保你的业务逻辑知道什么是“异常”。
- 散点图的重叠:如果数据点太多,散点会重叠成一片。可以使用
symbolSize根据数据量动态调整,或者使用blurSize让重叠区域更清晰。
第二章:配色方案——决定图表颜值的关键
如果说数据结构是骨架,那配色就是皮肤。一个丑的配色,再好的数据也讲不出好故事。
2.1 为什么你的图表看起来很“土”?
常见原因:
- 颜色太饱和:使用了默认的纯色(如大红、大绿),刺眼且廉价。
- 对比度不够:背景是白色,文字是浅灰,根本看不清。
- 颜色太多:一张图用了 7-8 种颜色,读者记不住。
- 忽略色盲友好:红绿色盲用户无法区分红绿柱状图。
2.2 推荐配色方案(直接复制可用)
方案一:莫兰迪色系(高级、柔和、适合汇报)
莫兰迪色系的特点是降低饱和度,加入灰调,看起来非常舒服,适合长时间观看。
const morandiPalette = [
'#9E9E9E', // 灰色
'#B39DDB', // 淡紫
'#90A4AE', // 灰蓝
'#A5D6A7', // 灰绿
'#FFE0B2', // 浅橙
'#EF9A9A', // 淡红
'#CE93D8' // 淡紫红
];
option = {
color: morandiPalette,
// ... 其他配置
};
方案二:赛博朋克风(高对比、科技感、适合数据大屏)
深色背景 + 高饱和霓虹色,视觉冲击力强。
const cyberPalette = [
'#00f2ff', // 青色
'#ff0055', // 品红
'#ffe600', // 黄色
'#00ff9d', // 亮绿
'#7d00ff' // 紫色
];
option = {
color: cyberPalette,
backgroundColor: '#0a0a0a', // 深色背景
// ... 其他配置
};
方案三:专业商务风(稳重、清晰、适合报表)
蓝绿色系为主,传达信任和专业感。
const businessPalette = [
'#1f77b4', // 主蓝
'#ff7f0e', // 辅助橙
'#2ca02c', // 绿色
'#d62728', // 红色(用于警示)
'#9467bd' // 紫色
];
option = {
color: businessPalette,
// ... 其他配置
};
2.3 配色黄金法则
- 主色不超过 3 种:一个图表中,主要强调的颜色最多 3 种,其他作为辅助或中性色。
- 用颜色传达语义:
- 红色 = 警告、下降、亏损
- 绿色 = 正常、上升、盈利
- 蓝色 = 中性、信息、数据
- 黄色/橙色 = 注意、次要重点
- 考虑无障碍访问:避免红绿搭配。可以使用 ColorBrewer 或 Viz Palette 等工具检查配色是否对色盲友好。
- 图例颜色与图表颜色一致:不要让用户自己去猜哪个颜色对应哪个类别。
第三章:交互与细节——让图表“活”起来
图表不是静态图片,它是用户可以互动的界面。
3.1 Tooltip 的优化
默认 tooltip 在很多情况下不够用。
tooltip: {
trigger: 'axis', // 触发类型:axis(坐标轴)或 item(数据项)
backgroundColor: 'rgba(255, 255, 255, 0.9)', // 半透明背景
borderColor: '#ddd',
textStyle: {
color: '#333'
},
formatter: function(params) {
// 自定义 tooltip 内容
let str = `<div style="font-weight:bold">${params[0].name}</div>`;
params.forEach(item => {
str += `<div><span style="display:inline-block;width:10px;height:10px;background:${item.color};margin-right:5px;"></span>${item.seriesName}: ${item.value}</div>`;
});
return str;
}
}
技巧:
- axis 触发:柱状图和折线图用
axis,饼图和散点图用item。 - 自定义 HTML:Echarts 支持 HTML 格式化,可以做得更漂亮。
3.2 数据缩放与漫游
当数据量很大时(如一年的每分钟内数据),用户需要缩放查看细节。
dataZoom: [
{
type: 'inside', // 鼠标滚轮缩放
start: 0,
end: 100
},
{
start: 0,
end: 100,
handleIcon: 'M10.7,11.9H9.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
handleSize: '80%',
handleStyle: {
color: '#fff',
shadowBlur: 3,
shadowColor: 'rgba(0, 0, 0, 0.6)',
shadowBlur: 5
}
}
]
技巧:
- 内置缩放:
type: 'inside'允许用户用鼠标滚轮缩放,体验更流畅。 - 双 dataZoom:一个用于内部缩放(滚轮),一个用于外部拖拽(滑动条),满足不同场景。
3.3 标记线(MarkLine)和标记点(MarkPoint)
突出显示最大值、最小值、平均值或阈值。
series: [{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
markLine: {
data: [
{ type: 'average', name: '平均值' }, // 平均值线
{ yAxis: 1000, name: '目标线' } // 固定值线
],
lineStyle: {
type: 'dashed',
color: '#ff7f0e'
},
label: {
position: 'end',
formatter: '{b}: {c}'
}
}
}]
技巧:
- 平均值线:快速了解数据分布中心。
- 阈值线:如“及格线”、“警戒线”,让用户一眼看出是否超标。
第四章:性能优化——大数据量怎么办?
当数据点超过 1000 个时,Echarts 可能会卡顿。
4.1 开启简化渲染
option = {
series: [{
type: 'line',
progressive: 1000, // 增量渲染阈值
progressiveThreshold: 5000, // 超过 5000 个点时开启简化
progressiveChunkMode: 'mod' // 分块渲染模式
}]
};
原理:当数据量超过 progressiveThreshold 时,Echarts 会自动简化路径,减少绘制点数,提升性能。
4.2 使用 canvas 替代 svg
Echarts 默认使用 canvas,但在某些情况下可以手动指定:
option = {
renderer: 'canvas' // 强制使用 canvas
};
注意:Echarts 4+ 默认就是 canvas,除非你显式设置了 renderer: 'svg'。
4.3 懒加载
对于分页数据或大量数据,不要一次性加载所有数据。可以先加载前 100 个,当用户拖拽数据缩放时,再动态加载更多数据。
第五章:实战案例——一个完整的仪表盘设计
假设我们要设计一个“电商实时销售仪表盘”,需要包含:
- 顶部关键指标(销售额、订单数、用户数)
- 中间左侧:实时销售趋势(折线图)
- 中间右侧:商品类别占比(环形图)
- 底部:各区域销售排名(条形图)
”`javascript // 整体布局使用 grid 和 toolbox option = { backgroundColor: ‘#f5f7fa’, // 浅灰背景,减少眼睛疲劳 color: [‘#1f77b4’, ‘#ff7f0e’, ‘#2ca02c’, ‘#d62728’], grid: [
{ left: '5%', top: '10%', width: '45%', height: '40%' },
{ right: '5%', top: '10%', width: '45%', height: '40%' },
{ left: '5%', top: '55%', width: '90%', height: '40%' }
], tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255,255,2
