【echarts】vue2中根据后端返回的数据动态生成echarts图表,处理数据,合并同类数据

前言:
我们需要根据后端返回的数据来制作表格,但是往往并不是一组数据对应一个图,很可能需要将某个参数相同的两组或多组数据处理到一个图中,这里就需要处理数据并动态渲染图表。

例如:
在这里插入图片描述
后端返回数组包含四组数据,按理来说应该渲染四个图,但是业务要求将unit和type相同的图合为一张图,转成多个图例,我们就需要渲染三张图。
后端返回的数据格式:
在这里插入图片描述

data里面定义:

	  echartsData: [], //请求获取的数据
      editableTabs: [], //处理的图表不同的数据
      editableTabs1: [], //合并后的数据
      options: [],  //echarts的option合集

html中根据图表的数量动态渲染echarts图

         <div class="echarts">
            <a-empty v-if="editableTabs.length === 0" />
            <div id="wh" v-for="item in editableTabs1" :key="item.id">
              <div :style="{width: '88%', height: '360px', margin: '10px'}" :id="item.id" :ref="item.id">
                {{ item.title }}
              </div>
            </div>
          </div>

请求图表数据

getEchartsData() {
      // 请求获得图表数据
      this.$api
        .get('/pointInspectionDetail/statDetail', {
          params: {
            deviceCode: this.deviceCode,
            startTime: this.startDate + this.hourStart,
            endTime: this.endDate + this.hourEnd
          }
        })
        .then(res => {
          this.echartsData = res.data.data;
        })
        .then(val => this.drawLine()); 
    },

处理图表数据

drawLine() {
      // 遍历整理信息
      this.editableTabs = [];
      this.echartsData.forEach((item, key) => {
        let obj = {
          title: this.getName(this.pointMetrologyList, item.type), //图表名字
          id: 'chart' + key, //图表id
          chart: null, //用来存储图表实例
          name: [item.name], //图例
          unit: item.unit, //图表单位
          type: item.type, //图表类型
          value: [item.value] //图表数据
        };
        this.editableTabs.push(obj);
      });
      // console.log(this.editableTabs, 'editableTabs');
      // type与unit相同的合并,原理同数组去重
      function fn1(tempArr) {
        for (let i = 0; i < tempArr.length; i++) {
          for (let j = i + 1; j < tempArr.length; j++) {
            if (tempArr[i].unit === tempArr[j].unit && tempArr[i].type === tempArr[j].type) {
              tempArr[i].name.push(tempArr[j].name[0]);
              tempArr[i].value.push(tempArr[j].value[0]);
              tempArr.splice(j, 1);
              j--;
            }
          }
        }
        return tempArr;
      }
      // console.log(fn1(this.editableTabs), 'chuli');
      this.editableTabs1 = fn1(this.editableTabs);
      this.chartInit();
      this.createLineChart(this.editableTabs1);
    },

分配初始化表格

chartInit() {
      this.$nextTick(() => {
        for (let it in this.editableTabs1) {
          this.editableTabs1[it].chart = this.$echarts.init(document.getElementById(this.editableTabs1[it].id));
        }
      });
    },

创建图表数据 数据处理完成之后,将携带数据的data传递给渲染图表的方法

