[Bug] Toolbox DataZoom behaves wrong with multiple axes with different min/max
Opened this issue · 3 comments
Version
5.5.1
Link to Minimal Reproduction
https://codesandbox.io/p/sandbox/vw8p5g
Steps to Reproduce
I did encounter this bug in my professional work, so I cannot share this context but it is easily explainable via the minimal reproduction.
I have multiple yAxis and want to use the dataZoom in the toolbox. The yAxis have different min/max values set. The dataZoom is not configured specifically, so it controls all y and xAxis per default.
Current Behavior
Using the dataZoom from the toolbox sets all yAxes to the same start and end value.
This is before the zoom, look at the axes.
This is after the zoom, again please look at the axes.
Expected Behavior
Using the dataZoom from the toolbox should set all yAxes to the correct values. Inspecting the event triggered by the dataZoom reveals, that the event batch carries the correct start and end values for all axes
Environment
I reproduced the example with a CodeSandbox, I do not know which env it utilizes.
- OS:
- Browser:
- Framework:
Any additional comments?
No response
two additional observations:
- the problem disappears when option.dataZoom is removed
- the official example works ok
two additional observations:
* the problem disappears when _option.dataZoom_ is removed * the [official example](https://echarts.apache.org/examples/en/editor.html?c=area-rainfall) works ok
You are right. The bug lies in the addition of different min/max values for the two yAxes in the yAxis
option, that is why the official example works fine.
As this issue was a blocker for us I did try to come up with a workaround to solve this problem. It relies on a custom handler triggered by the datazoom
event which then sets the correct start
and end
for the correct dataZoom
slider. The following snippet may help people having the same issue or even fixing the bug in the codebase. I will also try to find some time, maybe I can contribute with a PR.
// Event Handlers
const handleDataZoom = (e: SyntheticEvent) => {
const chart = getInstanceByDom(chartRef.current)
// @ts-ignore getOption is poorly typed, it should return an array of the yAxis
const firstIndexWithSetRange = chart.getOption().yAxis.findIndex((yAxis) => {
// Utilizing == here, as this is an appropriate way to check if it is null OR undefined (nullish and not falsy)
return !(yAxis.min == null) && !(yAxis.max == null)
})
// The toolbox datazoom has a batch at its event, which carries the start and end
// of all axes that are controlled by it.
if (firstIndexWithSetRange !== -1 && e.hasOwnProperty('batch')) {
// I totally dislike this approach as we are looking for magic strings
// and generally this seems kind of hacky. But I think this is the best
// fix for the overall problem. Hopefully Echarts does simply fix the zoom via the toolbox.
// @ts-ignore We check for the existence of this prop in the if-clause
const yAxisEventForSetRangeAxis = e.batch.find((dataZoomEvent) => {
return dataZoomEvent.dataZoomId.includes(`yAxis${firstIndexWithSetRange}`)
})
const accordingYAxisToEventMaxValue = chart.getOption().yAxis[firstIndexWithSetRange].max
chart.dispatchAction({
type: 'dataZoom',
dataZoomIndex: chart
.getOption()
// @ts-ignore As already mentioned, dataZoom is poorly typed
.dataZoom.findIndex((dataZoomObj) => dataZoomObj?.id === DATA_ZOOM_Y_AXIS_ID),
start: (yAxisEventForSetRangeAxis.startValue / accordingYAxisToEventMaxValue) * 100,
end: (yAxisEventForSetRangeAxis.endValue / accordingYAxisToEventMaxValue) * 100,
})
}
}
Be aware that this is just the handler itself as it fits in our company context. The important part is getting e.batch
, calculating the start
and end
percentages and setting it via dispatchAction()