Grain College - integrated ECharts

Posted by arbab on Fri, 18 Feb 2022 12:40:46 +0100

Statistical analysis module

Demand: count the number of registrants of online education every day, and use the chart to display the number of registrants

preparation

Code generation and configuration file omission~~

Database tables: statistics_daily, which stores statistical data

CREATE TABLE `statistics_daily` (
  `id` char(19) NOT NULL COMMENT 'Primary key',
  `date_calculated` varchar(20) NOT NULL COMMENT 'Statistical date',
  `register_num` int(11) NOT NULL DEFAULT '0' COMMENT 'Number of registrants',
  `login_num` int(11) NOT NULL DEFAULT '0' COMMENT 'Number of login',
  `video_view_num` int(11) NOT NULL DEFAULT '0' COMMENT 'Number of videos played per day',
  `course_num` int(11) NOT NULL DEFAULT '0' COMMENT 'Number of new courses per day',
  `gmt_create` datetime NOT NULL COMMENT 'Creation time',
  `gmt_modified` datetime NOT NULL COMMENT 'Update time',
  PRIMARY KEY (`id`),
  KEY `statistics_day` (`date_calculated`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Website statistics daily data'

To count the number of registrants, you need to query the table: ucenter_member

  • For example, you need to query the number of registered people on January 2, 2019 (please use the DATE function to obtain the DATE part in the time format)
SELECT COUNT(*) FROM ucenter_member uc WHERE DATE(uc.`gmt_create`) = '2019-01-02' 
  • Now you need to put the queried data into the statistics table_ Daily to display in the page

Generate statistics

The interface is defined in the ucener module to query the number of registered people on a certain day

    //Query the number of people registered on a certain day
    @GetMapping("countRegister/{day}")
    public R countRegister(@PathVariable String day) {
        Integer count = memberService.countRegisterDay(day);
        return R.ok().data("countRegister",count);
    }
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.educenter.mapper.UcenterMemberMapper">

    <!--Query the number of people registered on a certain day-->
    <select id="countRegisterDay" resultType="java.lang.Integer">
        SELECT COUNT(*) FROM ucenter_member uc
         WHERE DATE(uc.gmt_create)=#{day}
    </select>
</mapper>

Statistics statistics analysis module calls the above interface remotely and starts the class to add annotation @ EnableFeignClients

@Component
@FeignClient("service-ucenter")
public interface UcenterClient {

    //Query the number of people registered on a certain day
    @GetMapping("/educenter/member/countRegister/{day}")
    public R countRegister(@PathVariable("day") String day);
}
    //Count the number of registered people on a certain day and generate statistical data
    @PostMapping("registerCount/{day}")
    public R registerCount(@PathVariable String day) {
        staService.registerCount(day);
        return R.ok();
    }
    @Autowired
    private UcenterClient ucenterClient;

    @Override
    public void registerCount(String day) {

        //Delete data of the same date in the table before adding records
        QueryWrapper<StatisticsDaily> wrapper = new QueryWrapper<>();
        wrapper.eq("date_calculated",day);
        baseMapper.delete(wrapper);

        //Remote call to get the number of registrants on a certain day
        R registerR = ucenterClient.countRegister(day);
        Integer countRegister = (Integer)registerR.getData().get("countRegister");

        //Add the obtained data to the database and statistical analysis table
        StatisticsDaily sta = new StatisticsDaily();
        sta.setRegisterNum(countRegister); //Number of registrants
        sta.setDateCalculated(day);//Statistical date

        sta.setVideoViewNum(RandomUtils.nextInt(100,200));
        sta.setLoginNum(RandomUtils.nextInt(100,200));
        sta.setCourseNum(RandomUtils.nextInt(100,200));
        baseMapper.insert(sta);
    }

Front end part

Call interface

    //1 generate statistics
    createStaData(day) {
        return request({
            url: '/staservice/sta/registerCount/'+day,
            method: 'post'
          })
    },

get data

<template>
  <div class="app-container">
    <!--form -->
    <el-form :inline="true" class="demo-form-inline">

      <el-form-item label="date">
        <el-date-picker
          v-model="day"
          type="date"
          placeholder="Select the date to be counted"
          value-format="yyyy-MM-dd" />
      </el-form-item>

      <el-button
        :disabled="btnDisabled"
        type="primary"
        @click="create()">generate</el-button>
    </el-form>

  </div>
</template>
<script>
import sta from '@/api/sta'
export default {
  data() {
    return {
      day: '',
      btnDisabled: false
    }
  },

  methods: {
    create() {
      sta.createStaData(this.day)
        .then(response => {
            this.$message({
                type: 'success',
                message: 'Data generation succeeded'
            });
            //Jump to icon display page
            this.$router.push({path:'/sta/show'})
        })
    }
  }
}
</script>

Add scheduled task

Add the annotation @ enableshcheduling on the startup class to create a scheduled task class, and use the cron expression to set when the program will execute automatically

@Component
public class ScheduledTask {

    @Autowired
    private StatisticsDailyService staService;

    // 0/5 * * * * ? Indicates that this method is executed every 5 seconds
    @Scheduled(cron = "0/5 * * * * ?")
    public void task1() {
        System.out.println("**************task1 Yes..");
    }

    //At 1 a.m. every day, query and add the data of the previous day
    @Scheduled(cron = "0 0 1 * * ?")
    public void task2() {
        staService.registerCount(DateUtil.formatDate(DateUtil.addDays(new Date(), -1)));
    }
}

Chart display data

Use the chart to display the data in the statistical analysis table, and remotely call the member module in the statistical analysis module to obtain the number of registered people in a day

Introduction to ECharts

ECharts is a project of Baidu. Later, baidu donated Echart to apache for chart display, providing conventional broken line chart, histogram, scatter chart, pie chart and K-line chart, box chart for statistics, map, heat map and line chart for geographic data visualization, and relationship chart, treemap and sunrise chart for relational data visualization, The parallel coordinates of multidimensional data visualization, as well as the funnel diagram and dashboard for BI, and support the mixing and matching between diagrams.

Official website: https://echarts.baidu.com/

    //The chart shows that it returns two parts of data, date json array and quantity json array
    @GetMapping("showData/{type}/{begin}/{end}")
    public R showData(@PathVariable String type,@PathVariable String begin,
                      @PathVariable String end) {
        Map<String,Object> map = staService.getShowData(type,begin,end);
        return R.ok().data(map);
    }

Query the corresponding data according to the conditions - > traverse and query all the data list sets, encapsulate them, put them into the map set, and return them

    //The chart shows that it returns two parts of data, date json array and quantity json array
    @Override
    public Map<String, Object> getShowData(String type, String begin, String end) {
        //Query corresponding data according to conditions
        QueryWrapper<StatisticsDaily> wrapper = new QueryWrapper<>();
        wrapper.between("date_calculated",begin,end);
        wrapper.select("date_calculated",type); // Type to query
        List<StatisticsDaily> staList = baseMapper.selectList(wrapper);

        //Because there are two parts of data returned: date and quantity corresponding to date
        //The front end requires an array json structure, and the corresponding back-end java code is a list set
        //Create two list sets, a date list and a quantity list
        List<String> date_calculatedList = new ArrayList<>();
        List<Integer> numDataList = new ArrayList<>();

        //Traverse and query all data list sets for encapsulation
        for (int i = 0; i < staList.size(); i++) {
            StatisticsDaily daily = staList.get(i);
            //Encapsulate date list collection
            date_calculatedList.add(daily.getDateCalculated());
            //Corresponding number of packages
            switch (type) {
                case "login_num":
                    numDataList.add(daily.getLoginNum());
                    break;
                case "register_num":
                    numDataList.add(daily.getRegisterNum());
                    break;
                case "video_view_num":
                    numDataList.add(daily.getVideoViewNum());
                    break;
                case "course_num":
                    numDataList.add(daily.getCourseNum());
                    break;
                default:
                     break;
            }
        }
        //Put the two list sets after encapsulation into the map set and return
        Map<String, Object> map = new HashMap<>();
        map.put("date_calculatedList",date_calculatedList);
        map.put("numDataList",numDataList);
        return map;
    }

front end

    // Get statistics
    getDataSta(searchObj) {
        return request({
            url: `/staservice/sta/showData/${searchObj.type}/${searchObj.begin}/${searchObj.end}`,
            method: 'post'
          })
    }

Chart display

<template>
  <div class="app-container">
    <!--form -->
    <el-form :inline="true" class="demo-form-inline">

      <el-form-item>
        <el-select v-model="searchObj.type" clearable placeholder="Please select">
          <el-option label="Student login statistics" value="login_num"/>
          <el-option label="Statistics of student enrollment" value="register_num"/>
          <el-option label="Statistics of course playback" value="video_view_num"/>
          <el-option label="Statistics of daily courses" value="course_num"/>
        </el-select>
      </el-form-item>

      <el-form-item>
        <el-date-picker
          v-model="searchObj.begin"
          type="date"
          placeholder="Select Start Date"
          value-format="yyyy-MM-dd" />
      </el-form-item>
      <el-form-item>
        <el-date-picker
          v-model="searchObj.end"
          type="date"
          placeholder="Select due date"
          value-format="yyyy-MM-dd" />
      </el-form-item>
      <el-button
        :disabled="btnDisabled"
        type="primary"
        icon="el-icon-search"
        @click="showChart()">query</el-button>
    </el-form>

    <div class="chart-container">
      <div id="chart" class="chart" style="height:500px;width:100%" />
    </div>
  </div>
</template>
<script>
import echarts from 'echarts'
import staApi from '@/api/sta'

export default {
  data() {
    return {
      searchObj: {},
      btnDisabled: false,
      chart: null,
      title: '',
      xData: [],

    }
  },
  methods: {
    showChart() {
      this.getDataSta(this.searchObj)

      this.setChart()
    },

    // Prepare chart data
    initChartData() {

    },

    // Set icon parameters
    setChart() {
      // Initialize the ecarts instance based on the prepared dom
      this.chart = echarts.init(document.getElementById('chart'))
      // console.log(this.chart)

      // Specify configuration items and data for the chart
      var option = {
        // The x-axis is the category axis (discrete data), and the category data must be set through data
        xAxis: {
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        },
        // The y-axis is the data axis (continuous data)
        yAxis: {
          type: 'value'
        },
        // List of series. Each series determines its own chart type by type
        series: [{
          // Array of data contents in series
          data: [820, 932, 901, 934, 1290, 1330, 1320],
          // Line chart
          type: 'line'
        }]
      }

      this.chart.setOption(option)
    }
  }
}
</script>

Topics: Java