vue项目需要实现这么个效果,饼图要有轮播效果,轮播的时候不是echart默认的highlight,而是需要凸出,中间要有空隙,如下图。
研究了一下,觉得echarts的dispatchAction方法太烦了,所以选用操控data里的selected属性。
主要实现这几个功能:
1.页面初始化会自动开启定时器
2.鼠标hover上去,定时器暂停
3.鼠标离开,定时器重启,从上次鼠标选中的扇形开始重新轮播
4.当用户切屏,暂停定时器
5.当用户回到页面,定时器重启
6.防止用户恶意快速mouseover这个扇形,做了防抖处理
代码如下:
<template>
<div>
<div id="chart1" style="width:600px; height: 400px;"></div>
<h2>{{title}}</h2>
</div>
</template>
<script>
import echarts from "echarts"
export default {
data() {
return {
option: null,
myChart: null,
num: 0,
timer: null,
title: ''
}
},
mounted() {
this.initData();
},
methods: {
initData() {
this.option = {
title: {
text: '饼图'
},
series: [{
name: '访问量',
type: 'pie',
radius: '80%',
legendHoverLink: true,
hoverAnimation: false,
selectedMode: 'single',
data: [
{ name: "智联招聘", value: 600 },
{ name: "51job", value: 310 },
{ name: "拉钩", value: 200 },
{ name: "Boss直聘", value: 800 }
]
}]
};
//初始化echarts实例
this.myChart = echarts.init(document.getElementById('chart1'));
//使用制定的配置项和数据显示图表
this.myChart.setOption(this.option);
//开启定时器
this.setTimeToDo();
this.setHighLight();
const data = this.option.series[0].data;
let debounce = null;
this.myChart.on('mouseover', params => {
clearInterval(this.timer);
// 鼠标快速移动时,会导致mouseover里的代码来不及执行,引起事件延迟,出现多个扇形区域同时被选中的现象,所以有必要设置防抖函数
debounce && clearTimeout(debounce);
debounce = setTimeout(() => {
const data = this.option.series[0].data;
data.forEach(e => e.selected = false);
data[params.dataIndex].selected = true;
this.myChart.setOption(this.option);
this.num = params.dataIndex;
this.title = params.name;
}, 300);
})
this.myChart.on('mouseout', params => {
this.setTimeToDo();
this.setHighLight();
})
// 当切屏时,定时器容易执行异常,所以如果用户切屏,就暂停定时器
window.onblur = () => {
clearInterval(this.timer);
}
window.onfocus = () => {
this.setHighLight();
}
},
setTimeToDo() {
const data = this.option.series[0].data;
data.forEach(e => e.selected = false);
data[this.num].selected = true;
this.title = data[this.num].name;
// 必须重新设置option,因为echart没有监听data的变化
this.myChart.setOption(this.option);
},
setHighLight() {
clearInterval(this.timer);
const data = this.option.series[0].data;
this.timer = setInterval(() => {
if (this.num < data.length - 1) {
this.num++
} else {
this.num = 0
}
this.setTimeToDo();
}, 3000);
}
}
}
</script>