diff --git a/src/components/custom-echart-line-line/index.vue b/src/components/custom-echart-line-line/index.vue index 50eccf7..2904c4b 100644 --- a/src/components/custom-echart-line-line/index.vue +++ b/src/components/custom-echart-line-line/index.vue @@ -33,7 +33,7 @@ export default { emits: ['click'], setup(props, { emit }) { const chartRef = ref(null); - const { setOptions, getInstance, resize } = useEcharts(chartRef); + const { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef); const optionVal = reactive({}); watchEffect(() => { @@ -55,6 +55,11 @@ export default { Object.assign(optionVal, cloneDeep(props.option)); } setOptions(props.option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); resize(); getInstance()?.off('click', onClick); getInstance()?.on('click', onClick); diff --git a/src/components/custom-echart-line/index.vue b/src/components/custom-echart-line/index.vue index c5ad9fd..65e8ac5 100644 --- a/src/components/custom-echart-line/index.vue +++ b/src/components/custom-echart-line/index.vue @@ -34,7 +34,7 @@ export default { emits: ['click'], setup(props, { emit }) { const chartRef = ref(null); - const { setOptions, getInstance } = useEcharts(chartRef); + const { setOptions, getInstance, startAutoPlay } = useEcharts(chartRef); const option = reactive({ tooltip: { trigger: 'axis', @@ -138,6 +138,11 @@ export default { option.series = seriesData; option.xAxis.data = xAxisData; setOptions(option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); getInstance()?.off('click', onClick); getInstance()?.on('click', onClick); } diff --git a/src/components/custom-echart-maps/index.vue b/src/components/custom-echart-maps/index.vue index 0864b06..b8d9b28 100644 --- a/src/components/custom-echart-maps/index.vue +++ b/src/components/custom-echart-maps/index.vue @@ -43,7 +43,7 @@ export default { emits: ['click'], setup(props, { emit }) { const chartRef = ref(null); - const { setOptions, getInstance, resize, registerMap } = useEcharts(chartRef); + const { setOptions, getInstance, resize, registerMap, startAutoPlay } = useEcharts(chartRef); const option = reactive({ // series: [], }); @@ -68,6 +68,11 @@ export default { } // option.series = props.chartData; setOptions(option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); registerMap(props.name, props.geo); resize(); getInstance()?.off('click', onClick); diff --git a/src/components/custom-echart-mixin/index.vue b/src/components/custom-echart-mixin/index.vue index a23cb57..f692132 100644 --- a/src/components/custom-echart-mixin/index.vue +++ b/src/components/custom-echart-mixin/index.vue @@ -29,7 +29,7 @@ export default { }, setup(props) { const chartRef = ref(null); - const { setOptions } = useEcharts(chartRef); + const { setOptions, startAutoPlay } = useEcharts(chartRef); const option = reactive({ tooltip: { trigger: 'axis', @@ -84,6 +84,11 @@ export default { option.series = seriesData; option.xAxis.data = xAxisData; setOptions(option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); } return { chartRef }; }, diff --git a/src/components/custom-echart-pictorial-bar/index.vue b/src/components/custom-echart-pictorial-bar/index.vue index c20864b..2c6327b 100644 --- a/src/components/custom-echart-pictorial-bar/index.vue +++ b/src/components/custom-echart-pictorial-bar/index.vue @@ -33,7 +33,7 @@ export default { emits: ['click'], setup(props, { emit }) { const chartRef = ref(null); - const { setOptions, getInstance, resize } = useEcharts(chartRef); + const { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef); const option = reactive({ grid: { left: '3%', @@ -104,6 +104,11 @@ export default { Object.assign(option, cloneDeep(props.option)); } setOptions(option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); resize(); getInstance()?.off('click', onClick); getInstance()?.on('click', onClick); diff --git a/src/components/custom-echart-pie-gauge/index.vue b/src/components/custom-echart-pie-gauge/index.vue index c704314..25d6ae0 100644 --- a/src/components/custom-echart-pie-gauge/index.vue +++ b/src/components/custom-echart-pie-gauge/index.vue @@ -33,7 +33,7 @@ export default { emits: ['click'], setup(props, { emit }) { const chartRef = ref(null); - const { setOptions, getInstance, resize } = useEcharts(chartRef); + const { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef); const option = reactive({ series: [], }); @@ -58,6 +58,11 @@ export default { } option.series = props.chartData; setOptions(option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); resize(); getInstance()?.off('click', onClick); getInstance()?.on('click', onClick); diff --git a/src/components/custom-echart-pie/index.vue b/src/components/custom-echart-pie/index.vue index 05f8c4e..e9c1234 100644 --- a/src/components/custom-echart-pie/index.vue +++ b/src/components/custom-echart-pie/index.vue @@ -33,7 +33,7 @@ export default { emits: ['click'], setup(props, { emit }) { const chartRef = ref(null); - const { setOptions, getInstance, resize } = useEcharts(chartRef); + const { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef); const option = reactive({ tooltip: { formatter: '{b} ({c})', @@ -74,6 +74,11 @@ export default { } option.series[0].data = props.chartData; setOptions(option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); resize(); getInstance()?.off('click', onClick); getInstance()?.on('click', onClick); diff --git a/src/components/custom-echart-radar/index.vue b/src/components/custom-echart-radar/index.vue index 79d506f..8304547 100644 --- a/src/components/custom-echart-radar/index.vue +++ b/src/components/custom-echart-radar/index.vue @@ -34,7 +34,7 @@ export default { emits: ['click'], setup(props, { emit }) { const chartRef = ref(null); - const { setOptions, getInstance } = useEcharts(chartRef); + const { setOptions, getInstance, startAutoPlay } = useEcharts(chartRef); const option = reactive({ title: { text: '', @@ -78,6 +78,11 @@ export default { option.radar.indicator = indicator; option.series[0]['data'] = data; setOptions(option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); getInstance()?.off('click', onClick); getInstance()?.on('click', onClick); } diff --git a/src/components/custom-echart-scatter-blister/index.vue b/src/components/custom-echart-scatter-blister/index.vue index ffb765a..a97ab29 100644 --- a/src/components/custom-echart-scatter-blister/index.vue +++ b/src/components/custom-echart-scatter-blister/index.vue @@ -33,7 +33,7 @@ export default { emits: ['click'], setup(props, { emit }) { const chartRef = ref(null); - const { setOptions, getInstance, resize } = useEcharts(chartRef); + const { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef); const option = reactive({ series: [], }); @@ -58,6 +58,11 @@ export default { } option.series = props.chartData; setOptions(option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); resize(); getInstance()?.off('click', onClick); getInstance()?.on('click', onClick); diff --git a/src/components/custom-echart-water-droplet/index.vue b/src/components/custom-echart-water-droplet/index.vue index e97942f..1a40294 100644 --- a/src/components/custom-echart-water-droplet/index.vue +++ b/src/components/custom-echart-water-droplet/index.vue @@ -33,7 +33,7 @@ export default { emits: ['click'], setup(props, { emit }) { const chartRef = ref(null); - const { setOptions, getInstance, resize } = useEcharts(chartRef); + const { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef); const option = reactive({ tooltip: { formatter: '{b} ({c})', @@ -73,6 +73,11 @@ export default { Object.assign(option, cloneDeep(props.option)); } setOptions(props.option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); resize(); getInstance()?.off('click', onClick); getInstance()?.on('click', onClick); diff --git a/src/components/custom-echart-word-cloud/index.vue b/src/components/custom-echart-word-cloud/index.vue index f74fdcd..a4e861e 100644 --- a/src/components/custom-echart-word-cloud/index.vue +++ b/src/components/custom-echart-word-cloud/index.vue @@ -33,7 +33,7 @@ export default { emits: ['click'], setup(props, { emit }) { const chartRef = ref(null); - const { setOptions, getInstance, resize } = useEcharts(chartRef); + const { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef); const option = reactive({ series: [], }); @@ -58,6 +58,11 @@ export default { } option.series = props.chartData; setOptions(option); + startAutoPlay({ + interval: 2000, + seriesIndex: 0, + showTooltip: true, + }); resize(); getInstance()?.off('click', onClick); getInstance()?.on('click', onClick); diff --git a/src/hooks/useEcharts.js b/src/hooks/useEcharts.js index 7a78abd..cc00ec0 100644 --- a/src/hooks/useEcharts.js +++ b/src/hooks/useEcharts.js @@ -6,6 +6,57 @@ import { useBreakpoint } from './useBreakpoint'; import echarts from '../utils/echarts'; export const useEcharts = (elRef, theme = 'default') => { + // 新增轮播相关状态 + const autoPlayTimer = ref(null); + const currentIndex = ref(-1); + const dataLength = ref(0); + + // 新增方法 - 启动轮播 + const startAutoPlay = (options = {}) => { + const { + interval = 2000, // 轮播间隔(ms) + seriesIndex = 0, // 默认操作第一个系列 + showTooltip = true, // 是否显示提示框 + } = options; + + stopAutoPlay(); // 先停止已有轮播 + + // 获取数据长度 + const seriesData = unref(getOptions).series?.[seriesIndex]?.data; + dataLength.value = seriesData?.length || 0; + if (dataLength.value === 0) return; + + autoPlayTimer.value = setInterval(() => { + currentIndex.value = (currentIndex.value + 1) % dataLength.value; + + // 执行轮播动作 + chartInstance?.dispatchAction({ + type: 'downplay', + seriesIndex: seriesIndex, + }); + chartInstance?.dispatchAction({ + type: 'highlight', + seriesIndex: seriesIndex, + dataIndex: currentIndex.value, + }); + if (showTooltip) { + chartInstance?.dispatchAction({ + type: 'showTip', + seriesIndex: seriesIndex, + dataIndex: currentIndex.value, + }); + } + }, interval); + }; + + // 新增方法 - 停止轮播 + const stopAutoPlay = () => { + if (autoPlayTimer.value) { + clearInterval(autoPlayTimer.value); + autoPlayTimer.value = null; + } + }; + const getDarkMode = computed(() => { return theme === 'default' ? 'dark' : theme; }); @@ -31,23 +82,39 @@ export const useEcharts = (elRef, theme = 'default') => { if (!el || !unref(el)) { return; } + nextTick(() => { + if (el.offsetWidth === 0 || el.offsetHeight === 0) { + // console.warn('图表容器不可见,延迟初始化'); + useTimeoutFn(() => initCharts(t), 100); + return; + } - chartInstance = echarts.init(el, t); - const { removeEvent } = useEventListener({ - el: window, - name: 'resize', - listener: resizeFn, + chartInstance = echarts.init(el, t); + const { removeEvent } = useEventListener({ + el: window, + name: 'resize', + listener: resizeFn, + }); + removeResizeFn = removeEvent; + const { widthRef } = useBreakpoint(); + if (unref(widthRef) <= 768 || el.offsetHeight === 0) { + useTimeoutFn(() => { + resizeFn(); + }, 30); + } }); - removeResizeFn = removeEvent; - const { widthRef } = useBreakpoint(); - if (unref(widthRef) <= 768 || el.offsetHeight === 0) { - useTimeoutFn(() => { - resizeFn(); - }, 30); - } } function setOptions(options = {}, clear = true) { + const mergedOptions = { + animation: true, + animationDuration: 3000, + animationEasing: 'cubicOut', + ...unref(options), + animationThreshold: 2000, // 数据量超过2000自动关闭动画 + animationDelayUpdate: (idx) => idx * 50, // 数据项延迟 + }; + cacheOptions.value = mergedOptions; cacheOptions.value = options; if (unref(elRef)?.offsetHeight === 0) { useTimeoutFn(() => { @@ -98,6 +165,7 @@ export const useEcharts = (elRef, theme = 'default') => { ); tryOnUnmounted(() => { + stopAutoPlay(); // 清理定时器 if (!chartInstance) return; removeResizeFn(); chartInstance.dispose(); @@ -115,7 +183,9 @@ export const useEcharts = (elRef, theme = 'default') => { setOptions, resize, echarts, - getInstance, + getInstance: () => chartInstance, registerMap, + startAutoPlay, // 暴露轮播方法 + stopAutoPlay, }; }; diff --git a/src/views/land/index.vue b/src/views/land/index.vue index c9317cd..3f6caa1 100644 --- a/src/views/land/index.vue +++ b/src/views/land/index.vue @@ -5,21 +5,21 @@
- +
- +
- +