How to Make ECharts Charts Responsive to Container Size Changes: A Complete Guide
Call the chart.resize() method whenever the container dimensions change, either via a window resize listener or a ResizeObserver, to make ECharts charts responsive to container size changes.
ECharts is a powerful visualization library, but it does not automatically listen for DOM size changes. To make ECharts charts responsive to container size changes, you must manually trigger the resize mechanism provided by the library. This guide explains the internal implementation and practical patterns for handling responsive layouts.
Why ECharts Requires Manual Resize Handling
ECharts intentionally avoids attaching global resize listeners to prevent unnecessary performance overhead when charts are hidden or when the page does not require dynamic resizing. According to the source code in src/core/echarts.ts, the chart instance stores a reference to the container (_dom) and the internal ZRender instance (_zr), but no observers are attached during initialization.
The responsibility to detect container size changes falls to the developer, who must invoke the public resize method when appropriate.
The Core resize() Method
The resize method is defined in src/core/echarts.ts and serves as the primary API for making ECharts charts responsive to container size changes.
Internal Implementation in src/core/echarts.ts
When you call chart.resize(), the method executes a four-step pipeline:
// src/core/echarts.ts – resize implementation
resize(opts?: ResizeOpts): void {
// 1️⃣ Let ZRender adjust its internal canvas / SVG size
this._zr.resize(opts);
// 2️⃣ Update loading effect size (if any)
this._loadingFX && this._loadingFX.resize();
// 3️⃣ If a model exists, trigger a full update with a 'resize' lifecycle type
if (this._model) {
const needPrepare = this._model.resetOption('media');
// Handle pending lazy updates...
updateMethods.update.call(this, {
type: 'resize',
animation: {duration: 0, ...opts?.animation}
});
}
// 4️⃣ Flush pending actions and emit the 'updated' event
flushPendingActions.call(this, opts?.silent);
triggerUpdatedEvent.call(this, opts?.silent);
}
Key technical details:
this._zr.resize(opts): The_zrobject (ZRender instance) handles low-level canvas or SVG resizing.resetOption('media'): Recomputes media queries to adjust responsive configurations defined inbaseOptionandmediacomponents.- Animation control: The
optsparameter accepts ananimationobject to enable smooth transitions during resize (default is immediate withduration: 0).
Implementation Patterns for Responsive Charts
To make ECharts charts responsive to container size changes in production applications, choose the pattern that matches your layout requirements.
Window Resize Listener
The simplest approach for full-page layouts attaches a listener to the global window object:
const chart = echarts.init(document.getElementById('main'));
// Initial render
chart.setOption({ /* your options */ });
// Handle window resize
window.addEventListener('resize', () => {
chart.resize();
});
This pattern is used throughout the official ECharts test suite, as seen in test/lib/testHelper.js, which provides a resizable utility that compares current dimensions against cached values before invoking resize.
ResizeObserver for Element-Level Changes
For modern applications using CSS Grid, Flexbox, or dynamic sidebars, the ResizeObserver API provides element-level notifications without polling:
const container = document.querySelector('.chart-wrapper');
const chart = echarts.init(container);
const observer = new ResizeObserver(() => {
chart.resize();
});
observer.observe(container);
Advantages:
- Reacts to container changes caused by CSS transitions, sidebar toggles, or split-pane adjustments.
- More performant than
windowlisteners when only specific elements change size. - Widely supported in modern browsers (Chrome 64+, Firefox 69+, Safari 13.1+).
Explicit Size Override
If you need to control dimensions programmatically rather than relying on the container's CSS size, pass explicit dimensions to resize:
chart.resize({
width: container.clientWidth,
height: container.clientHeight,
animation: {
duration: 300,
easing: 'cubicOut'
}
});
This approach is useful when:
- The container has no explicit CSS dimensions.
- You want to animate the resize transition.
- You are integrating with virtual scrolling or canvas-based layouts.
Disabling Automatic Resize
When using the test helper from test/lib/testHelper.js, automatic resize handling is enabled by default. To disable it and manage resize logic manually:
// When creating a chart via the test helper
createChart({
autoResize: false // Prevents automatic window resize listener
});
Then implement your own ResizeObserver or conditional resize logic as needed.
Complete Code Examples
Basic Responsive Chart
<!DOCTYPE html>
<html>
<head>
<style>
#main { width: 100%; height: 400px; }
</style>
</head>
<body>
<div id="main"></div>
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
<script>
const chart = echarts.init(document.getElementById('main'));
chart.setOption({
title: { text: 'Responsive Chart' },
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
yAxis: { type: 'value' },
series: [{ data: [120, 200, 150], type: 'bar' }]
});
window.addEventListener('resize', () => chart.resize());
</script>
</body>
</html>
Flexbox Layout with ResizeObserver
import * as echarts from 'echarts';
function initResponsiveChart(selector) {
const container = document.querySelector(selector);
if (!container) return;
const chart = echarts.init(container, null, {
renderer: 'canvas'
});
// Initial option
chart.setOption({
grid: { top: 30, right: 30, bottom: 30, left: 30, containLabel: true },
series: [{
type: 'line',
data: Array.from({length: 50}, () => Math.random() * 100),
smooth: true
}]
});
// Modern resize handling
const resizeObserver = new ResizeObserver(entries => {
// Optional: debounce for performance
requestAnimationFrame(() => {
chart.resize();
});
});
resizeObserver.observe(container);
// Cleanup function
return () => {
resizeObserver.disconnect();
chart.dispose();
};
}
// Usage
const cleanup = initResponsiveChart('.chart-container');
// Later: cleanup();
Summary
- ECharts does not auto-resize: The library intentionally avoids attaching DOM observers to prevent unnecessary performance costs.
- Use
chart.resize(): This method, defined insrc/core/echarts.ts, triggers ZRender resizing, media query recalculation, and a full chart update. - Choose your detection method: Use
window.addEventListener('resize')for simple layouts orResizeObserverfor CSS Grid/Flexbox containers. - Pass options for animation: The
resizemethod accepts ananimationobject to enable smooth transitions during size changes. - Clean up observers: Always disconnect
ResizeObserverinstances and remove event listeners when disposing charts to prevent memory leaks.
Frequently Asked Questions
Does ECharts automatically resize when the browser window changes?
No, ECharts does not automatically resize when the browser window changes. According to the source code in src/core/echarts.ts, the chart instance does not attach any internal listeners to the window object or the container element. You must explicitly call chart.resize() inside a window.addEventListener('resize') handler or use a ResizeObserver to detect container changes and trigger the resize method manually.
What is the difference between using window.resize and ResizeObserver for ECharts?
The window.resize event fires only when the viewport dimensions change, making it suitable for charts that occupy the full window or fixed percentages of it. However, ResizeObserver monitors specific DOM elements and fires when the element's content box changes size, regardless of whether the window resized. This is essential for responsive layouts using CSS Grid or Flexbox where the container might resize due to sidebar toggles or parent element changes without the window dimensions changing.
Can I animate the chart resize transition in ECharts?
Yes, you can animate the resize transition by passing an animation options object to the resize method. By default, the resize operation uses duration: 0 for immediate rendering, but you can override this to create smooth transitions. For example: chart.resize({ animation: { duration: 300, easing: 'cubicOut' } }). This triggers the internal update pipeline with animation parameters, allowing the chart to smoothly transition to new dimensions.
How do I prevent memory leaks when implementing responsive ECharts?
To prevent memory leaks when implementing responsive ECharts, you must properly clean up both the chart instance and any resize observers or event listeners when the component unmounts or the chart is no longer needed. Specifically, call resizeObserver.disconnect() to stop observing the container, remove the window resize event listener using removeEventListener, and finally call chart.dispose() to release the ZRender instance and DOM references. Failing to perform these cleanup steps will leave orphaned observers and canvas elements in memory.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →