ECharts 开源项目解读
项目信息
项目名称:ECharts
项目描述*ECharts 是一个面向 Web 的声明式数据可视化图表库,基于纯 JavaScript/TypeScript 开发,底层依赖自研 Canvas 渲染引擎 zrender。本项目是 Apache 软件基金会的顶级开源项目。
解决的核心痛点:
- 声明式 vs 命令式:开发者只需声明数据和图表配置(option),无需手动操作 Canvas API 逐像素绘制,极大降低可视化开发门槛。
- 复杂的图表交互:内置缩放、平移、框选、提示框、图例切换等丰富的交互行为,避免开发者重复造轮子。
- 跨平台一致性:统一的数据模型和渲染层,屏蔽 Canvas/SVG 底层差异,支持从 PC 到移动端的全平台一致性展示。
目标用户:
- 前端工程师:需要在产品中快速集成专业可视化图表
- 数据分析师:需要交互式探索数据,无需了解底层渲染细节
- 企业级 BI/SaaS 产品:需要高性能、可定制的商业图表方案
核心架构:插件化分层管道架构(6 层:API → 核心引擎 → 模型 → 调度管道 → 视图 → zrender 渲染)
技术亮点:23 种图表、28 个组件、8 种坐标系、Canvas/SVG 双渲染、渐进式渲染、插件按需加载。
1. 项目概览
1.1 项目定位与核心价值
Apache ECharts 是一个面向 Web 的声明式数据可视化图表库,基于纯 JavaScript/TypeScript 开发,底层依赖自研 Canvas 渲染引擎 zrender。本项目是 Apache 软件基金会的顶级开源项目。
| 属性 | 值 |
|---|---|
| 版本 | 6.1.0 |
| 语言 | TypeScript (639 .ts 文件) |
| 总文件数 | 2,069 |
| 源码行数 | ~211,836 |
| 许可证 | Apache-2.0 |
| 核心依赖 | zrender 6.1.0 |
| 主页 | https://echarts.apache.org |
解决的核心痛点:
声明式 vs 命令式:开发者只需声明数据和图表配置(option),无需手动操作 Canvas API 逐像素绘制,极大降低可视化开发门槛。
复杂的图表交互:内置缩放、平移、框选、提示框、图例切换等丰富的交互行为,避免开发者重复造轮子。
跨平台一致性:统一的数据模型和渲染层,屏蔽 Canvas/SVG 底层差异,支持从 PC 到移动端的全平台一致性展示。
1.2 目标用户与使用场景
目标用户:
- 前端工程师:需要在产品中快速集成专业可视化图表
- 数据分析师:需要交互式探索数据,无需了解底层渲染细节
- 企业级 BI/SaaS 产品:需要高性能、可定制的商业图表方案
核心业务场景:
| 场景 | 描述 | 关键功能 |
|---|---|---|
| 商业仪表盘 | 企业 BI 产品构建交互式数据大屏 | 折线/柱状图、地图、饼图、visualMap、dataZoom |
| 实时监控 | 运维系统实时更新折线图和仪表盘 | dataset、dataZoom 时间窗口、动态数据 |
| 数据报告 | 服务端渲染生成静态图表图片 | SSR 模式、SVG 渲染器 |
1.3 核心技术亮点
- 23 种图表类型:涵盖折线、柱状、饼图、散点、地图、K线、桑基、旭日等
- 28 个交互组件:legend、tooltip、dataZoom、visualMap、brush、timeline 等
- 8 种坐标系:笛卡尔、极坐标、地理、雷达、日历、平行、单轴、矩阵
- Canvas/SVG 双渲染:大数据量用 Canvas,精细交互用 SVG,SSR 用 SVG
- 渐进式渲染:10万+ 数据点时支持分帧渲染,不阻塞 UI
- 插件化架构:按需加载,Tree Shaking 友好
- 全面国际化:55+ 语言支持
- 完善的 TypeScript 类型:自动补全和类型检查
1.4 技术栈与选型对比
| 技术选型 | 方案 | 替代方案 | 选择理由 |
|---|---|---|---|
| 渲染引擎 | zrender (自研) | D3.js, PixiJS | 完整的 Displayable 对象模型和事件系统,适合声明式框架 |
| 语言 | TypeScript | JavaScript | 大型代码库的类型安全,复杂 option 的自动补全 |
| 构建 | Rollup + esbuild | Webpack | 高效的 ESM/CJS/UMD 多格式输出 |
| 数据模型 | dataset + Source | series.data | 数据与图表解耦,一份数据多种图表复用 |
| 架构 | 插件化管道 | 单体架构 | 按需加载,核心小巧 (IoC 模式) |
2. 整体架构设计
2.1 架构概述
ECharts 采用插件化分层管道架构。核心引擎提供扩展注册机制和调度管道,所有功能(图表类型、组件、坐标系、视觉编码、布局算法、数据处理器)均以插件形式注册。系统自顶向下分为 6 个逻辑层:
- 用户 API 层:暴露
init()、setOption()、dispatchAction()等顶层 API - 核心引擎层:ECharts 主类,管理实例生命周期(创建/更新/销毁)、zrender 渲染器绑定、扩展 API 创建
- 模型层 (Model):GlobalModel 解析并存储 option,SeriesModel/ComponentModel 管理各自配置与状态
- 调度管道层 (Scheduler):按优先级排序的 Stage 管道,分为 dataProcessor 和 visual 两大阶段
- 视图层 (View):ChartView 负责图表绘制,ComponentView 负责组件绘制,与 zrender Displayable 绑定
- 基础渲染层 (zrender):提供 Canvas/SVG 双渲染后端、事件系统、图形基类
2.2 整体架构图
+===========================================================================+
| 用户 API 层 (Public API) |
| init(dom, theme?, opts?) | setOption(option) | dispatchAction(payload) |
+===================================+=======================================+
| (创建 & 绑定)
v
+===========================================================================+
| 核心引擎层 (Core Engine) |
| +---------------------+ +------------------+ +----------------------+ |
| | ECharts Instance | | ExtensionAPI | | CoordinateSystem | |
| | - _zr: ZRender | | - getModel() | | Manager | |
| | - _model: Global | | - getWidth() | | - register() | |
| | - _scheduler | | - getDom() | | - get() | |
| | - _api | +------------------+ +----------------------+ |
| +----------+-----------+ |
+=============+==============================================================+
| (操作)
v
+===========================================================================+
| 模型层 (Model Layer) |
| +------------------+ +------------------+ +---------------------+ |
| | GlobalModel | | SeriesModel | | ComponentModel | |
| | - option | | - getData() | | - option | |
| | - series[] | | - coordinate- | | - mainType/subType | |
| | - components[] | | System | | - dependences | |
| +--------+---------+ +--------+---------+ +----------+----------+ |
+===========+====================+=======================+===================+
| | |
v v v
+===========================================================================+
| 调度管道层 (Scheduler Pipeline) |
| |
| +--- dataProcessor Stages (优先级排序) ---+ |
| | SERIES_FILTER(800) -> DATASTACK(900) -> AXIS_STATS(920) |
| | -> FILTER(1000) -> STATISTICS(5000) |
| +----------------------------------------+ |
| | |
| +--- visual Stages (优先级排序) ---------+ |
| | LAYOUT(1000) -> PROGRESSIVE_LAYOUT(1100) -> GLOBAL(2000) |
| | -> CHART(3000) -> COMPONENT(4000) -> CHART_DATA_CUSTOM(4500) |
| | -> POST_CHART_LAYOUT(4600) -> BRUSH(5000) -> ARIA(6000) -> DECAL(7000)|
| +----------------------------------------+ |
+===========================================+===============================+
|
v
+===========================================================================+
| 视图层 (View Layer) |
| +------------------+ +------------------+ +----------------------+ |
| | ChartView | | ComponentView | | zrender | |
| | - render() | | - render() | | Displayable | |
| | - updateData() | | - afterRender() | | - Group | |
| | - remove() | | - dispose() | | - Rect, Line, Text | |
| +------------------+ +------------------+ +----------------------+ |
+===========================================+===============================+
|
v
+===========================================================================+
| 基础渲染层 (zrender Renderer) |
| +------------------+ +------------------+ +----------------------+ |
| | Canvas Painter | | SVG Painter | | SSR Renderer | |
| +------------------+ +------------------+ +----------------------+ |
+===========================================================================+2.3 目录结构
echarts/
├── src/ # 【核心基建】源代码主目录
│ ├── core/ # 【核心基建】核心引擎层
│ │ ├── echarts.ts # 【核心基建】ECharts 主类 - 实例化、setOption、dispatchAction、事件系统、全局注册表
│ │ ├── ExtensionAPI.ts # 【核心基建】扩展 API - 内部调用接口,暴露给组件和图表使用
│ │ ├── Scheduler.ts # 【核心基建】任务调度器 - 管理 dataProcessor/visual 双阶段管道
│ │ ├── lifecycle.ts # 【核心基建】生命周期管理 - afterinit、afterupdate、rendered 事件钩子
│ │ ├── CoordinateSystem.ts # 【核心基建】坐标系管理器 - 按 mainType 索引所有坐标系实例
│ │ ├── impl.ts # 【核心基建】内部实现注册表 - getImpl() 获取平台特定实现
│ │ ├── locale.ts # 【核心基建】国际化 - 根据语言标识创建 Locale 对象
│ │ └── task.ts # 【核心基建】Task 定义 - Pipeline 任务的 createTask 工厂
│ ├── model/ # 【核心基建】数据模型层 (Model)
│ │ ├── Global.ts # 【核心基建】GlobalModel - option 解析、series/components 管理、数据恢复
│ │ ├── Series.ts # 【核心基建】SeriesModel - 系列基类,坐标系统绑定、数据访问
│ │ ├── Component.ts # 【核心基建】ComponentModel - 组件基类,mainType/subType 标识
│ │ ├── OptionManager.ts # 【核心基建】OptionManager - setOption 时的 timeline、media 查询处理
│ │ ├── globalDefault.ts # 【配置】全局默认值配置
│ │ └── mixin/ # 【工具集】Model Mixin 混入(areaStyle、lineStyle、itemStyle 等)
│ ├── view/ # 【核心基建】视图层基类 (View)
│ │ ├── Chart.ts # 【核心基建】ChartView 基类 - render()、dispose()、坐标系绑定
│ │ └── Component.ts # 【核心基建】ComponentView 基类 - render()、afterRender()、事件分发
│ ├── data/ # 【核心基建】数据管理系统
│ │ ├── SeriesData.ts # 【核心基建】核心数据容器 - 多维数据存储、CRUD、视觉编码存取
│ │ ├── DataDiffer.ts # 【核心基建】数据差分器 - 增量更新(new/old 对比)、最小操作集
│ │ ├── DataDimensionInfo.ts # 【核心基建】数据维度信息 - 维度名称、类型、索引管理
│ │ ├── Tree.ts # 【核心基建】树形结构 - 用于 tree/treemap/sunburst 图
│ │ ├── Graph.ts # 【核心基建】图结构 - 节点/边管理,用于 graph/sankey 图
│ │ ├── Source.ts # 【核心基建】数据源抽象 - 统一数组/对象/Dataset 输入格式
│ │ ├── helper/ # 【工具集】数据转换辅助函数 (createDimensions、createSource 等)
│ │ └── OrdinalMeta.ts # 【核心基建】序数元数据 - 管理序数轴的类别映射
│ ├── chart/ # 【业务模块】图表类型实现 (23 种图表,每个含 Series/View/install)
│ │ ├── line/ # 【业务模块】折线图/面积图 - LineSeries + LineView + install
│ │ ├── bar/ # 【业务模块】柱状图/条形图 - BarSeries + BarView + install
│ │ ├── pie/ # 【业务模块】饼图/环形图 - PieSeries + PieView + install
│ │ ├── scatter/ # 【业务模块】散点图/气泡图 - ScatterSeries + ScatterView + install
│ │ ├── map/ # 【业务模块】地图 - MapSeries + MapView + install
│ │ ├── graph/ # 【业务模块】关系图/力导向图 - GraphSeries + GraphView + install
│ │ ├── candlestick/ # 【业务模块】K 线图 - CandlestickSeries + CandlestickView + install
│ │ ├── boxplot/ # 【业务模块】箱线图 - BoxplotSeries + BoxplotView + install
│ │ ├── funnel/ # 【业务模块】漏斗图 - FunnelSeries + FunnelView + install
│ │ ├── gauge/ # 【业务模块】仪表盘 - GaugeSeries + GaugeView + install
│ │ ├── heatmap/ # 【业务模块】热力图 - HeatmapSeries + HeatmapView + install
│ │ ├── parallel/ # 【业务模块】平行坐标图 - ParallelSeries + ParallelView + install
│ │ ├── radar/ # 【业务模块】雷达图 - RadarSeries + RadarView + install
│ │ ├── sankey/ # 【业务模块】桑基图 - SankeySeries + SankeyView + install
│ │ ├── sunburst/ # 【业务模块】旭日图 - SunburstSeries + SunburstView + install
│ │ ├── themeRiver/ # 【业务模块】主题河流图 - ThemeRiverSeries + ThemeRiverView + install
│ │ ├── tree/ # 【业务模块】树图 - TreeSeries + TreeView + install
│ │ ├── treemap/ # 【业务模块】矩形树图 - TreemapSeries + TreemapView + install
│ │ ├── chord/ # 【业务模块】和弦图 - ChordSeries + ChordView + install
│ │ ├── lines/ # 【业务模块】路径图 (飞线) - LinesSeries + LinesView + install
│ │ ├── effectScatter/ # 【业务模块】涟漪散点图 - EffectScatterSeries + EffectScatterView + install
│ │ ├── pictorialBar/ # 【业务模块】象形柱图 - PictorialBarSeries + PictorialBarView + install
│ │ ├── custom/ # 【业务模块】自定义图表 - CustomSeries + CustomView (用户 renderItem)
│ │ └── helper/ # 【工具集】图表辅助(createClipPathFromCoordSys、label 样式等)
│ ├── component/ # 【业务模块】交互组件 (28 个组件,每个含 Model/View/install)
│ │ ├── axis/ # 【核心基建】坐标轴组件 - AxisModel + AxisView + AxisBuilder (1632行)
│ │ ├── axisPointer/ # 【业务模块】坐标轴指示器 - 跟随鼠标显示数值
│ │ ├── legend/ # 【业务模块】图例组件 - 图例切换/滚动 (plain + scroll 子类型)
│ │ ├── tooltip/ # 【业务模块】提示框组件 - 悬停数据提示
│ │ ├── visualMap/ # 【业务模块】视觉映射 - continuous 连续型 + piecewise 分段型
│ │ ├── dataZoom/ # 【业务模块】数据缩放 - inside/slider/select 多种交互类型
│ │ ├── grid/ # 【业务模块】绘图网格 - 定义矩形绘图区域 (含 gridSimple 简化类型)
│ │ ├── geo/ # 【业务模块】地理坐标系组件 - 管理 GeoJSON 地图注册与解析
│ │ ├── brush/ # 【业务模块】框选组件 - 矩形/多边形/任意区域选择联动
│ │ ├── toolbox/ # 【业务模块】工具箱 - saveAsImage、dataView、magicType 等功能
│ │ ├── title/ # 【业务模块】标题组件
│ │ ├── timeline/ # 【业务模块】时间轴组件 - 时间序列切换
│ │ ├── calendar/ # 【业务模块】日历坐标系 - 日期网格布局
│ │ ├── aria/ # 【业务模块】无障碍访问 - 屏幕阅读器支持
│ │ ├── dataset/ # 【核心基建】数据集 - 声明式数据源管理 (SourceManager)
│ │ ├── transform/ # 【业务模块】数据变换 - filter/sort/aggregate 等数据操作
│ │ ├── graphic/ # 【业务模块】原生图形 - 自定义 SVG-like 图形元素
│ │ ├── marker/ # 【业务模块】标记 - markPoint/markLine/markArea 标注
│ │ ├── polar/ # 【业务模块】极坐标组件 - 角度轴/半径轴管理
│ │ ├── radar/ # 【业务模块】雷达坐标系组件
│ │ ├── parallel/ # 【业务模块】平行坐标组件
│ │ ├── singleAxis/ # 【业务模块】单轴组件 - 一维坐标轴
│ │ ├── matrix/ # 【业务模块】矩阵组件 - 矩阵热力图坐标
│ │ ├── thumbnail/ # 【业务模块】缩略图组件 - dataZoom 的缩略图预览
│ │ └── helper/ # 【工具集】组件辅助函数 (listComponent、interactionMutex 等)
│ ├── coord/ # 【核心基建】坐标系抽象层 (接口定义 + 8 种实现)
│ │ ├── CoordinateSystem.ts # 【核心基建】坐标系接口 + 创建器/主控器类型定义
│ │ ├── cartesian/ # 【核心基建】笛卡尔坐标系 - Grid + Axis2D (x/y 轴)
│ │ ├── polar/ # 【核心基建】极坐标系 - 角度轴 + 半径轴
│ │ ├── geo/ # 【核心基建】地理坐标系 - GeoJSON 区域映射
│ │ ├── radar/ # 【核心基建】雷达坐标系 - 多边形轴
│ │ ├── calendar/ # 【核心基建】日历坐标系 - 日期单元格
│ │ ├── parallel/ # 【核心基建】平行坐标系 - 多轴平行
│ │ ├── single/ # 【核心基建】单轴坐标系 - 一维映射
│ │ └── matrix/ # 【核心基建】矩阵坐标系 - 行列索引到像素
│ ├── scale/ # 【核心基建】比例尺系统 - Interval/Ordinal/Time/Log Scale
│ ├── visual/ # 【核心基建】视觉编码系统
│ │ ├── style.ts # 【核心基建】全局样式编码 - seriesStyleTask + dataStyleTask
│ │ ├── symbol.ts # 【核心基建】符号编码 - seriesSymbolTask + dataSymbolTask
│ │ ├── decal.ts # 【核心基建】图案填充 - decalVisualStageHandler (无障碍)
│ │ ├── helper.ts # 【工具集】视觉辅助函数
│ │ └── visualMapCommon.ts # 【工具集】visualMap 通用逻辑
│ ├── layout/ # 【核心基建】布局算法引擎
│ │ ├── points.ts # 【核心基建】散点布局 - layoutPoints (笛卡尔坐标映射)
│ │ ├── barGrid.ts # 【核心基建】柱状图网格布局
│ │ └── forceLayout.ts # 【核心基建】力导向布局 (graph 图)
│ ├── animation/ # 【核心基建】动画系统 - 数据更新时的过渡动画
│ ├── label/ # 【核心基建】标签布局 - 标签防重叠、自动排列算法
│ ├── processor/ # 【核心基建】数据处理器
│ │ ├── dataStack.ts # 【核心基建】数据堆叠 - dataStackStageHandler (堆叠图表)
│ │ └── dataSample.ts # 【核心基建】数据采样 - 大数据量降采样 (LTTB 算法)
│ ├── preprocessor/ # 【核心基建】预处理管道
│ │ ├── backwardCompat.ts # 【核心基建】向后兼容 - 旧版 option 格式转换
│ │ └── helper/ # 【工具集】预处理辅助 (compatStyle 等)
│ ├── renderer/ # 【核心基建】渲染器安装
│ │ └── installCanvasRenderer.ts # 【核心基建】Canvas 渲染器安装函数
│ ├── theme/ # 【配置】内置主题
│ │ └── dark.ts # 【配置】暗色主题 (dark)
│ ├── loading/ # 【UI 视图】加载动画
│ │ └── default.ts # 【UI 视图】默认加载动画效果
│ ├── i18n/ # 【配置】国际化源文件 (55+ 语言)
│ ├── util/ # 【工具集】通用工具函数库
│ │ ├── types.ts # 【核心基建】全局类型定义 (2211行) - Payload, Event, Option 类型
│ │ ├── graphic.ts # 【工具集】图形工具 - 创建 zrender 元素、裁剪路径
│ │ ├── states.ts # 【工具集】状态管理 - 高亮/淡化/选中/强调 的状态机
│ │ ├── model.ts # 【工具集】模型工具 - option 查找、组件引用解析
│ │ ├── format.ts # 【工具集】格式化 - 数值/时间/文本格式化
│ │ ├── number.ts # 【工具集】数值计算 - 精度处理、范围计算
│ │ ├── color.ts # 【工具集】颜色处理 - 渐变、调色板
│ │ ├── time.ts # 【工具集】时间处理 - 日期解析、格式化
│ │ ├── layout.ts # 【工具集】布局辅助 - 盒模型布局计算
│ │ ├── innerStore.ts # 【工具集】内部存储 - getECData/setECData 元素元数据
│ │ ├── ECEventProcessor.ts # 【工具集】事件处理器 - 事件代理和分发
│ │ ├── component.ts # 【工具集】组件辅助 - getUID、SubTypeDefaulter
│ │ ├── clazz.ts # 【工具集】类工具 - enableClassCheck、parseClassType
│ │ ├── log.ts # 【工具集】日志工具 - warn/error/deprecateLog
│ │ ├── event.ts # 【工具集】事件辅助 - findEventDispatcher
│ │ ├── throttle.ts # 【工具集】节流函数
│ │ └── shape/ # 【工具集】自定义 zrender 形状
│ ├── legacy/ # 【废弃】向后兼容的旧版 API (dataSelect 等)
│ ├── export/ # 【核心基建】公开导出层
│ │ ├── core.ts # 【核心基建】核心 API 导出 - 组合所有核心功能
│ │ ├── option.ts # 【核心基建】EChartsOption 类型组合
│ │ └── api/ # 【核心基建】API 函数导出 (time/number/format/graphic)
│ ├── echarts.all.ts # 【配置】全量入口 - 安装所有 23 种图表 + 28 种组件
│ ├── echarts.blank.ts # 【配置】空白入口 - 最小包,仅核心功能
│ ├── echarts.common.ts # 【配置】通用入口 - 常用图表 (line/bar/pie/scatter) + 基础组件
│ ├── echarts.simple.ts # 【配置】简化入口 - 基础图表 + 少量组件
│ ├── echarts.ts # 【配置】默认入口 - Canvas 渲染器 + Dataset
│ └── extension.ts # 【核心基建】扩展系统 - use() 函数 + extensionRegisters
├── build/ # 【工具集】构建脚本和配置
│ ├── build.js # 【工具集】构建主脚本 - Rollup/esbuild 配置
│ ├── build-i18n.js # 【工具集】国际化构建脚本
│ ├── build-lib.js # 【工具集】库构建 - lib 目录下的单独模块
│ ├── dev-fast.js # 【工具集】开发模式快速构建
│ └── config.js # 【配置】构建配置
├── test/ # 【质量保证】测试目录
│ ├── ut/ # 【质量保证】单元测试 - Jest 配置和测试用例
│ ├── runTest/ # 【质量保证】可视化测试 - 截屏比对、测试服务器
│ ├── data/ # 【质量保证】测试数据 - 大型数据集、GeoJSON
│ ├── lib/ # 【工具集】测试辅助库 - testHelper.js (3562行)
│ └── build/ # 【工具集】测试构建工具 - mktest 测试用例生成
├── dist/ # 【配置】构建产物目录
├── types/ # 【配置】TypeScript 声明文件发布目录
├── theme/ # 【配置】预置主题文件 (40+ 主题)
├── i18n/ # 【配置】国际化文件发布目录 (55+ 语言)
├── extension-src/ # 【业务模块】扩展源码
│ └── bmap/ # 【业务模块】百度地图扩展 - BMapCoordSys + BMapModel + BMapView
├── ssr/ # 【业务模块】服务端渲染
│ └── client/ # 【业务模块】SSR 客户端 - Node.js 端渲染入口
├── asset/ # 【配置】静态资源 (logo 等)
├── .github/ # 【配置】GitHub Actions CI/CD
├── package.json # 【配置】项目配置 NPM 包定义 (v6.1.0)
├── tsconfig.json # 【配置】TypeScript 编译配置
├── README.md # 【配置】项目英文说明文档
├── README-CN.md # 【配置】项目中文说明文档 (本次分析生成)
├── LICENSE # 【配置】Apache 2.0 许可证
└── CONTRIBUTING.md # 【配置】贡献指南3. 模块依赖与调用关系
3.1 全局入口与核心路由
逻辑说明:用户通过 echarts.init() 创建 ECharts 实例。扩展(图表、组件)通过 use() 函数注册到全局注册表。setOption() 触发调度管道依次执行 dataProcessor 和 visual 阶段。每个阶段遍历所有已注册的 handler,按优先级排序后执行。
调用拓扑:
echarts.all.ts (全量入口 - 安装所有图表 + 组件 + 功能)
|
+---> echarts.ts (默认入口 - Canvas + Dataset)
| |
| +---> extension.ts::use() -- 注册扩展到全局注册表
| +---> export/core.ts -- 导出核心 API
|
+---> core/echarts.ts (核心引擎)
|
+---> ECharts.constructor()
| |
| +---> zrender.init(dom, opts) -- 创建渲染器
| +---> createExtensionAPI(ec) -- 创建内部 API
| +---> new Scheduler(ec, api, dataProcessorFuncs, visualFuncs)
| +---> new CoordinateSystemManager()
|
+---> ECharts.setOption(option)
| |
| +---> OptionManager.setOption() -- 解析 option
| +---> GlobalModel.restoreData() -- 恢复数据状态
| +---> Scheduler.restoreData() -- 标记所有任务为 dirty
| +---> Scheduler.wipTasks() -- 执行调度管道
| |
| +---> [dataProcessor Stage 1..N]
| | |
| | +---> processor/dataStack.ts
| | +---> processor/dataSample.ts
| | +---> component/dataZoom/
| |
| +---> [visual Stage 1..N]
| |
| +---> visual/style.ts (seriesStyleTask, dataStyleTask)
| +---> visual/symbol.ts (seriesSymbolTask, dataSymbolTask)
| +---> visual/decal.ts
| +---> component/visualMap/
|
+---> ECharts.dispatchAction(payload)
|
+---> ComponentView/ChartView::onAction()
+---> ECharts.setOption() (可能触发重新渲染)3.2 核心业务实体与关联
实体定义:
- ECharts (Instance):图表主实例,管理整个图表生命周期,每个 DOM 元素对应一个实例
- GlobalModel (ecModel):全局选项模型,解析并持有整个 option 对象树,管理所有 SeriesModel 和 ComponentModel
- SeriesModel:系列模型,管理单个系列的数据、类型、样式配置
- ComponentModel:组件模型,管理单个组件(如 legend、tooltip、axis)的配置
- SeriesData:系列数据存储,持有实际的二维数据表(类似 DataFrame),支持维度定义和数据操作
- ChartView:图表视图,负责将 SeriesModel + SeriesData 渲染为 zrender 图形元素
- ComponentView:组件视图,负责渲染 UI 控件(图例、提示框等)
- CoordinateSystem:坐标系,提供数据点到像素的映射能力
实体引用拓扑 (plainText):
[ECharts Instance] 1 -----> 1 [GlobalModel (ecModel)]
|
+-- 1 -----> N [SeriesModel]
| |
| +-- 1 -----> 1 [SeriesData]
| | |
| | +-- 1 -----> N [Dimension]
| |
| +-- 1 -----> 1 [ChartView]
| |
| +-- 1 -----> 1 [CoordinateSystem]
|
+-- 1 -----> N [ComponentModel]
| |
| +-- 1 -----> 1 [ComponentView]
|
+-- 1 -----> 1 [Scheduler]
|
+-- 1 -----> N [StageHandler (Pipeline Task)]4. 核心模块详解
模块一:扩展系统 (Extension System)
设计说明:ECharts 的核心设计模式是插件化扩展。所有功能模块(图表、组件、坐标系、视觉编码、布局算法、数据处理器等)通过统一的
install()函数注册。use()函数管理全局扩展状态,避免重复注册。extensionRegisters提供所有可注册的类型入口,每个扩展函数接收此对象并调用需要的注册方法。这是典型的 IoC(控制反转) 模式。内部结构图 (plainText):
use(CustomExtInstaller)
|
v
+-------------------+ +-----------------------------------+
| extensions[] | ----> | extensionRegisters |
| (去重检查) | | |
+-------------------+ | registerChartView() |
| registerSeriesModel() |
| registerComponentModel() |
| registerComponentView() |
| registerPreprocessor() |
| registerProcessor() |
| registerVisual() |
| registerLayout() |
| registerAction() |
| registerCoordinateSystem() |
| registerTransform() |
| registerMap() |
| registerLoading() |
| registerPostInit() |
| registerPostUpdate() |
| registerUpdateLifecycle() |
+-------------------+---------------+
|
+---------------------+---------------------+
| | |
v v v
+-----------+ +-----------+ +-----------+
| ChartView | | SeriesModel| | coordinate |
| .register | | .register | | System |
| Class() | | Class() | | Manager |
+-----------+ +-----------+ +-----------+模块二:调度管道 (Scheduler Pipeline)
设计说明:调度器是 ECharts 的数据处理编排核心。当
setOption()被调用时,调度器将所有注册的 dataProcessor 和 visual handler 按优先级排序后组成 Pipeline 任务链。每个 Pipeline 的 head 到 tail 按顺序执行。任务支持渐进式渲染(progressive rendering):大数据量时可以在多个帧中分块渲染,避免阻塞 UI。整体任务 (OverallTask) 在整个管道完成后执行,用于跨系列计算(如 dataZoom)。内部结构图 (plainText):
Scheduler.wipTasks(ecModel, payload)
|
+---> _pipelineMap (key: pipelineId)
| |
| +-- Pipeline: { head -> Task1 -> Task2 -> ... -> tail }
| |
| +-- progressiveEnabled (是否允许渐进渲染)
| +-- blockIndex (阻塞点位置)
| +-- context.progressiveRender / large
|
+---> getPerformArgs(task) -- 计算增量步长
|
+---> performStageTask(task, {block, setDirty, visualType})
|
+-- [SeriesTask1, SeriesTask2, ...] (per-series handler)
| |
| +-- handler.plan(seriesModel) -- 计划阶段
| +-- handler.reset(seriesModel, ecModel, api, payload)
| | |
| | +-- 操作 SeriesData (过滤/映射/统计)
| |
| +-- [OverallTask] (跨系列 handler)
| |
| +-- handler.overallReset(ecModel, api, payload)
|
+-- (所有 task 完成后) -> Scheduler.unfinished = false模块三:数据管理系统 (Data System)
设计说明:SeriesData 是 ECharts 的核心数据容器,类似于 DataFrame。它管理多维数据(dimensions),提供 CRUD 操作、数据差分(DataDiffer)、数据映射和视觉编码存取。Source 是对原始输入数据的抽象层,支持数组、对象、Dataset 等多种格式。DataDiffer 通过比较新旧数据索引数组,实现最小化的增删操作,减少渲染开销。
内部结构图 (plainText):
+-------------------+ +-----------------------+
| Source | | SeriesData |
| (数据源抽象) | ----> | (核心数据容器) |
| | | |
| - sourceFormat | | - _chunkList[] |
| - dimensions[] | | - _dimensions[] |
| - data[] | | - _count |
| - schema | | - _rawCount |
+-------------------+ | - _indices |
| |
Dataset Component | + getItem(idx, dim) |
(src/component/dataset) | + appendData() |
| | + getVisual() |
v | + setVisual() |
+-------------------+ | + mapDimension() |
| SourceManager | | + mapArray() |
| (管理多个 Source) | +-----------+-----------+
+-------------------+ |
| 使用
v
+-----------------------+
| DataDiffer |
| (增量更新算法) |
| |
| + diff(oldIdx, newIdx)|
| -> added[] |
| -> removed[] |
| -> updated[] |
+-----------------------+模块四:坐标系系统 (Coordinate System)
设计说明:坐标系是 ECharts 中数据空间到像素空间的映射器。每种图表类型布局在特定的坐标系上(例如折线图在 Cartesian2D,饼图无坐标系)。CoordinateSystemManager 管理所有已注册的坐标系创建器。每个坐标系包含轴(Axis)和区域(Area,如 Grid/Rect),负责将数据值转换为画布上的像素坐标。
内部结构图 (plainText):
+-------------------------------+ +------------------------------+
| CoordinateSystemManager | | CoordinateSystem Interface |
| | | |
| - _coordinateSystems[] | | + getAxes(): Axis[] |
| - create(ecModel, api) | | + dataToPoint(val[]): number[]|
| - get(mainType): Coordinate | | + pointToData(pt[]): number[]|
| System[] | | + getRect(): BoundingRect |
+-----------+-------------------+ +-------------+----------------+
| |
| 管理 | 实现
v v
+-----------+-------+ +-------+--------+ +--------+----------+
| cartesian/ | | polar/ | | geo/ |
| Cartesian2D | | Polar | | Geo |
| - xAxis: Axis | | - radiusAxis | | - region[] |
| - yAxis: Axis | | - angleAxis | | - nameCoordMap |
| - gridRect | | - cx, cy | | |
+-------------------+ +----------------+ +-------------------+
+-------------------+ +----------------+ +-------------------+
| calendar/ | | radar/ | | parallel/ |
| Calendar | | Radar | | Parallel |
| - cellWidth | | - cx, cy | | - axes[] |
| - cellHeight | | - radius | | - layoutInfo |
+-------------------+ +----------------+ +-------------------+模块五:视觉编码系统 (Visual Encoding)
设计说明:视觉编码将数据属性映射为视觉通道(颜色、大小、形状、透明度等)。系统通过 registerVisual() 注册视觉处理函数,在调度管道的 visual 阶段执行。关键视觉任务包括:style 任务(seriesStyleTask、dataStyleTask)应用 itemStyle 配置;symbol 任务计算图例和数据的符号样式;visualMap 组件提供连续/分段数据到视觉通道的映射;decal 任务生成图案填充以备无障碍访问。
内部结构图:
Visual Stage 执行顺序 (按 PRIORITY.VISUAL 排序):
LAYOUT (1000)
|
v
PROGRESSIVE_LAYOUT (1100)
|
v
GLOBAL (2000) ---- seriesStyleTask, dataStyleTask
| (应用全局 itemStyle 配置)
v
CHART (3000) ------ seriesSymbolTask, dataSymbolTask
| (图表特定的视觉编码)
v
COMPONENT (4000) --- visualMap 视觉映射
| legend 图例颜色
v
CHART_DATA_CUSTOM (4500)
| (data 级别的 itemStyle 覆盖)
v
POST_CHART_LAYOUT (4600)
| (基于视觉结果的二次布局,如 symbolSize)
v
BRUSH (5000) ------ brush 框选高亮
|
v
ARIA (6000) ------- aria 无障碍标签
|
v
DECAL (7000) ------ decal 图案填充5. 关键数据流程
5.1 初始化与渲染完整流程
场景说明:用户在页面上初始化一个折线图,并通过 setOption() 传入数据。系统完整经历了:实例创建 → option 解析 → 数据处理管道 → 视觉编码管道 → 视图渲染 → zrender 绘制的全过程。
流转时序图:
6. 接口与契约规范
6.1 核心内部模块契约 (TypeScript Interfaces)
/**
* ECharts 实例初始化选项
*/
export interface EChartsInitOpts {
/** 渲染器类型 */
renderer?: 'canvas' | 'svg';
/** 设备像素比 */
devicePixelRatio?: number;
/** 画布宽度 */
width?: number | 'auto';
/** 画布高度 */
height?: number | 'auto';
/** 是否使用脏矩形优化 */
useDirtyRect?: boolean;
/** 是否为服务端渲染 */
ssr?: boolean;
/** 国际化语言标识 */
locale?: string | LocaleOption;
/** 粗指针模式 (触屏优化) */
useCoarsePointer?: 'auto' | boolean;
/** 指针事件区域大小 */
pointerSize?: number;
}
/**
* ECharts 实例核心接口
*/
export interface EChartsType extends Eventful<ECEventDefinition> {
/** 实例 ID */
id: string;
/** 分组 ID (用于联动) */
group: string;
/** 设置图表配置项 */
setOption<Opt extends ECBasicOption>(
option: Opt,
notMerge?: boolean | SetOptionOption,
lazyUpdate?: boolean
): void;
/** 获取 DOM 容器宽度 */
getWidth(): number;
/** 获取 DOM 容器高度 */
getHeight(): number;
/** 获取 zrender 实例 */
getZr(): ZRenderType;
/** 获取选项 */
getOption(): ECOption;
/** 改变图表尺寸 */
resize(opts?: { width?: number; height?: number; silent?: boolean }): void;
/** 派发行为 (触发图表交互) */
dispatchAction(payload: Payload): void;
/** 绑定事件处理器 */
on(eventName: string, handler: EventCallback, context?: object): void;
/** 解绑事件处理器 */
off(eventName: string, handler?: EventCallback): void;
/** 转换为 Base64 图片 */
getDataURL(opts?: { type?: 'png' | 'jpeg'; pixelRatio?: number; backgroundColor?: string }): string;
/** 获取连接的 DataURL */
getConnectedDataURL(opts?: object): string;
/** 转换为图片 (Canvas) */
convertToPixel(
finder: ModelFinder,
value: ScaleDataValue | ScaleDataValue[]
): number | number[];
/** 从像素坐标转换为数据值 */
convertFromPixel(
finder: ModelFinder,
value: number | number[]
): number | number[];
/** 销毁实例 */
dispose(): void;
/** 是否已销毁 */
isDisposed(): boolean;
/** 显示加载动画 */
showLoading(type?: string, opts?: object): void;
/** 隐藏加载动画 */
hideLoading(): void;
/** 判断是否为 SSR 模式 */
isSSR(): boolean;
}
/**
* 调度器核心接口
*/
interface SchedulerCore {
/** 恢复数据状态 (标记 dirty) */
restoreData(ecModel: GlobalModel, payload: Payload): void;
/** 执行所有 pending 任务 */
wipTasks(): void;
/** 创建 Pipeline (seriesUID -> pipelineId) */
createPipeline(seriesUID: string): string;
}
/**
* SeriesData 数据容器核心接口
*/
interface SeriesDataCore<VisualMetaInfo> {
/** 数据项数量 */
count(): number;
/** 获取指定维度名称 */
getDimension(dim: DimensionIndex): string;
/** 获取数据值 */
get(dim: DimensionIndex, dataIndex: number): OptionDataValue;
/** 获取数据项的视觉编码 */
getVisual(key: string): any;
/** 设置视觉编码 */
setVisual(key: string, value: any): void;
/** 追加数据 (增量更新) */
appendData(values: OptionDataValue[][]): void;
/** 获取完整的数据项模型 */
getItemModel<ItemOpts>(idx: number): Model<ItemOpts>;
/** 映射数据到数组 */
mapArray<OutputT>(dim: DimensionIndex | string, cb: (val: any, idx: number) => OutputT): OutputT[];
}扩展安装器契约 (TypeScript Interface)
/**
* 扩展安装器类型
* 每个图表/组件模块导出 install 函数,接收注册器对象
*/
export type EChartsExtensionInstaller = (ec: EChartsExtensionInstallRegisters) => void;
/**
* 扩展安装注册器 - 提供所有可注册类型的入口
*/
export interface EChartsExtensionInstallRegisters {
registerChartView(ChartViewClass: typeof ChartView): void;
registerSeriesModel(SeriesModelClass: Constructor): void;
registerComponentModel(ComponentModelClass: Constructor): void;
registerComponentView(ComponentViewClass: typeof ComponentView): void;
registerPreprocessor(fn: OptionPreprocessor): void;
registerProcessor(priority: number, fn: StageHandler): void;
registerVisual(priority: number, fn: StageHandler): void;
registerLayout(fn: StageHandler): void;
registerAction(actionInfo: ActionInfo, handler: ActionHandler): void;
registerCoordinateSystem(type: string, creator: CoordinateSystemCreator): void;
registerTransform(spec: ExternalDataTransformSpec): void;
registerMap(mapName: string, geoJson: object, specialAreas?: object): void;
registerLoading(name: string, creator: LoadingEffectCreator): void;
registerPostInit(fn: PostIniter): void;
registerPostUpdate(fn: PostUpdater): void;
registerUpdateLifecycle(name: string, fn: UpdateLifecycleHandler): void;
registerCustomSeries(seriesType: string, renderItem: CustomSeriesRenderItem): void;
registerSubTypeDefaulter(componentType: string, defaulter: SubTypeDefaulter): void;
PRIORITY: typeof PRIORITY;
ComponentModel: typeof ComponentModel;
ComponentView: typeof ComponentView;
SeriesModel: typeof SeriesModel;
ChartView: typeof ChartView;
}8. 快速开始
8.1 环境配置
# 要求 Node.js 18+
node --version
# 安装依赖
npm install8.2 开发模式
# 开发模式(监听文件变化,自动构建)
npm run dev
# TypeScript 类型检查
npm run checktype
# 运行单元测试
npm test8.3 典型用例
import * as echarts from 'echarts';
// 初始化
const chart = echarts.init(document.getElementById('main'));
// 设置数据和配置
chart.setOption({
title: { text: 'ECharts 入门示例' },
tooltip: {},
xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] },
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
});8.4 按需引入
// 仅引入核心
import * as echarts from 'echarts/core';
// 按需引入图表和组件
import { BarChart } from 'echarts/charts';
import { TooltipComponent, GridComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
echarts.use([BarChart, TooltipComponent, GridComponent, CanvasRenderer]);8.5 构建发布
# 构建所有格式
npm run release
# 产物在 dist/ 目录