Browse Source

新增在线时长热力图和登录频次柱状图

zengyicheng 1 year ago
parent
commit
0f367c3845

+ 2 - 2
src/components/pages/dataBoardNew/school/bar/index.vue

@@ -26,10 +26,10 @@ export default {
           formatter: "{b}   {c}(小时)",
         },
         grid: {
-          top: '5%',
+          top: '15%',
           left: '5%',
           right: '5%',
-          bottom: '5%',
+          bottom: '15%',
           containLabel: true
         },
         xAxis: {

+ 209 - 0
src/components/pages/dataBoardNew/school/barToolUser/index.vue

@@ -0,0 +1,209 @@
+<template>
+  <div class="data_body">
+    <div style="width: 100%; height: 100%">
+      <div id="charts_canvas" class="echart" style="width: 100%; height: 100%; "></div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    yearArray: {
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      chartObj: null,
+      ooption: {
+        xdata: [],
+        sdata: [],
+      },
+      option: {
+        // title: {
+        //   text: '登录频次',
+        //   textStyle: {
+        //     fontSize: 12,
+        //   },
+        //   padding: [10, 0, 0, 10]
+        // },
+        tooltip: {
+          position: 'top',
+          formatter: function(params){
+            return params.name + '  ' + params.data[2] + '(小时)';
+          }
+        },
+        grid: {
+          top: '50',
+          left: '5%',
+          right: '5%',
+          bottom: '5%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          // data: [
+          //     '1月', '2月', '3月', '4月', '5月', '6月', '7月',
+          //     '8月', '9月', '10月', '11月', '12月'
+          // ],
+          data: [],
+          splitArea: {
+            show: true
+          },
+          axisLabel: {
+            formatter: function (value) {
+              console.log(value);
+              var ret = "";//拼接加\n返回的类目项  
+              var maxLength = 2;//每项显示文字个数  
+              var valLength = value.length;//X轴类目项的文字个数  
+              var rowN = Math.ceil(valLength / maxLength); //类目项需要换行的行数  
+              if (rowN > 1)//如果类目项的文字大于5,  
+              {
+                for (var i = 0; i < rowN; i++) {
+                  var temp = "";//每次截取的字符串  
+                  var start = i * maxLength;//开始截取的位置  
+                  var end = start + maxLength;//结束截取的位置  
+                  //这里也可以加一个是否是最后一行的判断,但是不加也没有影响,那就不加吧  
+                  temp = value.substring(start, end) + "\n";
+                  ret += temp; //凭借最终的字符串  
+                }
+                return ret;
+              }
+              else {
+                return value;
+              }
+            }
+          }
+        },
+        yAxis: {
+          type: 'category',
+          data: [
+            '星期天', '星期一', '星期二', '星期三',
+            '星期四', '星期五', '星期六',
+          ],
+          splitArea: {
+            show: true
+          },
+        },
+        visualMap: {
+          min: 0,
+          max: 10,
+          calculable: true,
+          orient: 'horizontal',
+          right: '10',
+          top: '0%'
+        },
+        series: [
+          {
+            name: '',
+            type: 'heatmap',
+            data: [],
+            label: {
+              show: true
+            },
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      },
+    };
+  },
+  methods: {
+    setChart(option) {
+      // 雷达图显示的标签
+      let newPromise = new Promise((resolve) => {
+        resolve();
+      });
+      //然后异步执行echarts的初始化函数
+      newPromise.then(() => {
+        const chartObj = this.$echarts.init(
+          //劳动课程
+          this.$el.querySelector("#charts_canvas")
+        );
+
+        this.option.xAxis.data = option.xdata;
+        this.option.series[0].data = option.sdata;
+        this.option.visualMap.max = option.max ? option.max : 0;
+        // 初始化雷达图
+        this.chartObj = chartObj;
+        this.chartObj.setOption(this.option);
+      });
+    },
+    setJson(array) {
+      this.ooption = {
+        xdata: [],
+        sdata: [],
+        max: 0
+      }
+      let _array = array
+      let max = []
+      for (var i = 0; i < _array.length; i++) {
+        this.ooption.xdata.push(_array[i].Month + '月')
+        this.ooption.sdata.push([i, 0, _array[i].sun])
+        this.ooption.sdata.push([i, 1, _array[i].mon])
+        this.ooption.sdata.push([i, 2, _array[i].tue])
+        this.ooption.sdata.push([i, 3, _array[i].wed])
+        this.ooption.sdata.push([i, 4, _array[i].thur])
+        this.ooption.sdata.push([i, 5, _array[i].fri])
+        this.ooption.sdata.push([i, 6, _array[i].sat])
+        // let _data = [_array[i].Month-1,] //[月份,星期,值]
+        max.push(_array[i].sun)
+        max.push(_array[i].mon)
+        max.push(_array[i].tue)
+        max.push(_array[i].wed)
+        max.push(_array[i].thur)
+        max.push(_array[i].fri)
+        max.push(_array[i].sat)
+      }
+      this.ooption.max = max.sort(function (a, b) {
+        return b - a;
+      })[0];
+      if (!this.chartObj) {
+        this.setChart(this.ooption);
+      } else {
+        this.option.xAxis.data = this.ooption.xdata;
+        this.option.series[0].data = this.ooption.sdata;
+        this.option.visualMap.max = this.ooption.max ? this.ooption.max : 0;
+        this.chartObj.setOption(this.option);
+      }
+    }
+  },
+  watch: {
+    yearArray: {
+      immediate: true,
+      deep: true,
+      handler(newValue, oldValue) {
+        this.setJson(newValue)
+        this.$forceUpdate();
+      },
+    },
+  },
+  mounted() {
+    this.setJson(this.yearArray)
+
+    window.addEventListener("resize", () => {
+      if (_this.chartObj) {
+        _this.chartObj.resize();
+      }
+    });
+  },
+};
+</script>
+
+<style scoped>
+.data_body {
+  height: 100%;
+  position: relative;
+  border-radius: 5px;
+  margin: 0 auto;
+  box-sizing: border-box;
+  padding: 0;
+  width: 95%;
+  background: #fff;
+}
+</style>

+ 80 - 13
src/components/pages/dataBoardNew/school/index.vue

@@ -82,16 +82,29 @@
             <span>{{ userOnlineTime > 0 ? (userOnlineTime / allUser).toFixed(0) : 0 }}</span>
           </div>
         </div>
-        <div class="dataBox" style="height: calc(100% - 115px);">
-          <toolUser style="height: calc(100%)" v-if="skType == 1" :yearArray="loginCountYearArray"></toolUser>
-          <bar style="height: calc(100%)" v-if="skType == 0" :loginArray="[teacherOnlineTime, studentOnlineTime]"></bar>
-          <!-- <div class="otherCss">
-            <div v-if="!oType">切换为柱状图</div>
-            <div v-if="oType">切换为热力图</div>
+        <div class="dataBox" style="height: calc(100% - 135px);">
+          <!-- 登录频次热力图 -->
+          <toolUser style="height: calc(100%)" v-if="skType == 1 && !oType1" :yearArray="loginCountYearArray"></toolUser> 
+          <!-- 登录频次柱状图 -->
+          <toolUserBar style="height: calc(100%)" v-if="skType == 1 && oType1" :loginArray="[teacherLoginCount, studentLoginCount]"></toolUserBar>
+          <!-- 在线时长柱状图 -->
+          <bar style="height: calc(100%)" v-if="skType == 0 && !oType" :loginArray="[teacherOnlineTime, studentOnlineTime]"></bar>
+          <!-- 在线时长热力图 -->
+          <barToolUser style="height: calc(100%)" v-if="skType == 0 && oType" :yearArray="allTimeYearArray"></barToolUser>
+          <div class="otherCss" v-if="skType == 0">
+            <div v-if="!oType">切换为热力图</div>
+            <div v-if="oType">切换为柱状图</div>
             <div class="otherImg" @click="otherEchart">
               <img src="../../../../assets/icon/other.png" alt="" />
             </div>
-          </div> -->
+          </div>
+          <div class="otherCss" v-if="skType == 1">
+            <div v-if="!oType1">切换为柱状图</div>
+            <div v-if="oType1">切换为热力图</div>
+            <div class="otherImg" @click="otherEchart1">
+              <img src="../../../../assets/icon/other.png" alt="" />
+            </div>
+          </div>
         </div>
       </div>
     </div>
@@ -321,6 +334,8 @@ import toolUser from "./toolUser";
 import bar from "./bar";
 import courseNum from "./courseNum";
 import workNum from "./workNum";
+import barToolUser from "./barToolUser";
+import toolUserBar from "./toolUserBar";
 
 
 
@@ -334,6 +349,8 @@ export default {
     bar,
     courseNum,
     workNum,
+    barToolUser,
+    toolUserBar,
   },
   props: {
     oid: {
@@ -357,6 +374,7 @@ export default {
       tType: 0,
       courseType: 0,
       oType: false,
+      oType1: false,
       shType: false,
       allUser: 0,
       loginCountMonthArray: [],
@@ -390,7 +408,10 @@ export default {
         gsCourseStudents: 0,//协同课程
         commentStudents: 0,//协同交流
       },
-      weekCourse2: []
+      weekCourse2: [],
+      allTimeYearArray: [],
+      teacherLoginCount: 0,
+      studentLoginCount: 0,
     };
   },
   mounted() {
@@ -403,6 +424,9 @@ export default {
     otherEchart() {
       this.oType = !this.oType;
     },
+    otherEchart1() {
+      this.oType1 = !this.oType1;
+    },
     shEchart() {
       this.shType = !this.shType;
     },
@@ -507,7 +531,6 @@ export default {
               }
             }
           }
-          console.log(loginCountYearArray);
           this.loginCountYearArray = loginCountYearArray
 
           let _userOnlineTime = res.data[7][0].time;//在线时长 所有用户
@@ -568,7 +591,6 @@ export default {
               }
             }
           }
