Bladeren bron

将 chart 相关的页面和代码全部放到 views/chart 模块

reghao 7 maanden geleden
bovenliggende
commit
30933f1ecf

+ 7 - 0
src/router/chart.js

@@ -1,6 +1,7 @@
 const ChartIndex = () => import('views/chart/ChartIndex')
 const HeatMap = () => import('views/chart/HeatMap')
 const LineChart = () => import('views/chart/LineChart')
+const PieChart = () => import('views/chart/PieChart')
 const Timeline = () => import('views/chart/Timeline')
 
 export default {
@@ -27,6 +28,12 @@ export default {
       component: LineChart,
       meta: { needAuth: false }
     },
+    {
+      path: '/chart/pie',
+      name: '饼图',
+      component: PieChart,
+      meta: { needAuth: false }
+    },
     {
       path: '/chart/timeline',
       name: 'Timeline',

+ 4 - 0
src/views/chart/ChartIndex.vue

@@ -25,6 +25,10 @@
             <i class="el-icon-map-location" />
             <span slot="title">折线图</span>
           </el-menu-item>
+          <el-menu-item index="/chart/pie">
+            <i class="el-icon-map-location" />
+            <span slot="title">饼图</span>
+          </el-menu-item>
           <el-menu-item index="/chart/timeline">
             <i class="el-icon-map-location" />
             <span slot="title">Timeline</span>

+ 444 - 2
src/views/chart/LineChart.vue

@@ -29,27 +29,78 @@
     <el-row class="movie-list">
       <el-card>
         <div slot="header" class="clearfix">
-          <span>饼图</span>
+          <span style="margin-right: 5px">选择图表</span>
+          <el-select
+            v-model="selectedValue"
+            clearable
+            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="chart4" style="width: 800px;height:400px;" />
+        <div id="chart4" style="height:400px;" />
       </el-card>
     </el-row>
+    <el-row class="movie-list">
+      <el-col :md="12" class="movie-list">
+        <el-card>
+          <div id="chart5" style="height:400px;" />
+        </el-card>
+      </el-col>
+      <el-col :md="12" class="movie-list">
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col class="movie-list" :md="12">
+        <el-card>
+          <div id="chart7" style="width: 600px;height:400px;" />
+        </el-card>
+      </el-col>
+      <el-col class="movie-list" :md="12">
+        <el-card>
+          <div id="chart8" style="width: 600px;height:400px;" />
+        </el-card>
+      </el-col>
+    </el-row>
   </el-row>
 </template>
 
 <script>
 import * as echarts from 'echarts'
+import { getExamCount, getExamPassRate, getLineChartData } from '@/api/exam'
+import { getUserWatch, getUserWatchRegion } from '@/api/analysis'
 
 export default {
   name: 'LineChart',
   data() {
     return {
+      // 考试名称
+      examNames: [],
+      // 考试通过率
+      passRate: [],
+      // 饼图的数据
+      pieData: [],
+      selectedValue: '1',
+      chartOption: null,
+      barChartNames: [],
+      barChartData: [],
+      pieChartNames: [],
+      pieChartData: [],
+      chartOption1: null
     }
   },
   mounted() {
     this.initChart1()
     this.initChart2()
     this.initChart3()
+    this.getExamPassRate()
+    this.getExamNumbers()
+    this.getUserWatchWrapper()
+    this.getUserWatchRegionWrapper()
   },
   created() {
     document.title = 'LineChart'
@@ -309,6 +360,397 @@ export default {
           myChart.resize()
         }
       })
+    },
+    handleChange(val) {
+      this.$message.info('select -> ' + val)
+    },
+    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(',')
+
+          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()
+            this.drawChart6()
+          }
+
+          const myChart = this.$echarts.init(document.getElementById('chart4'))
+          // setOption 是 merge,而非赋值, setOption 支持 notMerge 参数, 值为 true 时重新渲染
+          myChart.setOption(this.chartOption, true)
+          this.loading.close()
+        }
+      })
+    },
+    // 考试通过率柱状图
+    drawLine() {
+      this.chartOption = {
+        title: {
+          text: '考试通过率',
+          subtext: 'dashbord1',
+          x: 'center',
+          y: 'top',
+          textAlign: 'center'
+        },
+        tooltip: {},
+        xAxis: {
+          data: this.examNames
+        },
+        yAxis: {},
+        series: [{
+          name: '通过率',
+          type: 'bar',
+          data: this.passRate
+        }]
+      }
+    },
+    // 通过率的折线图
+    drawBrokenLine() {
+      this.chartOption = {
+        // 标题
+        title: {
+          text: '考试通过率折线图',
+          x: 'center'
+        },
+        // x轴
+        xAxis: {
+          data: this.examNames
+        },
+        // y轴没有显式设置,根据值自动生成y轴
+        yAxis: {},
+        // 数据-data是最终要显示的数据
+        series: [{
+          name: '通过率',
+          type: 'line',
+          areaStyle: {
+            normal: {}
+          },
+          data: this.passRate
+        }]
+      }
+    },
+    drawImg4() {
+      this.chartOption = {
+        color: ['#cd5c5c'],
+        textStyle: {
+          color: 'black'
+        },
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          formatter: '{a} <br/>{b} : {c}'
+        },
+        grid: {
+          containLabel: true
+        },
+        xAxis: {
+          type: 'value',
+          boundaryGap: [0, 0.01],
+          axisLine: {
+            lineStyle: {
+              color: '#fff'
+            }
+          },
+          'axisLabel': {
+            'interval': 0,
+            fontSize: 18,
+            formatter: '{value}'
+          }
+        },
+        yAxis: {
+          axisLine: {
+            lineStyle: {
+              color: '#fff'
+            }
+          },
+          'axisLabel': {
+            'interval': 0,
+            fontSize: 18
+          },
+          type: 'category',
+          data: this.examNames
+        },
+        series: [{
+          name: '通过率:',
+          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'] // 三个折线的颜色
+      }
+    },
+    drawChart6() {
+      getLineChartData().then(resp => {
+        if (resp.code === 0) {
+          const data = resp.data
+          this.chartOption = {
+            title: {
+              text: '卡拉云新用户激活数据',
+              subtext: 'Demo 虚构数据',
+              x: 'center'
+            },
+            tooltip: {},
+            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: data.xName,
+              type: 'category',
+              data: data.xLabel
+            },
+            yAxis: {
+              name: data.yName,
+              type: 'value',
+              min: data.yMin, // 配置 Y 轴刻度最小值
+              max: data.yMax, // 配置 Y 轴刻度最大值
+              splitNumber: data.ySplitNumber // 配置 Y 轴数值间隔
+            },
+            series: [
+              {
+                name: '实际',
+                data: data.xValue,
+                type: 'line',
+                symbol: 'circle', // 实心圆点
+                smooth: 0.5 // 设置折线弧度
+              }
+            ],
+            color: ['#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('chart5'))
+      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)
+    },
+    async getUserWatchWrapper() {
+      await getUserWatch().then((resp) => {
+        if (resp.code === 0) {
+          this.barChartNames = resp.data[0].split(',')
+          this.barChartData = resp.data[1].split(',')
+          this.drawBarChart()
+          const myChart = this.$echarts.init(document.getElementById('chart7'))
+          // setOption 是 merge,而非赋值, setOption 支持 notMerge 参数, 值为 true 时重新渲染
+          myChart.setOption(this.chartOption1, true)
+        }
+      })
+    },
+    drawBarChart() {
+      this.chartOption1 = {
+        title: {
+          text: '观看时长',
+          subtext: '最近一周',
+          x: 'center',
+          y: 'top',
+          textAlign: 'center'
+        },
+        tooltip: {},
+        xAxis: {
+          data: this.barChartNames
+        },
+        yAxis: {},
+        series: [{
+          name: '时长',
+          type: 'bar',
+          data: this.barChartData
+        }]
+      }
+    },
+    async getUserWatchRegionWrapper() {
+      await getUserWatchRegion().then((resp) => {
+        const pieNames = resp.data[0].split(',')
+        const pieNumbers = resp.data[1].split(',')
+        pieNames.forEach((item, index) => {
+          this.pieChartData.push({
+            name: item,
+            value: parseInt(pieNumbers[index])
+          })
+        })
+        this.drawPieChart()
+      })
+    },
+    drawPieChart() {
+      // 基于准备好的dom,初始化echarts实例
+      const myChart = this.$echarts.init(document.getElementById('chart8'))
+      const option = {
+        title: {
+          text: '分区占比',
+          subtext: '视频分区',
+          x: 'center'
+        },
+        tooltip: {
+          trigger: 'item',
+          formatter: '{a} <br/>{b} : {c}次 ({d}%)'
+        },
+        legend: {
+          orient: 'vertical',
+          left: 'left',
+          data: this.pieChartData
+        },
+        series: [
+          {
+            name: '时长',
+            type: 'pie',
+            radius: '55%',
+            data: this.pieChartData,
+            roseType: 'angle',
+            itemStyle: {
+              normal: {
+                shadowBlur: 200,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      }
+      myChart.setOption(option)
     }
   }
 }

+ 367 - 0
src/views/chart/PieChart.vue

@@ -0,0 +1,367 @@
+<template>
+  <el-row>
+    <el-row class="movie-list">
+      <el-col :md="12" class="movie-list">
+        <el-card>
+          <div slot="header" class="clearfix">
+            <span>饼图</span>
+          </div>
+          <div id="chart2" style="height:400px;" />
+        </el-card>
+      </el-col>
+      <el-col :md="12" class="movie-list">
+        <el-card>
+          <div slot="header" class="clearfix">
+            <span>金字塔图</span>
+          </div>
+          <div id="chart3" style="height:400px;" />
+        </el-card>
+      </el-col>
+    </el-row>
+    <el-row class="movie-list">
+      <el-col :md="12" class="movie-list">
+        <el-card>
+          <div id="chart5" style="height:400px;" />
+        </el-card>
+      </el-col>
+      <el-col class="movie-list" :md="12">
+        <el-card>
+          <div id="chart8" style="width: 600px;height:400px;" />
+        </el-card>
+      </el-col>
+    </el-row>
+  </el-row>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+import { getExamCount } from '@/api/exam'
+import { getUserWatchRegion } from '@/api/analysis'
+
+export default {
+  name: 'PieChart',
+  data() {
+    return {
+      // 考试名称
+      examNames: [],
+      // 考试通过率
+      passRate: [],
+      // 饼图的数据
+      pieData: [],
+      selectedValue: '1',
+      chartOption: null,
+      barChartNames: [],
+      barChartData: [],
+      pieChartNames: [],
+      pieChartData: []
+    }
+  },
+  mounted() {
+    this.initChart2()
+    this.initChart3()
+    this.getExamNumbers()
+    this.getUserWatchRegionWrapper()
+  },
+  created() {
+    document.title = 'LineChart'
+  },
+  methods: {
+    initChart2() {
+      var option = {
+        tooltip: {
+          trigger: 'item'
+        },
+        legend: {
+          top: '5%',
+          left: 'center'
+        },
+        series: [
+          {
+            name: 'Access From',
+            type: 'pie',
+            radius: ['40%', '70%'],
+            avoidLabelOverlap: false,
+            padAngle: 5,
+            itemStyle: {
+              borderRadius: 10
+            },
+            label: {
+              show: false,
+              position: 'center'
+            },
+            emphasis: {
+              label: {
+                show: true,
+                fontSize: 40,
+                fontWeight: 'bold'
+              }
+            },
+            labelLine: {
+              show: false
+            },
+            data: [
+              { value: 1048, name: 'Search Engine' },
+              { value: 735, name: 'Direct' },
+              { value: 580, name: 'Email' },
+              { value: 484, name: 'Union Ads' },
+              { value: 300, name: 'Video Ads' }
+            ]
+          }
+        ]
+      }
+
+      const myChart = this.$echarts.init(document.getElementById('chart2'))
+      myChart.setOption(option, true)
+      window.addEventListener('resize', () => {
+        if (myChart) {
+          myChart.resize()
+        }
+      })
+    },
+    initChart3() {
+      var maleData = [
+        14, 4, 10, 66,
+        54, 98, 116, 144,
+        210, 358, 484, 562,
+        706, 671, 566, 345,
+        200, 92, 24, 12,
+        0.0
+      ]
+
+      var femaleData = [
+        0, 0, 0, 15, 19,
+        29, 30, 25, 27, 34,
+        36, 48, 36, 56, 60,
+        48, 36, 12, 8, 0,
+        0.0
+      ]
+
+      var maleTotal = maleData.map(function(x) {
+        return Math.abs(x)
+      }).reduce(function(a, b) {
+        return a + b
+      })
+
+      var femaleTotal = femaleData.map(function(x) {
+        return Math.abs(x)
+      }).reduce(function(a, b) {
+        return a + b
+      })
+
+      var malePercentage = maleData.map(function(x) {
+        return -(x / maleTotal * 100)
+      })
+
+      var femalePercentage = femaleData.map(function(x) {
+        return x / femaleTotal * 100
+      })
+
+      const myChart = this.$echarts.init(document.getElementById('chart3'))
+      var option = {
+        title: {
+          text: '唐朝人口金字塔', // 设置标题文本为“唐朝人口金字塔”
+          left: 'center', // 标题水平居中
+          top: '4%', // 标题距离顶部的距离为4%
+          textStyle: {
+            color: '#333', // 标题字体颜色
+            fontSize: 24, // 标题字体大小
+            fontWeight: 'bold', // 标题字体加粗
+            fontFamily: 'KaiTi, serif' // 标题字体样式,楷体或Serif字体
+          }
+        },
+        tooltip: {
+          trigger: 'axis', // 提示框触发类型为坐标轴
+          axisPointer: {
+            type: 'shadow' // 坐标轴指示器类型为阴影
+          },
+          formatter: function(params) {
+            return params[0].name + '<br/>' +
+              params[0].seriesName + ': ' + Math.abs(maleData[params[0].dataIndex]) + ' (' + Math.abs(params[0].data).toFixed(2) + '%)' + '<br/>' +
+              params[1].seriesName + ': ' + Math.abs(femaleData[params[0].dataIndex]) + ' (' + Math.abs(params[1].data).toFixed(2) + '%)'
+            // 提示框内容格式化函数,params参数包含了鼠标悬停时的数据
+          }
+        },
+        legend: {
+          data: ['男性', '女性'], // 图例数据为“男性”和“女性”
+          align: 'left', // 图例左对齐
+          top: '6%', // 图例距离顶部的距离为6%
+          right: 2 // 图例距离右边的距离为2
+        },
+        xAxis: {
+          type: 'value',
+          axisLabel: {
+            formatter: function(value) {
+              // 自定义X轴标签的格式化函数,返回绝对值百分比
+              return Math.abs(value) + '%'
+            }
+          }
+        },
+        yAxis: {
+          type: 'category',
+          data: [
+            '0-4', '5-9', '10-14', '15-19',
+            '20-24', '25-29', '30-34', '35-39', '40-44',
+            '45-49', '50-54', '55-59', '60-64', '65-69',
+            '70-74', '75-79', '80-84', '85-89', '90-94',
+            '95-99', '100 + '
+          ]
+        },
+        series: [
+          {
+            name: '男性', // 数据系列的名称
+            type: 'bar', // 系列类型为条形图
+            stack: 'total', // 数据堆叠,同一个堆叠组的数据会堆叠显示
+            itemStyle: {
+              // 条形图的颜色渐变设置
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: '#3d8e86' },
+                { offset: 0.5, color: '#5da39d' },
+                { offset: 1, color: '#88bfb8' }
+              ])
+            },
+            emphasis: {
+              focus: 'series' // 强调设置
+            },
+            data: malePercentage // 男性数据百分比
+          },
+          {
+            name: '女性', // 数据系列的名称
+            type: 'bar', // 系列类型为条形图
+            stack: 'total', // 数据堆叠
+            emphasis: {
+              focus: 'series' // 强调设置
+            },
+            itemStyle: {
+              // 条形图的颜色渐变设置
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: '#d2a36c' },
+                { offset: 0.5, color: '#d5c8a0' },
+                { offset: 1, color: '#dfd6b8' }
+              ])
+            },
+            data: femalePercentage // 女性数据百分比
+          }
+        ]
+      }
+
+      myChart.setOption(option, true)
+      window.addEventListener('resize', () => {
+        if (myChart) {
+          myChart.resize()
+        }
+      })
+    },
+    handleChange(val) {
+      this.$message.info('select -> ' + val)
+    },
+    // 获取考试次数数据
+    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('chart5'))
+      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)
+    },
+    async getUserWatchRegionWrapper() {
+      await getUserWatchRegion().then((resp) => {
+        const pieNames = resp.data[0].split(',')
+        const pieNumbers = resp.data[1].split(',')
+        pieNames.forEach((item, index) => {
+          this.pieChartData.push({
+            name: item,
+            value: parseInt(pieNumbers[index])
+          })
+        })
+        this.drawPieChart()
+      })
+    },
+    drawPieChart() {
+      // 基于准备好的dom,初始化echarts实例
+      const myChart = this.$echarts.init(document.getElementById('chart8'))
+      const option = {
+        title: {
+          text: '分区占比',
+          subtext: '视频分区',
+          x: 'center'
+        },
+        tooltip: {
+          trigger: 'item',
+          formatter: '{a} <br/>{b} : {c}次 ({d}%)'
+        },
+        legend: {
+          orient: 'vertical',
+          left: 'left',
+          data: this.pieChartData
+        },
+        series: [
+          {
+            name: '时长',
+            type: 'pie',
+            radius: '55%',
+            data: this.pieChartData,
+            roseType: 'angle',
+            itemStyle: {
+              normal: {
+                shadowBlur: 200,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      }
+      myChart.setOption(option)
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.movie-list {
+  padding-top: 5px;
+  padding-left: 5px;
+  padding-right: 5px;
+}
+</style>

+ 6 - 362
src/views/exam/ExamDashboard.vue

@@ -24,54 +24,10 @@
         </div>
       </el-card>
     </el-row>
-    <el-row class="movie-list">
-      <el-card>
-        <div slot="header" class="clearfix">
-          <span style="margin-right: 5px">选择图表</span>
-          <el-select
-            v-model="selectedValue"
-            clearable
-            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="height:400px;" />
-      </el-card>
-    </el-row>
-    <el-row class="movie-list">
-      <el-col :md="12" class="movie-list">
-        <el-card>
-          <div id="chart2" style="height:400px;" />
-        </el-card>
-      </el-col>
-      <el-col :md="12" class="movie-list">
-        <el-card>
-          <div slot="header" class="clearfix">
-            <span style="margin-right: 5px">三级联动</span>
-            <el-cascader
-              :options="cascaderOptions"
-              placeholder="试试搜索: 武侯"
-              clearable
-              filterable
-              @change="handleChange"
-            />
-          </div>
-          <div id="chart3" style="height:400px;" />
-        </el-card>
-      </el-col>
-    </el-row>
   </el-row>
 </template>
 
 <script>
-import { getExamCount, getExamPassRate, getLineChartData } from '@/api/exam'
-import { getAreaCascadeOptions } from '@/api/map'
-
 export default {
   name: 'ExamDashboard',
   data() {
@@ -83,8 +39,7 @@ export default {
       // 饼图的数据
       pieData: [],
       selectedValue: '1',
-      chartOption: null,
-      cascaderOptions: []
+      chartOption: null
     }
   },
   created() {
@@ -95,326 +50,15 @@ export default {
       text: '数据拼命加载中,(*╹▽╹*)',
       spinner: 'el-icon-loading'
     })
-    this.getExamPassRate()
-    this.getExamNumbers()
-    this.getData()
+
+    setTimeout(() => {
+      this.$message.info('data loaded')
+      this.loading.close()
+    }, 3000)
   },
   methods: {
-    getData() {
-      getAreaCascadeOptions().then(resp => {
-        if (resp.code === 0) {
-          this.cascaderOptions = resp.data
-        }
-      })
-    },
     handleChange(val) {
       this.$message.info('select -> ' + val)
-    },
-    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(',')
-
-          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()
-            this.drawChart6()
-          }
-
-          const myChart = this.$echarts.init(document.getElementById('chart1'))
-          // setOption 是 merge,而非赋值, setOption 支持 notMerge 参数, 值为 true 时重新渲染
-          myChart.setOption(this.chartOption, true)
-          this.loading.close()
-        }
-      })
-    },
-    // 考试通过率柱状图
-    drawLine() {
-      this.chartOption = {
-        title: {
-          text: '考试通过率',
-          subtext: 'dashbord1',
-          x: 'center',
-          y: 'top',
-          textAlign: 'center'
-        },
-        tooltip: {},
-        xAxis: {
-          data: this.examNames
-        },
-        yAxis: {},
-        series: [{
-          name: '通过率',
-          type: 'bar',
-          data: this.passRate
-        }]
-      }
-    },
-    // 通过率的折线图
-    drawBrokenLine() {
-      this.chartOption = {
-        // 标题
-        title: {
-          text: '考试通过率折线图',
-          x: 'center'
-        },
-        // x轴
-        xAxis: {
-          data: this.examNames
-        },
-        // y轴没有显式设置,根据值自动生成y轴
-        yAxis: {},
-        // 数据-data是最终要显示的数据
-        series: [{
-          name: '通过率',
-          type: 'line',
-          areaStyle: {
-            normal: {}
-          },
-          data: this.passRate
-        }]
-      }
-    },
-    drawImg4() {
-      this.chartOption = {
-        color: ['#cd5c5c'],
-        textStyle: {
-          color: 'black'
-        },
-        tooltip: {
-          trigger: 'axis',
-          axisPointer: {
-            type: 'shadow'
-          },
-          formatter: '{a} <br/>{b} : {c}'
-        },
-        grid: {
-          containLabel: true
-        },
-        xAxis: {
-          type: 'value',
-          boundaryGap: [0, 0.01],
-          axisLine: {
-            lineStyle: {
-              color: '#fff'
-            }
-          },
-          'axisLabel': {
-            'interval': 0,
-            fontSize: 18,
-            formatter: '{value}'
-          }
-        },
-        yAxis: {
-          axisLine: {
-            lineStyle: {
-              color: '#fff'
-            }
-          },
-          'axisLabel': {
-            'interval': 0,
-            fontSize: 18
-          },
-          type: 'category',
-          data: this.examNames
-        },
-        series: [{
-          name: '通过率:',
-          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'] // 三个折线的颜色
-      }
-    },
-    drawChart6() {
-      getLineChartData().then(resp => {
-        if (resp.code === 0) {
-          const data = resp.data
-          this.chartOption = {
-            title: {
-              text: '卡拉云新用户激活数据',
-              subtext: 'Demo 虚构数据',
-              x: 'center'
-            },
-            tooltip: {},
-            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: data.xName,
-              type: 'category',
-              data: data.xLabel
-            },
-            yAxis: {
-              name: data.yName,
-              type: 'value',
-              min: data.yMin, // 配置 Y 轴刻度最小值
-              max: data.yMax, // 配置 Y 轴刻度最大值
-              splitNumber: data.ySplitNumber // 配置 Y 轴数值间隔
-            },
-            series: [
-              {
-                name: '实际',
-                data: data.xValue,
-                type: 'line',
-                symbol: 'circle', // 实心圆点
-                smooth: 0.5 // 设置折线弧度
-              }
-            ],
-            color: ['#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)
     }
   }
 }

+ 1 - 140
src/views/post/PostAnalysis.vue

@@ -1,161 +1,22 @@
 <template>
   <el-container>
-    <el-row>
-      <el-col class="card-style" :md="12">
-        <el-card>
-          <div id="chart1" style="width: 600px;height:400px;" />
-        </el-card>
-      </el-col>
-      <el-col class="card-style" :md="12">
-        <el-card>
-          <div id="chart2" style="width: 600px;height:400px;" />
-        </el-card>
-      </el-col>
-    </el-row>
+    <span>Post Analysis</span>
   </el-container>
 </template>
 
 <script>
-import { getUserWatch, getUserWatchRegion } from '@/api/analysis'
-
 export default {
   name: 'PostAnalysis',
   data() {
     return {
-      barChartNames: [],
-      barChartData: [],
-      pieChartNames: [],
-      pieChartData: [],
-      chartOption: null
     }
   },
   created() {
-    // 页面数据加载的等待状态栏
-    this.loading = this.$loading({
-      body: true,
-      lock: true,
-      text: '数据拼命加载中,(*╹▽╹*)',
-      spinner: 'el-icon-loading'
-    })
-    this.getData()
   },
   methods: {
-    getData() {
-      this.getUserWatchWrapper()
-      this.getUserWatchRegionWrapper()
-    },
-    async getUserWatchWrapper() {
-      await getUserWatch().then((resp) => {
-        if (resp.code === 0) {
-          this.barChartNames = resp.data[0].split(',')
-          this.barChartData = resp.data[1].split(',')
-          this.drawBarChart()
-          const myChart = this.$echarts.init(document.getElementById('chart1'))
-          // setOption 是 merge,而非赋值, setOption 支持 notMerge 参数, 值为 true 时重新渲染
-          myChart.setOption(this.chartOption, true)
-          this.loading.close()
-        }
-      })
-    },
-    drawBarChart() {
-      this.chartOption = {
-        title: {
-          text: '观看时长',
-          subtext: '最近一周',
-          x: 'center',
-          y: 'top',
-          textAlign: 'center'
-        },
-        tooltip: {},
-        xAxis: {
-          data: this.barChartNames
-        },
-        yAxis: {},
-        series: [{
-          name: '时长',
-          type: 'bar',
-          data: this.barChartData
-        }]
-      }
-    },
-    async getUserWatchRegionWrapper() {
-      await getUserWatchRegion().then((resp) => {
-        const pieNames = resp.data[0].split(',')
-        const pieNumbers = resp.data[1].split(',')
-        pieNames.forEach((item, index) => {
-          this.pieChartData.push({
-            name: item,
-            value: parseInt(pieNumbers[index])
-          })
-        })
-        this.drawPieChart()
-        this.loading.close()
-      })
-    },
-    drawPieChart() {
-      // 基于准备好的dom,初始化echarts实例
-      const myChart = this.$echarts.init(document.getElementById('chart2'))
-      const option = {
-        title: {
-          text: '分区占比',
-          subtext: '视频分区',
-          x: 'center'
-        },
-        tooltip: {
-          trigger: 'item',
-          formatter: '{a} <br/>{b} : {c}次 ({d}%)'
-        },
-        legend: {
-          orient: 'vertical',
-          left: 'left',
-          data: this.pieChartData
-        },
-        series: [
-          {
-            name: '时长',
-            type: 'pie',
-            radius: '55%',
-            data: this.pieChartData,
-            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;
-}
-
-@keyframes leftMoveIn {
-  0% {
-    transform: translateX(-100%);
-    opacity: 0;
-  }
-  100% {
-    transform: translateX(0%);
-    opacity: 1;
-  }
-}
-
-.card-style {
-  padding-top: 3px;
-  padding-bottom: 3px;
-  padding-left: 3px;
-  padding-right: 3px;
-}
 </style>