先给大家看一下实现的效果。
3个饼图排成一排,点击各个饼图内的颜色块会在鼠标点击处生成一个绘制对应数据的div;点击除了饼图以外的区域此div会消失,如果第二次点击的区域也是饼图内,则原div消失,新div替换。
主要功能点如下:
- 饼图内区域的点击效果
- 饼图外区域的点击效果
- 在鼠标点击位置绘制div
- 减少代码冗余,复用代码,根据不同饼图的块得到不同对应数据
下面贴一下代码,各位看官直接在本地引入一下echarts就可以看到交互效果了,没有做屏幕适配,具体看逻辑实现吧,各位根据demo举一反三,有问题可以在下面留言~
<template>
<div class="" style="position:relative;">
<div @click="clickdemo4">
<div id="demo4" class="demo4"></div>
<div id="demo5" class="demo4"></div>
<div id="demo6" class="demo4"></div>
<div id="popmenu" class="popmenu"></div>
</div>
</div>
</template>
<script>
import echarts from "echarts";
export default {
name: "",
components: {},
props: {},
data() {
return {
clickPie:false,//默认没点击在饼图里
pieChartsArr0:[
{
name:'直接访问',
xData : ['0Mon0', 'Tue0', 'Wed0', 'Thu0', 'Fri0', 'Sat0', 'Sun0'],
yData : [820, 932, 901, 934, 1290, 1330, 1320],
type : "line",
pointerType:"cross"
},{
name:'邮件营销',
xData : ['0Mon1', 'Tue1', 'Wed1', 'Thu1', 'Fri1', 'Sat1', 'Sun1'],
yData : [820, 932, 901, 934, 1290, 1330, 1320],
type : "bar",
pointerType:"shadow"
},{
name:'联盟广告',
xData : ['0Mon2', 'Tue2', 'Wed2', 'Thu2', 'Fri2', 'Sat2', 'Sun2'],
yData : [123, 888, 666, 23, 234, 54, 9],
type : "bar",
pointerType:"shadow"
},{
name:'视频广告',
xData : ['0Mon3', 'Tue3', 'Wed3', 'Thu3', 'Fri3', 'Sat3', 'Sun3'],
yData : [63, 1, 190, 77, 11, 52, 1320],
type : "line",
pointerType:"cross"
},{
name:'搜索引擎',
xData : ['0Mon4', 'Tue4', 'Wed4', 'Thu4', 'Fri4', 'Sat4', 'Sun4'],
yData : [820, 24, 57, 40, 654, 88, 44],
type : "line",
pointerType:"cross"
},
],
pieChartsArr1:[
{
name:'直接访问',
xData : ['1Mon0', 'Tue0', 'Wed0', 'Thu0', 'Fri0', 'Sat0', 'Sun0'],
yData : [820, 932, 901, 934, 1290, 1330, 1320],
type : "line",
pointerType:"cross"
},{
name:'邮件营销',
xData : ['1Mon1', 'Tue1', 'Wed1', 'Thu1', 'Fri1', 'Sat1', 'Sun1'],
yData : [820, 932, 901, 934, 1290, 1330, 1320],
type : "bar",
pointerType:"shadow"
},{
name:'联盟广告',
xData : ['1Mon2', 'Tue2', 'Wed2', 'Thu2', 'Fri2', 'Sat2', 'Sun2'],
yData : [123, 888, 666, 23, 234, 54, 9],
type : "bar",
pointerType:"shadow"
},{
name:'视频广告',
xData : ['1Mon3', 'Tue3', 'Wed3', 'Thu3', 'Fri3', 'Sat3', 'Sun3'],
yData : [63, 1, 190, 77, 11, 52, 1320],
type : "line",
pointerType:"cross"
},{
name:'搜索引擎',
xData : ['1Mon4', 'Tue4', 'Wed4', 'Thu4', 'Fri4', 'Sat4', 'Sun4'],
yData : [820, 24, 57, 40, 654, 88, 44],
type : "line",
pointerType:"cross"
},
],
pieChartsArr2:[
{
name:'直接访问',
xData : ['2Mon0', 'Tue0', 'Wed0', 'Thu0', 'Fri0', 'Sat0', 'Sun0'],
yData : [820, 932, 901, 934, 1290, 13300000, 1320],
type : "line",
pointerType:"cross"
},{
name:'邮件营销',
xData : ['2Mon1', 'Tue1', 'Wed1', 'Thu1', 'Fri1', 'Sat1', 'Sun1'],
yData : [820, 932, 901, 934, 129000000, 1330, 1320],
type : "bar",
pointerType:"shadow"
},{
name:'联盟广告',
xData : ['2Mon2', 'Tue2', 'Wed2', 'Thu2', 'Fri2', 'Sat2', 'Sun2'],
yData : [123, 888, 666, 23, 234000000000, 54, 9],
type : "bar",
pointerType:"shadow"
},{
name:'视频广告',
xData : ['2Mon3', 'Tue3', 'Wed3', 'Thu3', 'Fri3', 'Sat3', 'Sun3'],
yData : [63, 1, 190, 77, 11, 52, 1320],
type : "line",
pointerType:"cross"
},{
name:'搜索引擎',
xData : ['2Mon4', 'Tue4', 'Wed4', 'Thu4', 'Fri4', 'Sat4', 'Sun4'],
yData : [820, 24, 57, 40, 654, 88, 44],
type : "line",
pointerType:"cross"
},
],
};
},
created() {},
mounted() {
this.draw4("demo4",this.pieChartsArr0);
this.draw4("demo5",this.pieChartsArr1);
this.draw4("demo6",this.pieChartsArr2);
},
watch: {
clickPie:{ //监听的对象
deep:true, //深度监听设置为 true
handler:function(newV,oldV){
console.log('watch中:',newV , oldV)
}
}
},
computed: {},
methods: {
draw4(id,pieChartsArr){
let myChart = echarts.init(document.getElementById(id));
let option = {
title: {
text: '某站点用户访问来源',
subtext: '纯属虚构',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left',
data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']
},
series: [
{
name: '访问来源',
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
data: [
{value: 335, name: '直接访问'},
{value: 310, name: '邮件营销'},
{value: 234, name: '联盟广告'},
{value: 135, name: '视频广告'},
{value: 1548, name: '搜索引擎'}
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
let optionTemp = myChart; //临时存储Chart的属性
myChart.clear();
myChart = optionTemp;
myChart.setOption(option);
let _this = this;
myChart.on('click', function (event) {
//数据的名称 event.name 根据这个去查相应的图表数据
console.log(event.name);
let matchData = pieChartsArr.filter((item)=>{
return item.name === event.name;
});
console.log(matchData,"匹配到的对象");
_this.drawChart(matchData);
_this.clickPie = true;
if(event.name){
_this.clickPie = true;//true代表点击的是饼图内 默认false 代表点击的是饼图外
}
});
},
drawChart(arr){
console.log(arr);
let data = arr[0];
let myChart = echarts.init(document.getElementById("popmenu"));
let option = {
color:"#1871FF",
title: [
{
text: data.name,
top: 10,
left: 10,
textStyle: {
fontSize: 14,
fontWeight: "bolder",
width: 100
}
}
],
tooltip: {
trigger: "axis",
axisPointer: {
type: data.pointerType
}
},
grid: {
top: 40,
right: 10,
bottom: 70,
left: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: data.xData
},
yAxis: {
splitLine: {
lineStyle: {
type: "dashed",
color: "#E8E8E8"
}
},
type: 'value'
},
series: [{
barWidth: 20,
data: data.yData,
type: data.type
}]
};
let optionTemp = myChart; //临时存储Chart的属性
myChart.clear();
myChart = optionTemp;
myChart.setOption(option);
},
clickdemo4(event){
// console.log(this.clickPie,"this.clickPiethis.clickPie");
console.log(event,"id demo4 div 点击数据");
let menu = document.getElementById("popmenu");
if(this.clickPie){
// console.log(this.clickPie,"if");
// console.log("pie");
//点击在饼图区域里
let e = event ? event : window.event;
// let t = e.target || e.srcElement;
// menu.style.left = getPointerX(e) + "px";
// menu.style.top = getPointerY(e) + "px";
menu.style.left = e.clientX - 400 + "px";
menu.style.top = e.layerY + 40 + "px";
menu.style.display = "block";
}else{
menu.style.display = "none";
}
this.clickPie = false;
}
}
};
</script>
<style lang="scss" scoped>
.demo4 {
display: inline-block;
margin: 20px;
width: 400px;
height: 400px;
border: 1px solid pink;
}
.popmenu {
width: 400px;
height: 200px;
background-color: rgba(255,255,255,0.7);
/*border: 1px solid red;*/
display: none;
position: absolute;
}
</style>
完结撒花