1
长话短说,先看效果

效果图

思路

  • 来一个定时器setInterval每隔一秒触发一次showTip展示tootip
  • 关键代码如下:(派发一次,就弹出一次tootip
  • tootip切换就是更改一下数据的下标索引dataIndex
chart.dispatchAction({
    type: 'showTip',
    seriesIndex: 0,
    dataIndex: i
})
  • 最后当鼠标移入进去以后,再取消定时器轮播即可
  • 当然,需要绑定一些鼠标事件

完整代码(复制粘贴即可使用)

option配置项

数据在option中的dataset里面

const option = ref({
    "legend": {
        "show": true,
        "top": "5%",
        "textStyle": {
            "color": "#B9B8CE"
        },
        "pageTextStyle": {
            "color": "#B9B8CE"
        },
        "orient": "horizontal",
        "itemGap": 14,
        "padding": -14
    },
    "xAxis": {
        "show": true,
        "name": "",
        "nameGap": 15,
        "nameTextStyle": {
            "color": "#B9B8CE",
            "fontSize": 12
        },
        "inverse": false,
        "axisLabel": {
            "show": true,
            "fontSize": 12,
            "color": "#B9B8CE",
            "rotate": 0
        },
        "position": "bottom",
        "axisLine": {
            "show": true,
            "lineStyle": {
                "color": "#B9B8CE",
                "width": 1
            },
            "onZero": true
        },
        "axisTick": {
            "show": true,
            "length": 5,
            "alignWithLabel": true
        },
        "splitLine": {
            "show": false,
            "lineStyle": {
                "color": "#484753",
                "width": 1,
                "type": "solid"
            }
        },
        "type": "category"
    },
    "yAxis": [
        {
            "type": "value",
            "splitNumber": 4,
            "splitLine": {
                "show": false
            },
            "axisLine": {
                "show": true,
                "lineStyle": {
                    "color": "#BDBDBD",
                    "width": 1,
                    "type": "solid"
                }
            },
            "axisLabel": {
                "show": true,
                "color": "#BDBDBD",
                "fontSize": "12"
            },
            "yAxisIndex": 0,
            "show": true,
            "name": "件",
            "nameGap": 12
        },
        {
            "type": "value",
            "splitLine": {
                "show": false
            },
            "axisLine": {
                "show": true,
                "lineStyle": {
                    "color": "#BDBDBD",
                    "width": 1,
                    "type": "solid"
                }
            },
            "splitNumber": 6,
            "axisLabel": {},
            "yAxisIndex": 1,
            "show": true,
            "name": "%",
            "nameGap": 12
        }
    ],
    "grid": {
        "show": false,
        "left": "50",
        "top": "50",
        "right": "50",
        "bottom": "30"
    },
    "tooltip": {
        "trigger": "axis",
        "axisPointer": {
            "type": "shadow",
            "label": {
                "show": true,
                "backgroundColor": "#7B7DDC"
            }
        },
        formatter(params) {
            let unit1 = '件'
            let unit2 = '件'
            let key = '通过率'
            let list = []
            let listItem = ''
            params.forEach((item) => {
                let unitValue = ''
                if (item.seriesType == 'line') {
                    unitValue = item.value[key] + '%'
                } else {
                    unitValue = item.componentIndex === 0 ? item.value[item.seriesName] + unit1 : item.value[item.seriesName] + unit2
                }
                list.push(item.marker + '' + item.seriesName + ' : ' + unitValue)
            })
            listItem = list.join('<br/>')
            return '<div>' + params[0].name + "<br />" + listItem + '</div>'
        }
    },
    "dataset": {
        "dimensions": [
            "城市",
            "申报数",
            "通过数",
            "通过率"
        ],
        "source": [
            {
                "城市": "北京",
                "申报数": 352,
                "通过数": 254,
                "通过率": 72.16
            },
            {
                "城市": "上海",
                "申报数": 107,
                "通过数": 79,
                "通过率": 73.83
            },
            {
                "城市": "广州",
                "申报数": 51,
                "通过数": 47,
                "通过率": 92.16
            },
            {
                "城市": "深圳",
                "申报数": 201,
                "通过数": 172,
                "通过率": 85.57
            },
            {
                "城市": "成都",
                "申报数": 36,
                "通过数": 26,
                "通过率": 72.22
            },
            {
                "城市": "重庆",
                "申报数": 24,
                "通过数": 13,
                "通过率": 54.17
            },
            {
                "城市": "合肥",
                "申报数": 31,
                "通过数": 14,
                "通过率": 45.16
            },
            {
                "城市": "南京",
                "申报数": 147,
                "通过数": 117,
                "通过率": 79.59
            },
            {
                "城市": "杭州",
                "申报数": 330,
                "通过数": 314,
                "通过率": 95.15
            },
            {
                "城市": "苏州",
                "申报数": 140,
                "通过数": 113,
                "通过率": 80.71
            },
            {
                "城市": "宁波",
                "申报数": 273,
                "通过数": 134,
                "通过率": 49.08
            },
            {
                "城市": "石家庄",
                "申报数": 265,
                "通过数": 181,
                "通过率": 68.3
            },
            {
                "城市": "武汉",
                "申报数": 118,
                "通过数": 46,
                "通过率": 38.98
            },
            {
                "城市": "长沙",
                "申报数": 249,
                "通过数": 184,
                "通过率": 73.9
            },
            {
                "城市": "南昌",
                "申报数": 215,
                "通过数": 92,
                "通过率": 42.79
            },
        ]
    },
    "series": [
        {
            "type": "bar",
            "barWidth": 15,
            "label": {
                "show": true,
                "position": "top",
                "color": "#fff",
                "fontSize": 12
            },
            "itemStyle": {
                "color": {
                    "colorStops": [
                        {
                            "offset": 0,
                            "color": "#8063B0"
                        },
                        {
                            "offset": 1,
                            "color": "#342A61"
                        }
                    ],
                    "x": 0,
                    "y": 0,
                    "x2": 0,
                    "y2": 1,
                    "type": "linear",
                    "global": false
                },
                "borderRadius": [
                    12,
                    12,
                    3,
                    3
                ]
            },
            "barGap": "-100%",
            "name": "申报数"
        },
        {
            "type": "bar",
            "barWidth": 15,
            "label": {
                "show": true,
                "position": "inside",
                "color": "#fff",
                "fontSize": 12,
                "distance": -8
            },
            "itemStyle": {
                "color": {
                    "colorStops": [
                        {
                            "offset": 0,
                            "color": "#9781D4"
                        },
                        {
                            "offset": 1,
                            "color": "#3BA1E3"
                        }
                    ],
                    "x": 0,
                    "y": 0,
                    "x2": 0,
                    "y2": 1,
                    "type": "linear",
                    "global": false
                },
                "borderRadius": [
                    12,
                    12,
                    3,
                    3
                ]
            },
            "name": "通过数"
        },
        {
            "smooth": true,
            "showAllSymbol": true,
            "symbol": "emptyCircle",
            "type": "line",
            "yAxisIndex": 1,
            "symbolSize": 10,
            "label": {
                "show": true,
                "color": "#FFFFFFFF",
                "fontSize": 12,
                "position": "top",
                "distance": 3,
                "fontStyle": "italic",
                "fontWeight": "normal"
            },
            "lineStyle": {
                "width": 2,
                "type": "solid",
                "color": "#946496"
            },
            "name": "通过率",
            "step": false,
            "emphasis": {
                "disabled": true,
                "scale": 1.5,
                "itemStyle": {
                    "borderWidth": 2.4,
                    "color": "#2EC7C9",
                    "borderColor": "#fff"
                }
            },
            "itemStyle": {
                "color": "#2EC7C9",
                "borderColor": "#2EC7C9"
            }
        }
    ],
})

js逻辑控制(重点)

<template>
    <div style="width:100%; height:80vh">
        <v-chart ref="vChartRef" theme="dark" resize :option="option"></v-chart>
    </div>
</template>

<script setup>
import * as echarts from "echarts"; // 本代码中的echarts的版本5.3.2
import VChart from "vue-echarts"; // echarts的套壳子的vue-echarts组件版本6.0.2
import { onMounted, ref } from "vue"; // vue版本3.3.4

const vChartRef = ref(null); // vue-echarts实例,注意再往里一层才是echarts
let timer = ref(null) // 定时器一直派发

const option = 上面一大堆的option数据

const addE = (chartObj, option) => {
    return new Promise((resolve, reject) => {
        // vue-echarts实例,再往里一层才是echarts(可打印瞅瞅就知道了)
        const chart = chartObj.chart
        let zRender = chart.getZr();
        // 鼠标经过清除定时器
        chart.on('mouseover', () => {
            if (timer.value) { clearInterval(timer.value) }
        })
        // 鼠标移动清除定时器
        zRender.on('mousemove', () => {
            if (timer.value) { clearInterval(timer.value) }
        });
        // 鼠标移动离开再开启轮播
        chart.on('mouseout', function () {
            loopTootip(chart, option)
        });
        // 鼠标全局离开再开启轮播
        zRender.on('globalout', () => {
            loopTootip(chart, option)
        });
        resolve(true)
    })
}

const loopTootip = (chart, option) => {
    if (timer.value) { clearInterval(timer.value) } // 清空定时器并再设置一个新的定时器
    let i = 0 // 索引0开始tootip轮播
    let length = option.dataset.source.length // 多少个需要轮播
    timer.value = setInterval(() => {
        /**
         * 派发展示tootip事件,第一个系列,从柱状图第一项开始
         * 派发一次,就弹出tootip【关键代码】
         * */
        chart.dispatchAction({
            type: 'showTip',
            seriesIndex: 0,
            dataIndex: i
        })
        // chart.dispatchAction({ type: 'highlight', seriesIndex: 0, dataIndex: i }); // 派发高亮此案例用不到
        /**
         * 当跑到最后一个柱状图的时候,再回到第一项
         * */
        if (i == length - 1) {
            i = 0
        } else {
            i = i + 1
        }
    }, 1000);
}

onMounted(async () => {
    // 先绑定监听鼠标事件,再开始轮播tootip
    await addE(vChartRef.value, option.value)
    loopTootip(vChartRef.value, option.value)
})
</script>
好了,又shui了一篇文章...

水冗水孚
1.1k 声望585 粉丝

每一个不曾起舞的日子,都是对生命的辜负