createLineChart(data) {
      this.options = [];
      // 封装处理value数组横轴按时间排序并对应纵轴数据
      let dealWith = eachValue => {
        let dataDe = []; //键值对一条数据,echarts多条数据的话可以用键值对的方式,他会自动对应x轴的。
        let dataSort = [];
        for (const key in eachValue) {
          dataSort.push({
            time: key,
            number: eachValue[key]
          });
        }
        dataSort.sort(function (prev, next) {
          //处理日期排序
          let date1 = new Date(prev.time);
          let date2 = new Date(next.time);
          return date1 - date2;
        });
        dataSort.forEach(item => {
          dataDe.push([item.time, item.number]);
        });
        return {
          dataDe
        };
      };
      data.forEach(item => {
        let dataSeries = [];
        item.value.forEach(item1 => {
          dataSeries.push(dealWith(item1));
        });
        // console.log(dataSeries,'dataSeries');
        // legend
        let legend = [];
        item.name.forEach(item1 => {
          legend.push(item1);
        });
        // x轴,取数据中最长的作为X轴
        let xAxis = [];
        function findLongestArray(obj) {
          let longestArray = [];
          for (let key in obj) {
            if (Array.isArray(obj[key].dataDe)) {
              if (obj[key].dataDe.length > longestArray.length) {
                longestArray = obj[key].dataDe;
              }
            }
          }
          return longestArray;
        }
        let tempAxis = findLongestArray(dataSeries);
        tempAxis.forEach(item1 => {
          xAxis.push(item1[0]);
        });
        // series
        let series = [];
        item.name.forEach((item1, key) => {
          let obj = {
            name: item1,
            type: 'line',
            data: dataSeries[key].dataDe
          };
          series.push(obj);
        });
        //设置option
        let option = {
          title: {
            text: item.title
          },
          tooltip: {
            trigger: 'axis'
          },
          legend: {
            data: legend,
            top: '36',
            left: '220'
          },
          grid: {
            left: '5%',
            right: '4%',
            bottom: '3%',
            top: '20%',
            containLabel: true
          },
          xAxis: {
            type: 'category',
            axisLabel: {
              rotate: 60
            },
            data: xAxis
          },
          yAxis: {
            type: 'value',
            name: '单位 : ' + item.unit,
            nameTextStyle: {
              fontSize: 14
            },
            axisLine: {
              show: true
            }
          },
          series: series
        };
        this.options.push(option);
      });
      this.$nextTick(() => {
        this.editableTabs1.forEach((item, key) => {
          //对对应标签的echarts实例执行setOption()
          item.chart.setOption(this.options[key], true);
        });
      });
    }

这样就可以了。

效果如图:
在这里插入图片描述
比较笨的方法,欢迎大家提建议。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,针对你的问题,我们可以通过使用Vue.js的v-for指令来循环渲染生成不同的按钮。 首先,你需要在后端返回一个包含不同按钮数据的数组,例如: ```javascript buttons: [ { label: '按钮1', value: 'value1', action: 'handleClick1' }, { label: '按钮2', value: 'value2', action: 'handleClick2' }, { label: '按钮3', value: 'value3', action: 'handleClick3' } ] ``` 然后,在Vue组件,你可以这样使用v-for指令来循环渲染这些按钮: ```html <template> <div> <button v-for="button in buttons" :key="button.value" @click="handleClick(button)">{{ button.label }}</button> </div> </template> ``` 在这里,我们使用v-for指令循环渲染按钮,并且使用:key指令来指定每个按钮的唯一标识符,这里我们使用按钮的value属性作为唯一标识符。 同时,我们使用@click指令来绑定按钮的点击事件,并且将整个按钮对象作为参数传入handleClick方法。 最后,在Vue组件,你可以定义handleClick方法来处理不同按钮的点击事件: ```javascript <script> export default { data() { return { buttons: [] }; }, created() { // 在组件创建时,调用后端接口获取按钮数据 this.fetchButtons(); }, methods: { fetchButtons() { // 调用后端接口获取按钮数据 // 在获取到数据后,将数据赋值给组件的buttons属性 this.buttons = response.data.buttons; }, handleClick(button) { switch(button.action) { case 'handleClick1': this.handleClick1(button.value); break; case 'handleClick2': this.handleClick2(button.value); break; case 'handleClick3': this.handleClick3(button.value); break; default: break; } }, handleClick1(value) { // 处理按钮1的点击事件 }, handleClick2(value) { // 处理按钮2的点击事件 }, handleClick3(value) { // 处理按钮3的点击事件 } } }; </script> ``` 在这里,我们定义了handleClick方法来根据按钮的action属性来判断需要调用哪个具体的处理方法来处理按钮的点击事件。 同时,我们也定义了三个具体的处理方法,分别处理不同按钮的点击事件,并且传入了每个按钮对应的value属性作为参数,以便处理方法能够根据不同按钮传入的值来进行不同的处理。 在组件创建时,我们调用后端接口获取按钮数据,并且将数据赋值给组件的buttons属性,然后通过v-for指令循环渲染按钮,实现根据后端返回数据动态生成不同的按钮。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值