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>