echart图表动态获取数据,异步渲染数据,并在el-tabs标签页展示,解决标签页切换之后echart收缩问题

1628947235734

思路:
两个图
标签页分别为饼图和柱状图,默认显示第二个标签页。两个标签页的数据尽量不要同时获取,否则加载太慢。

第二个标签页在进入页面时,在mounted里调用方法sortGet,获取柱状图的数据,
第一个标签页在el-tabs点击时,执行的 @tab-click=“handleClick” 方法中获取数据。

解决标签页切换之后echart收缩问题

宽高设成固定的形式

<div id="bar" style="width: 1274px; height: 600px"></div>

完整代码如下:

<template>
  <div class="app-container">
    <el-col :span="24">
      <el-tabs v-model="activeName" @tab-click="handleClick">
        <el-tab-pane label="成绩分数段统计" name="first">
          <div class="gradeCensus title">成绩分数段统计</div>
          <div
            id="chart"
            class="myChart"
            style="width: 1274px; height: 600px"
          ></div>
        </el-tab-pane>
        <el-tab-pane label="成绩分类统计" name="second">
          <div class="gradeCensus title">成绩分类统计</div>
          <div id="bar" style="width: 1274px; height: 600px"></div>
        </el-tab-pane>
      </el-tabs>
    </el-col>
  </div>
</template>
<script>
import * as echarts from "echarts";
import crudStats from "@/api/safeEducation/stats";

let getBar;
let getChart;
export default {
  name: "Stats",
  data() {
    return {
      activeName: "second",
      id: null,
      sortData: [],
      sortTrue: [],
      sortFalse: [],
      sortName: [],
      lineData: [],
    };
  },
  created() {
    if (this.$route.query) {
    	//获得接口id
      this.id = this.$route.query.examID;
    }
  },
  mounted() {	
  	//柱图方法,调用接口
  	this.sortGet(this.id);	
    this.initEcharts();    //初始化echart实例方法
  },
  watch: {
    //观察option的变化
    option: {
      handler(newVal, oldVal) {
        if (this.getBar) {
          if (newVal) {
            this.getBar.setOption(newVal);
            this.getChart.setOption(newVal);
          } else {
            this.getBar.setOption(oldVal);
            this.getChart.setOption(oldVal);
          }
        } else {
          this.initEcharts();
        }
      },
      deep: true, //对象内部属性的监听,关键。
    },
  },
  methods: {
  
  //此方法为标签页点击事件,饼图请求接口,得到数据
  
    async handleClick(tab, event) {
      if (tab.index == 0) {      	//第一个标签页,所以tab.index == 0
        getChart.showLoading();  	//getChart为饼图的初始化实例,
        await crudStats.getGrade(this.id).then((response) => {  //调用接口
          if (response.data != null) {
            getChart.hideLoading();

				//饼图的配置数据
				
            getChart.setOption( 
              {
                title: {
                  text: "成绩分布图",
                  left: "center",
                },
                legend: {             //设置颜色标签
                  orient: "vertical", //垂直显示颜色标签
                  x: "left", //居右显示
                  padding: 20,
                },
                tooltip: {             //自定义提示框
                	show: true,
                	trigger: "item",
                },    		
                series: [
                  {
                    name: "题目数量",
                    data: [    			//response.data接口获得的数据
                      { value: response.data.fail, name: "不及格" },
                      { value: response.data.middle, name: "中等" },
                      { value: response.data.well, name: "良好" },
                      { value: response.data.excellent, name: "优秀" },
                      { value: response.data.full, name: "满分" },
                    ],
                    type: "pie",
                    radius: "55%",
                  },
                ],
              },
              true
            );
          }
        }); 
      }
    },
    
    //此方法为柱图请求接口方法,
    
    async sortGet(id) {
      await crudStats.getSort(id).then((response) => {  //调用接口
      
        this.sortTrue.length = 0;          //每次调用接口,使数据清0,不然会多一个图,正确数 (柱图)
        this.sortFalse.length = 0;		   //错误数 (柱图)
        this.sortName.length = 0;		   //横坐标名字
        this.lineData.length = 0;			//正确率 (折线)
        
        for (let i = 0; i < response.data.length; i++) {
          this.lineData.push(           				//获得折线数据
            response.data[i].correct /
              (response.data[i].correct + response.data[i].mistake) * 100
          );											
          this.sortTrue.push(response.data[i].correct);  //获得正确数 (柱图)
          this.sortFalse.push(response.data[i].mistake); //获得错误数 (柱图)
          this.sortName.push(response.data[i].safeTypeName);//获得横坐标名字

		  //柱状图的配置数据

       	  getBar.setOption(
          {
            legend: {},
            tooltip: {},
            xAxis: {
              type: "category",
              data: this.sortName,  //x坐标轴的名字
            },
            yAxis: [
              {
                type: "value",
                name: "题目数量",   //y坐标轴的左侧名字
                splitLine: {
                  //显示分割线
                  show: false,
                },
              },
              {
                type: "value",
                name: "正确率",
                axisLabel: {
                  formatter: "{value}%", //y坐标轴的右侧名字
                },
                splitLine: {
                  //网格线
                  show: false,
                },
              },
            ],
            series: [
              {
                type: "bar",             //柱形图(可添加多个)
                name: "正确数",
                color: "#14ab46",
                barWidth: "80",
                data: this.sortTrue,
              },
              {
                type: "bar",
                name: "错误数",
                color: "#e62d2d",
                barWidth: "80",
                data: this.sortFalse, 
              },
              {
                color: "#ff6e0d",
                name: "正确率", 
                type: "line", 
                yAxisIndex: 1,
                data: this.lineData,
              },
            ],
          },
          true
        );
        }
      });
    },
    
    //此方法为初始化echart实例
    
    initEcharts() {
    	//getbar:柱图,getChart:饼图
      getBar = echarts.init(document.getElementById("bar"));
      getChart = echarts.init(document.getElementById("chart"));
    },
  },
};
</script>
<style scoped>
.myChart {
  width: 100%;
  height: 600px;
}
.head {
  padding-bottom: 20px;
  font-size: 20px;
}
ul {
  list-style: none;
  margin: 0;
  padding: 20px 0;
  width: 100%;
  height: 60px;
  font-size: 14px;
  float: left;
}
li {
  padding: 0 20px;
  display: inline-block;
}
.el-tabs__content {
  text-align: center;
}
.analysis {
  width: 100%;
  padding: 40px;
  height: 100px;
}
.analysis-title {
  font-weight: bold;
  padding-bottom: 9px;
}
.title {
  text-align: center;
}
.gradeCensus {
  width: 100%;
  padding: 20px 0;
}
.gradeChart {
  font-weight: bold;
  font-size: 19px;
  padding-top: 10px;
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-form-item--small .el-form-item__label {
  font-weight: normal;
  color: black;
}
::v-deep .el-form--inline .el-form-item {
  margin: 0 20px 0 0;
}
</style>

你可能感兴趣的:(笔记,echarts)