需求:当鼠标移上线图时,饼图的数据是鼠标移上线图的当前显示数据。

思路:按常理是用echarts的自带事件,但是查了API还是没找到合适的事件。然后想到的是Echarts中的tooltip.formatter就是鼠标事件显示的信息弾层,函数详情:www.echartsjs.com/option.html… 通过此函数的params参数能获取到当前显示的数据。拿到这些数据就得想办法怎么让饼图使用,从而实现所谓的数据联动。

  • 第一步获取数据
  • HTML部分
  1. 这里把饼图独立出去了
<div class="wrap">
    <el-row :gutter="20" style="margin: 20px 0 0;">
      <el-col :span="16">
        <div class="echart-row echart-line">
          <div id="chratLine"></div>
      </el-col>
      <el-col :span="8">
        <div class="echart-row1 echart-pie">
          <echart-pie v-if="pieData" :id="pieID" :pieData="pieData"></echart-pie>
        </div>
      </el-col>
    </el-row>
</div>

复制代码
  • js部分
data() {
    return {
        pieData: {},  //饼图配置数据
        lineOption: {   //线图配置数据 
            title : {
                text: '线图'
            },
            tooltip: {
                formatter: (params, ticket, callback) => {
                    let val = [];
                    val.push(`${params[0].axisValueLabel}<br/>`);
                    this.pieData.l = [];  //初始化
                    this.pieData.s = [];       //初始化
                    params.forEach(item => {
                        this.pieData.l.push(item.seriesName);     //赋值
                        this.pieData.s.push({value: item.value, name: item.seriesName});   //赋值
                        val.push(`${item.seriesName} ${item.value}<br/>`);  //toolTip显示的值
                    });
                    return val.join(' ');
                }
            }
        }
    }
}

复制代码

动态的把数据赋值过去了,你会发现一个问题,就是formatter函数调用多次的问题。是因为echarts鼠标事件触发函数的调用。

  • 数据拿到了,该去用这些数据了,注意: 注释部分是解决formatter函数调用多次的问题。

<script>
const colors = ['#37a2da', '#d87a80', '#9fe6b8', '#ffdb5c', '#e7bcf3', '#ff9f7f'];
export default {
  name: 'ChartsPie',
  props: {
    id: {
      type: String
    },
    pieData: {
      type: Object,
      default: {}
    }
  },
  data () {
    return {
      oldVal: [],
      initFlag: false,
      isEmpty: false,
      option: {
        color: colors,
        title : {
          text: '饼图'
        },
        tooltip : {
          trigger: 'item',
          formatter: "{b} : {c} ({d}%)"
        },
        legend: {
          x : 'center',
          y : 'bottom',
          data:[]
        },
        series : [
          {
            name:'',
            type:'pie',
            radius : [20, '60%'],
            center : ['50%', '50%'],
            roseType : 'area'
            label: {
              normal: {
                formatter: '{b} \n {d}%'
              }
            },
            data:[]
          }
        ]
      }
    }
  },
  created () {
    this.initData();
  },
  watch: {
    pieData: {
      handler (to, from) {  //深监听数据是否有改变
        if (this.isObjectValueEqual(to.y, this.oldVal)) return; //如果数据数据同上次的一样则不做初始化
        this.oldVal = to.y;
        this.initData();
        this.initChart(this.id);
      },
      deep: true
    }
  },
  methods: {
    initData () {
      this.option.legend.data = this.pieData.l;
      this.option.series[0].data = this.pieData.s;
    },
    initChart (id) {
      if (this.initFlag) return;    //节流如果在初始化则退出
      this.initFlag = true;
      let chartDom = document.getElementById(id);
      if (chartDom) {
        let myChart = this.$echarts.init(chartDom);
        this.chartShowLoading(myChart);
        setTimeout(() => {
          this.initFlag = false;
          this.setChartOption(this.id);
        }, 500);
      };
    },
    setChartOption (id) { 
      let myChart = this.$echarts.init(document.getElementById(id));
      myChart.hideLoading();
      myChart.clear();
      myChart.setOption(this.option);
    },
    chartShowLoading (obj) {
      obj.showLoading({
        text : '加载数据中...',
        textStyle : {
          fontSize : 14
        },
        maskColor: '#fff'
      });
    },
    isObjectValueEqual (a, b) { //判断两数组数据是否一样
      if (a.length != b.length){
        return false;
      }
      for (let i = 0; i < a.length; i++) {
        if (a[i].value != b[i].value) {
          return false;
        }
      }
      return true;
    }
  },
  mounted() {
    this.initChart(this.id);
  }
}
</script>

复制代码

结束语:核心是利用Echarts的tooltip.formatter获取鼠标事件上的数据,然后通过Vue的监听事件watch来监听传过来的值是否有变化,从而来初始化饼图。
注意的问题是:tooltip.formatter触发次数,从而得初始化饼图时得做下处理。

  1. 判断数据是否没有改变 ? 有就做初始化 : 没有则退出
  2. 做一个500毫秒的时间差来解决多次触发初始化饼图动作。
Logo

前往低代码交流专区

更多推荐