-          console.log(_courseArray);
           // this.gradeCourse = _gradeCourse / _grade.length
           // this.subjectCourse = _subjectCourse / _subject.length
           this.courseArray = _courseArray
@@ -705,14 +727,12 @@ export default {
               weekArray.toWeek.push(a.getFullYear() + '-' + (a.getMonth() + 1) + '-' + a.getDate());
             }
           }
-          console.log(weekArray);
           let weekCourse = [];
           let weekCourse2 = [];
           let lastWeekCouseCount = 0
           let toWeekCouseCount = 0
           for (var z = 0; z < _course.length; z++) {
             let _date = new Date(weekArray.lastWeek[weekArray.lastWeek.length - 1])
-            // console.log(_date) 
             if (new Date(_course[z].create_at) > _date && _course[z].pid == '34628934-d02f-11ec-8c78-005056b86db5') {
               weekCourse.push(_course[z])
               var a = new Date(_course[z].create_at)
@@ -773,8 +793,55 @@ export default {
             toCourse: (toWeekCouseCount - toCourseidWeek.length) > 0 ? (toWeekCouseCount - toCourseidWeek.length) : 0,
           })
 
-          console.log(weekCourse2);
           this.weekCourse2 = weekCourse2
+
+          let allTimeYear = res.data[26]; //累计时长热力图
+          this.teacherLoginCount = res.data[27].length; //教师登录频次柱状图
+          this.studentLoginCount = res.data[28].length; //学生登录频次柱状图
+
+          let allTimeYearArray = []
+          for (var i = Month; i > Month - 12; i--) {
+            if (i <= 0) {
+              allTimeYearArray.push({
+                Year: Year - 1,
+                Month: 12 + i,
+                mon: 0,
+                tue: 0,
+                wed: 0,
+                thur: 0,
+                fri: 0,
+                sat: 0,
+                sun: 0,
+              })
+            } else {
+              allTimeYearArray.push({
+                Month: i,
+                Year: Year,
+                mon: 0,
+                tue: 0,
+                wed: 0,
+                thur: 0,
+                fri: 0,
+                sat: 0,
+                sun: 0,
+              })
+            }
+          }
+          allTimeYearArray = allTimeYearArray.reverse()
+          for (var i = 0; i < allTimeYear.length; i++) {
+            let _date = new Date(allTimeYear[i].create_at)
+            var _month = _date.getMonth() + 1
+            var _year = _date.getFullYear()
+            var _day = _date.getDay()
+            let dayArray = ['sun', 'mon', 'tue', 'wed', 'thur', 'fri', 'sat']
+            for (var j = 0; j < allTimeYearArray.length; j++) {
+              if (_month == allTimeYearArray[j].Month && _year == allTimeYearArray[j].Year) {
+                allTimeYearArray[j][dayArray[_day]] += parseInt((parseInt(allTimeYear[i].text) / 3600).toFixed(0));
+                break;
+              }
+            }
+          }
+          this.allTimeYearArray = allTimeYearArray
           this.$forceUpdate();
         })
         .catch((err) => {

+ 120 - 0
src/components/pages/dataBoardNew/school/toolUserBar/index.vue

@@ -0,0 +1,120 @@
+<template>
+  <div class="data_body">
+    <div style="width: 100%; height: 100%">
+      <div id="charts_canvas" class="echart" style="width: 100%; height: 100%"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    loginArray: {
+      type: Array
+    },
+  },
+  data() {
+    return {
+      chartObj: null,
+      ooption: {
+        xdata: [],
+        type: [],
+      },
+      option: {
+        tooltip: {
+          trigger: "item",
+          formatter: "{b}   {c}(次)",
+        },
+        grid: {
+          top: '15%',
+          left: '5%',
+          right: '5%',
+          bottom: '15%',
+          containLabel: true
+        },
+        xAxis: {
+          type: "category",
+          data: ["老师", "学生"],
+        },
+        yAxis: {
+          type: "value",
+          data: [],
+        },
+        series: [
+          {
+            data: [],
+            barWidth: 30,
+            type: "bar",
+          },
+        ],
+      },
+    };
+  },
+  methods: {
+    setChart(array) {
+      // 雷达图显示的标签
+      let newPromise = new Promise((resolve) => {
+        resolve();
+      });
+      //然后异步执行echarts的初始化函数
+      newPromise.then(() => {
+        const chartObj = this.$echarts.init(
+          this.$el.querySelector("#charts_canvas")
+        );
+        this.option.series[0].data = array;
+        // 初始化雷达图
+        this.chartObj = chartObj;
+        this.chartObj.setOption(this.option);
+      });
+    },
+    setJson(array) {
+      this.ooption = {
+        xdata: [],
+        sdata: [],
+        max: 0
+      }
+
+      if (!this.chartObj) {
+        this.setChart(array);
+      } else {
+        this.option.series[0].data = array;
+        this.chartObj.setOption(this.option);
+      }
+    }
+  },
+  watch: {
+    loginArray: {
+      immediate: true,
+      deep: true,
+      handler(newValue, oldValue) {
+        this.setJson(newValue)
+        this.$forceUpdate();
+      },
+    },
+  },
+  mounted() {
+    this.setJson(this.loginArray)
+    var _this = this;
+    window.addEventListener("resize", () => {
+      if (_this.chartObj) {
+        _this.chartObj.resize();
+      }
+    });
+  },
+};
+</script>
+
+<style scoped>
+.data_body {
+  height: 100%;
+  /* display: flex; */
+  position: relative;
+  border-radius: 5px;
+  /* border: 1px solid #eee; */
+  margin: 0 auto;
+  box-sizing: border-box;
+  padding: 0;
+  width: 95%;
+  background: #fff;
+}
+</style>