eacharts图表
遇到的问题
- 控制台报错:
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in nextTick: "TypeError: Cannot read property 'getAttribute' of undefined"
这个问题一般是由于图表挂载的
DOM
节点没有被渲染,可能是由于该节点使用了v-if
进行判断是否进行渲 染,应该改为v-show
;具体原因参照v-if
与v-show
的区别。
- 点击左侧图表时,会触发事件,隐藏或者显示对应的饼图。
option.legend.selectedMode = true | false;
进行选择是否禁用点击事件
echarts
图表渲染的阶段因为要涉及到操作
DOM
节点,因此在vue
中渲染图形要么在mounted(){}
周期函数中,要么在created(){}
中配合$nextTick
进行使用
echarts
图表的异步渲染阶段建议做法:绘图的配置项写在一个方法里,所有动态数据设为变量,拿到异步数据后,进行调用该方法,并将数据传入该方法中
代码部分
如果想使用该代码,可更改falseData
函数里的数据
html
<template>
<div class="container">
<div class="content">
<div id="chart-pie" ref="chartPie" v-show="true"></div>
</div>
</div>
</template>
js
<script>
export default {
name: "eacharts",
data() {
return {
ensureTotal: {
traffic: "0.00",
housing: "0.00",
meals: "0.00",
clothes: "0.00",
},
};
},
methods: {
/**
* 画饼状图
* @param {object} echartsData 饼状图的数据
*/
drawing(echartsData) {
let chartDom = this.$refs.chartPie;
let myChart = this.$echarts.init(chartDom);
let option = {
tooltip: {
trigger: "item",
formatter: "{b} : {d} %",
},
legend: { //关于图标的设置
orient: "vertical",
x: 30,
top: 50,
itemGap: 10, //图标之间的间距
itemWidth: 8, //图标的大小
// itemHeight: 50,
icon: "circle", //图标的形状
formatter: "{name}",
textStyle: {
fontSize: 10,
color: "#7A8087",
},
selectedMode: false, //图标禁止点击事件,
data: [
{
name: echartsData.lName.traffic,
},
{
name: echartsData.lName.housing,
},
{
name: echartsData.lName.meals,
},
{
name: echartsData.lName.clothes,
},
],
},
calculable: true,
//图的配置项
series: [
{
type: "pie",
radius: "60%", //饼图的半径大小
center: ["60%", "45%"], //饼图的位置
label: {
//饼图图形上的文本标签
normal: {
show: true,
position: "inner", //标签的位置
textStyle: {
fontWeight: 300,
fontSize: 10, //文字的字体大小
},
formatter: "{d}%",
},
},
data: [
{
value: echartsData.value.traffic,
name: echartsData.lName.traffic,
itemStyle: {
normal: {
color: "#FF9393",
},
},
},
{
value: echartsData.value.housing,
name: echartsData.lName.housing,
itemStyle: {
normal: {
color: "#FFD485",
},
},
},
{
value: echartsData.value.meals,
name: echartsData.lName.meals,
itemStyle: {
normal: {
color: "#FFB585",
},
},
},
{
value: echartsData.value.clothes,
name: echartsData.lName.clothes,
itemStyle: {
normal: {
color: "#9FC9FF",
},
},
},
],
},
],
};
option && myChart.setOption(option);
},
/**
* 模拟异步请求数据,获取饼状图的数据
* @returns {object} promise 返回一个promise对象
*/
falseData() {
let promise = new Promise((res, rej) => {
setTimeout(() => {
let ensureTotal = {
traffic: 10,
housing: 33,
meals: 45,
clothes: 0,
};
res(ensureTotal);
}, 2000);
});
return promise;
},
},
created() {
this.falseData().then((res) => {
if (res) {
this.ensureTotal.traffic = res.traffic;
this.ensureTotal.housing = res.housing;
this.ensureTotal.meals = res.meals;
this.ensureTotal.clothes = res.clothes;
}
this.$nextTick(() => {
// 传给echarts的数据
let echartsData = {
value: {
traffic: this.ensureTotal.traffic,
housing: this.ensureTotal.housing,
meals: this.ensureTotal.meals,
clothes: this.ensureTotal.clothes,
},
lName: {
traffic: "交通",
housing: "住房",
meals: "吃饭",
clothes: "衣服",
},
};
// 根据数据进行判断饼状图以及图例是否显示
for (let key in echartsData.value) {
if (echartsData.value[key] == 0) {
echartsData.value[key] = "";
echartsData.lName[key] = false;
}
}
this.drawing(echartsData);
});
});
},
};
</script>
css
<style lang="scss" scoped>
.container {
width: 100vw;
height: 100vh;
flex-direction: column;
> content {
flex: 1;
}
}
#chart-pie {
height: 300px;
}
</style>
},
};
### css
```css
<style lang="scss" scoped>
.container {
width: 100vw;
height: 100vh;
flex-direction: column;
> content {
flex: 1;
}
}
#chart-pie {
height: 300px;
}
</style>