# How to Make ECharts Charts Responsive to Container Size Changes: A Complete Guide

> Learn to make ECharts charts responsive. Call chart.resize() on container dimension changes using window resize or ResizeObserver for a seamless user experience.

- Repository: [The Apache Software Foundation/echarts](https://github.com/apache/echarts)
- Tags: how-to-guide
- Published: 2026-03-04

---

**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`](https://github.com/apache/echarts/blob/main/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`](https://github.com/apache/echarts/blob/main/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:

```typescript
// 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 `_zr` object (ZRender instance) handles low-level canvas or SVG resizing.
- **`resetOption('media')`**: Recomputes media queries to adjust responsive configurations defined in `baseOption` and `media` components.
- **Animation control**: The `opts` parameter accepts an `animation` object to enable smooth transitions during resize (default is immediate with `duration: 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:

```javascript
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`](https://github.com/apache/echarts/blob/main/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:

```javascript
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 `window` listeners 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`:

```javascript
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`](https://github.com/apache/echarts/blob/main/test/lib/testHelper.js), automatic resize handling is enabled by default. To disable it and manage resize logic manually:

```javascript
// 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

```html
<!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

```javascript
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 in [`src/core/echarts.ts`](https://github.com/apache/echarts/blob/main/src/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 or `ResizeObserver` for CSS Grid/Flexbox containers.
- **Pass options for animation**: The `resize` method accepts an `animation` object to enable smooth transitions during size changes.
- **Clean up observers**: Always disconnect `ResizeObserver` instances 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`](https://github.com/apache/echarts/blob/main/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.