[Feature] Prevent empty gaps at chart edges when zooming on time axis
- 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
Assessment
This issue has not been assessed yet.