76 lines
2.1 KiB
TypeScript
76 lines
2.1 KiB
TypeScript
import * as echarts from 'echarts';
|
||
|
||
/**
|
||
* 为 ECharts 实例添加自动滚动功能(精确固定窗口项数 + 用户操作暂停)
|
||
* @param chartInstance ECharts 实例
|
||
* @param totalItems x轴总项数
|
||
* @param windowSize 显示窗口项数,默认 6
|
||
* @param interval 滚动间隔,默认 1500ms
|
||
* @returns 停止函数
|
||
*/
|
||
export function enableEchartsAutoScroll(
|
||
chartInstance: echarts.ECharts,
|
||
totalItems: number,
|
||
windowSize: number = 6,
|
||
interval: number = 1500
|
||
): () => void {
|
||
let index = 0;
|
||
let isUserInteracting = false;
|
||
let lastInteractionTime = Date.now();
|
||
let currentWindowSize = windowSize;
|
||
|
||
// 主动初始化窗口大小(如果设置了 dataZoom)
|
||
const option = chartInstance.getOption();
|
||
const zoom = option?.dataZoom?.[0];
|
||
if (zoom && zoom.start != null && zoom.end != null) {
|
||
const startIndex = Math.round((zoom.start / 100) * totalItems);
|
||
const endIndex = Math.round((zoom.end / 100) * totalItems);
|
||
currentWindowSize = endIndex - startIndex;
|
||
}
|
||
|
||
// 监听用户操作
|
||
const dataZoomHandler = (params: any) => {
|
||
const zoom = params.batch ? params.batch[0] : params;
|
||
const startIndex = Math.round((zoom.start / 100) * totalItems);
|
||
const endIndex = Math.round((zoom.end / 100) * totalItems);
|
||
currentWindowSize = endIndex - startIndex;
|
||
|
||
isUserInteracting = true;
|
||
lastInteractionTime = Date.now();
|
||
};
|
||
|
||
chartInstance.on('dataZoom', dataZoomHandler);
|
||
|
||
// 自动滚动定时器
|
||
const timer = setInterval(() => {
|
||
const now = Date.now();
|
||
if (isUserInteracting && now - lastInteractionTime < 1000) return;
|
||
|
||
isUserInteracting = false;
|
||
|
||
if (index + currentWindowSize > totalItems) {
|
||
index = 0;
|
||
}
|
||
|
||
const startPercent = (index / totalItems) * 100;
|
||
const endPercent = ((index + currentWindowSize) / totalItems) * 100;
|
||
|
||
chartInstance.setOption({
|
||
dataZoom: [
|
||
{
|
||
start: startPercent,
|
||
end: endPercent
|
||
}
|
||
]
|
||
});
|
||
|
||
index++;
|
||
}, interval);
|
||
|
||
// 返回停止方法
|
||
return () => {
|
||
clearInterval(timer);
|
||
chartInstance.off('dataZoom', dataZoomHandler);
|
||
};
|
||
}
|