How to Update ECharts Data Dynamically Without Re-Rendering the Entire Chart

Use the appendData API to push new points into a specific series while preserving the existing canvas state, avoiding the costly full re-render triggered by setOption.

When building real-time dashboards or streaming data visualizations with apache/echarts, calling setOption for every new data point causes the entire chart to rebuild. This guide explains how to update ECharts data dynamically without re-rendering the whole chart by leveraging the internal appendData pipeline.

Why setOption Triggers a Full Re-Render

When you invoke chart.setOption(option), ECharts performs a deep merge of the entire option tree in src/core/echarts.ts (lines 1539–1564). The Scheduler (src/core/Scheduler.ts, line 214) then schedules a complete view refresh, walking through every series, component, and graphic element. For large datasets or high-frequency updates, this full pipeline creates significant CPU and memory overhead because the canvas (or SVG) is cleared and redrawn completely.

The appendData API: Incremental Updates Without Re-Rendering

The appendData method provides a dedicated pathway for streaming data into an existing series without disturbing the rest of the chart. According to the apache/echarts source code, this API bypasses the heavy option-merge logic and writes directly to the underlying data storage.

How appendData Works Internally

The call chain demonstrates the efficiency of this approach:

  1. Entry Pointsrc/core/echarts.ts receives chart.appendData({ seriesIndex: 0, data: [...] }) and routes it to the target SeriesModel.
  2. Series Delegation – In src/model/Series.ts (lines 334–339), SeriesModel.appendData forwards the payload to its SeriesData instance.
  3. Data Store Mutationsrc/data/SeriesData.ts (lines 571–574) passes the raw array to DataStore.appendData in src/data/DataStore.ts (lines 318–322). Here, the new items are pushed into the underlying raw array; no new series objects are created, and existing graphic elements remain attached to their old indices.
  4. Partial View Update – The scheduler flags the series for an incremental update. src/view/Chart.ts (lines 284–304) executes incrementalPrepareRender and incrementalRender, painting only the new marks onto the existing canvas.

The Incremental Render Pipeline

Because the view is updated incrementally, the canvas is not cleared. The Scheduler (src/core/Scheduler.ts) detects the appendData flag and skips the full render cycle, invoking only the incremental methods for the affected series. This yields smooth, low-latency updates even when streaming millions of points.

Practical Code Examples

Setting Up a Chart for Streaming Data

Initialize a line chart with an empty dataset to prepare for dynamic updates:

var chart = echarts.init(document.getElementById('main'));

chart.setOption({
    xAxis: { type: 'category' },
    yAxis: { type: 'value' },
    series: [{
        type: 'line',
        data: []
    }]
});

Appending Data to a Specific Series

Push new points every second without re-rendering the entire chart:

setInterval(function () {
    var newPoints = [];
    for (var i = 0; i < 3; i++) {
        newPoints.push(Math.round(Math.random() * 100));
    }
    
    // seriesIndex: 0 targets the first series
    chart.appendData({
        seriesIndex: 0,
        data: newPoints
    });
}, 1000);

Using Series IDs Instead of Indices

For maintainability, reference series by the id defined in setOption:

chart.appendData({
    seriesId: 'realTimeSeries',
    data: [10, 20, 30]
});

Replacing Full Dataset Without Structural Rebuild

If you must replace all data but want to avoid option-merge overhead, use notMerge: true. Note this still triggers a full repaint, unlike appendData:

chart.setOption({
    series: [{ data: bigNewArray }]
}, { notMerge: true });

Performance Comparison: appendData vs setOption

Method Re-render Scope Use Case Internal Mechanism
appendData Affected series only Streaming, real-time feeds Direct DataStore mutation; incrementalRender
setOption Entire chart Structural changes, initial load Deep option merge; full render pipeline
setOption with notMerge: true Entire chart (full repaint) Dataset replacement, schema changes Model rebuild; full repaint

Reserve setOption for changes to axes, legends, or series configuration. For high-frequency data updates, appendData is the only method that preserves the existing render state and maintains 60fps performance.

Summary

  • Use chart.appendData to update ECharts data dynamically without re-rendering the entire chart, preserving canvas state and achieving high-performance streaming.
  • The method writes directly to src/data/DataStore.ts, bypassing the expensive option-merge logic in src/core/echarts.ts.
  • Incremental rendering in src/view/Chart.ts paints only new marks, leaving existing elements untouched.
  • Use setOption only for structural changes or initial configuration, and setOption with notMerge: true for complete dataset replacements that require a full repaint.

Frequently Asked Questions

What is the difference between appendData and setOption in ECharts?

appendData is a specialized API for streaming new data points into an existing series without triggering a full chart re-render. It mutates the underlying DataStore directly and invokes an incremental render. setOption performs a deep merge of the entire configuration tree and schedules a complete repaint of every series and component, making it suitable for structural changes but expensive for frequent updates.

Can I use appendData with multiple series at once?

No, appendData targets a single series per call. You must specify either seriesIndex (zero-based position) or seriesId (the string identifier set in the series configuration). To update multiple series simultaneously, invoke appendData separately for each series; the scheduler will batch the incremental renders efficiently.

Does appendData work with all chart types?

appendData works best with series that support incremental rendering, such as line, scatter, and custom series. It is designed for Cartesian coordinate systems where data points are appended to the end of the dataset. Chart types requiring complete data recomputation (such as pie charts or treemaps) may not benefit from incremental updates and should use setOption instead.

How do I clear old data when using appendData?

appendData only adds data; it does not remove existing points. To clear historical data while keeping the chart instance alive, you must call setOption with a new empty data array and notMerge: true to reset the series, then resume appending. Alternatively, maintain a sliding window in your application logic and use setOption with replaceMerge: ['series'] to update the dataset efficiently without a full structural rebuild.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →