apache / apache/echarts

[Feature] Prevent empty gaps at chart edges when zooming on time axis

Open
#21,341 3 comments 0 reactions 0 assignees View on GitHub
en new-feature pending
Dominant language
TypeScript
Stars
67.3k
Forks
19.8k
Avg merge
11d 14h
Merged PRs (30d)
8

Description

### What problem does this feature solve?

### Issue Description

When using the `time` axis in ECharts and applying zoom-in using `dataZoom` (scroll wheel),
there comes a point where the interval between ticks expands too much and the first/last data points
become visually detached from the chart boundaries. This causes large empty areas on both edges of the chart.

It looks like this (simplified illustration):

| (Empty space) ----●●●●●---- (Empty space) |

Even though the zoom behavior is correct from the axis perspective,
it feels like missing data exists beyond the current zoom range.

### Expected Behavior

When zooming in:
- The chart should keep the first/last visible data points closer to the boundaries
- Avoid showing visually large blank areas unless actual data or range padding is configured
- Possibly auto-adjust zoom max/min to the nearest data points

### Current Behavior

- `minSpan`, `minValueSpan` do not fully prevent this behavior
- Setting `boundaryGap: false` helps but does not completely solve the issue
- The chart zooms into a region **outside the actual data range**,
causing empty left/right gaps that grow significantly

### Example Options

```js
xAxis: {
type: 'time',
boundaryGap: false,
},
dataZoom: [{
type: 'inside',
zoomLock: false
}]

### What does the proposed API look like?

Proposed solution & example API

This issue stems from the time axis zooming past the actual data extent, creating large empty edges. I propose adding two small, opt-in APIs that keep zoom and axis range aligned with the series extents, plus an optional auto-padding for nicer UX.

1) Clamp the visible window to data extents

New options

xAxis: {
// If true, the computed xAxis extent (including dataZoom) cannot exceed
// the min/max timestamps from any visible series in this grid.
clampToData?: boolean; // default: false
}

dataZoom: [{
// Hard clamp prevents the zoom window from going outside series extent.
// 'soft' allows minor overflow (<= edgePadding) for smoothness.
clampMode?: 'none' | 'soft' | 'hard'; // default: 'none'
}]

Behavior

When xAxis.clampToData = true, the final model extent (after dataZoom) is intersected with the min/max timestamp of visible series in the same grid.

dataZoom.clampMode = 'hard' rejects wheel/pan deltas that would push beyond the series range.

dataZoom.clampMode = 'soft' allows small overflow up to the configured edge padding (see below).

This eliminates the empty left/right regions that occur when the zoom window goes outside real data.

2) Optional, explicit edge padding

New options

xAxis: {
// Add breathing room beyond the last data point without fake points.
// Number = milliseconds; 'auto' derives from data cadence.
edgePadding?: number | 'auto'; // default: 0

// When edgePadding = 'auto', pick a strategy:
edgePaddingStrategy?: {
// Use median inter-sample gap of visible series
mode: 'median-gap' | 'percent';
// If mode = 'percent', percentage of current window (0.0 ~ 1.0)
percent?: number; // e.g., 0.05 for 5%
// Hard bounds for auto padding
min?: number; // ms
max?: number; // ms
}
}

Behavior

Padding is applied inside clamping rules:

If clampToData = true and clampMode = 'soft', the axis can extend at most edgePadding beyond min/max data.

If clampMode = 'hard', edgePadding is ignored for clamping (strict).

Padding does not add fake points; it only expands the axis extent.

This gives a natural “there could be next data” feel without misleading large gaps.

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.