Skip to main content
Technology & EngineeringData Visualization162 lines

Echarts

Expert guidance for building feature-rich interactive charts with Apache ECharts

Quick Summary25 lines
You are an expert in creating data visualizations with Apache ECharts.

## Key Points

- **DataZoom**: Add `dataZoom` components (slider or inside) to enable zooming and scrolling through large time-series data.
- **Large Dataset Rendering**: Enable `large: true` and `largeThreshold` on series to use progressive rendering for hundreds of thousands of points.
- **Geographic Maps**: Register map GeoJSON with `echarts.registerMap()` and use `type: "map"` series for choropleth and scatter maps.
- **Graphic Component**: Use the `graphic` option to overlay arbitrary shapes, text, and images on charts.
- **Toolbox**: Add a built-in `toolbox` with save-as-image, data view, zoom, and restore buttons.
- Call `myChart.resize()` on window resize events or use a ResizeObserver to keep charts responsive.
- Use `dataset` with `encode` for cleaner data-driven configurations instead of embedding data directly in each series.
- Dispose chart instances with `myChart.dispose()` when the component unmounts to avoid memory leaks.
- Not calling `resize()` after the container changes size, which leaves the chart rendered at its original dimensions.

## Quick Example

```bash
npm install echarts
```

```bash
npm install echarts-for-react
```
skilldb get data-visualization-skills/EchartsFull skill: 162 lines
Paste into your CLAUDE.md or agent config

Apache ECharts — Data Visualization

You are an expert in creating data visualizations with Apache ECharts.

Overview

Apache ECharts is a powerful, open-source charting and visualization library originally developed by Baidu. It renders via Canvas (default) or SVG, supports dozens of chart types (including 3D, maps, and graph networks), and handles large datasets efficiently with progressive rendering. Use ECharts when you need a batteries-included solution with extensive chart types, built-in interactivity, and strong support for dashboards and geographic visualizations.

Setup & Configuration

Install via npm:

npm install echarts

Basic usage:

import * as echarts from "echarts";

const chartDom = document.getElementById("chart");
const myChart = echarts.init(chartDom);

myChart.setOption({
  title: { text: "Monthly Sales" },
  tooltip: { trigger: "axis" },
  xAxis: { type: "category", data: ["Jan", "Feb", "Mar", "Apr", "May"] },
  yAxis: { type: "value" },
  series: [
    { name: "Sales", type: "bar", data: [120, 200, 150, 80, 70] }
  ]
});

Tree-shaking (recommended for production):

import * as echarts from "echarts/core";
import { BarChart } from "echarts/charts";
import { TitleComponent, TooltipComponent, GridComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";

echarts.use([BarChart, TitleComponent, TooltipComponent, GridComponent, CanvasRenderer]);

React Integration

npm install echarts-for-react
import ReactECharts from "echarts-for-react";

function MyChart() {
  const option = {
    xAxis: { type: "category", data: ["A", "B", "C"] },
    yAxis: { type: "value" },
    series: [{ type: "bar", data: [10, 20, 30] }]
  };
  return <ReactECharts option={option} style={{ height: 400 }} />;
}

Core Patterns

Line and Area Charts

myChart.setOption({
  xAxis: { type: "category", data: ["Mon", "Tue", "Wed", "Thu", "Fri"] },
  yAxis: { type: "value" },
  series: [{
    type: "line",
    data: [820, 932, 901, 934, 1290],
    smooth: true,
    areaStyle: { opacity: 0.3 }
  }]
});

Pie and Doughnut Charts

myChart.setOption({
  tooltip: { trigger: "item" },
  series: [{
    type: "pie",
    radius: ["40%", "70%"],  // doughnut
    data: [
      { value: 1048, name: "Search" },
      { value: 735, name: "Direct" },
      { value: 580, name: "Email" },
    ]
  }]
});

Dataset and Encoding

myChart.setOption({
  dataset: {
    source: [
      ["product", "2024", "2025"],
      ["Tea", 43, 85],
      ["Milk", 83, 73],
      ["Cheese", 86, 65],
    ]
  },
  xAxis: { type: "category" },
  yAxis: {},
  series: [{ type: "bar" }, { type: "bar" }]
});

Advanced Features

  • DataZoom: Add dataZoom components (slider or inside) to enable zooming and scrolling through large time-series data.
  • Large Dataset Rendering: Enable large: true and largeThreshold on series to use progressive rendering for hundreds of thousands of points.
  • Geographic Maps: Register map GeoJSON with echarts.registerMap() and use type: "map" series for choropleth and scatter maps.
  • Graphic Component: Use the graphic option to overlay arbitrary shapes, text, and images on charts.
  • Toolbox: Add a built-in toolbox with save-as-image, data view, zoom, and restore buttons.

Best Practices

  • Call myChart.resize() on window resize events or use a ResizeObserver to keep charts responsive.
  • Use dataset with encode for cleaner data-driven configurations instead of embedding data directly in each series.
  • Dispose chart instances with myChart.dispose() when the component unmounts to avoid memory leaks.

Core Philosophy

ECharts is a batteries-included visualization engine. Its design philosophy is that the option object is the visualization: you declare what you want (title, axes, series, tooltips, zoom controls) as a configuration object, and ECharts handles the rendering, interactivity, and animation. This declarative approach means you spend time thinking about what to show rather than how to draw it. The trade-off is that customizations outside the option schema can be difficult or impossible without writing custom extensions.

The merge-by-default behavior of setOption is both a feature and a source of confusion. When you call setOption with a new configuration, ECharts merges it with the previous one rather than replacing it. This is efficient for incremental updates (change one series without redeclaring everything) but dangerous when you expect a clean slate. Understanding when to use the default merge versus { notMerge: true } is essential for building dynamic dashboards where the chart type or structure changes based on user interaction.

Responsiveness is a manual responsibility. Unlike CSS-driven SVG charts, Canvas-rendered ECharts instances do not automatically resize when their container changes. You must call chart.resize() in response to window resize events or container layout changes. In component-based frameworks, this means wiring up a ResizeObserver or window listener and cleaning it up on unmount. Forgetting this step is the most common reason ECharts look broken in responsive layouts.

Anti-Patterns

  • Not disposing chart instances on unmount: Creating an ECharts instance in a component without calling chart.dispose() when the component is destroyed. This leaks memory and event listeners, and it accumulates over navigation in single-page applications.

  • Assuming setOption replaces the configuration: Calling setOption with a partial configuration and expecting it to clear the previous series or components. Because the default behavior is to merge, stale series from prior calls persist unless you pass { notMerge: true }.

  • Skipping resize() after layout changes: Initializing a chart in a container that later changes size (responsive layout, tab switch, sidebar toggle) without calling chart.resize(). The chart remains rendered at its initial dimensions, clipping or leaving blank space.

  • Importing the full ECharts bundle for one chart type: Using import * as echarts from "echarts" in production when only a bar chart is needed. ECharts supports tree-shaking via echarts/core and per-chart/component imports; the full bundle is significantly larger than necessary.

  • Embedding large datasets directly in the option object: Placing thousands of data points inline in the series configuration instead of using the dataset component. The dataset approach separates data from visual mapping, enables data reuse across series, and makes the configuration more maintainable.

Common Pitfalls

  • Not calling resize() after the container changes size, which leaves the chart rendered at its original dimensions.
  • Calling setOption with notMerge: false (the default) and expecting it to replace the entire configuration; unchanged series from prior calls persist. Pass { notMerge: true } when you need a full reset.

Install this skill directly: skilldb add data-visualization-skills

Get CLI access →