Browse Source

更新 ExamDashboard.vue 中的 echart 图表, 注意 echart 的渲染问题

reghao 1 year ago
parent
commit
198765d8e2
1 changed files with 182 additions and 79 deletions
  1. 182 79
      src/views/exam/ExamDashboard.vue

+ 182 - 79
src/views/exam/ExamDashboard.vue

@@ -1,16 +1,26 @@
 <template>
   <el-container>
-
     <el-row>
-      <div id="img1" style="width: 800px;height:400px;" />
-      <div id="img2" style="width: 800px;height:400px;" />
+      <el-row class="card-style">
+        <el-card>
+          <div slot="header" class="clearfix">
+            <span>选择图表</span>
+            <el-select v-model="selectedValue" placeholder="选择图表" @change="onSelectChange">
+              <el-option label="考试通过率" value="1" />
+              <el-option label="考试次数占比" value="2" />
+              <el-option label="考试通过率折线图" value="3" />
+              <el-option label="新用户激活数" value="4" />
+            </el-select>
+          </div>
+          <div id="chart1" style="width: 800px;height:400px;" />
+        </el-card>
+      </el-row>
+      <el-row class="card-style">
+        <el-card>
+          <div id="chart2" style="width: 800px;height:400px;" />
+        </el-card>
+      </el-row>
     </el-row>
-
-    <el-row>
-      <div id="img3" style="width: 800px;height:400px;" />
-      <div id="img4" style="width: 800px;height:400px;" />
-    </el-row>
-
   </el-container>
 </template>
 
