我正在 React 应用程序中使用 ECharts,在同步两个折线图之间的缩放状态时遇到了问题。所需的行为是,当一个图表的缩放发生更改时,另一个图表应反映相同的缩放级别。然而,我发现在调整一张图表上的缩放后,它似乎“弹回”到其原始位置。
这是代码的简化表示:
// LineChart.tsx
export const LineChart = React.forwardRef<ReactECharts, LineChartProps>((props, ref) => {
{ zoomState, onDataZoom } = props
const option: EChartsOption = {
dataZoom: [{
type: 'slider',
start: zoomState.start,
end: zoomState.end,
}],
}
return (
<ReactECharts
ref={ref}
option={option}
onEvents={{
'datazoom': onDataZoom,
}}
/>
);
});
// index.tsx
const [zoomState, setZoomState] = useState<{start: number, end: number}>({ start: 80, end: 100 });
function onDataZoom(params: any) {
const newZoom = { start: params.start, end: params.end };
setZoomState(newZoom);
}
var co2Chart = (
<LineChart
ref={co2ChartRef}
data={device.deviceData}
zoomState={zoomState}
onDataZoom={onDataZoom}
valueToPlot={'co2'}
// ... (rest of the props)
/>
)
var tempChart = (
<LineChart
ref={tempChartRef}
data={device.deviceData}
zoomState={zoomState}
onDataZoom={onDataZoom}
valueToPlot={'temperature'}
// ... (rest of the props)
/>
)
根据我的观察:
我仍在学习 React,虽然我认为我明白发生了什么,但我不知道如何解决它。
我通过为 onDataZoom 函数实现去抖动技术成功解决了缩放“回弹”问题。这种策略有效地打破了 React 的异步状态更新和 ECharts 自己的渲染周期之间的反馈循环。
为什么去抖动有效
当您在 ECharts 中拖动缩放滑块时,datazoom 事件会快速连续触发多次。这些事件中的每一个通常都会触发 React 状态更新,从而由于 ECharts 和 React 之间的反馈循环而导致不必要的行为。对 onDataZoom 函数进行反跳会限制它的调用速率,本质上是在实际运行原始函数之前等待一段时间,而没有任何新的调用。这为 React 提供了足够的时间来更新其状态并重新渲染组件,从而有效地同步两个图表之间的缩放状态。
// index.tsx
import { debounce } from 'lodash';
function onDataZoom(params: any) {
const newZoom = { start: params.start, end: params.end };
setZoomState(newZoom);
}
const debouncedOnDataZoom = debounce(onDataZoom, 200);
var co2Chart = (
<LineChart
data={device.deviceData}
zoomState={zoomState}
onDataZoom={debouncedOnDataZoom}
valueToPlot={'co2'}
>
)