ECharts零基础学习路线:跟着案例从配置第一条折线图到做出数据大屏:新手常见的报错问题全梳理
嘿,朋友!看到你在学ECharts,我特别理解那种刚接触图表库时一头雾水的感觉。别担心,这条路线是我带过很多新人后总结出来的,保证你从”这玩意儿是啥”到”哇我做出了数据大屏”。咱们一步步来。
第一部分:先搞明白ECharts是什么
ECharts是百度开源的一个纯JavaScript图表库,说白了就是你想要什么图表,它都能给你画出来。支持折线图、柱状图、饼图、散点图、地图……反正数据可视化能想到的它基本都支持。
为什么选ECharts?
- 中文文档,对国内开发者极其友好
- 社区活跃,百度维护,文档更新频繁
- 图表类型丰富,30+图表类型
- 性能好,支持大数据量渲染
先确认你已经有了基础的HTML/CSS/JS知识,如果JavaScript还不太熟,建议先去补一补基础再回来,不然配置项看到头晕就亏了。
第二部分:环境搭建——第一步不能踩坑
很多人在这一步就放弃了,其实特别简单。
方式一:CDN引入(推荐新手)
直接在HTML里加这一行:
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
方式二:npm安装(适合有前端工程化基础的同学)
npm install echarts
然后在JS里引入:
import * as echarts from 'echarts';
方式三:下载源码自己用
去官网echarts.apache.org下载,解压后在HTML里引入echarts.min.js就行。
第三部分:你的第一条折线图——从”Hello World”开始
别急着上大屏,先把最简单的东西跑起来,建立信心。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>我的第一条ECharts</title>
<!-- 引入ECharts -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
<!-- 准备一个容器 -->
<div id="main" style="width:600px;height:400px;"></div>
<script>
// 初始化ECharts实例
var chart = echarts.init(document.getElementById('main'));
// 配置项
var option = {
title: {
text: '一周天气温度变化'
},
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value'
},
series: [{
data: [12, 15, 13, 18, 22, 25, 20],
type: 'line',
smooth: true // 让线条平滑一些
}]
};
// 把配置项应用到图表
chart.setOption(option);
</script>
</body>
</html>
跑起来了吗?看到了那条弯弯的折线吗?恭喜你,你已经入门了。
几个关键概念你必须记住:
echarts.init()初始化图表,参数是DOM容器option是所有配置的集合,几乎一切都在这里setOption()把配置应用到图表xAxis是横轴,yAxis是纵轴,series是数据系列
第四部分:常见报错全梳理——新手踩过的坑我帮你铺平了
这部分的含金量最高,很多教程不会详细说,但我踩过所有坑。
报错1:图表显示不出来
现象: HTML页面打开了,但div里空空如也,控制台也没报错。
原因分析: 最常见的是容器没有设置宽高。ECharts需要知道画布多大,你不告诉它,它就画不出来。
// ❌ 错误:容器没有宽高
<div id="main"></div>
// ✅ 正确:给容器设置宽高
<div id="main" style="width:600px;height:400px;"></div>
或者:
#main {
width: 100%;
height: 400px;
}
经验: 把容器宽高设置成像素值比百分比更稳,尤其是初期调试的时候。
报错2:TypeError: Cannot read properties of undefined (reading ‘init’)
现象: 控制台直接报错,图表完全没加载。
原因分析: ECharts没有加载成功。
检查方法:
- 打开开发者工具,看Network面板,echarts.min.js有没有加载成功(状态码应该是200)
- CDN链接有没有写错,比如@后面的版本号
// ❌ 错误写法
<script src="https://cdn.jsdelivr.net/npm/echarts"></script>
// ✅ 正确写法,指定版本
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
报错3:TypeError: chart.setOption is not a function
现象: 控制台报错,说setOption不是一个函数。
原因分析: 初始化失败了,echarts.init()返回了undefined。
// ❌ 错误:init之前容器不存在
var chart = echarts.init(document.getElementById('main'));
// 如果#main不存在,init返回undefined
// ✅ 正确:确保DOM已加载
window.onload = function() {
var chart = echarts.init(document.getElementById('main'));
};
或者把script放在body底部:
<body>
<div id="main" style="width:600px;height:400px;"></div>
<script>
var chart = echarts.init(document.getElementById('main'));
</script>
</body>
报错4:图表数据不更新
现象: 第一次渲染正常,但调用setOption更新数据后图表没变化。
原因分析: setOption不会自动清空上次的数据,需要做合并策略处理。
// ❌ 错误:直接setOption,可能覆盖不对
chart.setOption({
series: [{ data: newData }]
});
// ✅ 正确:追加模式更新
chart.setOption({
series: [{
data: newData
}]
}, true); // true表示不合并,直接替换
或者更规范的做法:
// 保存初始配置,更新时只改数据
var baseOption = {
title: { text: '温度变化' },
xAxis: { data: ['周一','周二','周三'] },
yAxis: { type: 'value' },
series: [{ type: 'line', data: [12, 15, 13] }]
};
chart.setOption(baseOption);
// 更新时
chart.setOption({
series: [{ data: [20, 18, 25] }]
});
报错5:坐标轴数据显示不全/重叠
现象: xAxis的标签文字挤在一起,或者被截断了。
原因分析: 标签太多或者容器太小,没有做间隔设置。
xAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
axisLabel: {
interval: 0, // 显示所有标签,0表示不间隔
rotate: 30 // 旋转30度,解决重叠
}
}
或者用省略号:
axisLabel: {
interval: 0,
formatter: function(value) {
return value.length > 3 ? value.substring(0, 3) + '...' : value;
}
}
报错6:series.data里的数据格式不对
现象: 图表渲染了,但数据没有显示,或者显示成错误的位置。
常见错误:
// ❌ 错误:直接放对象数组但series.type是line
series: [{
data: [
{ value: 12, name: '周一' },
{ value: 15, name: '周二' }
]
}]
// ✅ 正确:line类型直接放数值数组
series: [{
data: [12, 15, 18],
type: 'line'
}]
// ✅ 正确:如果用对象,type需要是scatter或其他支持的对象格式
series: [{
data: [
[0, 12], // [x, y]格式
[1, 15]
],
type: 'scatter'
}]
报错7:tooltip提示框不显示
现象: 鼠标悬停没有任何反应。
原因分析: 没有配置tooltip,或者trigger设置不对。
// ✅ 折线图/柱状图需要设置axis触发
tooltip: {
trigger: 'axis'
}
// ✅ 饼图用item触发
tooltip: {
trigger: 'item'
}
报错8:图表自适应窗口大小
现象: 窗口缩放后图表大小不变,留白很多或者被裁剪。
// 监听窗口变化,自动resize
window.addEventListener('resize', function() {
chart.resize();
});
第五部分:进阶——配置项深入理解
理解option的结构,是写出复杂图表的基础。
option的整体结构
var option = {
// 标题
title: {},
// 提示框
tooltip: {},
// 图例
legend: {},
// 网格区域
grid: {},
// 坐标轴
xAxis: {}, // 横轴,可以是数组(多轴)
yAxis: {}, // 纵轴,可以是数组(多轴)
// 数据系列(最重要)
series: [
{ name: '销量', type: 'bar', data: [...] },
{ name: '利润', type: 'line', data: [...] }
],
// 颜色
color: [],
// 数据区域缩放
dataZoom: [],
// 标记点/线
markPoint: {},
markLine: {},
// 过渡动画
animation: true
};
series的type有哪些
常见的type值:
'line'折线图'bar'柱状图'pie'饼图'scatter'散点图'effectScatter'涟漪散点图'radar'雷达图'tree'树形图'treemap'树形图'sunburst'旭日图'boxplot'箱线图'candlestick'K线图'heatmap'热力图'map'地图'parallel'平行坐标系'lines'线系'graph'关系图'sankey'桑基图'gauge'仪表盘'funnel'漏斗图'custom'自定义系列
第六部分:从折线图到复杂图表——循序渐进的案例
案例一:双Y轴折线图
var option = {
title: {
text: '销售额与利润趋势',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['销售额', '利润'],
bottom: 10
},
grid: {
left: '3%',
right: '4%',
bottom: '15%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: ['1月', '2月', '3月', '4月', '5月', '6月']
}
],
yAxis: [
{
type: 'value',
name: '销售额',
position: 'left',
axisLine: { show: true, lineStyle: { color: '#5470c6' } },
axisLabel: { formatter: '{value} 万' }
},
{
type: 'value',
name: '利润',
position: 'right',
axisLine: { show: true, lineStyle: { color: '#91cc75' } },
axisLabel: { formatter: '{value}%' }
}
],
series: [
{
name: '销售额',
type: 'line',
yAxisIndex: 0,
data: [820, 932, 901, 934, 1290, 1330],
smooth: true,
itemStyle: { color: '#5470c6' },
areaStyle: { opacity: 0.2 }
},
{
name: '利润',
type: 'line',
yAxisIndex: 1,
data: [12, 18, 15, 20, 28, 25],
smooth: true,
itemStyle: { color: '#91cc75' }
}
]
};
案例二:柱状图+折线图混合
var option = {
title: {
text: '月度业绩看板',
subtext: '柱状图=实际业绩,折线图=目标完成率'
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
data: ['实际业绩', '目标完成率'],
bottom: 0
},
grid: {
left: '3%',
right: '4%',
bottom: '12%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['北京', '上海', '广州', '深圳', '杭州', '成都']
},
yAxis: [
{
type: 'value',
name: '业绩(万元)',
position: 'left'
},
{
type: 'value',
name: '完成率',
position: 'right',
axisLabel: { formatter: '{value}%' }
}
],
series: [
{
name: '实际业绩',
type: 'bar',
yAxisIndex: 0,
data: [320, 450, 280, 510, 380, 290],
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#83bff6' },
{ offset: 0.5, color: '#188df0' },
{ offset: 1, color: '#188df0' }
])
}
},
{
name: '目标完成率',
type: 'line',
yAxisIndex: 1,
data: [85, 92, 78, 95, 88, 80],
smooth: true,
itemStyle: { color: '#ff7036' },
lineStyle: { width: 3 }
}
]
};
案例三:饼图(环形图)
var option = {
tooltip: {
trigger: 'item',
formatter: '{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left',
top: 'center'
},
series: [
{
name: '流量来源',
type: 'pie',
radius: ['40%', '70%'], // 环形图的关键
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: true,
formatter: '{b}\n{c}',
fontSize: 12
},
emphasis: {
label: {
show: true,
fontSize: 14,
fontWeight: 'bold'
}
},
data: [
{ value: 1048, name: '搜索引擎' },
{ value: 735, name: '直接访问' },
{ value: 580, name: '邮件营销' },
{ value: 484, name: '联盟广告' },
{ value: 300, name: '视频广告' }
]
}
]
};
第七部分:数据大屏实战——从0到1做一个大屏
数据大屏是ECharts最常见的应用场景,也是很多新手的目标。我们一步步来。
大屏布局思路
先画草图,确定好每个图表的位置和大小。典型的大屏布局:
┌─────────────────────────────────────────────────────┐
│ 标题栏(居中) │
├──────────┬──────────────┬──────────┤
│ 左上图 │ 中间核心 │ 右上图 │
│ 饼图 │ 指标卡片 │ 柱状图 │
├──────────┼──────────────┼──────────┤
│ 左下图 │ 中间趋势 │ 右下图 │
│ 折线图 │ 折线图 │ 雷达图 │
└──────────┴──────────────┴──────────┘
完整大屏代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>数据大屏</title>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #0b1120;
color: #fff;
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
overflow: hidden;
}
.dashboard {
width: 100vw;
height: 100vh;
display: grid;
grid-template-rows: 60px 1fr 1fr;
grid-template-columns: 1fr 1.2fr 1fr;
gap: 10px;
padding: 10px;
}
.header {
grid-column: 1 / -1;
text-align: center;
line-height: 60px;
font-size: 24px;
font-weight: bold;
color: #00d4ff;
background: linear-gradient(90deg, transparent, rgba(0,212,255,0.1), transparent);
letter-spacing: 4px;
}
.chart-box {
background: rgba(255,255,255,0.03);
border: 1px solid rgba(0,212,255,0.2);
border-radius: 8px;
padding: 10px;
position: relative;
}
.chart-box::before {
content: '';
position: absolute;
top: -1px; left: 20px; right: 20px;
height: 2px;
background: linear-gradient(90deg, transparent, #00d4ff, transparent);
}
.chart-title {
font-size: 14px;
color: #8ecae6;
margin-bottom: 8px;
padding-left: 10px;
border-left: 3px solid #00d4ff;
}
.chart { width: 100%; height: calc(100% - 25px); }
/* 中间核心指标卡片 */
.kpi-card {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 15px;
}
.kpi-item {
text-align: center;
}
.kpi-value {
font-size: 36px;
font-weight: bold;
color: #00d4ff;
}
.kpi-label {
font-size: 13px;
color: #8ecae6;
}
.kpi-change {
font-size: 12px;
color: #06d6a0;
}
.kpi-change.down { color: #ef476f; }
/* 网格位置 */
.pos-left-top { grid-column: 1; grid-row: 2; }
.pos-center { grid-column: 2; grid-row: 2 / 4; }
.pos-right-top { grid-column: 3; grid-row: 2; }
.pos-left-bottom { grid-column: 1; grid-row: 3; }
.pos-right-bottom{ grid-column: 3; grid-row: 3; }
</style>
</head>
<body>
<div class="dashboard">
<div class="header">实时运营数据监控大屏</div>
<!-- 左上:流量来源饼图 -->
<div class="chart-box pos-left-top">
<div class="chart-title">流量来源分布</div>
<div id="chart-pie" class="chart"></div>
</div>
<!-- 中间:核心指标+趋势图 -->
<div class="chart-box pos-center">
<div class="chart-title">核心运营指标</div>
<div class="kpi-card">
<div style="display:flex;gap:40px;">
<div class="kpi-item">
<div class="kpi-value" id="kpi1">1,284,560</div>
<div class="kpi-label">今日访问</div>
<div class="kpi-change">↑ 12.5%</div>
</div>
<div class="kpi-item">
<div class="kpi-value" id="kpi2">38,420</div>
<div class="kpi-label">今日订单</div>
<div class="kpi-change">↑ 8.3%</div>
</div>
<div class="kpi-item">
<div class="kpi-value" id="kpi3">¥2,847,120</div>
<div class="kpi-label">今日营收</div>
<div class="kpi-change down">↓ 2.1%</div>
</div>
</div>
<div id="chart-line" style="width:100%;height:200px;"></div>
</div>
</div>
<!-- 右上:各渠道转化柱状图 -->
<div class="chart-box pos-right-top">
<div class="chart-title">渠道转化效率</div>
<div id="chart-bar" class="chart"></div>
</div>
<!-- 左下:24小时流量折线图 -->
<div class="chart-box pos-left-bottom">
<div class="chart-title">24小时访问趋势</div>
<div id="chart-hr" class="chart"></div>
</div>
<!-- 右下:用户画像雷达图 -->
<div class="chart-box pos-right-bottom">
<div class="chart-title">用户画像分析</div>
<div id="chart-radar" class="chart"></div>
</div>
</div>
<script>
// 公共配色方案
const COLORS = ['#00d4ff', '#06d6a0', '#ffd166', '#ef476f', '#118ab2'];
// 通用主题配置
const commonTheme = {
textStyle: { color: '#fff' },
backgroundColor: 'transparent'
};
// ---- 饼图 ----
const pieChart = echarts.init(document.getElementById('chart-pie'));
pieChart.setOption({
tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
legend: {
orient: 'vertical',
right: 10,
top: 'center',
textStyle: { color: '#8ecae6', fontSize: 11 }
},
series: [{
type: 'pie',
radius: ['35%', '65%'],
center: ['35%', '50%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 6,
borderColor: '#0b1120',
borderWidth: 2
},
label: { show: false },
emphasis: {
label: { show: true, fontSize: 13, color: '#fff' }
},
data: [
{ value: 35, name: '搜索引擎', itemStyle: { color: COLORS[0] } },
{ value: 25, name: '直接访问', itemStyle: { color: COLORS[1] } },
{ value: 18, name: '社交媒体', itemStyle: { color: COLORS[2] } },
{ value: 12, name: '广告投放', itemStyle: { color: COLORS[3] } },
{ value: 10, name: '其他', itemStyle: { color: COLORS[4] } }
]
}]
});
// ---- 中间折线图 ----
const lineChart = echarts.init(document.getElementById('chart-line'));
lineChart.setOption({
tooltip: { trigger: 'axis' },
legend: {
data: ['昨日', '今日'],
textStyle: { color: '#8ecae6' },
bottom: 0
},
grid: { left: '5%', right: '5%', top: '10%', bottom: '15%' },
xAxis: {
type: 'category',
data: ['00:00','04:00','08:00','12:00','16:00','20:00','24:00'],
axisLine: { lineStyle: { color: '#334155' } },
axisLabel: { color: '#8ecae6' }
},
yAxis: {
type: 'value',
axisLine: { show: false },
splitLine: { lineStyle: { color: '#1e293b' } },
axisLabel: { color: '#8ecae6' }
},
series: [
{
name: '昨日',
type: 'line',
data: [1200, 800, 3200, 5800, 4200, 3800, 2100],
smooth: true,
lineStyle: { color: COLORS[4], width: 2 },
areaStyle: { color: new echarts.graphic.LinearGradient(0,0,0,1,[
{offset:0,color:'rgba(239,71,111,0.3)'},
{offset:1,color:'rgba(239,71,111,0)'}
]) }
},
{
name: '今日',
type: 'line',
data: [1500, 1100, 4100, 6200, 5500, 4800, 2800],
smooth: true,
lineStyle: { color: COLORS[0], width: 2 },
areaStyle: { color: new echarts.graphic.LinearGradient(0,0,0,1,[
{offset:0,color:'rgba(0,212,255,0.3)'},
{offset:1,color:'rgba(0,212,255,0)'}
]) }
}
]
});
// ---- 柱状图 ----
const barChart = echarts.init(document.getElementById('chart-bar'));
barChart.setOption({
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
xAxis: {
type: 'category',
data: ['SEO', 'SEM', '社媒', '邮件', '线下'],
axisLine: { lineStyle: { color: '#334155' } },
axisLabel: { color: '#8ecae6', rotate: 15 }
},
yAxis: {
type: 'value',
axisLine: { show: false },
splitLine: { lineStyle: { color: '#1e293b' } },
axisLabel: { color: '#8ecae6' }
},
series: [{
type: 'bar',
data: [
{ value: 42, itemStyle: { color: COLORS[0] } },
{ value: 38, itemStyle: { color: COLORS[1] } },
{ value: 29, itemStyle: { color: COLORS[2] } },
{ value: 55, itemStyle: { color: COLORS[3] } },
{ value: 18, itemStyle: { color: COLORS[4] } }
],
barWidth: '50%',
label: {
show: true,
position: 'top',
color: '#fff',
formatter: '{c}%'
}
}]
});
// ---- 24小时折线图 ----
const hrChart = echarts.init(document.getElementById('chart-hr'));
const hours = Array.from({length:24}, (_,i) => i + ':00');
const hrData = [120,80,60,50,45,55,200,580,1200,1800,2200,2500,
2400,2300,2100,1900,1700,1500,1200,900,700,550,400,300];
hrChart.setOption({
tooltip: { trigger: 'axis' },
grid: { left: '5%', right: '5%', top: '10%', bottom: '15%' },
xAxis: {
type: 'category',
data: hours,
axisLine: { lineStyle: { color: '#334155' } },
axisLabel: { color: '#8ecae6', interval: 2, fontSize: 10 }
},
yAxis: {
type: 'value',
axisLine: { show: false },
splitLine: { lineStyle: { color: '#1e293b' } },
axisLabel: { color: '#8ecae6' }
},
series: [{
type: 'line',
data: hrData,
smooth: true,
symbol: 'none',
lineStyle: { color: COLORS[0], width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0,0,0,1,[
{offset:0, color:'rgba(0,212,255,0.4)'},
{offset:1, color:'rgba(0,212,255,0)'}
])
}
}]
});
// ---- 雷达图 ----
const radarChart = echarts.init(document.getElementById('chart-radar'));
radarChart.setOption({
tooltip: { trigger: 'item' },
radar: {
indicator: [
{ name: '年龄', max: 100 },
{ name: '消费能力', max: 100 },
{ name: '活跃度', max: 100 },
{ name: '复购率', max: 100 },
{ name: '粘性', max: 100 },
{ name: '口碑', max: 100 }
],
center: ['50%', '55%'],
radius: '60%',
axisName: { color: '#8ecae6' },
splitLine: { lineStyle: { color: 'rgba(0,212,255,0.2)' } },
splitArea: { areaStyle: { color: 'rgba(0,212,255,0.05)' } }
},
series: [{
type: 'radar',
data: [
{
value: [75, 82, 68, 90, 72, 85],
name: '核心用户',
lineStyle: { color: COLORS[0] },
itemStyle: { color: COLORS[0] },
areaStyle: { color: 'rgba(0,212,255,0.3)' }
},
{
value: [55, 60, 80, 45, 88, 65],
name: '潜力用户',
lineStyle: { color: COLORS[1] },
itemStyle: { color: COLORS[1] },
areaStyle: { color: 'rgba(6,214,160,0.2)' }
}
]
}],
legend: {
data: ['核心用户', '潜力用户'],
bottom: 0,
textStyle: { color: '#8ecae6' }
}
});
// ---- 响应式 ----
window.addEventListener('resize', () => {
pieChart.resize();
lineChart.resize();
barChart.resize();
hrChart.resize();
radarChart.resize();
});
</script>
</body>
</html>
第八部分:实战中容易忽略的细节
内存泄漏问题
大屏应用经常会有定时更新数据的需求,如果操作不当,会出现内存泄漏。
// ❌ 错误:每次更新都重新init,旧的实例没有被释放
setInterval(() => {
// 每次都new,旧的chart还在内存里!
var chart = echarts.init(document.getElementById('main'));
chart.setOption(option);
}, 5000);
// ✅ 正确:init一次,后面复用
var chart = echarts.init(document.getElementById('main'));
setInterval(() => {
chart.setOption(getNewOption());
}, 5000);
大数据量优化
当数据点超过几千个时,图表会明显卡顿。
// 方案一:开启采样
series: [{
type: 'line',
data: largeData,
sampling: 'lttb' // 采样算法
}]
// 方案二:关闭动画
series: [{
animation: false
}]
// 方案三:按需加载,分页渲染
图片加载失败的处理
tooltip: {
trigger: 'item',
formatter: function(params) {
if (!params.value) return '暂无数据';
return params.name + ': ' + params.value;
}
}
第九部分:学习路径总结
给你梳理一个清晰的学习路线:
第1周:基础打牢
- 完成第一个折线图,理解option结构
- 学会看官方文档的例子的能力比背配置项重要
- 把tooltip、legend、grid这几个核心模块搞懂
第2周:图表类型扩展
- 柱状图、饼图必须熟练
- 尝试组合图(柱+折)
- 学会处理异步数据加载(用fetch或axios)
第3周:大屏实战
- 用CSS Grid或者Flex布局做网格
- 实现图表的自适应resize
- 加上动态数据更新的效果
- 尝试加一些动效(过渡动画、数据加载动画)
第4周:进阶提升
- 学习自定义系列(custom series)
- 尝试ECharts GL做3D效果
- 了解ECharts的交互API(on、dispatchAction等)
第十部分:推荐的资源
- 官方文档:echarts.apache.org —— 例子极其丰富,遇到问题先看官网的例子
- ECharts示例库:gallery.echartsjs.com —— 直接复制例子的配置,改改数据就能用
- 官方QQ群:有官方人员和热心用户在线解答
- GitHub:apache/echarts —— 关注Issues能找到很多已知问题的解决方案
学ECharts最重要的心态是:不要害怕配置项多,不要害怕报错。每一个报错都说明你在往前走。我刚接触的时候,光是那个series里的data格式就折腾了半小时——有时候传数组报错了,有时候传对象又不对,试了十几次才搞明白不同图表类型的data格式要求不一样。
你现在看到的这个从零到数据大屏的路线,是我踩过所有坑之后帮你铺好的路。照着做,遇到困难把报错信息复制到搜索引擎,十有八九有人遇到过同样的问题。
加油,期待看到你的第一个数据大屏跑起来的那一天!