@@ -26,7 +36,9 @@ export default {
       // 考试通过率
       passRate: [],
       // 饼图的数据
-      pieData: []
+      pieData: [],
+      selectedValue: '1',
+      chartOption: null
     }
   },
   created() {
@@ -41,24 +53,36 @@ export default {
     this.getExamNumbers()
   },
   methods: {
+    onSelectChange() {
+      this.getExamPassRate()
+    },
     async getExamPassRate() {
       await getExamPassRate().then((resp) => {
         if (resp.code === 0) {
           this.examNames = resp.data[0].split(',')
           this.passRate = resp.data[1].split(',')
-          this.drawLine()
-          this.drawBrokenLine()
-          this.drawImg4()
+
+          const intValue = parseInt(this.selectedValue)
+          if (intValue === 1) {
+            this.drawLine()
+          } else if (intValue === 2) {
+            this.drawBrokenLine()
+          } else if (intValue === 3) {
+            this.drawImg4()
+          } else {
+            this.drawChart5()
+          }
+
+          const myChart = this.$echarts.init(document.getElementById('chart1'))
+          // setOption 是 merge,而非赋值, setOption 支持 notMerge 参数, 值为 true 时重新渲染
+          myChart.setOption(this.chartOption, true)
           this.loading.close()
         }
       })
     },
     // 考试通过率柱状图
     drawLine() {
-      // 基于准备好的dom,初始化echarts实例
-      const myChart = this.$echarts.init(document.getElementById('img1'))
-      // 绘制图表
-      myChart.setOption({
+      this.chartOption = {
         title: {
           text: '考试通过率',
           subtext: 'dashbord1',
@@ -76,64 +100,11 @@ export default {
           type: 'bar',
           data: this.passRate
         }]
-      })
-    },
-    // 获取考试次数数据
-    async getExamNumbers() {
-      await getExamCount().then((resp) => {
-        const examNames = resp.data[0].split(',')
-        const examNumbers = resp.data[1].split(',')
-        examNames.forEach((item, index) => {
-          this.pieData.push({
-            name: item,
-            value: parseInt(examNumbers[index])
-          })
-        })
-        this.drawPie()
-      })
-    },
-    // 考试次数饼图
-    drawPie() {
-      // 基于准备好的dom,初始化echarts实例
-      const myChart = this.$echarts.init(document.getElementById('img2'))
-      myChart.setOption({
-        title: {
-          text: '考试次数占比',
-          subtext: 'dashbord2',
-          x: 'center'
-        },
-        tooltip: {
-          trigger: 'item',
-          formatter: '{a} <br/>{b} : {c}次 ({d}%)'
-        },
-        legend: {
-          orient: 'vertical',
-          left: 'left',
-          data: this.pieData
-        },
-        series: [
-          {
-            name: '考试次数',
-            type: 'pie',
-            radius: '55%',
-            data: this.pieData,
-            roseType: 'angle',
-            itemStyle: {
-              normal: {
-                shadowBlur: 200,
-                shadowColor: 'rgba(0, 0, 0, 0.5)'
-              }
-            }
-          }
-        ]
-      })
+      }
     },
     // 通过率的折线图
     drawBrokenLine() {
-      // 初始化ehcharts实例
-      const myChart = this.$echarts.init(document.getElementById('img3'))
-      // 指定图表的配置项和数据
-      var option = {
+      this.chartOption = {
         // 标题
         title: {
           text: '考试通过率折线图',
@@ -155,12 +126,9 @@ export default {
           data: this.passRate
         }]
       }
-      // 使用刚刚指定的配置项和数据项显示图表
-      myChart.setOption(option)
     },
     drawImg4() {
-      const myChart = this.$echarts.init(document.getElementById('img4'))
-      myChart.setOption({
+      this.chartOption = {
         color: ['#cd5c5c'],
         textStyle: {
           color: 'black'
@@ -172,7 +140,6 @@ export default {
           },
           formatter: '{a} <br/>{b} : {c}'
         },
-
         grid: {
           containLabel: true
         },
@@ -208,19 +175,148 @@ export default {
           type: 'bar',
           data: this.passRate
         }]
+      }
+    },
+    drawChart5() {
+      this.chartOption = {
+        title: {
+          text: '卡拉云新用户激活数据',
+          subtext: 'Demo 虚构数据',
+          x: 'center'
+        },
+        legend: { // 图例配置选项
+          orient: 'horizontal', // 图例布局方式:水平 'horizontal' 、垂直 'vertical'
+          x: 'left', // 横向放置位置,选项:'center'、'left'、'right'、'number'(横向值 px)
+          y: 'top', // 纵向放置位置,选项:'top'、'bottom'、'center'、'number'(纵向值 px)
+          data: ['猜想', '预期', '实际']
+        },
+        grid: { // 图表距离边框的距离,可用百分比和数字(px)配置
+          top: '20%',
+          left: '3%',
+          right: '10%',
+          bottom: '5%',
+          containLabel: true
+        },
+        xAxis: {
+          name: '月份',
+          type: 'category',
+          data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
+        },
+        yAxis: {
+          name: '人次',
+          type: 'value',
+          min: 0, // 配置 Y 轴刻度最小值
+          max: 4000, // 配置 Y 轴刻度最大值
+          splitNumber: 7 // 配置 Y 轴数值间隔
+        },
+        series: [
+          {
+            name: '猜想',
+            data: [454, 226, 891, 978, 901, 581, 400, 543, 272, 955, 1294, 1581],
+            type: 'line',
+            symbolSize: function(value) { // 点的大小跟随数值增加而变大
+              return value / 150
+            },
+            symbol: 'circle',
+            itemStyle: {
+              normal: {
+                label: {
+                  show: true
+                },
+                lineStyle: {
+                  color: 'rgba(0,0,0,0)'// 折线颜色设置为0,即只显示点,不显示折线
+                }
+              }
+            }
+          },
+          {
+            name: '预期',
+            data: [2455, 2534, 2360, 2301, 2861, 2181, 1944, 2197, 1745, 1810, 2283, 2298],
+            type: 'line',
+            symbolSize: 8, // 设置折线上圆点大小
+            itemStyle: {
+              normal: {
+                label: {
+                  show: true // 在折线拐点上显示数据
+                },
+                lineStyle: {
+                  width: 3, // 设置虚线宽度
+                  type: 'dotted' // 虚线'dotted' 实线'solid'
+                }
+              }
+            }
+          },
+          {
+            name: '实际',
+            data: [1107, 1352, 1740, 1968, 1647, 1570, 1343, 1757, 2547, 2762, 3170, 3665],
+            type: 'line',
+            symbol: 'circle', // 实心圆点
+            smooth: 0.5 // 设置折线弧度
+          }
+        ],
+        color: ['#3366CC', '#FFCC99', '#99CC33'] // 三个折线的颜色
+      }
+    },
+    // 获取考试次数数据
+    async getExamNumbers() {
+      await getExamCount().then((resp) => {
+        const examNames = resp.data[0].split(',')
+        const examNumbers = resp.data[1].split(',')
+        examNames.forEach((item, index) => {
+          this.pieData.push({
+            name: item,
+            value: parseInt(examNumbers[index])
+          })
+        })
+        this.drawPie()
       })
+    },
+    // 考试次数饼图
+    drawPie() {
+      // 基于准备好的dom,初始化echarts实例
+      const myChart = this.$echarts.init(document.getElementById('chart2'))
+      const option = {
+        title: {
+          text: '考试次数占比',
+          subtext: 'dashbord2',
+          x: 'center'
+        },
+        tooltip: {
+          trigger: 'item',
+          formatter: '{a} <br/>{b} : {c}次 ({d}%)'
+        },
+        legend: {
+          orient: 'vertical',
+          left: 'left',
+          data: this.pieData
+        },
+        series: [
+          {
+            name: '考试次数',
+            type: 'pie',
+            radius: '55%',
+            data: this.pieData,
+            roseType: 'angle',
+            itemStyle: {
+              normal: {
+                shadowBlur: 200,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      }
+      myChart.setOption(option)
     }
   }
 }
 </script>
 
 <style scoped lang="scss">
-
 .el-container {
   width: 100%;
   height: 100%;
 }
-
 .el-container {
   animation: leftMoveIn .7s ease-in;
 }
@@ -235,4 +331,11 @@ export default {
     opacity: 1;
   }
 }
+
+.card-style {
+  padding-top: 3px;
+  padding-bottom: 3px;
+  padding-left: 3px;
+  padding-right: 3px;
+}
 </style>