vue中echarts 实现下钻(饼图为例)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

1.echarts图是以子组件的形式引入

import comChart from "/components/com-chart.vue"; //引入子组件charts

2.注册子组件

  components: {
    comChart
  }

3.template中写入组件

//id 组件的唯一辨识,不能重复,因为是多图渲染,所以引用了变量
// data 即option
// @clickc 子组件调用父组件的方法(这里有坑)
 <com-chart  ref="charts" :id="'right'+index" @clickc="clickc" :data="loadCharts(item,fatherData)"></com-chart>

4.子组件comChart页面,实现图形下钻和图形后退返回
(坑) $emit子组件调用父组件的方法需满足两个条件

<template>
  <div ref="cc" :id="id" :data="data" class="comCharts"></div>
</template>

<script>
const elementResizeDetectorMaker = require("element-resize-detector");

export default {
  data() {
    return {
      chart: null,
      stack:[], //用来记录下钻的option数据
      top:false, //最上层
    };
  },
  watch: {
    data: {
      handler(newValue, oldValue) {
        this.drawChart(this.id, newValue);
      },
      deep: true,
      screenWidth: 0,
    },
  },
  props: ["id", "data", "drill"], //父组件的传值
  created() {},
  mounted() {
    this.drawChart(this.id, this.data);
    const that = this;
    const erd = elementResizeDetectorMaker();
    erd.listenTo(document.getElementById(this.id), function (element) {
      that.$nextTick(function () {
        that.chart.resize();
      });
    });
  },
  methods: {
    drawChart(id, data) {
      this.stack = [] //每次初始化清空栈option
      this.top = false 
      const _this = this;
      this.chart = this.$echarts.init(document.getElementById(id));
      this.chart.clear();
      this.chart.setOption(data); //第一次渲染图形
      this.stack.push(data) //push第一次的图形option
      this.chart.on("click", function (param) { //监听是否有点击下钻行为,param 点击行为的返回值
      //这里是因为多个图形渲染,有些图形不提供下钻功能即根据props中drill判断
        if (_this.drill !== undefined) { 
     //  $emit子组件调用父组件的方法需满足两个条件 1.this 需要重定义,否则无法指向vue 2.方法需要在组件中声明,不然可能会无法触发
          _this.$emit("clickc", param); 
        } else {
          return;
        }
      });
    },
    parentHandleclick(res) { //父组件调用的方法,其中res 是返回的新option数据
      let _this = this; //this需重新声明
      // 这里是option中如果需要有返回的功能的话,则在option需要添加属性 graphic
      res.graphic = [
        {
        //官网中使用的是 type = 'text' 这里使用的type: "image",
          type: "image",
          right: 50,
          top: 10,
          style: {
          //官网上是直接写url,可是怎么也加载不出图片,这里需要reqiure
            image: require('../assets/img/gis-back.png'), 
            height:18,
            width:18,
          },
          // 当返回键被点击时,需要给chart 重新setOption
          onclick: function () {
          // 栈中始终要保持最初的option
            if(_this.stack.length>1){
            // 当每次点击返回时,删除栈中的最后一个option
               _this.stack.pop();
            }else{
            //this.top 记录是否是最初的图形option
              this.top = true
              _this.$notify({
                 title: '警告',
                 message: '请勿重复点击',
                 type: 'warning'
             });
            }
            if(this.top){
              return
            }else{
            //_this.stack 的最后一个数据重新渲染图形
              _this.chart.setOption(_this.stack[_this.stack.length-1]);
            }
          },
        },
      ];
      //这里是点击下钻时图形的重新渲染
      this.chart.setOption(res);
      this.stack.push(res)
    },
  },
  beforeDestroy() {
    if (this.chart) {
      this.chart.clear();
    }
  },
};
</script>

<style scoped>
.comCharts {
  margin-top: 0px;
  height: 200px;
  width: 100%;
}
</style>

5.父组件的方法调用

 loadCharts() {
 // 返回首次的option
     let option3= {
        color: [
          "#6AC2E3",
          "#5A8DEF",
          "#6C5DEF",
          "#ECB718",
          "#57D0A1",
          "#5C6F8F",
        ],
        title: {
          left: "center",
        },
        tooltip: {
          trigger: "item",
        },
        legend: {
          orient: "horizontal",
          bottom: "15px",
          icon: "circle",
          textStyle: {
            color: "rgba(251, 249, 249, 1)",
          },
          type: "scroll",
          itemWidth: 7.5,
          itemHeight: 7.5,
        },
        series: [
          {
            name: "",
            type: "pie",
            radius: "50%",
            data: [ //自己的数据
            ],
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: "rgba(0, 0, 0, 0.5)",
              },
            },
            labelLine: {
              length: 15,
              length2: 5,
            },
            label: {
              show: true,
              formatter: "{d}%",
              color: "rgba(248, 244, 244, 1)",
            },
          },
        ],
      }
      return option3
    },
    //子组件触发的方法
      clickc(param){ //params 返回数据
      console.log('click',param)
      let dataE = {
        caList:[],
        gtList:[]
      }
      if(param.data.data[0] !== undefined && param.data.data[0].length > 0){
        dataE.caList = param.data.data[0]
      }if(param.data.data[1] !== undefined && param.data.data[1].length > 0){
        dataE.gtList = param.data.data[1]
      }
      // 这里是我自己的方法返回新的option
     let res =  this.loadCharts(param.data.tm,dataE)
    if(param.data.tm === "v0"){
    // 因为是多个图形,所以我是以数组的方式来判断的
    //调用对应图形的子组件方法 parentHandleclick(res) 传入参数res实现下钻
    //  this.$ refs[`'echarts'${变量名}`] 
      this.$refs.charts[0].parentHandleclick(res);
     } if(param.data.tm === "v1"){
      this.$refs.charts[1].parentHandleclick(res);
     } if(param.data.tm === "v2"){
      this.$refs.charts[2].parentHandleclick(res);
     }
    },
   

总结

坑:
1.子组件调用父组件的方法(满足两个条件)
2.多个图形渲染时refs需指示明确,可能是数组需判断,或者ref绑定变量,但是在获取组件本身时用变量的话 是这样的this.$ refs['echarts'${变量名}],可是我没成功
3.echarts中option的graphic属性在引入照片时需要调用require

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值