apache / apache/echarts

[Bug] TypeError in getDataParams when getData() returns null on disposed series

Open
#21,535 1 comment 0 reactions 0 assignees View on GitHub
en pending
Dominant language
TypeScript
Stars
67.3k
Forks
19.8k
Avg merge
11d 14h
Merged PRs (30d)
8

Description

### Version

6.0.0 (bug present since at least 4.1.0)

### Link to Minimal Reproduction

N/A — occurs in any framework (React, Vue, Angular) where chart components unmount during user interaction.

### Steps to Reproduce

1. Render any chart (sankey, treemap, pie, line) with mouse event handlers
2. Navigate away (unmount the component) or call `setOption` with replacement data while the mouse cursor is over the chart
3. A stale `mousemove`/`mouseout` event fires after `dispose()` clears the series data

### Current Behavior

TypeError crashes:
- `Cannot read properties of undefined (reading 'getRawIndex')` — from `DataFormatMixin.getDataParams()` base method
- `Cannot read properties of undefined (reading 'tree')` — from `TreemapSeriesModel.getDataParams()` override
- Similar crashes possible in pie (`.each`), funnel (`.mapDimension`), sunburst/tree (`.tree`), chord (`.getName`)

Stack trace (Sankey example):
```
DataFormatMixin.getDataParams (dataFormat.ts)
SankeySeriesModel.getDataParams (SankeySeries.ts)
(echarts.ts:778) — findEventDispatcher callback
ECharts.handler → Handler.mousemove → HandlerDomProxy.mousemove
```

Stack trace (Treemap example):
```
TreemapSeriesModel.getDataParams (TreemapSeries.ts:126)
(echarts.ts:778)
findEventDispatcher → ECharts.handler → Handler.mousemove
```

### Expected Behavior

Mouse events on disposed chart elements should be silently ignored, not throw TypeErrors.

### Root Cause

`SeriesModel.getData()` can return `null`/`undefined` when a series is not alive. The comment in `Series.ts` explicitly acknowledges this:

```typescript
// When series is not alive (that may happen when click toolbox
// restore or setOption with not merge mode), series data may
// be still need to judge animation or something when graphic
// elements want to know whether fade out.
return inner(this).data; // ← can be undefined
```

But `getDataParams()` and its 6 chart-specific overrides unconditionally access properties on the result. The event handler at `echarts.ts` calls `getDataParams()` on mouse events, which can fire on stale DOM elements after the series is disposed.

**13+ vulnerable call sites identified:**
- `dataFormat.ts` — base `getDataParams()` calls `data.getRawIndex()`, `data.getName()`, etc.
- `echarts.ts:778` — event handler calls `getDataParams()` on potentially dead series
- `TreemapSeries.ts`, `SunburstSeries.ts`, `TreeSeries.ts` — override accesses `data.tree`
- `PieSeries.ts` — override accesses `data.each()`, `data.mapDimension()`
- `FunnelSeries.ts` — override accesses `data.mapDimension()`, `data.getSum()`
- `ChordSeries.ts` — override accesses `data.getName()`, `this.getGraph()`
- `TooltipView.ts:385, 458` — unguarded callers

**Affects all chart types and all frameworks** where component lifecycle causes chart disposal during user interaction.

### Related Issues

- #9402 — Original report (pie chart, closed 2018 as "cannot-reproduce" but never fixed)
- #16998 — Same error on stacked line chart (open)

### Environment

- **OS:** macOS (also reproducible on Linux/Windows)
- **Browser:** Chrome, Firefox, Safari
- **Framework:** React 19 + Next.js 16 (but framework-agnostic)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.