Skip to content

ECharts 开源项目解读

项目信息

  • 项目名称:ECharts

  • 项目描述*ECharts 是一个面向 Web 的声明式数据可视化图表库,基于纯 JavaScript/TypeScript 开发,底层依赖自研 Canvas 渲染引擎 zrender。本项目是 Apache 软件基金会的顶级开源项目。

  • 项目地址:https://github.com/apache/echarts

  • 官方文档:https://echarts.apache.org/zh/index.html

  • 解决的核心痛点

    • 声明式 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

解决的核心痛点

  1. 声明式 vs 命令式:开发者只需声明数据和图表配置(option),无需手动操作 Canvas API 逐像素绘制,极大降低可视化开发门槛。

  2. 复杂的图表交互:内置缩放、平移、框选、提示框、图例切换等丰富的交互行为,避免开发者重复造轮子。

  3. 跨平台一致性:统一的数据模型和渲染层,屏蔽 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 对象模型和事件系统,适合声明式框架
语言TypeScriptJavaScript大型代码库的类型安全,复杂 option 的自动补全
构建Rollup + esbuildWebpack高效的 ESM/CJS/UMD 多格式输出
数据模型dataset + Sourceseries.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 整体架构图

text
+===========================================================================+
|                         用户 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 目录结构

shell
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,按优先级排序后执行。

调用拓扑

text
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)

text
[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)

text
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)

text
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)

text
+-------------------+       +-----------------------+
|     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)

text
+-------------------------------+       +------------------------------+
| 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 任务生成图案填充以备无障碍访问。

内部结构图

text
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)

typescript
/**
 * 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)

typescript
/**
 * 扩展安装器类型
 * 每个图表/组件模块导出 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 环境配置

shell
# 要求 Node.js 18+
node --version

# 安装依赖
npm install

8.2 开发模式

shell
# 开发模式(监听文件变化,自动构建)
npm run dev

# TypeScript 类型检查
npm run checktype

# 运行单元测试
npm test

8.3 典型用例

typescript
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 按需引入

typescript
// 仅引入核心
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 构建发布

shell
# 构建所有格式
npm run release
# 产物在 dist/ 目录