第 1 章 ECharts 简介与快速入门
1.1 什么是 ECharts
| 概念名称 | 说明 | 注意事项 |
|---|---|---|
| ECharts | 一个由百度开源的基于 JavaScript 的可视化图表库,可在浏览器中生成交互式数据图表。 | 需通过 npm 安装或 CDN 引入,依赖 DOM 容器渲染图表。 |
| 开源协议 | 使用 Apache License v2.0,允许商业项目免费使用。 | 使用时建议保留版权信息,遵守开源协议。 |
| 核心能力 | 支持折线图、柱状图、饼图、散点图、地图、雷达图等多种图表类型。 | 所有图表均支持响应式、动画和交互操作。 |
| 渲染方式 | 使用 Canvas、SVG(可选)进行图形渲染,兼顾性能与清晰度。 | 默认使用 Canvas;SVG 渲染需在初始化时指定 renderer: 'svg'。 |
| 跨平台支持 | 兼容 PC 端与移动端,支持 IE8+ 浏览器(需 polyfill)。 | 在低版本浏览器中可能需要引入 polyfill 支持 ES5+ 特性。 |
1.2 ECharts 的核心特点与应用场景
| 特点名称 | 说明 | 注意事项 |
|---|---|---|
| 丰富的图表类型 | 提供超过 20 种图表类型,满足绝大多数数据可视化需求。 | 某些高级图表(如 graph、treemap)需额外引入对应模块。 |
| 高度可定制化 | 所有视觉元素(颜色、字体、动画等)均可通过配置项调整。 | 过度定制可能影响性能,建议结合主题统一管理样式。 |
| 强大的交互能力 | 支持鼠标悬停、点击、缩放、拖拽、数据区域选择等交互行为。 | 交互行为可通过 dispatchAction 手动触发或禁用。 |
| 响应式布局 | 图表自动适应容器尺寸变化,支持 window resize 监听。 | 在 Vue/React 中需手动调用 resize() 方法以确保正确更新。 |
| 数据驱动 | 图表状态由 option 配置驱动,调用 setOption 即可更新视图。 | 多次 setOption 调用会合并配置,注意避免覆盖关键设置。 |
| 支持大数据量渲染 | 可通过渐进渲染(progressive)机制处理上万级数据点。 | 大数据场景建议关闭动画、启用 dataZoom 并限制渲染粒度。 |
| 地理可视化支持 | 内置世界地图、中国省市地图,支持 GeoJSON 自定义地图。 | 地图数据需单独引入(如 china.js),否则无法显示。 |
| 框架兼容性 | 可与 Vue、React、Angular 等主流前端框架集成。 | 需注意生命周期管理,避免内存泄漏。 |
| 应用场景 | 说明 | 建议图表类型 |
|---|---|---|
| 数据看板 | 实时监控业务指标,展示关键 KPI。 | 柱状图、折线图、饼图、仪表盘、地图 |
| 报表系统 | 展示结构化统计数据,支持导出与打印。 | 表格结合图表、堆叠柱状图、多轴折线图 |
| 地理分析 | 显示区域分布、人口密度、物流路径等空间数据。 | 地图、热力图、迁徙图 |
| 用户行为分析 | 分析点击流、访问路径、转化漏斗等用户行为数据。 | 漏斗图、桑基图、关系图 |
| 财务与金融数据展示 | 展示股价走势、交易量、财务报表趋势。 | K 线图、带 dataZoom 的折线图、双轴图 |
| 社交网络与知识图谱 | 展示人物关系、组织结构、信息传播路径。 | 关系图(graph)、树图(tree) |
1.3 快速开始:引入与第一个图表
| 方法/步骤 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
| CDN 引入 | <script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script> | 在 HTML 中直接引入 ECharts 库文件 | 推荐用于快速原型开发;生产环境建议使用 npm 安装并构建打包。 |
| npm 安装 | npm install echarts | 通过包管理器安装 ECharts | 安装后需通过 import 或 require 引入模块。 |
| 创建 DOM 容器 | <div id="main" style="width: 600px; height: 400px;"></div> | 提供一个具有宽高的容器用于渲染图表 | 必须设置 width 和 height,否则图表无法显示。 |
| 初始化实例 | echarts.init(dom, theme?, renderer?) | 创建 ECharts 实例并绑定到 DOM 元素 | theme 可选(如 'dark'),renderer 可设为 'svg' 或 'canvas'。 |
| 配置图表 option | 对象结构,包含 series、xAxis、yAxis 等组件配置 | 定义图表类型、数据、样式等信息 | 必须包含 series 字段,否则图表为空。 |
| 渲染图表 | myChart.setOption(option) | 将配置项应用到图表实例并渲染 | 必须在 DOM 加载完成后调用,否则可能报错。 |
| 页面 resize 响应 | window.addEventListener('resize', () => myChart.resize()) | 当窗口大小改变时,重新调整图表尺寸 | 在 SPA 或组件化框架中需手动管理事件监听的添加与移除。 |
代码示例:
- CDN 引入
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
- npm 安装
npm install echarts
- 初始化实例
const myChart = echarts.init(document.getElementById('main'));
- 配置图表 option
{
title: { text: '示例图表' },
series: [{ type: 'bar', data: [5, 20, 36] }]
}
- 渲染图表
myChart.setOption({ series: [{ type: 'bar', data: [5, 20, 36] }] });
- 页面 resize 响应
window.addEventListener('resize', () => myChart.resize());
第 2 章 ECharts 基础结构与配置项
2.1 ECharts 实例的创建与初始化
| 方法名称 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
echarts.init | echarts.init(dom, theme?, renderer?) | 初始化 ECharts 实例,绑定到指定 DOM 元素 | dom 必须是真实存在的 HTML 元素;theme 为字符串,renderer 可选 'canvas'/'svg' |
echarts.getInstanceByDom | echarts.getInstanceByDom(dom) | 根据 DOM 获取已存在的 ECharts 实例 | 若未初始化则返回 null;用于避免重复初始化。 |
echarts.connect | echarts.connect(group) | 将多个图表实例连接为一组,实现联动(如同步缩放、高亮) | group 可为字符串或实例数组;常用于多图联动分析。 |
echarts.dispose | echarts.dispose(chartInstance) 或 chartInstance.dispose() | 销毁指定图表实例,释放内存 | 销毁后不可再调用其方法;建议在组件卸载时调用。 |
echarts.version | echarts.version | 获取当前 ECharts 版本号 | 用于调试或兼容性判断。 |
代码示例:
- 初始化实例(暗色主题)
const chart = echarts.init(document.getElementById('chart'), 'dark');
- 获取已存在实例
const chart = echarts.getInstanceByDom(document.getElementById('chart'));
- 连接多个图表
echarts.connect('group1');
- 销毁图表实例
myChart.dispose();
// 或
echarts.dispose(myChart);
- 获取版本号
console.log(echarts.version);
2.2 核心配置项 overview:option 结构解析
| 配置项名称 | 说明 | 是否必需 | 注意事项 |
|---|---|---|---|
series | 定义图表数据系列,包括类型、数据、样式等 | 是 | 至少包含一个 series 对象,type 字段决定图表类型。 |
xAxis | 定义 X 轴配置(如类别轴、数值轴) | 视图表而定 | 折线图、柱状图等需要坐标轴的图表必需;饼图等无需坐标轴的图表可省略。 |
yAxis | 定义 Y 轴配置 | 视图表而定 | 通常与 xAxis 配合使用。 |
grid | 控制直角坐标系内绘图网格区域的位置和大小 | 否 | 默认自动生成;可通过 left/right/top/bottom 控制边距。 |
title | 图表标题配置,支持主标题和副标题 | 否 | 支持 rich 文本样式,可设置位置、对齐方式等。 |
tooltip | 提示框组件,鼠标悬停时显示数据详情 | 否 | 可全局配置或在 series 中单独设置;支持 formatter 自定义内容。 |
legend | 图例组件,用于筛选和标识不同数据系列 | 否 | data 字段需与 series.name 对应;支持 horizontal/vertical 布局。 |
color | 定义图表系列的默认颜色顺序 | 否 | 数组形式,如 ['#c23531', '#2f4554', '#61a0a8'];可被 series.color 覆盖。 |
toolbox | 工具栏,提供保存图片、数据视图、动态类型切换等功能 | 否 | 功能按钮可自定义;saveAsImage 功能依赖 Canvas 渲染。 |
dataZoom | 数据区域缩放组件,用于大数据集的局部查看 | 否 | 支持 inside(内置)和 slider(滑块)类型。 |
visualMap | 视觉映射组件,将数据映射到颜色、大小等视觉元素 | 否 | 支持 continuous(连续)和 piecewise(分段)两种模式。 |
animation | 控制图表动画是否开启及动画参数 | 否 | 大数据量时建议关闭以提升性能:animation: false。 |
backgroundColor | 图表背景色 | 否 | 可设为颜色值或渐变对象。 |
2.3 常用基础组件:title、legend、grid、tooltip
title 配置项
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
text | '销售额统计' | 设置主标题文本 | 支持换行符 \n |
subtext | '2024年度数据' | 设置副标题文本 | 通常用于补充说明 |
left | 'center' / 'left' / 'right' / 20 | 设置标题水平对齐位置 | 数值表示距离容器左侧的像素值 |
top | 'top' / 'middle' / 'bottom' / 10 | 设置标题垂直对齐位置 | |
textStyle | { fontSize: 18, color: '#333' } | 设置主标题样式 | 支持 fontFamily、fontWeight 等 CSS 字体属性 |
subtextStyle | { color: '#666', fontSize: 12 } | 设置副标题样式 | |
textAlign | 'auto' / 'left' / 'center' / 'right' | 文本对齐方式 | 通常由 left/top 自动决定 |
triggerEvent | true / false | 是否触发事件(如点击) | 用于实现标题交互 |
legend 配置项
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
data | ['销量', '利润'] | 指定图例项,通常与 series.name 对应 | 若未设置,则自动从 series 中提取 name |
type | 'plain' / 'scroll' | 图例类型:普通或可滚动 | 数据过多时建议使用 scroll |
orient | 'horizontal' / 'vertical' | 布局方向 | horizontal 为横向,vertical 为纵向 |
left | 'center' / '10%' / 20 | 水平位置 | 支持百分比、像素值或关键字 |
top | 'top' / '20%' / 30 | 垂直位置 | |
itemWidth | 25 | 图例标记的宽度 | 默认 25px |
itemHeight | 14 | 图例标记的高度 | 默认 14px |
textStyle | { color: '#333', fontSize: 12 } | 图例标签文字样式 | |
selected | { '销量': true, '利润': false } | 初始选中状态 | false 的系列将不显示在图表中 |
inactiveColor | '#ccc' | 未选中项的文字颜色 | 用于视觉区分 |
grid 配置项
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
left | '10%' / 50 | 距容器左侧距离 | 常用百分比或像素值 |
right | '10%' / 50 | 距容器右侧距离 | |
top | '20%' / 60 | 距容器顶部距离 | |
bottom | '15%' / 40 | 距容器底部距离 | |
width | '80%' / 500 | 网格宽度(优先级高于 left/right) | 一般不建议与 left/right 同时使用 |
height | '70%' / 400 | 网格高度(优先级高于 top/bottom) | |
containLabel | true | 确保标签不被裁剪 | 建议设为 true,尤其当坐标轴标签较长时 |
tooltip 配置项
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
trigger | 'item' / 'axis' / 'none' | 触发类型:数据项触发 / 坐标轴触发 / 不触发 | 'axis' 适用于多系列柱状图/折线图,显示同 x 轴所有数据 |
show | true / false | 是否显示提示框 | 默认 true |
formatter | '{a} <br/> {b}: {c}' 或函数 | 自定义提示框内容 | 支持模板变量:{a} 系列名,{b} 数据名,{c} 数据值 |
axisPointer | { type: 'line' } | 坐标轴指示器类型(line、shadow、none) | 仅在 trigger: 'axis' 时生效 |
backgroundColor | 'rgba(0,0,0,0.7)' | 背景颜色 | |
textStyle | { color: '#fff' } | 文字样式 | |
position | [10, 10] 或函数 | 自定义提示框位置 | 可用于避免遮挡图表元素 |
第 3 章 常用图表类型详解
3.1 折线图(line)与面积图
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
series.type | 'line' | 指定系列类型为折线图 | 必须设置为 'line' 才能渲染折线图 |
series.data | [10, 20, 30] 或 [[0, 10], [1, 20], [2, 30]] | 设置数据点值,支持一维数组或二维坐标数组 | 一维数组自动映射到 Y 轴;二维数组用于自定义 X/Y 坐标 |
series.smooth | true / false / 0.5 | 是否平滑曲线,true 表示平滑,false 为折线,数值控制曲率 | 平滑曲线在数据点少时效果更明显 |
series.stack | 'group1' | 启用堆叠模式,相同 stack 值的系列将堆叠显示 | 堆叠折线图用于展示累计趋势 |
series.areaStyle | { opacity: 0.3 } | 配置面积图填充样式,启用后显示为面积图 | 不设置则为普通折线图;opacity 控制透明度 |
series.symbol | 'circle' / 'rect' / 'none' | 数据点标记的形状 | 可选值包括 'circle'、'rect'、'roundRect'、'triangle' 等 |
series.symbolSize | 6 / [10, 15] | 标记大小,数值或数组(宽高) | 数组形式用于气泡图变体 |
xAxis.type | 'category' / 'value' | X 轴类型:类别轴或数值轴 | 折线图常用 category 类型显示文本标签 |
yAxis.type | 'value' | Y 轴类型:数值轴 | 默认类型,用于展示数值数据 |
代码示例:
{
series: [
{
type: 'line',
data: [5, 15, 25, 35],
smooth: true,
areaStyle: {},
symbol: 'diamond',
symbolSize: 8
}
]
}
3.2 柱状图(bar)与堆叠柱状图
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
series.type | 'bar' | 指定系列类型为柱状图 | 必须设置为 'bar' |
series.data | [10, 20, 30] | 柱子的高度值 | 每个数值对应一个柱子 |
series.stack | 'group1' | 启用堆叠,相同 stack 值的柱子将堆叠在一起 | 用于对比各部分对整体的贡献 |
series.barWidth | 20 / '60%' | 柱子宽度,可设像素值或百分比 | 百分比基于类目宽度计算 |
series.barGap | '30%' / 0 | 不同系列柱子之间的间距(相对于类目宽度) | 0 表示重叠,负值可实现部分覆盖 |
series.barCategoryGap | '20%' / '50%' | 不同类目柱子之间的间距 | 影响整体布局紧凑度 |
series.itemStyle | { color: '#c23531' } | 单个柱子的样式,可设置颜色、边框等 | 可在 data 数组中为每个点单独设置 itemStyle |
xAxis.type | 'category' | X 轴为类目轴,显示类目标签 | 通常绑定类目数据 |
yAxis.type | 'value' | Y 轴为数值轴 | 展示柱子高度对应数值 |
series.layout | 'horizontal' / 'vertical' | 布局方向,vertical 为纵向柱状图,horizontal 为横向条形图 | horizontal 时 xAxis 为数值轴,yAxis 为类目轴 |
代码示例:
{
series: [
{
type: 'bar',
data: [5, 15, 25],
stack: '销售总额',
barWidth: '30%',
itemStyle: { color: '#5470c6' }
}
]
}
3.3 饼图(pie)与环形图
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
series.type | 'pie' | 指定系列类型为饼图 | 必须设置 |
series.data | [{ value: 335, name: '直接访问' }] | 数据项数组,每项包含 value 和 name | name 用于图例和提示框显示 |
series.radius | '50%' / ['40%', '60%'] | 饼图半径,单值为圆形饼图,数组为环形图(内径,外径) | 环形图常用于展示占比同时留出中心区域显示标题等 |
series.center | ['50%', '50%'] | 饼图中心位置(x, y) | 可调整位置以适应布局 |
series.label | { show: true, formatter: '{b}: {d}%' } | 标签配置,控制是否显示及内容格式 | formatter 支持 {b} 名称、{c} 值、{d}% 占比 |
series.labelLine | { show: true, length: 10 } | 引导线配置,连接扇区与标签 | length 控制引导线长度 |
series.itemStyle | { color: '#dd6b66' } | 扇区样式,可设置颜色 | 可为每个 data 项单独设置颜色 |
series.selectedMode | 'single' / 'multiple' / false | 选中模式,控制是否可点击选中 | 选中后扇区会偏移(可通过 selectedOffset 控制) |
series.selectedOffset | 10 | 选中后扇区偏移距离(像素) | 默认 10px |
代码示例:
{
series: [
{
type: 'pie',
data: [{ value: 234, name: '邮件营销' }],
radius: ['50%', '70%'],
center: ['40%', '60%'],
label: { position: 'outside' },
labelLine: { smooth: true },
itemStyle: { borderColor: '#fff', borderWidth: 2 },
selectedMode: 'single',
selectedOffset: 15
}
]
}
3.4 散点图(scatter)与气泡图
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
series.type | 'scatter' | 指定系列类型为散点图 | 必须设置 |
series.data | [[1, 2], [3, 4], [5, 6]] | 二维坐标点数组,每项为 [x, y] | 可包含第三维数据用于气泡大小 |
series.symbolSize | 10 / (value) => value[2] / 20 | 标记大小,可设固定值或函数动态计算 | 函数参数为数据项,返回像素大小;实现气泡图 |
xAxis.type | 'value' | X 轴为数值轴 | 用于展示连续数值 |
yAxis.type | 'value' | Y 轴为数值轴 | 与 X 轴共同构成坐标系 |
series.large | true | 启用大数据量优化模式 | 数据量 > 1000 时建议开启,提升性能 |
series.itemStyle | { color: 'red' } | 标记颜色样式 | 可结合 visualMap 实现颜色映射 |
series.clip | false | 是否裁剪超出坐标系的点 | false 时显示全部点,true 时只显示坐标系内 |
代码示例:
{
series: [
{
type: 'scatter',
data: [[10, 20], [15, 25], [20, 30]],
symbolSize: function (val) { return val[2] / 10; },
itemStyle: { borderColor: 'black', borderWidth: 1 },
clip: false
}
]
}
3.5 雷达图(radar)
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
series.type | 'radar' | 指定系列类型为雷达图 | 必须设置 |
series.data | [{ value: [420, 300, 200, 334], name: '预算' }] | 数据值数组,对应各个指标 | value 数组长度需与 indicator 一致 |
radar.indicator | [{ name: '销售', max: 650 }] | 定义雷达图的指标名称和最大值 | 必须在 option 顶层配置 radar 组件 |
radar.shape | 'polygon' / 'circle' | 雷达图形状:多边形或圆形 | polygon 为直线连接,circle 为圆弧 |
radar.splitNumber | 5 | 圆周分割段数(圈数) | 控制同心圆数量 |
radar.name | { show: true } | 指标名称显示配置 | 可设置字体样式 |
series.areaStyle | {} | 填充样式,设置后显示为填充区域 | 实现面积雷达图 |
series.lineStyle | { width: 2 } | 连线样式 | 可设置线宽、类型等 |
代码示例:
{
radar: {
indicator: [
{ name: '效率', max: 100 },
{ name: '质量', max: 100 }
],
shape: 'circle',
splitNumber: 4,
name: { color: '#333' }
},
series: [
{
type: 'radar',
data: [{ value: [420, 300, 200], name: '实际' }],
areaStyle: { opacity: 0.2 },
lineStyle: { type: 'dashed' }
}
]
}
3.6 地图(map)基础使用
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
series.type | 'map' | 指定系列类型为地图 | 必须设置 |
series.map | 'china' / 'world' / '广东' | 指定地图类型或行政区划名称 | 需提前引入对应地图 JSON 数据 |
series.data | [{ name: '北京', value: 100 }] | 地区数据,name 必须与地图区域名称匹配 | 名称不匹配则无法显示值 |
series.roam | true / 'scale' / 'move' / false | 是否开启缩放和平移 | true 时支持鼠标滚轮缩放和拖拽 |
series.zoom | 1.2 | 初始缩放比例 | 配合 roam 使用 |
series.center | [104.114129, 37.550339] | 地图中心经纬度 | 用于定位到特定区域 |
series.label | { show: true } | 是否显示区域名称标签 | 默认不显示 |
series.itemStyle | { areaColor: '#eee', borderColor: '#444' } | 区域样式,设置填充色和边框 | 可在 data 中为特定区域单独设置 |
| 注册地图 | echarts.registerMap('name', { geoJSON }) | 注册自定义地图 | geoJSON 为 GeoJSON 格式地理数据 |
代码示例:
// 注册自定义地图
echarts.registerMap('myMap', geoJson);
{
series: [
{
type: 'map',
map: 'china',
roam: true,
zoom: 1.5,
center: [116.405285, 39.904989],
data: [{ name: '上海', value: 200 }],
label: { color: '#000' },
itemStyle: { borderWidth: 1 }
}
]
}
3.7 仪表盘(gauge)与漏斗图(funnel)
仪表盘(gauge)
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
series.type | 'gauge' | 指定系列类型为仪表盘 | 必须设置 |
series.data | [{ value: 50, name: '完成率' }] | 仪表盘指针值和名称 | value 为当前值 |
series.min | 0 | 仪表盘最小值 | 默认 0 |
series.max | 100 | 仪表盘最大值 | 默认 100 |
series.splitNumber | 10 | 刻度段数 | 影响刻度线数量 |
series.axisLine | { show: true, lineStyle: { width: 30 } } | 仪表盘轴线(背景弧线)样式 | color 可设渐变色段,实现不同区间颜色 |
series.axisTick | { show: true, splitNumber: 5 } | 刻度线配置 | splitNumber 控制每大段内的小刻度数 |
series.axisLabel | { show: true, distance: -20 } | 刻度标签配置 | distance 控制标签距离 |
series.pointer | { show: true, length: '80%' } | 指针配置 | length 可设百分比或像素值 |
series.title | { show: true, offsetCenter: [0, '-40%'] } | 仪表盘标题(中心文本) | offsetCenter 控制相对中心偏移 |
series.detail | { show: true, formatter: '{value}%' } | 详细数值显示 | 默认显示在中心 |
代码示例:
{
series: [
{
type: 'gauge',
data: [{ value: 75, name: '速度' }],
min: 0,
max: 200,
splitNumber: 5,
axisLine: {
lineStyle: {
color: [[0.5, 'green'], [1, 'red']]
}
},
axisTick: { length: 8 },
axisLabel: { formatter: '{value}%' },
pointer: { width: 5 },
title: { fontWeight: 'bold' },
detail: { backgroundColor: '#ccc' }
}
]
}
漏斗图(funnel)
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
series.type | 'funnel' | 指定系列类型为漏斗图 | 必须设置 |
series.data | [{ value: 60, name: '访问' }] | 数据项,value 决定层级大小 | 按 value 降序排列显示 |
series.sort | 'descending' / 'ascending' / 'none' | 数据排序方式 | descending 为上宽下窄,ascending 为上窄下宽 |
series.funnelAlign | 'left' / 'center' / 'right' | 漏斗图对齐方式 | 影响整体布局 |
series.width | '80%' / 300 | 漏斗图总宽度 | |
series.height | '80%' / 400 | 漏斗图总高度 | |
series.label | { show: true, position: 'inside' } | 标签显示配置 | inside 显示在区块内,outside 显示在外侧 |
series.itemStyle | { borderColor: '#fff', borderWidth: 2 } | 区块样式 | 可设置边框和颜色 |
代码示例:
{
series: [
{
type: 'funnel',
data: [{ value: 40, name: '点击' }],
sort: 'ascending',
funnelAlign: 'center',
width: '70%',
label: { formatter: '{b}: {c}' },
itemStyle: { color: '#c23531' }
}
]
}
第 4 章 数据处理与动态交互
4.1 异步数据加载与更新
| 方法/属性 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
fetch / axios | fetch('/api/data').then(res => res.json()) | 获取异步数据 | 推荐使用现代 Promise 风格请求 |
setOption | myChart.setOption(option) | 更新图表配置,首次调用渲染,后续调用更新 | 是数据更新的核心方法 |
| loading 动画 | myChart.showLoading() / hideLoading() | 显示加载中提示,提升用户体验 | 建议在请求开始时 show,结束时 hide |
window.addEventListener | 'resize' | 监听窗口变化 | 异步加载后需手动触发 resize 以适应容器 |
代码示例:
- fetch 获取数据
fetch('/data.json').then(data => myChart.setOption({ series: [{ data }] }));
- setOption 更新
myChart.setOption({ series: [{ data: asyncData }] });
- loading 动画
myChart.showLoading();
fetch(/* ... */).then(() => myChart.hideLoading());
- resize 响应
window.addEventListener('resize', () => myChart.resize());
4.2 动态数据更新与 setOption 详解
| 方法/参数 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
setOption | setOption(option, notMerge?, replace?) | 更新图表状态 | notMerge=true 时不合并旧配置,replace=true 时替换整个 option |
notMerge | true / false | 是否不合并新旧配置,默认 false(合并) | 设为 true 可避免旧数据残留 |
replace | true / false | 是否完全替换配置(高级用法) | 一般不建议使用 |
appendData | myChart.appendData({ seriesIndex: 0, data }) | 向指定系列追加数据(用于流数据) | 需 series 设置 large: true 或数据量大时使用 |
clear | myChart.clear() | 清空图表内容,保留实例 | 清空后可重新 setOption |
isDisposed | myChart.isDisposed() | 判断实例是否已被销毁 | 避免在销毁后调用方法 |
代码示例:
- setOption(不合并旧配置)
myChart.setOption(newOption, true);
- setOption(replace 模式)
myChart.setOption(opt, false, true);
- appendData 追加数据
myChart.appendData({ seriesIndex: 0, data: [10] });
- clear 清空图表
myChart.clear();
- isDisposed 安全操作
if (!myChart.isDisposed()) { /* 安全操作 */ }
4.3 数据集(dataset)与数据映射
| 属性名称 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
dataset | { source: [[...], [...]] } / { source: {} } | 定义数据源,支持二维数组或对象数组 | 可在 option 顶层定义,被多个 series 复用 |
series.encode | { x: '销量', y: '利润' } | 指定数据维度到坐标轴的映射 | 替代 xAxisIndex/yAxisIndex,更语义化 |
dataset.fromDataset | true | 指示 series 数据来自 dataset | datasetIndex 指定使用第几个 dataset |
| 支持 Transform | transform: 'filter' / 'sort' | 对数据集进行转换(实验性) | 需 ECharts 5+ 支持 |
代码示例:
- 二维数组数据源
dataset: {
source: [
['产品', '销量'],
['A', 100],
['B', 200]
]
}
- encode 维度映射
encode: { tooltip: [0, 1, 2] }
- series 引用 dataset
series: [{ type: 'bar', datasetIndex: 0 }]
- Transform 转换
transform: { type: 'sort', config: 'desc' }
4.4 响应式设计与图表自适应
| 方法/属性 | 语法示例 | 用途 | 注意事项 |
|---|---|---|---|
resize | myChart.resize() | 手动触发图表重绘以适应容器尺寸 | 在容器大小变化后调用 |
| window resize 监听 | addEventListener('resize', handler) | 监听浏览器窗口变化 | SPA 中需在组件卸载时移除监听 |
| 主题响应式 | theme.config 支持 media query | 主题级响应式(高级) | 不直接支持,需手动切换;建议通过 JavaScript 检测屏幕尺寸后 setOption |
grid.containLabel | true | 确保坐标轴标签不被裁剪 | 强烈建议设为 true |
| 尺寸使用百分比 | width: '100%', height: '100%' | 容器使用相对尺寸 | 配合 CSS 实现弹性布局 |
| debounce resize | 防抖处理频繁 resize 事件 | 避免性能问题 | 使用 lodash.debounce 或自定义防抖函数;每 100ms 最多触发一次 resize |
代码示例:
- 手动 resize
myChart.resize();
- resize 监听
window.addEventListener('resize', () => myChart.resize());
- containLabel 配置
grid: { containLabel: true }
- 百分比尺寸容器
style: { width: '100%', height: '400px' }
第 5 章 组件与高级配置
5.1 视觉映射(visualMap)详解
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
type | 'continuous' / 'piecewise' | 指定 visualMap 组件类型:连续型或分段型 | |
min | number | 数据最小值,用于映射起点 | 必须与数据范围匹配,否则影响视觉效果 |
max | number | 数据最大值,用于映射终点 | 常配合 inRange 使用控制颜色区间 |
inRange | Object | 定义在数据范围内使用的视觉元素 | 支持 color、symbolSize、opacity 等 |
outOfRange | Object | 定义超出数据范围时的视觉样式 | 可增强异常值提示效果 |
dimension | number / string | 指定绑定的数据维度(从 0 开始) | |
seriesIndex | number / number[] | 控制哪些系列受 visualMap 影响 | |
calculable | boolean | 是否显示拖拽手柄(仅 continuous) | 已废弃,推荐使用 realtime 配合 slider |
splitNumber | number | 分段数量(piecewise) | 实际段数可能因算法调整略有不同 |
categories | string[] | 类别型数据标签(piecewise) | 用于离散分类映射 |
realtime | boolean | 是否实时更新视觉效果 | 性能敏感场景可设为 false |
orient | 'horizontal' / 'vertical' | 组件布局方向 | |
left / top / right / bottom | string / number | 组件位置定位 |
代码示例:
- piecewise 分段型
type: 'piecewise'
- min / max 设置
min: 0,
max: 100
- inRange 颜色映射
inRange: { color: ['#blue', '#red'] }
- outOfRange 异常值样式
outOfRange: { color: '#ccc' }
- dimension 绑定
dimension: 2
- seriesIndex 控制
seriesIndex: [0, 1]
- calculable / splitNumber
calculable: true,
splitNumber: 5
- categories 类别映射
categories: ['低', '中', '高']
- realtime / orient / left
realtime: true,
orient: 'horizontal',
left: 'center'
⚠️ 注意:
visualMap是配置项对象,不是方法。通过option.visualMap设置后调用setOption()生效。
5.2 数据缩放(dataZoom)组件
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
type | 'slider' / 'inside' | 缩放组件类型:滑块式或内置交互式 | |
xAxisIndex | number / number[] | 控制哪个 X 轴的数据缩放 | |
yAxisIndex | number / number[] | 控制 Y 轴缩放 | |
filterMode | 'filter' / 'empty' / 'none' | 数据过滤模式 | |
start | number (0~100) | 初始缩放起始百分比 | 表示从数据的 20% 处开始显示 |
end | number (0~100) | 初始缩放结束百分比 | 默认 100,结合 start 实现局部预览 |
startValue / endValue | any | 按具体数值设定初始范围 | 时间轴等非数字类坐标适用 |
minValueSpan / maxValueSpan | number | 最小/最大跨度限制 | 防止过度缩放导致空数据 |
zoomLock | boolean | 锁定比例缩放(inside) | 配合鼠标滚轮使用,保持宽高比 |
brushSelect | boolean | 是否启用区域选择(inside) | 提升交互灵活性 |
realtime | boolean | 是否实时渲染缩放结果 | 关闭可提高大数据量下的响应速度 |
show | boolean | 是否显示 slider 组件 | false 可隐藏 UI 但保留功能 |
borderColor / backgroundColor | Color | 自定义外观样式 | 支持 CSS 颜色格式 |
代码示例:
- inside 类型
type: 'inside'
- xAxisIndex / yAxisIndex
xAxisIndex: 0,
yAxisIndex: [0]
- start / end 局部预览
start: 20,
end: 80
- startValue / endValue
startValue: '2023-01'
- minValueSpan / maxValueSpan
minValueSpan: 5
- zoomLock / brushSelect
zoomLock: true,
brushSelect: false
- realtime / show / 样式
realtime: true,
show: true,
borderColor: '#ccc'
📌 **提示:**可通过
dispatchAction({ type: 'dataZoom', ... })手动触发缩放行为(见第 6 章)。
5.3 极坐标(polar)与地理坐标系(geo)
5.3.1 极坐标(polar)
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
polar | Object | 定义极坐标系主容器 | 可定义多个 polar 坐标系 |
radius | string / number / [start, end] | 径向距离(内径到外径) | |
center | [x, y] | 极坐标中心点位置 | x/y 支持像素或百分比 |
angleAxis | Object | 角度轴配置(类似 X 轴) | 支持 category/value 类型 |
radiusAxis | Object | 径向轴配置(类似 Y 轴) | 通常表示数值大小 |
startAngle | number | 起始角度(顺时针,0 在正右) | 默认 90 度(上方) |
direction | 'clockwise' / 'counterclockwise' | 角度增长方向 | |
axisLine / axisTick / axisLabel | Object | 坐标轴线、刻度、标签样式 | 可精细控制显示效果 |
代码示例:
- polar 半径配置
polar: { radius: '80%' }
- center 中心位置
center: ['50%', '50%']
- angleAxis / radiusAxis
angleAxis: { type: 'value' },
radiusAxis: { min: 0 }
- startAngle / direction / axisLabel
startAngle: 90,
direction: 'clockwise',
axisLabel: { show: true }
✅ 示例系列:
series.type: 'line'或'scatter'并设置coordinateSystem: 'polar'
5.3.2 地理坐标系(geo)
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
geo | Object | 定义地理坐标区域 | 需提前注册地图 JSON |
map | string | 地图名称(对应已注册的地图) | 如 'china', 'usa' 等 |
roam | boolean / 'scale' / 'move' | 是否允许缩放和平移 | |
center | [lng, lat] | 地图中心经纬度 | China 中心约为此值 |
aspectScale | number | 长宽比缩放系数 | 防止拉伸失真 |
boundingCoords | [[lng1, lat1], [lng2, lat2]] | 限定缩放视野范围 | 限制用户查看区域 |
scaleLimit | { min, max } | 缩放级别限制 | 结合 roam 使用 |
regions | Object[] | 区域个性化设置 | 可单独设置某省样式 |
label / itemStyle / emphasis | Object | 标签、默认样式、高亮样式 | emphasis 控制 hover 效果 |
layoutCenter / layoutSize | [x%, y%], size | 相对容器布局控制 | 用于自适应布局 |
代码示例:
- geo 地图配置
geo: { map: 'china' }
- map 指定地图
map: 'world'
- center 中心经纬度
center: [104.114129, 37.550339]
- aspectScale / boundingCoords
aspectScale: 0.75,
boundingCoords: [/* ... */]
- scaleLimit / regions
scaleLimit: { min: 1, max: 2 },
regions: [{ name: '广东', itemStyle: {/* ... */} }]
- label / itemStyle / emphasis
itemStyle: { areaColor: '#eee' }
- layoutCenter / layoutSize
layoutCenter: ['50%', '50%']
🔗 使用前必须通过
echarts.registerMap(name, { geoJson })注册地图数据。
5.4 工具箱(toolbox)功能配置
| 功能项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
saveAsImage | Object | 导出图片功能 | 默认按钮图标为下载 |
restore | Object | 重置选项,恢复原始状态 | 清除缩放、高亮等操作 |
dataView | Object | 显示原始数据视图 | 可编辑模式允许修改数据 |
dataZoom | Object | 内置缩放控制按钮 | 配合 dataZoom 组件使用 |
magicType | Object | 图表类型切换 | 实现折线图/柱状图互切 |
iconStyle | Object | 自定义工具图标样式 | 控制正常状态样式 |
emphasis | Object | 工具项高亮样式 | hover 时的效果 |
featureTitle | Object | 各功能标题文本 | 支持国际化配置 |
show | boolean | 是否显示工具箱 | 设为 false 则完全隐藏 |
orient | 'horizontal' / 'vertical' | 工具项排列方向 | |
itemSize | number | 图标尺寸 | 单位为 px |
itemGap | number | 图标间距 | 调整美观度 |
代码示例:
- saveAsImage 导出
saveAsImage: { type: 'png', name: 'chart' }
- restore 重置
restore: { show: true }
- dataView 数据视图
dataView: { readOnly: false }
- dataZoom 内置缩放
dataZoom: { title: { zoom: '放大', back: '还原' } }
- magicType 类型切换
magicType: { type: ['line', 'bar'] }
- iconStyle / emphasis / featureTitle
iconStyle: { borderColor: '#000' },
emphasis: { iconStyle: { color: 'red' } },
title: { saveAsImage: '保存为图片' }
- orient / itemSize / itemGap
orient: 'vertical',
itemSize: 15,
itemGap: 10
💡 所有功能均通过
toolbox.features.xxx配置启用,不涉及独立方法调用。
5.5 时间轴(timeline)与图例(legend)进阶控制
5.5.1 时间轴(timeline)
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
timeline | Object | 启用时间轴控制器 | 控制多 option 切换 |
data | Array<string | Object> | 时间节点列表 | |
axisType | 'category' / 'time' / 'value' | 轴类型 | |
currentIndex | number | 当前激活索引 | 可动态更新切换状态 |
autoPlay | boolean | 是否自动播放 | 配合 playInterval 使用 |
playInterval | number (ms) | 播放间隔时间 | 单位毫秒 |
loop | boolean | 是否循环播放 | false 则播完停止 |
rewind | boolean | 播放结束是否回到开头 | 配合 loop 控制逻辑 |
show | boolean | 是否显示 timeline 组件 | 隐藏后仍可通过 API 控制 |
label | Object | 节点标签样式 | 可旋转避免重叠 |
checkpointStyle | Object | 当前节点标记样式 | 强调当前帧 |
代码示例:
- timeline 数据与 autoPlay
timeline: {
data: ['2023', '2024'],
autoPlay: true
}
- data 对象形式
data: ['Q1', 'Q2', { value: 'Q3', tooltip: '第三季度' }]
- currentIndex / playInterval
currentIndex: 0,
playInterval: 2000
- loop / rewind
loop: true,
rewind: false
- label / checkpointStyle
label: { rotate: -45 },
checkpointStyle: { symbol: 'diamond' }
⚙️ timeline 需配合多个 options 数组使用,每次切换加载一个完整图表配置。
5.5.2 图例(legend)
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
legend | Object | 定义图例组件 | 可有多个 legend |
data | Array<string | Object> | 图例项名称列表 | |
type | 'plain' / 'scroll' | 图例类型 | |
icon | 'circle' / 'rect' / 自定义路径 | 图标形状 | |
selected | Object | 初始选中状态 | 控制默认显示哪些系列 |
inactiveColor | Color | 未选中项颜色 | 提供视觉反馈 |
selectedMode | boolean / 'single' / 'multiple' | 选择模式 | |
orient | 'horizontal' / 'vertical' | 排列方向 | |
left / top / align | string / number | 位置与对齐方式 | 支持 'center'/'right' |
formatter | string / Function | 文本格式化 | |
tooltip | Object | 图例项提示框 | 鼠标悬停显示附加信息 |
代码示例:
- legend 基础配置
legend: { data: ['销量', '利润'] }
- data / type / icon
data: ['A', 'B'],
type: 'scroll'
- selected / inactiveColor
selected: { 'A': false },
inactiveColor: '#ccc'
- orient / left / align
orient: 'vertical',
left: 'left'
- formatter 格式化
formatter: '{name}'
// 或函数形式
formatter: (name) => name.toUpperCase()
- tooltip
tooltip: { show: true }
🔄 图例点击会自动触发系列显隐,也可通过事件监听自定义行为。
第 6 章 事件与用户交互
6.1 常用事件绑定:click、mouseover 等
ECharts 支持丰富的事件绑定机制,通过 chartInstance.on(event, handler) 实现。
| 事件名 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
click | chart.on('click', handler) | 点击图表任意位置 | params 包含点击元素信息 |
mouseover | chart.on('mouseover', handler) | 鼠标悬停 | 触发频繁,注意性能 |
mouseout | chart.on('mouseout', handler) | 鼠标离开 | 常与 mouseover 成对使用 |
legendselectchanged | chart.on('legendselectchanged', ...) | 图例选择改变时 | 获取 deselected 列表 |
legendselected | chart.on('legendselected', ...) | 某一项被选中 | 只响应单个 name |
legendunselected | chart.on('legendunselected', ...) | 某一项被取消选中 | 可用于联动控制 |
datazoom | chart.on('datazoom', ...) | dataZoom 发生变化 | 获取当前缩放范围 |
timelinechanged | chart.on('timelinechanged', ...) | timeline 帧切换 | 获取新帧索引 |
magictypechanged | chart.on('magictypechanged', ...) | magicType 切换图表类型 | 获取目标图表类型 |
geoselectchanged / geoselected / geounselected | chart.on(...) | 地图区域选择变化 | 仅限 geo 图表使用 |
pieselected / pieunselected / pieselectedchanged | chart.on(...) | 饼图扇区选择变化 | 配合 pie.select 高亮使用 |
代码示例:
- click 事件
chart.on('click', function(params) { /* ... */ });
- mouseover / mouseout
chart.on('mouseover', fn);
chart.on('mouseout', fn);
- legendselectchanged
chart.on('legendselectchanged', function(params) { /* 获取 deselected 列表 */ });
- legendselected / legendunselected
chart.on('legendselected', function(params) { /* 只响应单个 name */ });
chart.on('legendunselected', function(params) { /* 可用于联动控制 */ });
- datazoom
chart.on('datazoom', function({ start, end }) { /* 获取当前缩放范围 */ });
- timelinechanged
chart.on('timelinechanged', function({ currentIndex }) { /* 获取新帧索引 */ });
- magictypechanged
chart.on('magictypechanged', function({ newType }) { /* 获取目标图表类型 */ });
- geoselectchanged / geoselected / geounselected
chart.on('geoselectchanged', function(params) { /* 仅限 geo 图表使用 */ });
chart.on('geoselected', function(params) { /* ... */ });
chart.on('geounselected', function(params) { /* ... */ });
- pieselected / pieunselected / pieselectedchanged
chart.on('pieselectedchanged', function(params) { /* 配合 pie.select 高亮使用 */ });
chart.on('pieselected', function(params) { /* ... */ });
chart.on('pieunselected', function(params) { /* ... */ });
✅
params参数包含常用字段:name、value、seriesName、componentType、dataType等。
6.2 事件监听与 dispatchAction 方法
dispatchAction 是 ECharts 提供的用于程序化触发图表行为的核心方法。
| 方法名 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
dispatchAction | chart.dispatchAction(action) | 触发内置行为 | 必须在 chart 初始化后调用 |
highlight | { type: 'highlight', ... } | 高亮某个元素 | 不影响选中状态 |
unhighlight | { type: 'unhighlight', ... } | 取消高亮 | 与 highlight 配对使用 |
select | { type: 'select', ... } | 选中元素(如饼图) | 触发 select 事件 |
unselect | { type: 'unselect', ... } | 取消选中 | 回到默认样式 |
toggleSelected | { type: 'toggleSelected', ... } | 切换选中状态 | 类似 checkbox 行为 |
dataZoom | { type: 'dataZoom', ... } | 缩放数据视图 | 可替代用户手动操作 |
takeGlobalCursor | { type: 'takeGlobalCursor', key: 'dataZoom', dataZoomCursor: 'cross' } | 全局光标样式 | 启用十字准星 |
timelineChange | { type: 'timelineChange', currentIndex: 2 } | 切换时间轴帧 | 需存在 timeline 组件 |
restore | { type: 'restore' } | 恢复原始视图 | 清除所有交互变更 |
代码示例:
- highlight 高亮
chart.dispatchAction({
type: 'highlight',
seriesName: 'A'
});
- highlight / unhighlight 配对
{ type: 'highlight', seriesIndex: 0, dataIndex: 2 }
{ type: 'unhighlight', seriesIndex: 0, dataIndex: 2 }
- select / unselect / toggleSelected
{ type: 'select', seriesIndex: 0, dataIndex: 1 }
{ type: 'unselect', seriesIndex: 0, dataIndex: 1 }
{ type: 'toggleSelected' }
- dataZoom 缩放
{ type: 'dataZoom', start: 10, end: 50 }
- takeGlobalCursor 十字准星
{ type: 'takeGlobalCursor', key: 'dataZoom', dataZoomCursor: 'cross' }
- timelineChange / restore
{ type: 'timelineChange', currentIndex: 1 }
chart.dispatchAction({ type: 'restore' })
📣 所有 action 对象必须包含
type字段,其余参数依具体行为而定。
6.3 自定义交互行为与高亮控制
本节主要结合事件 + dispatchAction 实现高级交互。
| 技术点 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
| 高亮联动 | on('click') + dispatchAction('highlight') | 点击一个图表,高亮另一个 | 需持有多个 chart 实例引用 |
| 跨图表通信 | 全局变量存储实例 | 多图之间同步状态 | 注意内存释放 |
| 自定义提示框 | dispatchAction('showTip') | 主动显示 tooltip | 需先 enableShowTip: true |
| 隐藏提示框 | { type: 'hideTip' } | 隐藏当前 tooltip | 常用于 mouseout 后 |
| 动态 setOption | chart.setOption(newOpt, notMerge) | 更新配置实现动画过渡 | 第三个参数开启合并 |
| 防抖处理 | debounce(fn, delay) | 避免高频事件卡顿 | 特别用于 mouseover |
| 数据拾取格式化 | params 回调处理 | 提取有意义的信息 | 不同图表结构不同 |
| 条件判断 | if (...) + dispatchAction(...) | 按条件执行动作 | 提升交互智能性 |
代码示例:
- showTip 显示提示框
{ type: 'showTip', seriesIndex: 0, dataIndex: 3 }
- hideTip 隐藏提示框
chart.dispatchAction({ type: 'hideTip' })
- 动态 setOption
chart.setOption({/* ... */}, true, true)
- 防抖处理
const handleClick = debounce(function() { /* ... */ }, 200)
- 数据拾取格式化
const name = params.name;
const val = params.value[1];
- 条件判断交互
if (params.componentType === 'series') { /* ... */ }
✅ 典型应用场景示例(跨图高亮):
chart1.on('mouseover', function(params) {
chart2.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: params.dataIndex
});
});
chart1.on('mouseout', function() {
chart2.dispatchAction({
type: 'unhighlight',
seriesIndex: 0,
dataIndex: params.dataIndex
});
});
⚠️ **注意:**跨图表交互时确保
dataIndex对齐,且 series 结构一致。
第 7 章 主题与样式定制
7.1 内置主题使用与加载
| 配置/方法 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
echarts.init | echarts.init(dom, theme?, opts?) | 初始化图表时指定主题 | 第二个参数传入主题名称 |
| 主题名称(内置) | 'default', 'dark' | 使用 ECharts 内置主题 | dark 适合深色背景页面 |
| 引入主题 JS 文件 | <script src=".../theme/dark.js"></script> | 加载内置或自定义主题脚本 | 需在 echarts.js 后引入;可从 echarts/theme 目录获取 |
| 判断主题是否注册 | echarts.getTheme('dark') | 检查主题是否已加载 | 返回主题配置对象或 undefined |
| CDN 加载主题 | https://cdn.jsdelivr.net/npm/echarts/dist/theme/dark.js | 在线引入主题资源 | 推荐用于快速原型开发;注意版本一致性 |
代码示例:
// 指定 dark 主题初始化
const chart = echarts.init(dom, 'dark');
// 获取主题
console.log(echarts.getTheme('dark'));
💡 **dark 主题提供黑底白字风格,适用于大屏展示。**其他官方主题需自行构建或下载。
7.2 自定义主题生成与注册
| 方法/配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
generateTheme | 通过 ECharts Theme Builder 生成 | 图形化创建自定义主题 | 下载 JSON 主题文件;支持颜色、字体、阴影等定制 |
registerTheme | echarts.registerTheme(name, themeObject) | 注册自定义主题 | 必须在 init 前调用 |
| 主题对象结构 | { color: [], backgroundColor, textStyle, ... } | 定义全局视觉风格 | 支持所有全局样式配置 |
color 调色板 | Array<Color> | 定义系列默认颜色顺序 | 按 series 顺序循环使用 |
textStyle | Object | 全局文字样式 | 影响 label、title、legend 等 |
seriesCnt | number | 控制 color 数组重复次数 | 超出数组长度时循环取值 |
customImageLoader | themeObject 中可包含图片资源引用 | 支持背景图等资源 | 需处理跨域问题 |
代码示例:
- 注册主题
echarts.registerTheme('myTheme', {
backgroundColor: '#f0f0f0',
// ...
});
- color 调色板
color: ['#c23531', '#2f4554', /* ... */]
- textStyle / backgroundColor
color: ['#c23531', '#2f4554', /* ... */],
backgroundColor: '#fff'
- seriesCnt / backgroundImage
textStyle: { fontFamily: 'Arial', fontSize: 12 }
seriesCnt: 6
// 背景图引用
backgroundImage: 'url(./bg.png)'
✅ 示例:注册一个浅蓝商务风主题
echarts.registerTheme('blueBiz', {
backgroundColor: '#f8f9fa',
color: ['#1e88e5', '#0d47a1', '#42a5f5', '#90caf9'],
textStyle: {
fontFamily: 'Microsoft YaHei, sans-serif'
},
lineStyle: {
width: 2
}
});
⚠️ 主题一旦注册,可在多个图表间复用;建议统一管理主题文件。
7.3 样式优先级与 emphasis 配置
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
normal | Object(已废弃) | ECharts 4.x 以前的常态样式写法 | 已废弃,请使用非嵌套结构 |
emphasis | Object | 高亮状态样式(hover/选中) | 自动触发,无需手动调用 |
blur | Object | 模糊状态样式(非激活时) | 配合 emphasis 实现对比效果 |
select | Object | 选中状态样式 | 饼图、地图区域常用 |
itemStyle | Object | 图形元素样式(柱、点、区域等) | 支持渐变:new echarts.graphic.LinearGradient(...) |
label | Object | 文本标签样式 | position 因图表类型而异 |
lineStyle | Object | 线条样式(折线、边框) | type 支持 solid/dashed/dotted |
areaStyle | Object | 区域填充样式(如面积图) | 用于堆叠图或趋势区域 |
| 样式优先级顺序 | inline > series > option > theme > 默认值 | 样式覆盖规则 | 直接在 data 中设置 color 优先级最高;层层覆盖,调试时注意来源 |
| 渐变色定义 | new echarts.graphic.LinearGradient(...) | 创建线性渐变 | 需在 itemStyle.color 中使用 |
代码示例:
- normal 废弃写法
normal: { color: 'red' }
- emphasis 高亮
emphasis: { color: 'yellow', label: { show: true } }
- blur / select
blur: { opacity: 0.5 },
select: { disabled: false, itemStyle: { borderColor: 'red' } }
- itemStyle / label / lineStyle / areaStyle
itemStyle: { color: 'green' },
label: { show: true, position: 'top' },
lineStyle: { type: 'dashed', width: 3 },
areaStyle: { opacity: 0.2 }
- 渐变色定义
new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'red' },
{ offset: 1, color: 'blue' }
])
✅ 强调状态典型用法:
series: [{
type: 'bar',
data: [10, 20, 30],
itemStyle: {
color: 'blue'
},
emphasis: {
itemStyle: {
color: 'red',
shadowBlur: 10,
shadowColor: 'rgba(0,0,0,0.5)'
},
label: {
show: true,
formatter: '↑{c}'
}
}
}]
⚠️ ECharts 5+ 推荐直接在
series或data中设置样式,避免使用normal层级。
第 8 章 高级图表与扩展
8.1 关系图(graph)与树图(tree)
8.1.1 关系图(graph)
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
type: 'graph' | series.type = 'graph' | 启用关系图 | 展示节点与边的关系 |
nodes | Array<Object> | 节点数据 | 必须包含 id |
links / edges | Array<Object> | 连接边数据 | 支持有向/无向 |
categories | Array<Object> | 节点分类 | 可用于 color 分组 |
layout | 'none' / 'force' / 'circular' | 布局方式 | force 为力导向,circular 为环形 |
force | Object | 力导向图参数 | 调整 repulsion 防止重叠 |
roam | boolean / 'scale' / 'move' | 是否允许缩放平移 | 大图必备 |
focusNodeAdjacency | boolean | 高亮相邻节点 | 提升交互体验 |
lineStyle | Object | 边线样式 | curveness 实现弧线 |
itemStyle / label | Object | 节点样式与标签 | 支持 emphasis 高亮 |
代码示例:
- 基础关系图
series: [{ type: 'graph', /* ... */ }]
- nodes / links
nodes: [{ id: 'A', name: '节点A', value: 10 }],
links: [{ source: 'A', target: 'B' }]
- categories / layout / force
categories: [{ name: '类别1' }],
layout: 'force',
force: { repulsion: 100, gravity: 0.1 }
- roam / focusNodeAdjacency / lineStyle / itemStyle
roam: true,
focusNodeAdjacency: true,
lineStyle: { curveness: 0.3 },
itemStyle: { borderColor: '#000' }
8.1.2 树图(tree)
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
type: 'tree' | series.type = 'tree' | 启用树状图 | 层级结构数据 |
data | Object (tree structure) | 树形数据结构 | 支持嵌套无限层级 |
orient | 'LR' / 'RL' / 'TB' / 'BT' | 布局方向 | 左右/上下排列 |
symbol | string | 节点图形 | 支持 path 字符串自定义 |
symbolSize | number / Function | 节点大小 | 可根据 value 动态调整 |
initialTreeDepth | number | 初始展开深度 | -1 表示全部展开 |
expandAndCollapse | boolean | 是否可展开收起 | 结合点击事件使用 |
animationDuration | number / Function | 动画持续时间 | 控制展开动画速度 |
label.position | 'inside' / 'left' / 'right' | 标签位置 | LR 方向常用 left/right |
leaves | Object | 叶子节点特殊配置 | 与非叶子节点区分样式 |
代码示例:
- 树图基础配置
series: [{ type: 'tree', data: [/* ... */] }]
- data 树形结构
{ name: '根', children: [{ name: '子' }] }
- orient / symbol / symbolSize
orient: 'LR',
symbol: 'emptyCircle',
symbolSize: 10
- initialTreeDepth / expandAndCollapse / animationDuration
initialTreeDepth: 2,
expandAndCollapse: true,
animationDuration: 500
- label.position / leaves
label: { position: 'left' },
leaves: { label: { position: 'inside' } }
🌲 树图常用于组织架构、目录结构等场景。
8.2 热力图(heatmap)与盒须图(boxplot)
8.2.1 热力图(heatmap)
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
type: 'heatmap' | series.type = 'heatmap' | 启用热力图 | 常用于时间矩阵 |
data | [xIndex, yIndex, value] | 二维数值数据 | 使用索引映射坐标轴 |
xAxis.type | 'category' | 类别型 X 轴 | 必须为 category |
yAxis.type | 'category' | 类别型 Y 轴 | 同上 |
visualMap | Object | 颜色映射控制 | 必配项,控制颜色梯度 |
coordinateSystem | 'cartesian2d' | 坐标系类型 | 默认值,可省略 |
emphasis.itemStyle | Object | 高亮样式 | hover 时突出显示 |
代码示例:
- heatmap 系列
series: [{ type: 'heatmap', /* ... */ }]
- data 格式
data: [[0, 0, 10], [0, 1, 20], /* ... */]
- xAxis / yAxis category
xAxis: { type: 'category', data: ['A', 'B'] },
yAxis: { type: 'category', data: ['X', 'Y'] }
- visualMap / emphasis.itemStyle
visualMap: { min: 0, max: 100, inRange: { color: ['white', 'red'] } },
emphasis: { itemStyle: { borderWidth: 2 } }
🔥 日历热力图可用
calendar坐标系 + heatmap 实现。
8.2.2 盒须图(boxplot)
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
type: 'boxplot' | series.type = 'boxplot' | 启用箱线图 | 展示数据分布 |
| 数据格式 | [min, Q1, median, Q3, max] | 五数概括法 | 每个数组代表一个箱子 |
prepareBoxplotData | echarts.toolbox.prepareBoxplotData(rawData) | 从原始数据生成箱线图数据 | 需引入 toolbox.js |
outlier | Object | 异常值样式 | 默认显示为散点 |
itemStyle.boxWidth | number (0~1) | 箱体宽度比例 | 相对于类目宽度 |
tooltip.formatter | Function | 自定义提示框内容 | 显示详细统计值 |
代码示例:
- boxplot 数据
data: [[10, 15, 20, 25, 30]]
- prepareBoxplotData
const boxData = prepareBoxplotData([[1, 2, 3, /* ... */]])
- outlier / itemStyle.boxWidth
itemStyle: { color: 'red' },
itemStyle: { boxWidth: 0.6 }
- tooltip.formatter
formatter: param => `最大值: ${param.data[4]}`
📦 注意:需额外引入 echarts-stat 或 echarts-toolbox 来处理原始数据转换。
8.3 地理图与迁徙图(geo & lines)
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
geo 组件 | { geo: { map: 'china', roam: true } } | 定义地理坐标系区域 | 必须注册地图数据(如通过 registerMap) |
map 名称 | 'china', 'world', 或自定义名称 | 指定要显示的地图区域 | 可使用 GeoJSON 自定义行政区划 |
roam | false / true / 'scale' / 'move' | 是否允许缩放和平移 | 大地图建议开启,移动端需测试手势冲突 |
zoom / center | 数值配置 | 初始缩放级别与中心点 | center 格式为 [经度, 纬度] |
label | { show: true, formatter: '{b}' } | 显示区域名称标签 | 可控制颜色、字体大小等样式 |
itemStyle | { borderColor, areaColor } | 区域填充样式 | 推荐直接使用 itemStyle 设置常态样式 |
emphasis.itemStyle | { areaColor: 'red' } | 高亮状态下的区域样式 | hover 或选中时自动触发 |
series.type: 'scatter' | 配合 coordinateSystem: 'geo' | 在地图上绘制散点 | 常用于标记城市热点 |
series.type: 'effectScatter' | 含涟漪动画的散点 | 实现”脉冲”效果 | brushType: 'fill' 为实心,'stroke' 为空心 |
series.type: 'lines' | 绘制两点间连线 | 表示迁徙、流向关系 | 支持带权重的线段 |
lineStyle | { color, width, type } | 迁徙线样式 | curveness 实现弧线连接(0~1) |
effect | { show: true, symbol, period } | 动态特效(如箭头移动) | trailLength 控制尾迹长度 |
polyline | true / false | 是否支持多段线路径 | 适用于复杂航线或轨迹 |
blendMode | 'lighter' | 混合模式增强视觉叠加效果 | 常用于大量线条叠加时提亮显示 |
zlevel | 数字层级 | 分层渲染优化性能 | 将地图背景、点、线分置于不同 Canvas 层 |
代码示例:
- geo 基础配置
geo: { map: 'china', label: { show: true }, itemStyle: { /* ... */ } }
- map / roam / zoom / center
map: 'shanghai',
roam: true,
zoom: 1.2,
center: [104.114129, 37.550339]
- label / itemStyle / emphasis.itemStyle
label: { color: '#fff', fontSize: 10 },
itemStyle: { borderColor: '#409EFF', areaColor: '#eee' },
emphasis: { itemStyle: { areaColor: '#c23531' } }
- scatter / effectScatter
// 地图散点
type: 'scatter',
coordinateSystem: 'geo',
data: [[lng, lat, value]]
// 涟漪散点
type: 'effectScatter',
rippleEffect: { period: 4, scale: 2, brushType: 'stroke' }
- lines 迁徙线
type: 'lines',
data: [{ coords: [[lng1, lat1], [lng2, lat2]], value: 100 }]
- lineStyle / effect / polyline / blendMode / zlevel
lineStyle: { curveness: 0.3 },
effect: { symbol: 'circle', trailLength: 0.2 },
polyline: true,
blendMode: 'lighter',
zlevel: 2
✅ 典型应用场景:
- 热力分布:
effectScatter + geo显示城市活跃度- 人口迁徙:
lines + effect实现动态流动动画- 物流路径:
lines + polyline展示运输路线
⚠️ 注意事项:
- 地图数据需提前加载(可通过
fetch获取 GeoJSON 并调用echarts.registerMap(name, { geoJson }))- 移动端注意
roam手势与页面滚动冲突- 大量 lines 数据建议启用
large: true或使用progressive渐进渲染
8.4 自定义系列(custom series)简介
| 配置项 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
series.type: 'custom' | 'custom' | 启用自定义图表类型 | 是实现非标准图表的核心机制 |
renderItem | (params, api) => Object | 定义每个数据项的图形渲染逻辑 | 必须返回一个图形对象描述 |
params 参数 | { dataIndex, dataIndexInside, seriesIndex, ... } | 当前数据项上下文信息 | 可获取当前索引、系列索引等 |
api.value(dim) | api.value(0) | 获取当前数据维度的值 | dim=0 对应第一列数据 |
api.coord([x, y]) | 像素坐标转换 | 将数据坐标转为画布像素坐标 | 适用于 cartesian2d 坐标系 |
api.size([w, h]) | 尺寸映射 | 数据维度到像素尺寸的比例转换 | 用于响应式图形大小 |
api.style(...) | 继承主题样式 | 获取默认样式并融合 emphasis 状态 | 自动处理高亮、透明度等状态 |
返回图形类型 type | 'circle', 'rect', 'path', 'text', 'image' 等 | 指定绘制的图形种类 | 支持 SVG 类基本图形 |
shape 属性 | 因图形类型而异 | 定义图形几何属性 | 必须符合对应图形要求 |
style 样式 | { fill, stroke, lineWidth, opacity } | 图形视觉样式 | 支持渐变色、阴影等高级样式 |
emphasis / blur | 同其他系列 | 定义高亮与模糊状态 | 提升交互体验 |
z / zlevel | 控制图层层级 | 调整绘制顺序 | zlevel 跨 Canvas,z 同层内排序 |
progressive | 数值 | 渐进渲染大数据量自定义图形 | 避免主线程阻塞 |
data 结构灵活性 | 任意结构 | 支持复杂数据格式 | 可在 renderItem 中读取额外字段 |
代码示例:
- custom series 基础
type: 'custom', renderItem: renderFunc, data: [/* ... */]
- renderItem 函数签名
renderItem: function (params, api) {
// ... return shapeConfig;
}
- params / api
const dataIdx = params.dataIndex;
const xVal = api.value(0);
const yVal = api.value(1);
const point = api.coord([xVal, yVal]);
const size = api.size([1, 1]);
style: api.style({ fill: 'red' })
- 图形类型与 shape
type: 'rect',
shape: { x, y, width, height }
// circle: { cx, cy, r }
- style / emphasis / blur / z / zlevel / progressive
style: { fill: '#c23531', stroke: '#000' },
emphasis: { style: { fill: 'yellow' } },
zlevel: 1, z: 2,
progressive: 500
- data 灵活结构
data: [{ value: [10, 20], extra: 'info' }]
✅ 示例:使用 custom series 绘制矩形条形图
series: [{
type: 'custom',
renderItem: function (params, api) {
const height = api.size([0, 1])[1] * 0.6; // 高度占 60%
const xValue = api.value(0);
const point = api.coord([xValue, api.value(1)]);
return {
type: 'rect',
shape: {
x: point[0] - 10,
y: point[1] - height / 2,
width: 20,
height: height
},
style: api.style()
};
},
data: [[10, 0], [20, 1], [30, 2]]
}]
🛠️ 应用场景:
- 实现 ECharts 不支持的图表类型(如甘特图、象形图、仪表盘细节)
- 高度定制化可视化需求(如游戏 UI、工业监控界面)
- 复合图形组合(图标+文字+边框)
⚠️ 注意事项:
renderItem函数会被频繁调用,避免在此执行耗时操作- 建议结合
progressive和large优化大数据性能- 使用
api.style()可继承主题配色,提升一致性
第 9 章 性能优化与最佳实践
9.1 大数据量渲染优化策略
| 配置/方法 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
large 模式 | series.large = true | 启用大数据量优化(如 line、scatter) | 数据 > 5000 点时建议开启 |
progressive | series.progressive = 500 | 渐进式渲染:分块绘制避免卡顿 | 默认 1000,设为 0 关闭 |
progressiveThreshold | series.progressiveThreshold = 3000 | 数据量超过此值才启用渐进渲染 | 小数据无需启用 |
sampling | series.sampling = 'average' | 折线图数据采样策略 | 可选 'average', 'max', 'min' |
blendMode | series.itemStyle.blendMode = 'lighter' | 设置混合模式提升视觉效果 | 配合透明色实现光晕叠加 |
zlevel 分层渲染 | series.zlevel = 1 | 将复杂图形置于独立 Canvas 层 | 减少重绘区域,提升性能 |
使用 setOption 增量更新 | chart.setOption(option, notMerge=false, lazyUpdate=true) | 延迟更新减少重绘 | lazyUpdate: true 提升流畅度 |
| 简化 label 与动画 | label: { show: false }, animation: false | 关闭非必要视觉元素 | 大数据下动画易卡顿 |
| data 格式优化 | 使用数组而非对象数组 | 减少解析开销 | 尤其对 series.data 有效 |
| 使用 markLine/markPoint 节制 | 控制标记数量 | 避免过多辅助线影响性能 | limit markPoint count < 100;大量标记会显著降低帧率 |
代码示例:
- large / progressive / progressiveThreshold
large: true,
progressive: 500,
progressiveThreshold: 3000
- sampling / blendMode / zlevel
sampling: 'min',
blendMode: 'lighter',
zlevel: 1
- setOption 增量更新
setOption(newOpt, true, true)
- 简化 label / animation / data 格式
label: { show: false },
animation: false,
data: [10, 20, 30] // 而非 [{value:10}, ...]
✅ 推荐组合策略:
- 数据 > 5k:启用
large + progressive- 数据 > 10k:关闭动画、label、使用采样
- 时间序列:使用
dataZoom实现局部加载
9.2 图表销毁与内存管理
| 方法 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
dispose() | chart.dispose() | 销毁实例,释放 DOM 和事件 | 必须调用,防止内存泄漏 |
dispose(chart) | echarts.dispose(chart) | 静态方法销毁指定实例 | 与实例方法等效 |
isDisposed() | chart.isDisposed() | 判断图表是否已被销毁 | 安全调用前检查状态 |
| 解除事件监听 | chart.off('click', handler) | 移除事件避免闭包引用 | 手动解绑更安全 |
| 清空 DOM | container.innerHTML = '' | 清除容器内容 | 配合 dispose 使用 |
| 置空引用 | chart = null | 手动释放变量引用 | 帮助 GC 回收 |
| 避免全局持有 | 不将 chart 挂在 window 下 | 防止意外长期引用 | 应限定作用域 |
| Vue/React 中的 destroy 钩子 | beforeDestroy() / useEffect cleanup | 在组件卸载时销毁图表 | SPA 应用中至关重要 |
代码示例:
- dispose 销毁实例
if (chart) { chart.dispose(); chart = null; }
echarts.dispose(myChart);
- isDisposed 检查
if (!chart.isDisposed()) { /* ... */ }
- 解除事件监听
chart.off('click', onClick)
- 清空 DOM
while(container.firstChild) container.removeChild(container.firstChild)
- 避免全局持有
// 避免:window.chart = echarts.init(...)
- Vue/React 销毁
// Vue:
beforeDestroy() { this.chart?.dispose() }
// React:
useEffect(() => {
const chart = echarts.init(ref.current);
return () => chart.dispose();
}, [])
📌 **内存泄漏常见原因:**未调用
dispose、事件未解绑、chart 被全局变量引用。
9.3 懒加载与按需引入
| 方法/工具 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
| ESM 按需导入 | import * as echarts from 'echarts/core' | 只引入所需模块 | 显著减小打包体积 |
| 引入组件 | import TitleComponent from 'echarts/components/Title' | 按需加载组件 | 必须注册后才能使用 |
使用 echarts.use() | echarts.use([module1, module2]) | 注册已导入的模块 | 初始化前完成注册 |
| 动态 import(懒加载) | import('./chart.js').then(...) | 路由级懒加载图表模块 | 结合 Webpack/Vite 分包 |
| CDN 异步加载 | loadScript('https://cdn/echarts.min.js').then(initChart) | 页面加载后异步引入 | 动态创建 script 标签;适用于低优先级图表 |
| Tree Shaking | 构建工具自动移除未用代码 | 减少最终包大小 | 使用 webpack/rollup/vite 默认支持;确保使用 ESM 版本 |
| 自定义构建 ECharts | 通过 Apache ECharts 在线构建工具 | 生成最小化版本 | 勾选所需图表和组件下载 JS;适合嵌入式设备或性能敏感场景 |
代码示例:
- 引入图表与组件
import * as echarts from 'echarts/core';
import BarChart from 'echarts/charts/Bar';
import LineChart from 'echarts/charts/Line';
- 引入组件
import TitleComponent from 'echarts/components/Title';
- 使用 echarts.use 注册
echarts.use([TitleComponent, TooltipComponent]);
echarts.use([LineChart, TitleComponent]);
- 动态 import 懒加载
const Chart = await import('./dashboardChart');
✅ 推荐现代项目使用:
import * as echarts from 'echarts/core';
import { LineChart } from 'echarts/charts';
import { TitleComponent, TooltipComponent, GridComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
echarts.use([LineChart, TitleComponent, TooltipComponent, GridComponent, CanvasRenderer]);
const chart = echarts.init(dom);
⚠️ 注意:按需引入后必须调用
echarts.use()注册模块,否则图表不显示。
第 10 章 实战项目与常见问题
10.1 多图表联动实现
| 技术点 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
| 事件监听 + dispatchAction | chart1.on('click', e => chart2.dispatchAction(...)) | 实现图表间交互同步 | 需持有多个 chart 实例 |
| 共享 dataZoom | 设置相同的 dataZoom.id | 多图共享缩放状态 | 所有图表响应同一缩放操作 |
| 联动高亮 | 'highlight' action | 高亮另一图表对应数据 | dataIndex 需对齐 |
| 联动 tooltip | 'showTip' action | 主动显示其他图表提示框 | 需 enableShowTip |
| 使用全局事件中心 | mitt / EventEmitter | 解耦多个图表通信 | 适合复杂系统 |
| 同步 legend 选择 | 'legendselectchanged' 监听 | 保持图例状态一致 | 名称必须一致 |
| 防抖处理高频事件 | debounce(fn, 200) | 避免频繁触发影响性能 | 特别用于 mouseover |
| 使用 shared state(React/Vue) | Vuex / Redux / Pinia | 状态集中管理 | 框架项目推荐方式 |
代码示例:
- 事件联动基础
chart1.on('dataZoom', e => chart2.dispatchAction(e))
- 共享 dataZoom
dataZoom: [{ id: 'dz', /* ... */ }]
- 联动高亮
chart2.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: e.dataIndex
})
- 联动 tooltip
chart2.dispatchAction({
type: 'showTip',
dataIndex: e.dataIndex
})
- 全局事件中心
const bus = new EventEmitter();
bus.on('zoom', function() { /* ... */ });
- 同步 legend 选择
chart2.dispatchAction({ type: 'legendSelect', name: e.name })
- 防抖处理
const sync = debounce((e) => { /* ... */ }, 100)
- shared state
store.commit('setActiveIndex', idx)
✅ 示例:两个折线图共享 dataZoom
const option = {
dataZoom: [{
id: 'shared',
type: 'slider',
xAxisIndex: 0
}],
series: [/* ... */]
};
chart1.setOption(option);
chart2.setOption(option); // 共享同一 dataZoom 控制
⚠️ 联动时注意数据结构一致性,避免
dataIndex错位。
10.2 与 Vue / React 框架集成
10.2.1 Vue 集成
| 方法 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
ref 获取 DOM | <div ref="chartRef"></div> | 在 setup 中访问元素 | Vue 3 Composition API |
onMounted 初始化 | onMounted(() => { initChart() }) | 组件挂载后创建图表 | 避免 DOM 未就绪 |
watch 响应数据变化 | watch(data, () => setOption()) | 数据更新时刷新图表 | 推荐使用 notMerge: true |
beforeUnmount 销毁 | beforeUnmount(() => { chart?.dispose() }) | 组件卸载前清理资源 | 必须执行 |
使用 v-if 控制显示 | <div v-if="show" ref="chart"></div> | 条件渲染图表容器 | 配合 v-if 实现懒加载;注意销毁与重建 |
| 封装为组件 | defineComponent({ setup() }) | 复用图表逻辑 | 提高开发效率 |
代码示例:
- ref 获取 DOM + onMounted
const chartRef = ref(null);
onMounted(() => { const dom = chartRef.value; });
onMounted(() => { chart = echarts.init(chartRef.value) });
- watch 响应数据
watch(props.data, (newData) =>
chart.setOption({ series: [{ data: newData }] })
)
- beforeUnmount 销毁
beforeUnmount(() => {
if (chart) { chart.dispose(); }
})
- 封装为组件
// 创建 <BaseChart :option="opt" />
10.2.2 React 集成
| 方法 | 语法 | 用途 | 注意事项 |
|---|---|---|---|
useRef 获取 DOM | const chartRef = useRef() | 获取容器引用 | 类似 Vue 的 ref |
useEffect 初始化 | useEffect(() => { init() }, []) | 挂载时创建图表 | 清理函数中销毁 |
useEffect 响应 props | useEffect(() => { chart.setOption(opt) }, [data]) | 数据变化更新图表 | 依赖项数组控制更新频率;避免无限循环 |
| 返回清理函数 | useEffect(() => { /* ... */; return dispose }, []) | 自动销毁图表 | SPA 中防止内存泄漏 |
使用 useState 控制 loading | const [loading, setLoading] = useState(false) | 显示加载状态 | 提升用户体验 |
| TypeScript 类型定义 | import type { ECharts, EChartsOption } from 'echarts' | 类型安全开发 |
代码示例:
- useRef 获取 DOM
const dom = chartRef.current
- useEffect 初始化
useEffect(() => {
const c = echarts.init(chartRef.current);
return () => c?.dispose()
}, [])
- useEffect 响应 props
useEffect(() => { chart.setOption(opt) }, [data])
- 返回清理函数
useEffect(() => {
// ...
return () => { chart && chart.dispose() }
}, [])
- useState 控制 loading
option && !loading && chart.setOption(option)
- TypeScript 类型定义
const chart = useRef<ECharts | null>(null)
✅ 推荐封装通用组件:
function EChart({ option, style, onEvents }) {
const ref = useRef();
useEffect(() => {
const chart = echarts.init(ref.current);
chart.setOption(option);
return () => chart.dispose();
}, [option]);
return <div ref={ref} style={style} />;
}
10.3 常见报错与调试技巧
| 问题现象 | 可能原因 | 解决方法 | 调试技巧 | 注意事项 |
|---|---|---|---|---|
| ”Container not found” | DOM 元素未就绪或不存在 | 确保容器存在且传入正确引用 | console.log(dom) 是否为 null | Vue/React 中使用生命周期钩子 |
| 图表空白无显示 | setOption 未调用或数据格式错误 | 检查 option 结构和 data 格式 | console.log(option) 查看配置 | 使用官方示例对比 |
| 报错 “Uncaught TypeError” | 引入方式错误或模块未注册 | 使用 ESM 按需引入并调用 use() | 检查打包工具输出 | 避免混用 CJS 和 ESM |
| 内存泄漏、页面卡顿 | 未调用 dispose() 或事件未解绑 | 确保每次销毁图表 | Chrome DevTools Memory 快照对比 | SPA 中重点关注 |
| 中文乱码或字体异常 | 字体未加载或 CSS 冲突 | 设置 textStyle.fontFamily | 在全局 CSS 中定义 @font-face | 打包时嵌入字体 |
| dataZoom 不生效 | xAxis 类型不匹配或 index 错误 | 确认 xAxis.type 为 'value' 或 'category' | 检查 series 数据长度 | 配合 start/end 调试 |
| legend 点击无反应 | selectedMode 设为 false 或 data 不匹配 | 检查 legend.data 与 series.name 是否一致 | console.log(series[i].name) | 大小写敏感 |
| 地图显示不出 | 未注册地图或 geoJson 格式错误 | 使用 echarts.registerMap(name, { geoJson }) | 检查 geoJson 是否包含 features 数组 | 推荐使用官方地图数据 |
| dispatchAction 无效 | action 类型错误或参数缺失 | 查阅官方文档确认 action 结构 | 使用 chart.on('finished', ...) 监听渲染完成 | 某些 action 需图表已渲染 |
| tooltip 不显示 | trigger 设为 'none' 或数据异常 | 设置 tooltip.trigger: 'item' | 移动端注意 touch 事件支持 | 可通过 showContent: false 自定义 |
🔧 调试建议:
- 使用 ECharts 在线调试工具验证配置
- 开启
console.log(option)输出最终配置- 使用 Chrome DevTools 查看网络请求(地图 JSON 是否加载)
- 启用
silent: false(默认)确保错误提示可见
✅ 预防性最佳实践:
- 封装统一的
initChart/destroyChart方法- 建立图表配置校验机制
- 使用 TypeScript 提升类型安全