Comprehensive operational, architectural, and developer reference for Apache ECharts v6.0.0. Audience: platform engineers embedding ECharts at scale, library authors extending it, build engineers configuring tree-shaken bundles, and security/compliance reviewers.
Executive Summary
Apache ECharts is a browser-based charting and data-visualization library, governed by the Apache Software Foundation under the Apache 2.0 license. Version 6.0.0 (commit c8adaf4, 2026-02-26) ships 23 chart types, 28 component types, 7 coordinate systems, dual renderers (Canvas + SVG), server-side rendering, 53 locales, and 37 built-in themes.
| Attribute | Value |
|---|---|
| Package | echarts |
| Version analyzed | 6.0.0 |
| License | Apache-2.0 |
| Source repo | apache/echarts |
| Source commit | c8adaf4 (2026-02-26) |
| Runtime deps | zrender@6.0.0, tslib@2.3.0 |
| Build tool | Rollup 2.34.2 + esbuild 0.8.39 + Terser 5.x |
| Language | TypeScript 4.4.3 |
| Module system | ESM + UMD + CJS (multi-entry exports) |
| Test framework | Jest 26 (unit) + Puppeteer 23 (visual regression) |
| Source files (.ts) | 1,909 |
| Source size | ~5.49 M characters |
| Bundle entries | all, common, simple, blank, ssr, extension |
ECharts is library-as-platform: it does not run a server, does not own data, and does not perform network I/O. All operational concerns concern embedding it in a host application — bundle size, render performance, accessibility, SSR hydration, theme governance, and locale loading.
Architecture
High-level component diagram
┌────────────────────────────────────────────────────────────────────────┐
│ Host Application │
│ (React / Vue / Angular / vanilla — provides DOM container & data) │
└─────────────────────────────────┬──────────────────────────────────────┘
│ init(dom, theme, opts)
▼
┌────────────────────────────────────────────────────────────────────────┐
│ ECharts Instance (core) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │
│ │ GlobalModel │ │ Scheduler │ │ ChartView │ │ ComponentView│ │
│ │ (option → │→ │ (pipeline │→ │ (per- │ │ (axis, grid, │ │
│ │ models) │ │ stages) │ │ series) │ │ legend, …) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └──────────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ Coordinate Systems Manager │ │
│ │ cartesian (grid) │ polar │ geo │ single │ parallel │ calendar │ │
│ │ │ matrix (v6 NEW) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ Visual Pipeline (visual/, processor/, layout/) │ │
│ │ data transform → scale → visual mapping → label layout │ │
│ └──────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────┬──────────────────────────────────────┘
│ render display objects
▼
┌────────────────────────────────────────────────────────────────────────┐
│ zrender (graphics engine) │
│ ┌─────────────────────┴──────────────────────┐ │
│ ▼ ▼ │
│ ┌───────────────┐ ┌──────────────┐ │
│ │ CanvasPainter │ │ SVGPainter │ │
│ │ (default) │ │ (a11y / SSR)│ │
│ └───────────────┘ └──────────────┘ │
└────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────┐
│ DOM <canvas> / <svg> │
└───────────────────────────────┘
Layered model
ECharts is organized in five distinct layers, each with a clear contract. Files live under src/:
| Layer | Folders | Responsibility |
|---|---|---|
| Core | src/core/, src/echarts.*.ts |
Lifecycle (init, dispose), action dispatch, event center, scheduler, plugin registration (use()) |
| Model | src/model/, src/data/ |
option → typed models (GlobalModel, SeriesModel, ComponentModel); data store (SeriesData, DataStore, Source) |
| Coordinate | src/coord/ |
Map data values → screen coordinates (cartesian, polar, geo, single, parallel, calendar, matrix) |
| Visual & Layout | src/visual/, src/processor/, src/layout/, src/scale/, src/label/ |
Compute colors, sizes, positions; resolve axis scales; place labels with collision avoidance |
| View | src/view/, src/chart/{type}, src/component/{type} |
Build display objects, hand off to zrender painter |
The flow on every setOption() call is strictly one-way: option → models → coord systems → visual pipeline → views → zrender → painter → DOM. Data never flows backward; user interaction enters via actions dispatched at the core, which mutate models and trigger a new render cycle.
Note
The one-way data flow is a deliberate architectural constraint. If you are building a custom extension that needs to feed information back from a view to a model, use
dispatchActionto route through the core — never mutate model state directly from a view.
Core class hierarchy
Sourced from _briefing/extracted/class_hierarchy.tsv (53 classes). Highlights:
| Class | Inherits | Source | Role |
|---|---|---|---|
ECharts |
Eventful |
src/core/echarts.ts:366 |
Top-level instance. Owns Scheduler, GlobalModel, MessageCenter, zr instance. |
MessageCenter |
Eventful |
src/core/echarts.ts:275 |
Pub/sub for chart events (click, legendselectchanged, …) |
Scheduler |
— | src/core/Scheduler.ts:102 |
Pipeline of Task nodes; executes per-stream incremental updates |
Task |
— | src/core/task.ts:92 |
Single node in the rendering pipeline; supports streaming + dirty regions |
CoordinateSystemManager |
— | src/core/CoordinateSystem.ts:46 |
Registers/looks up coord-system creators (cartesian, polar, …) |
GlobalModel |
Model |
src/model/Global.ts:156 |
Root option container; holds all ComponentModel and SeriesModel instances |
Model |
— | src/model/Model.ts:48 |
Generic option-tree wrapper with get/getModel/getShallow |
ComponentModel |
— | src/model/Component.ts:53 |
Base for axis/grid/legend/tooltip/etc models |
SeriesModel |
— | src/model/Series.ts:129 |
Base for every chart-type model; owns one SeriesData |
OptionManager |
— | src/model/OptionManager.ts:58 |
Merges option, baseOption, timeline options[], media queries |
ChartView |
— | src/view/Chart.ts:98 |
Base class for chart rendering; subclasses override render() |
ComponentView |
— | src/view/Component.ts:63 |
Base for axis-line, legend, title, etc. views |
Axis |
— | src/coord/Axis.ts:54 |
Generic axis (extent + scale + ticks); reused across coord systems |
View |
Transformable |
src/coord/View.ts:42 |
Pan/zoom transform layer used by geo and tree |
LabelManager |
— | src/label/LabelManager.ts:197 |
Global label collision/overlap resolution |
IntervalScale |
— | src/scale/Interval.ts:30 |
Linear numeric scale with nice ticks |
LogScale |
IntervalScale |
src/scale/Log.ts:40 |
Log10 (base configurable) |
OrdinalScale |
Scale |
src/scale/Ordinal.ts:45 |
Categorical |
TimeScale |
IntervalScale |
src/scale/Time.ts:113 |
Time axis with locale-aware tick formatting |
SeriesData |
— | src/data/SeriesData.ts:151 |
Columnar data view backed by DataStore |
DataStore |
— | src/data/DataStore.ts:159 |
Typed-array-backed columnar storage; supports streaming appendData |
Graph |
— | src/data/Graph.ts:32 |
Node-link data structure for graph/sankey/chord |
Tree |
— | src/data/Tree.ts:321 |
Hierarchical data for tree/treemap/sunburst |
Render pipeline (Scheduler stages)
The Scheduler (src/core/Scheduler.ts) runs an ordered set of stages on every render. Each stage may register tasks via registerProcessor, registerVisual, or registerLayout. The pipeline:
- Preprocessor — normalize raw
option(legacy migrations live insrc/preprocessor/) - Statistic / Filter —
processor/dataFilter.ts,processor/dataSample.tsfor downsampling - Visual — color/size/symbol assignment (
visual/) - Coordinate system update — recompute axis extents, ticks, view rects
- Layout — series-specific positioning (bar layout, pie layout, force-directed, …)
- Render — instruct each
ChartView/ComponentViewto update display objects - Label layout —
LabelManagerresolves collisions globally
Tasks are stream-aware: large datasets run incrementally across animation frames so the main thread is never blocked for long.
Tip
When profiling render performance, look at the Scheduler pipeline in DevTools — each
Tasknode corresponds to a discrete render stage. Long-running tasks in the "Visual" or "Layout" stages typically indicate too many data points or overly complex label collision resolution.
Bundle anatomy
Three pre-built entries are shipped:
| Entry | File | Contents | Size class |
|---|---|---|---|
echarts (all) |
dist/echarts.js, dist/echarts.min.js |
Every chart, component, renderer | Largest |
echarts/core + use() |
dist/echarts.simple.js baseline + selective imports |
Tree-shakeable; pick what you need | Smallest |
echarts/common |
dist/echarts.common.js |
Common subset (line/bar/pie/scatter + grid/tooltip/legend/...) | Medium |
Build is driven by build/build.js (Rollup) and produces UMD (dist/echarts.js), ESM (dist/echarts.esm.mjs), and minified variants. The sideEffects array in package.json (lines 33-44 of dependencies.cbf) explicitly marks only the entry indexes, theme, i18n, chart, component, and extension modules as side-effecting; everything else is tree-shakable.
Module reference (top-level src/)
| Folder | Files | Responsibility |
|---|---|---|
src/core/ |
9 | Engine: echarts.ts (init, instance, MessageCenter), Scheduler.ts, task.ts, CoordinateSystem.ts |
src/model/ |
8 | Global.ts (root model), Component.ts, Series.ts, OptionManager.ts, referHelper.ts (component cross-refs) |
src/data/ |
8 | SeriesData, DataStore, Source, Graph, Tree, OrdinalMeta, DataDiffer (for animation) |
src/chart/ |
23 chart-type folders | Each has a model + view + visual; e.g. bar/, pie/, line/, treemap/, sankey/, custom/ |
src/component/ |
33 component-type folders | Axis, grid, legend, tooltip, dataZoom (3 variants), visualMap (2 variants), brush, geo, calendar, matrix (NEW v6), thumbnail (NEW v6) |
src/coord/ |
12 | One folder per coordinate system: cartesian/, polar/, geo/, single/, parallel/, calendar/, matrix/, plus Axis.ts and View.ts shared base |
src/visual/ |
11 | Color, symbol, opacity, decal mappings; VisualMapping.ts is the universal applier |
src/processor/ |
4 | Data-stage operators: dataFilter, dataSample, dataStack, dataset-related |
src/layout/ |
3 | Cross-series layout helpers (bar grouping, points-on-line, etc.) |
src/scale/ |
8 | Interval, Log, Ordinal, Time, Scale.ts base, helper.ts (ScaleCalculator), breakImpl.ts (axisBreak) |
src/label/ |
6 | LabelManager (collision resolution), labelLayoutHelper, labelGuideHelper |
src/animation/ |
5 | Universal transition, custom-graphic transitions, AnimationWrap |
src/loading/ |
1 | Default loading spinner used by showLoading() |
src/preprocessor/ |
1 + helper | Legacy option migrations |
src/renderer/ |
2 | installCanvasRenderer, installSVGRenderer |
src/theme/ |
1 | Default + dark theme registration |
src/i18n/ |
26 | Built-in locale registrations |
src/view/ |
2 | Chart.ts, Component.ts base classes |
src/util/ |
24 | Conditional expressions, KDTree (point picking), event processor, model utilities, shape helpers, throttle |
src/legacy/ |
2 | Deprecated-shape compatibility shims |
src/export/ |
8 + api/ | Public API surface re-exports for echarts.all.ts, .common.ts, .simple.ts |
extension-src/bmap/ |
5 | Baidu Maps coordinate system integration |
extension-src/dataTool/ |
3 | gexf parser, prepareBoxplotData quartile helper |
ssr/client/src/ |
2 | hydrate(dom, options) for SSR-rendered SVG |
Plugin / extension architecture
ECharts uses a registration-by-import model. Every chart, component, renderer, feature, and extension exports an install function. The user calls echarts.use([install1, install2, …]), which pushes each installer onto a registry consulted during init(). Tree-shakers can then prune unused installers.
Cross-repo pattern observation: this use() model resembles Mermaid's plugin API and Storybook's addon registration — a use() function that takes an array of installers, each registering capabilities into a global manager. Library authors who already understand those ecosystems can apply the same mental model here.
Built-in installer categories:
| Category | Examples | Source |
|---|---|---|
| Charts | BarChart, LineChart, PieChart, MapChart, CustomChart |
src/chart/{type}/install.ts |
| Components | GridComponent, TooltipComponent, LegendComponent, DataZoomComponent, MatrixComponent |
src/component/{type}/install.ts |
| Renderers | CanvasRenderer, SVGRenderer |
src/renderer/installCanvasRenderer.ts, installSVGRenderer.ts |
| Coord systems | GridSystem (cartesian), PolarSystem, GeoSystem, SingleAxisSystem, ParallelSystem, CalendarSystem, MatrixSystem |
src/coord/{system}/install.ts |
| Features | UniversalTransition, LabelLayout, AxisBreak, LegacyGridContainLabel, ScatterJitter |
src/feature/* |
Coordinate systems
| System | Source folder | Used by | Notes |
|---|---|---|---|
cartesian (grid) |
src/coord/cartesian/ |
line, bar, scatter, heatmap, candlestick, boxplot, custom | x/y axes; supports breaks (v6) |
polar |
src/coord/polar/ |
line, bar, scatter, heatmap | angle + radius axes |
geo |
src/coord/geo/ |
map, scatter, heatmap, lines, custom | Requires registered map (registerMap) |
single |
src/coord/single/ |
scatter, heatmap, themeRiver | One-axis (typically time) |
parallel |
src/coord/parallel/ |
parallel, lines | N parallel axes |
calendar |
src/coord/calendar/ |
heatmap, scatter, graph, custom | Year-grid heatmap layout |
matrix (v6 NEW) |
src/coord/matrix/ |
scatter, line, bar, heatmap, custom | Cell-based matrix layout |
radar |
src/coord/radar/ |
radar | Note: separate from coord folder; treated specially |
Build flavors and entry points
From package.json exports (dependencies.cbf:111-238):
| Import path | Use case |
|---|---|
echarts |
Full bundle. Convenience for development. |
echarts/core |
Empty engine; pair with use([...]) for production tree-shaking. |
echarts/charts |
All chart install functions as named exports (BarChart, LineChart, …) |
echarts/components |
All component installers |
echarts/features |
Optional features (UniversalTransition, LabelLayout, …) |
echarts/renderers |
CanvasRenderer, SVGRenderer |
echarts/index.common |
Pre-bundled common subset |
echarts/index.simple |
Pre-bundled minimal (line/bar/pie + tooltip/legend) |
echarts/index.blank |
Engine-only (you must use() everything) |
echarts/ssr/client/index |
hydrate() for SSR-rendered SVG |
echarts/extension/bmap/bmap |
Baidu Maps coord system |
echarts/extension/dataTool/* |
gexf parser, prepareBoxplotData |
echarts/lib/chart/* |
Per-chart installer (also lib/component/*, lib/i18n/*, lib/theme/*) |
echarts/dist/echarts.{esm,common,simple}{,.min}.{js,mjs} |
Pre-built dist files |
Type definitions are split (types/dist/{all,charts,components,core,echarts,features,option,renderers,shared}.d.ts) so tree-shaken bundles can have correspondingly narrow type imports.
System Requirements
Browser runtime
| Requirement | Detail |
|---|---|
| JS runtime | ES5+ (transpiled output). Modern bundles target ES2015. |
| DOM APIs | Required: <canvas> + Canvas 2D context OR <svg> + SVG DOM |
| Window APIs | requestAnimationFrame, addEventListener, getComputedStyle, devicePixelRatio |
| Resize observation | ResizeObserver (preferred) or manual resize() calls |
| Touch / pointer | Optional; enables useCoarsePointer mobile mode |
| Workers | Not required (no Web Worker usage in core) |
Build / Node
| Requirement | Detail |
|---|---|
| Node.js | ≥ 14 (used by build/build.js) |
| TypeScript | 4.4.3 (devDependency, declarations published) |
| Rollup | 2.34.2 |
| esbuild | 0.8.39 (used by build/dev-fast.js) |
| Terser | 5.16.x (minification) |
| ESLint | 7.x (@typescript-eslint 4.x) |
| Jest | 26.x (jest-canvas-mock 2.5+) |
| Puppeteer | 23.x (visual regression in test/runTest/) |
SSR runtime
| Requirement | Detail |
|---|---|
| Node | Any LTS that runs zrender (uses XMLSerializer polyfill or none for SVG string mode) |
init opts |
{ ssr: true, renderer: 'svg' } |
| Output | chart.renderToSVGString() |
| Hydration | Browser bundle imports echarts/ssr/client/index and calls hydrate(dom, options) |
Data scale guidance
| Data points / series | Recommendation |
|---|---|
| < 1,000 | Default settings, any renderer |
| 1,000 – 50,000 | Canvas renderer; consider progressive rendering on the series; enable large: true (line/scatter/bar) |
| 50,000 – 500,000 | Canvas; appendData streaming; useDirtyRect: true; downsample via dataset.transform or series.sampling: 'lttb' |
| > 500,000 | Always Canvas; use lines series with large mode + GL-backed extension if available; reduce label rendering; disable animations |
Configuration Reference
ECharts is option-driven — there is no .env, no config file, no global mutable settings beyond what is set per-instance via init() opts and per-render via setOption(). Three levels of configuration matter to operators.
Level 1 — init(dom, theme?, opts?) (per-instance)
| Option | Type | Default | Effect |
|---|---|---|---|
renderer |
'canvas' | 'svg' |
'canvas' |
Painter selection. Switching at runtime requires dispose() + new init(). |
useDirtyRect |
boolean |
false |
Canvas-only. Repaints only changed regions. Reduces CPU on incremental updates. |
useCoarsePointer |
'auto' | boolean |
'auto' |
Mobile-friendly enlarged hit areas for touch. |
pointerSize |
number |
unset | Pixel radius for hit-tolerance when useCoarsePointer is on. |
ssr |
boolean |
false |
Server-rendering mode. Combine with renderer: 'svg'. Skips DOM event binding. |
locale |
string | object |
'EN' |
Locale id (must be registered) or full locale object. |
devicePixelRatio |
number |
window.devicePixelRatio |
Override canvas DPR; lower for perf, higher for retina. |
width |
number | 'auto' |
container width | Initial canvas width. |
height |
number | 'auto' |
container height | Initial canvas height. |
Level 2 — setOption(option, opts?) (per-render)
option is the entire chart definition. The full schema is too large to enumerate here (every chart type, component, axis, item-style, label, and emphasis state has its own subtree). Top-level keys:
| Key | Type | Purpose |
|---|---|---|
title |
object | Chart title and subtitle |
legend |
object | Legend behavior + scroll mode |
tooltip |
object | Tooltip trigger + formatter |
grid |
object | Cartesian plot area positioning |
xAxis / yAxis |
object | array | Cartesian axes (single or multiple) |
polar / radar / geo / singleAxis / parallel / calendar / matrix |
object | array | Other coordinate systems |
dataZoom |
array | Zoom controls (type: 'inside' | 'slider') |
visualMap |
array | Color/size mapping legends |
toolbox |
object | Built-in feature buttons (saveAsImage, dataView, restore, …) |
axisPointer |
object | Crosshair pointer config |
dataset |
object | array | Declarative data + transforms (replaces inline series.data for many cases) |
series |
array | Required. List of series; each has its own type. |
animation |
boolean | Enable/disable all animations. |
animationDuration |
number | function | Default 1000 ms. |
animationEasing |
string | Default 'cubicOut'. |
animationDelay |
number | function | Per-element delay (e.g. (idx) => idx * 10). |
useUTC |
boolean | Default false. Forces time-axis interpretation in UTC. |
media |
array | Responsive option overrides keyed on viewport size. |
aria |
object | Accessibility config (decal generation, aria-label generation). |
darkMode |
boolean | 'auto' | Toggle dark-mode color resolution. |
color |
string[] | Series default palette. |
backgroundColor |
string | Whole-canvas background. |
textStyle |
object | Default font for all text elements. |
setOption second-arg opts:
| Field | Default | Effect |
|---|---|---|
notMerge |
false |
If true, replaces the entire option (otherwise deep-merged into existing). |
replaceMerge |
array of component types | Component types to wholly replace rather than merge. |
lazyUpdate |
false |
Defer the actual render until next animation frame (batch multiple setOption calls). |
silent |
false |
Suppress events emitted from this update. |
transition |
object | Universal-transition overrides. |
replaceAnimation |
false |
Force-replace currently running animations. |
Level 3 — module-level
| Function | Purpose |
|---|---|
echarts.use(installers[]) |
Register chart types, components, renderers, features. Required for tree-shaken builds. |
echarts.registerTheme(name, theme) |
Add a named theme (referenced by init(dom, name)). |
echarts.registerMap(name, geoJson, specialAreas?) |
Register a geo map (required before using series.type: 'map' or geo component with that name). |
echarts.getMap(name) |
Retrieve registered map data. |
echarts.registerLocale(name, locale) |
Add a locale (i18n strings + date formats). |
echarts.connect(group) |
Synchronize tooltips, axisPointers, dataZoom across charts in a group. |
echarts.disconnect(group) |
Reverse of connect. |
echarts.dispose(target) |
Dispose by DOM, id, or instance. |
echarts.getInstanceByDom(dom) |
Lookup. |
echarts.getInstanceById(id) |
Lookup. |
Negative knowledge — what does NOT exist
To prevent fabrication, the following commonly-assumed configuration does not exist in v6.0.0:
- No environment variables. ECharts reads no
process.envat runtime; bundle-time__DEV__is the only build flag and is replaced by Rollup. - No global config file. No
echarts.config.js, no.echartsrc. Pure JS API. - No CLI binary.
echartsis not a command; the package has nobinfield. Thebuild/build.jsscript is internal-only. - No automatic data fetching. ECharts never issues HTTP requests on its own. Data is always provided by the host.
- No persistence layer. No localStorage, no cookies, no IndexedDB writes by ECharts itself.
- No telemetry / analytics. No outbound network calls of any kind.
- No license key / activation. Apache-2.0; no key required.
Important
The negative-knowledge list above is exhaustive for v6.0.0. If your team's documentation or wiki references ECharts environment variables, config files, or CLI commands, those references are incorrect — ECharts is configured entirely through its JavaScript API.
Deployment
Bundling strategies
Strategy A — Pre-bundled CDN (zero build)
Best for static sites, demos, and admin dashboards where bundle size is not critical.
<script src="https://cdn.jsdelivr.net/npm/echarts@6.0.0/dist/echarts.min.js"></script>
Variants: echarts.common.min.js (smaller, common subset), echarts.simple.min.js (smallest, line/bar/pie only).
Operational notes: pin a specific version (@6.0.0, never @latest); add Subresource Integrity (integrity="sha384-..."); host a self-mirrored copy if your CSP forbids third-party CDNs.
Warning
Never use
@latestor unpinned CDN URLs in production. A breaking change in a patch release could silently break your dashboards across all deployed instances simultaneously.
Strategy B — npm + tree-shaken use() (recommended for prod)
import * as echarts from 'echarts/core';
import { LineChart, BarChart } from 'echarts/charts';
import {
GridComponent, TooltipComponent, LegendComponent, DataZoomComponent
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import { LabelLayout, UniversalTransition } from 'echarts/features';
echarts.use([
LineChart, BarChart,
GridComponent, TooltipComponent, LegendComponent, DataZoomComponent,
CanvasRenderer,
LabelLayout, UniversalTransition,
]);
Result: production bundle typically 150–300 KB minified+gzipped vs. ~1 MB for the full bundle.
Strategy C — SSR
// Server (Node):
import * as echarts from 'echarts';
const chart = echarts.init(null, null, {
renderer: 'svg', ssr: true, width: 600, height: 400,
});
chart.setOption(option);
const svg = chart.renderToSVGString();
chart.dispose();
// Send `svg` in HTML payload.
// Client (browser):
import { hydrate } from 'echarts/ssr/client';
hydrate(domElement, { option, /* same as server */ });
The hydrate path attaches event handlers to the existing SVG without re-painting.
Strategy D — Self-hosted dist
Copy node_modules/echarts/dist/echarts.min.js into your static/ and reference with a relative URL. Useful in airgapped or strict-CSP environments.
CSP (Content Security Policy)
ECharts itself does not evaluate strings as code. It is compatible with strict CSP. Considerations:
| CSP directive | Required for ECharts? |
|---|---|
script-src |
Allow self (or your CDN). No 'unsafe-eval' needed. |
style-src |
If you use 'unsafe-inline' styles in custom-graphic, allow accordingly. ECharts itself does not inject style tags. |
img-src |
Required if you use series.symbol: 'image://...' or pictorialBar with image symbols. |
connect-src |
Not required by ECharts; only if your code fetches data. |
worker-src |
Not required. |
font-src |
Required if labels reference custom web fonts. |
getDataURL() and getConnectedDataURL() produce data: URIs purely client-side; no network egress.
Deployment checklist
- [ ] Pin exact version (
echarts@6.0.0, no caret/tilde) in production lockfiles. - [ ] Use the tree-shaken
use()pattern; verify bundle size withwebpack-bundle-analyzeror equivalent. - [ ] Set
useDirtyRect: truefor canvas charts that update incrementally. - [ ] Decide renderer: Canvas for perf/large data; SVG for accessibility, vector export, or tiny-DOM constraints.
- [ ] Register only the locales your audience needs (each adds ~10–30 KB).
- [ ] Register only the maps you actually render (
world.jsonis ~700 KB). - [ ] Configure
ResizeObserverorwindow.resizelistener →chart.resize(). - [ ] Always call
chart.dispose()in component unmount paths to free Canvas/SVG GPU resources. - [ ] Verify SSR and hydration if you ship server-rendered charts.
- [ ] Add accessibility: enable
aria.enabled: trueand providearia.label.description. - [ ] If embedding user-supplied option, sanitize formatter functions (see Security).
- [ ] Subscribe to
apache/echartsCVE feeds and the ASF security mailing list.
Operations
ECharts has no daemon, no log file, no metric exporter. "Operations" means monitoring the host application for issues caused by the chart instance.
Lifecycle management
init(dom, theme?, opts?) → ECharts instance
↓
setOption(option) → render
↓ (repeat as data changes)
resize() | dispatchAction(...) | clear() | appendData(...)
↓
dispose() → release Canvas/SVG, detach listeners, free zrender scene
Always dispose. Failure to call dispose() on unmount leaks Canvas-backed buffers and prevents GC of the ECharts instance. In React: call inside useEffect cleanup. In Vue: onBeforeUnmount. In Angular: ngOnDestroy.
Caution
A single missed
dispose()call in a SPA can leak 10–50 MB per chart instance (Canvas buffer + zrender scene graph + event listeners). In dashboards that mount/unmount charts on tab switches, this compounds quickly and will eventually crash the browser tab.
Resize strategy
ECharts does not auto-resize. Hook ResizeObserver:
const ro = new ResizeObserver(() => chart.resize());
ro.observe(container);
// On unmount: ro.disconnect(); chart.dispose();
For mobile orientation changes, also hook window.addEventListener('orientationchange', () => chart.resize()).
Health signals to monitor
| Signal | How | Indicates |
|---|---|---|
| Frame drops during render | requestAnimationFrame timing in dev tools |
Too many series / data points; switch to canvas + dirty-rect, downsample. |
| Memory growth | DevTools heap snapshot | Missing dispose() calls; check for retained DOM containers. |
Long task on setOption |
Performance profiler | Missing lazyUpdate; consider splitting updates or replaceMerge. |
Error on init() |
"Initialize failed: invalid dom." (src/core/echarts.ts:2797) |
DOM not yet attached, container has zero dimensions, or non-element passed. |
Error in renderToCanvas / renderToSVGString |
"renderToCanvas can only be used in the canvas renderer." (src/core/echarts.ts:836) / "renderToSVGString can only be used in the svg renderer." (src/core/echarts.ts:852) |
Wrong renderer for the method called. |
| "Option should contains series." | src/model/Global.ts:926 |
setOption called with no series[]. |
| "render method must been implemented" | src/view/Chart.ts:153 |
Custom chart subclass missing render(). |
| "BMap api is not loaded" / "Only one bmap component can exist" | extension-src/bmap/BMapCoordSys.ts:173,177 |
Baidu Map JS not loaded before ECharts uses it; or duplicate bmap config. |
Operational runbooks
Runbook: Chart appears blank
- Verify container has non-zero width/height (CSS).
- Check console for
"Initialize failed: invalid dom." - Confirm
setOptionwas called andoption.seriesis non-empty. - For
series.type: 'map', confirmregisterMap()ran first. - Inspect with
chart.getOption()to see what model state exists.
Runbook: Memory leak in SPA
- Open DevTools → Memory → take heap snapshot.
- Search for
EChartsconstructor instances. - If retained, find the DOM container; the framework component likely did not call
dispose(). - Add
dispose()to unmount lifecycle.
Runbook: Slow update with large dataset
- Confirm
renderer: 'canvas'. - Set
useDirtyRect: trueatinit. - On the affected series, set
large: trueandprogressive: 5000(line/scatter/bar). - For streaming data, prefer
chart.appendData({ seriesIndex, data })over re-setOption. - Reduce label/axis tick density; disable animations on update (
setOption(opt, { lazyUpdate: true })+animation: false).
Runbook: SSR hydration mismatch
- Ensure server and client receive the same
option(serialize once). - Both sides must
use([...])the same installers. - Same
width/heightininit()opts on both sides. - Date/timezone: set
useUTC: trueto avoid server/client timezone divergence.
Observability
ECharts emits chart events via chart.on(eventName, handler). Useful events for instrumentation:
| Event | When |
|---|---|
rendered |
After a render completes (one-shot per frame) |
finished |
Animations complete |
click, dblclick, mousedown, mouseup, mouseover, mouseout |
DOM-style |
legendselectchanged |
User toggled a legend item |
datazoom |
DataZoom range changed |
brushselected |
Brush component selection changed |
axisareaselected |
Parallel axis brushed |
restore |
Toolbox restore clicked |
Integrate with your observability platform by hooking rendered for render-rate metrics and error-thrown paths via global window.addEventListener('error').
Tip
The
renderedevent'sparams.elapsedTimeis the most reliable signal for detecting render regression. Track its P95 over time — a sudden jump after a dependency update or option change indicates a performance problem before users notice.
Performance Tuning
| Knob | Where | Effect |
|---|---|---|
renderer: 'canvas' |
init() |
Best perf for large data and animations. |
useDirtyRect: true |
init() |
Canvas-only; repaint only changed regions. |
devicePixelRatio |
init() |
Lower (e.g. 1) on retina to halve fill cost; trade for sharpness. |
progressive |
series |
Render N points per frame; smooths large initial render. |
large: true, largeThreshold |
series (line/scatter/bar) |
Switch to optimized batch path. |
sampling: 'lttb' | 'average' | 'max' | 'min' |
series.line |
Downsample to viewport pixel count. |
animation: false |
top-level option | Skip animations entirely. |
lazyUpdate: true |
setOption opts |
Coalesce multiple updates within one frame. |
replaceMerge |
setOption opts |
Wholly replace components rather than deep-merge (faster + avoids stale fields). |
appendData |
instance method | Streaming-append rows without rebuilding SeriesData. |
series.silent: true |
series | Skip mouse-hit-test geometry maintenance. |
series.zlevel |
series | Group into separate canvases; updates to one don't repaint others. |
When to drop animations
- During rapid streaming (e.g. > 5 updates/sec): set
animation: falseat top level. - During programmatic
dataZoomfrom cursor: animations cause visible lag; disable on dataZoom updates. - For SSR: animations are irrelevant; set
animation: false.
Security
Threat model
ECharts runs entirely in the host's process (browser tab or Node). It does not introduce new network endpoints or persistent state. The threat surface is therefore:
- Untrusted
optioninjection — if your application accepts user-authored options (e.g. a dashboard editor), an attacker may pass formatter callbacks, image URLs, or HTML strings. - Untrusted data — series data fields rendered into tooltips/labels.
- Untrusted maps — registered GeoJSON contains arbitrary feature names that surface in tooltips.
- Bundle integrity — supply chain (CDN tampering, npm package compromise).
Mitigations
| Risk | Mitigation |
|---|---|
| XSS via tooltip formatter | Tooltip formatter accepts a string template or a function. The function may return a string that is set as innerHTML. Sanitize: prefer the string template form (auto-escapes); if you must use a function, return DOM nodes (object form { html, …} or use tooltip.renderMode: 'richText'). Never concatenate untrusted input into HTML strings. |
Warning
If your application allows users to define their own chart options (e.g., a dashboard builder), treat the entire
optionobject as untrusted input. Formatter functions,graphiccomponent configs, andimage://symbol URLs are all potential XSS or SSRF vectors. Whitelist allowed option keys rather than blacklisting dangerous ones. | XSS via labelformatter| Same. Labels are SVG text or canvas text — generally safe, but rich-text labels ({a|...}) parse markup. Sanitize. | | XSS viagraphiccomponent | Thegraphiccomponent allows raw display-object styles includingtext. Treat any user-providedgraphicconfig as untrusted. | | CSP-incompatible eval | ECharts core has noeval/new Function. Compatible withscript-src 'self'. | | Image symbol SSRF |series.symbol: 'image://https://attacker/'triggers an<img>request from the user's browser to that URL. This is the same risk as embedding a<img>tag — block viaimg-srcCSP. | | DoS via huge data | A malicious option could request 100 M points. Validate data length before passing to ECharts. | | Prototype pollution | ECharts deep-merges options; ensure your option-merge layer rejects__proto__,constructor,prototypekeys. (ECharts internal merge useshasOwnPropertychecks; risk is in your pre-processing.) | | Supply chain | Pin exact version. Use Subresource Integrity for CDN. Auditpackage-lock.json. Subscribe to ASF security advisories. | | Map data tampering | If you accept user-uploaded GeoJSON forregisterMap, validate the schema and bound coordinates. |
Renderer-specific notes
- Canvas: text rendered as glyphs — no HTML parsing, lower XSS surface. Best default for untrusted-data dashboards.
- SVG: text rendered into
<text>elements; rich-text uses<tspan>. Tooltips withrenderMode: 'html'(default) inject into a sibling DOM node — same XSS rules as any HTML output.
Reporting vulnerabilities
ECharts is governed by the Apache Software Foundation. Security issues should be reported to [email removed] (or the ECharts-specific list [email removed] if available). Do not file public GitHub issues for vulnerabilities.
Audit trail
ECharts emits no logs of its own. If you need an audit trail of user interactions:
chart.on('click', (params) => audit.log('chart-click', { name: params.name, value: params.value }));
chart.on('legendselectchanged', (params) => audit.log('legend-toggle', params));
chart.on('datazoom', (params) => audit.log('zoom', params));
Internationalization & Theming
i18n
53 locales ship in i18n/. Built-ins (registered via src/i18n/):
AR, BG, CA, CS, DA, DE, EL, EN (default), ES, ET, FA, FI, FR, HE, HR,
HU, ID, IT, JA, KO, LT, LV, MS, NL, NO, PL, PT-br, PT, RO, RU, SI, SK,
SL, SR, SV, TH, TR, UK, VI, ZH (Simplified Chinese), …
Custom locale:
import * as echarts from 'echarts/core';
echarts.registerLocale('myLocale', {
time: { month: ['Jan','Feb',...], dayOfWeek: [...], /* … */ },
legend: { selector: { all: 'All', inverse: 'Inv' } },
toolbox: { brush: { title: { rect: 'Rect', polygon: 'Poly', /* … */ } } },
series: { typeNames: { pie: 'Pie chart', /* … */ } },
// … see src/i18n/lang*.ts for full key list
});
echarts.init(dom, null, { locale: 'myLocale' });
Theming
37 themes in theme/ plus theme/tool/ (theme builder). Built-in themes registered automatically on import; custom themes via:
echarts.registerTheme('corporate', {
color: ['#0066cc', '#ff6600', /* palette */],
backgroundColor: '#ffffff',
textStyle: { fontFamily: 'Inter, sans-serif' },
title: { textStyle: { color: '#1a1a1a' } },
/* … per-component styles … */
});
echarts.init(dom, 'corporate');
Theme JSON files in theme/*.json can be loaded at runtime and passed directly:
fetch('/themes/corporate.json').then(r => r.json()).then(theme => {
echarts.init(dom, theme);
});
Testing
Test layers
| Layer | Tool | Location | Run |
|---|---|---|---|
| Unit tests | Jest 26 + jest-canvas-mock |
test/ut/spec/**/*.spec.ts |
npm test |
| Type-definition tests | dtslint + @definitelytyped/utils |
test/types/ |
npm run test:dts |
| Visual regression | Puppeteer 23 + pixelmatch | test/runTest/ |
npm run test:visual |
| Header check | custom script | build/checkHeader.js |
npm run checkheader |
| Lint | ESLint 7 + @typescript-eslint 4 |
.eslintrc |
npm run lint |
| Type check | tsc --noEmit |
tsconfig | npm run checktype |
Visual regression workflow
test/runTest/server.js (1909 lines) runs a Puppeteer-driven server. Test pages live under test/data/. Snapshots are stored per-version; mismatches produce diff images. The store version (recorded baseline) and run version must match — error: "Unmatched store version and run version." (test/runTest/server.js:366).
CLI for visual tests
node test/runTest/cli.js --tests <glob> --expected <version>
Required args (errors): "Tests are required" (test/runTest/cli.js:64), "Expected version is required" (test/runTest/cli.js:67).
Continuous integration recommendations
- Run
lint+checktype+teston every PR. - Run
test:visualon a stable Linux runner (font rendering is platform-sensitive; expect baseline drift on macOS/Windows).
Note
Visual regression baselines are recorded per-version. If the store version and run version mismatch, the test harness errors with "Unmatched store version and run version." Always re-record baselines after upgrading ECharts or Puppeteer.
- Build all flavors (
npm run release) before a release tag and verify eachdist/*.jsparses withnpm run lint:dist.
Code Patterns & Conventions
TypeScript style
- No semicolons inside object literals, two-space indent (Apache convention).
- All public types live in
src/util/types.tsand re-exported viasrc/echarts.{all,common,simple}.ts. - Interfaces for option types named
XxxOption, e.g.LineSeriesOption,GridComponentOption. - Mixin classes for shared model behavior — see
src/model/mixin/(palette, area, bordered, time, ...). Applied with TypeScript declaration merging +mixin()helper. - Branded types for ID + dimension safety (e.g.
OptionDataItemObjectvsOptionDataValue).
Naming conventions
| Pattern | Example | Meaning |
|---|---|---|
XxxModel |
SeriesModel, GridModel |
Option-tree wrapper class |
XxxView |
LineView, LegendView |
DOM/zrender renderer |
XxxOption |
BarSeriesOption |
TS interface for a piece of option |
installXxx |
installLineChart |
Plugin registrar consumed by use() |
*Helper.ts |
referHelper.ts |
Pure helper module (no class) |
Common patterns
encode— series.encode maps dataset dimensions to visual channels; consistent across all series types.emphasis/select/blur— universal interaction states. Each component supportsemphasis: { itemStyle, label, ... }.zlevel+z— layer ordering:zlevelcreates a separate canvas;zis in-canvas paint order.silent: true— suppress hit-testing on a series or graphic.
Custom chart authoring
Subclass ChartView (src/view/Chart.ts:98):
class MyChartView extends ChartView {
static type = 'mychart';
type = MyChartView.type;
render(seriesModel: MySeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
// Use this.group as the parent zrender Group.
// Read coord-system: seriesModel.coordinateSystem
// Read data: seriesModel.getData()
// Build display objects, add to this.group
}
}
Failure to override → error: "render method must been implemented" (src/view/Chart.ts:153).
Important
Custom chart and component classes must be registered via an
installfunction passed toecharts.use(). CallingregisterClassdirectly still works but bypasses tree-shaking — your custom type will be bundled even by consumers who never use it.
Extending ECharts
Custom series via series.type: 'custom'
The custom chart type (src/chart/custom/) lets you supply a renderItem function that emits zrender display objects per data row. No subclassing required. Use this for bespoke shapes when a built-in chart doesn't fit.
Custom component
- Define a
ComponentModelsubclass: option type, defaults, dependencies. - Define a
ComponentViewsubclass: render display objects. - Register:
ComponentModel.registerClass()+ComponentView.registerClass(). - Export an
installfunction that callsregisterComponentModel+registerComponentView.
Custom coordinate system
See extension-src/bmap/ as the canonical example. Implement the CoordinateSystem interface (defined in src/coord/CoordinateSystem.ts):
interface CoordinateSystem {
type: string;
dimensions: string[];
dataToPoint(data: number[]): number[];
pointToData?(point: number[]): number[];
containPoint(point: number[]): boolean;
// …
}
Register with CoordinateSystemManager.register(type, creator) (src/core/CoordinateSystem.ts:46).
Custom data transform
echarts.registerTransform({ type: 'myorg:filter', transform(params) { … } }). Used inside dataset.transform.
Repository Structure
echarts/
├── build/ Build orchestration (Rollup configs, dev-fast, i18n bundler)
├── dist/ Pre-built output (ignored in source; produced by `npm run release`)
├── extension/ Pre-built extensions (ignored)
├── extension-src/ Extension source
│ ├── bmap/ Baidu Maps coord system (5 files)
│ └── dataTool/ gexf parser, prepareBoxplotData (3 files)
├── i18n/ 53 locale JS files (legacy CommonJS form)
├── lib/ Per-module entry shims (ignored — generated)
├── licenses/ Third-party license texts
├── src/ TypeScript source (1,909 files, ~5.49 M chars)
│ ├── core/ Engine: echarts.ts, Scheduler, Task, CoordinateSystem
│ ├── model/ Global, Component, Series, OptionManager, referHelper
│ ├── data/ SeriesData, DataStore, Source, Graph, Tree, Differ
│ ├── chart/ 23 chart-type folders
│ ├── component/ 33 component-type folders
│ ├── coord/ 12 coord-system folders
│ ├── visual/ Visual mappings (color, symbol, decal, …)
│ ├── processor/ Data-stage operators (filter, sample, stack)
│ ├── layout/ Cross-series layout helpers
│ ├── scale/ Interval, Log, Ordinal, Time, AxisBreak
│ ├── label/ LabelManager + helpers
│ ├── animation/ UniversalTransition, AnimationWrap, custom transitions
│ ├── view/ Chart.ts, Component.ts base view classes
│ ├── renderer/ installCanvasRenderer, installSVGRenderer
│ ├── theme/ Default + dark theme registration
│ ├── i18n/ Locale registration helpers
│ ├── loading/ Default loading spinner
│ ├── preprocessor/ Legacy option migrations
│ ├── legacy/ Deprecated-shape compatibility shims
│ ├── export/ Public API surface and per-flavor entry points
│ ├── util/ Cross-cutting utilities (KDTree, throttle, conditional expressions, …)
│ ├── echarts.all.ts Full bundle entry
│ ├── echarts.common.ts Common-subset bundle entry
│ └── echarts.simple.ts Minimal bundle entry
├── ssr/
│ └── client/src/ hydrate(dom, options) for SSR
├── test/ ~600 files: ut/, types/, runTest/, data/, asset/, lib/, node/
├── theme/ 37 theme JSON files + theme/tool/
├── types/ Declaration generation outputs (ignored)
├── package.json Multi-entry exports (lines 111-238 of dependencies.cbf)
├── rollup.config.js Rollup config
├── tsconfig.json TS 4.4.3 config
└── LICENSE / NOTICE Apache-2.0 + Apache attribution
Build System
Build commands
| Command | Effect |
|---|---|
npm run build |
All flavors UMD + minified (--type all,common,simple --min) |
npm run build:esm |
ESM bundle (dist/echarts.esm.mjs) |
npm run build:i18n |
Compile i18n/*.js from src/i18n/lang*.ts |
npm run build:lib |
Build lib/ per-module shims (consumed by prepare) |
npm run build:extension |
Build extension-src/ → extension/ |
npm run build:ssr |
Build ssr/client/dist/ |
npm run dev |
Concurrent watcher + http-server on test/ |
npm run dev:fast |
esbuild-based fast dev build (no minification, no type-check) |
npm run release |
Full release: lib + i18n + UMD + ESM + extension + ssr |
npm run help |
node build/build.js --help |
Build CLI flags (build/build.js)
Discovered from extracted CLI commands (16 total). Common flags:
| Flag | Effect |
|---|---|
--type all,common,simple,blank,extension,ssr |
Select flavor(s) to build |
--min |
Produce *.min.js Terser-minified output alongside non-min |
--format umd | esm | cjs |
Module format (default UMD for dist/) |
--prepublish |
Build lib/ shims used by package.json exports |
--watch |
Rebuild on source changes |
--clean |
Wipe dist/ before build |
Output anatomy
dist/
├── echarts.js UMD bundle, all charts/components
├── echarts.min.js Terser-minified UMD
├── echarts.esm.mjs ESM bundle
├── echarts.esm.min.mjs Terser-minified ESM
├── echarts.common.js UMD common subset
├── echarts.common.min.js Minified common
├── echarts.simple.js UMD minimal
├── echarts.simple.min.js Minified simple
└── extension/
├── bmap.js / bmap.min.js
└── dataTool.js / dataTool.min.js
Type generation
Driven by @microsoft/api-extractor 7.31.2 + @lang/rollup-plugin-dts. Outputs:
types/dist/
├── all.d.ts
├── charts.d.ts
├── components.d.ts
├── core.d.ts
├── echarts.d.ts (canonical)
├── echarts.d.cts (CommonJS variant referenced by package.json:23)
├── features.d.ts
├── option.d.ts
├── renderers.d.ts
└── shared.d.ts
Build internals
build/build.js orchestrates Rollup with these plugins:
@rollup/plugin-node-resolve11@rollup/plugin-commonjs17@rollup/plugin-replace2 (substitutes__DEV__→falsefor prod)rollup-plugin-terser7 (when--min)- Custom esbuild loader for fast dev mode (
build/dev-fast.js)
The dev:fast path uses esbuild directly for sub-second incremental rebuilds; production uses Rollup for tree-shaking quality.
Error Reference
The library raises 31 distinct errors (extracted from _briefing/extracted/error_messages.tsv). The most operationally significant:
| Error | File:line | Cause / Fix |
|---|---|---|
Option should contains series. |
src/model/Global.ts:926 |
setOption called with empty/missing series[]. |
xAxis / yAxis (component not found) |
src/model/referHelper.ts:113,120 |
Series references an axis index that wasn't declared. |
singleAxis should be specified. |
src/model/referHelper.ts:149 |
Series uses single coord but no singleAxis component. |
angleAxis option not found |
src/model/referHelper.ts:169 |
Polar series with no polar.angleAxis. |
radiusAxis option not found |
src/model/referHelper.ts:172 |
Polar series with no polar.radiusAxis. |
matrix coordinate system should be specified. |
src/model/referHelper.ts:222 |
Series declares coordinateSystem: 'matrix' but no matrix component (v6 only). |
render method must been implemented |
src/view/Chart.ts:153 |
Custom chart subclass missing render(). |
BMap api is not loaded |
extension-src/bmap/BMapCoordSys.ts:173 |
Baidu Maps SDK script not loaded before chart init. |
Only one bmap component can exist |
extension-src/bmap/BMapCoordSys.ts:177 |
Two bmap components configured; merge into one. |
renderToCanvas can only be used in the canvas renderer. |
src/core/echarts.ts:836 |
Called renderToCanvas on an SVG-renderer instance. |
renderToSVGString can only be used in the svg renderer. |
src/core/echarts.ts:852 |
Called renderToSVGString on a Canvas-renderer instance. |
Initialize failed: invalid dom. |
src/core/echarts.ts:2797 |
init() passed null/undefined/non-element, or container detached from document. |
Illegal priority |
src/core/echarts.ts:3116 |
Custom processor registration with invalid priority enum. |
Unknown dimension |
src/data/SeriesData.ts:455 |
getDimensionInfo() called with name not present in SeriesData. |
Do not supported yet |
src/data/SeriesData.ts:871 |
Dataset transform path that hit unsupported branch. |
key must not be |
src/animation/customGraphicTransition.ts:424 |
Reserved key used in custom-graphic transition definition. |
Test-suite errors (test/runTest/, test/lib/) appear during local development only and are not user-facing.
Improvements & Tech-Debt Notes
Observations from the v6.0.0 source (open as suggestions; not bugs):
- Extracted-fact yield is low for TS-only libraries. The pipeline counted 0 functions in 1,909 files because all top-level surface is class-method based. Documentation tooling consumers should rely on
index.d.tswalks, not text extraction, when targeting ECharts. src/core/echarts.tsis 5,000+ lines. A future refactor could splitEChartsinstance methods (export, hydration, action dispatch) into adjacent files; this would simplify static analysis and tree-shaking.src/legacy/shim layer exists for deprecated shapes from v3/v4. A v7 release could drop these (with a migration guide), shrinking the engine bundle.- Type-test (
test:dts) requires a separate npm install intest/types/(declared intest/types/package.json). CI should cache that subtree to keep the verification fast. - No first-party React/Vue wrappers in the repo. Community wrappers exist (
echarts-for-react,vue-echarts); consumers should pin those to ECharts 6 explicitly. - Visual regression baselines are platform-sensitive. Linux container is the canonical reference; macOS/Windows differ slightly in font rasterization. Document this on the test harness page.
- Bundle entries have implicit transitive imports.
index.common.jsandindex.simple.jslock in a curated set; consumers wanting different subsets must use thecore+use([...])path, not edit the published flavors.
Contributing
ECharts is governed by the Apache Software Foundation; contributions follow ASF process.
- Sign the Apache ICLA (Individual Contributor License Agreement) before any non-trivial PR.
- Discuss large changes on
[email removed]before opening a PR. - Branching:
masterfor current major; release branches asrelease/X.Y. - Commit format: imperative subject, body explains why; reference GitHub issues with
#NNNN. - Required checks before PR:
npm run lint,npm run checktype,npm run test,npm run test:dts, header check. - Visual regression: add or update snapshots in
test/runTest/for any visual change; reviewer runs the full suite. - Code style: enforced by ESLint +
@typescript-eslint; runnpm run lint:fix. - Add an
installfunction for any new chart/component/feature so users can tree-shake. - Write at least one Jest unit test for new logic in
src/. - Update locale strings in
src/i18n/lang*.tsfor any new user-visible text.
Issue triage
Issues are tracked at https://github.com/apache/echarts/issues. Selected open threads relevant to operators:
- Memory growth in long-running dashboards (recurring; usually fixed by ensuring
dispose()on unmount). - DataZoom + scroll-wheel interaction inside scrollable containers (configure
dataZoom.preventDefaultMouseMove). - SSR + universal transition mismatch on hydration (workaround: disable universal transition during SSR).
Quick Reference Card
Module-level API
import * as echarts from 'echarts/core';
echarts.use(installers);
echarts.init(dom, theme?, opts?); // → ECharts instance
echarts.connect(groupIdOrCharts);
echarts.disconnect(groupId);
echarts.dispose(domOrIdOrInstance);
echarts.getInstanceByDom(dom);
echarts.getInstanceById(id);
echarts.registerTheme(name, theme);
echarts.registerMap(name, geoJson, specialAreas?);
echarts.getMap(name);
echarts.registerLocale(name, locale);
Instance API (53 public methods/props selected)
chart.setOption(option, opts?);
chart.getOption();
chart.getWidth();
chart.getHeight();
chart.getDom();
chart.getZr(); // zrender instance (advanced)
chart.resize(opts?);
chart.dispatchAction(action);
chart.on(eventName, query?, handler, context?);
chart.off(eventName, handler?);
chart.showLoading(type?, opts?);
chart.hideLoading();
chart.convertToPixel(finder, value);
chart.convertFromPixel(finder, value);
chart.containPixel(finder, value);
chart.getDataURL(opts?); // base64 data URL
chart.getConnectedDataURL(opts?); // composite of all connected
chart.appendData({ seriesIndex, data });
chart.clear();
chart.isDisposed();
chart.dispose();
chart.renderToCanvas(opts?); // canvas renderer only
chart.renderToSVGString(opts?); // svg renderer only
chart.makeActionFromEvent(event);
chart.group; // string; for connect()
Renderer matrix
| Capability | Canvas | SVG |
|---|---|---|
| Default | ✓ | — |
useDirtyRect |
✓ | — |
renderToCanvas |
✓ | ✗ (errors) |
renderToSVGString |
✗ (errors) | ✓ |
| SSR | partial | ✓ (recommended) |
| Best for large data | ✓ | — |
| Best for accessibility | — | ✓ |
| Best for vector export | — | ✓ |
Config file locations
ECharts has no config files. All settings via:
init(dom, theme, opts)→ instance settingschart.setOption(option)→ render settingsecharts.register*()→ module-level registration
Required global state
None. ECharts maintains a per-bundle module-level registry for plugins (populated by use()), maps (registerMap), themes (registerTheme), and locales (registerLocale). All other state is per-instance.