Bootstrap

SpringBoot+Vue2+Echarts实现图表的统计

SpringBoot+Vue2+Echarts实现图表的统计

一、需求

该功能是为了实现在对学生分班的人数统计下,所作出的相应调整。Echarts图表在实际项目中也有使用。

二、具体实现

1、数据库设计

班级表:classes

字段名类型长度小数点是否允许为空是否为主键说明
cidint00主键,自增
cnamevarchar2550班级名称

学生表:student

字段名类型长度小数点是否允许为空是否为主键说明
sidint00主键,自增
namevarchar2550姓名
sexint00性别
ageint00年龄
addressvarchar2550地址
cidint00所属班级

2、后端项目

  • 框架:SpringBoot
  • 数据库:MySQL
2.1、添加依赖
<parent>
	<artifactId>spring-boot-starter-parent</artifactId>
	<groupId>org.springframework.boot</groupId>
	<version>2.5.12</version>
</parent>

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
	</dependency>
	<dependency>
		<groupId>org.junit.platform</groupId>
		<artifactId>junit-platform-launcher</artifactId>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
	</dependency>
	<dependency>
		<groupId>com.baomidou</groupId>
		<artifactId>mybatis-plus-boot-starter</artifactId>
		<version>3.5.3.1</version>
	</dependency>
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>fastjson</artifactId>
		<version>2.0.3</version>
	</dependency>
</dependencies>
2.2、实体类
package org.example.entity;

public class StudentVO {
    
    private Integer total;
    
    private String cId;
    
    private String cName;

    public Integer getTotal() {
        return total;
    }

    public void setTotal(Integer total) {
        this.total = total;
    }

    public String getcId() {
        return cId;
    }

    public void setcId(String cId) {
        this.cId = cId;
    }

    public String getcName() {
        return cName;
    }

    public void setcName(String cName) {
        this.cName = cName;
    }
}
2.3、Mapper

StudentDao

package org.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hanscnc.entity.CountVO;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
@Mapper
public interface StudentDao extends BaseMapper<Student> {

    List<Student> selectCountStudent();

}

StudentMapper.xml

<?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="org.example.mapper.StudentDao">
    <select id="selectCountStudent" resultType="org.example.entity.StudentVO">
        select count(*) as total, s.cid as cId, c.cname as cName
        from student s join classes c on s.cid = c.cid
        group by c.cname;
    </select>
</mapper>
2.4、Service
package org.example.service;

import org.example.entity.StudentVO;
import java.util.List;

public interface StudentService {

    List<StudentVO> countStudent();

}
package org.example.service.impl;

import org.example.entity.StudentVO;
import org.example.mapper.StudentDao;
import org.example.service.StudentService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class StudentServiceImpl implements StudentService {

    private final Logger logger = LoggerFactory.getLogger(StudentService.class);

    private final StudentDao studentDao;

    public StudentServiceImpl(StudentDao studentDao) {
        this.studentDao = studentDao;
    }

    @Override
    public List<StudentVO> countStudent() {
        try {
            return studentDao.selectCountStudent();
        } catch (Exception e) {
            logger.error("StudentService---->countStudent(...)error." + e.getMessage());
            return null;
        }
    }

}
2.5、Controller
package org.example.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.example.entity.MsgResponse;
import org.example.entity.StudentVO;
import org.example.service.StudentService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/count")
public class StudentController {

    private final StudentService studentService;

    public StudentController(StudentService studentService) {
        this.studentService = studentService;
    }

    @GetMapping("/student")
    public String countStudent() {
        MsgResponse response = new MsgResponse();
        List<StudentVO> studentVOList = studentService.countStudent();
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject;
        for (StudentVO studentVO : studentVOList) {
            jsonObject = new JSONObject(true);
            jsonObject.put("total", studentVO.getTotal());
            jsonObject.put("cId", studentVO.getcId());
            jsonObject.put("cName", studentVO.getcName());
            jsonArray.add(jsonObject);
        }
        response.setData(jsonArray.toString());
        return response.toString();
    }

}

3、前端项目

  • Vue2
  • Axios
  • Vue Router
  • Echarts

添加依赖

npm install echarts --save

在main.js中配置

import * as echarts from 'echarts';

Vue.prototype.$echarts = echarts;

在项目中使用

<template>
    <el-container>
        <el-header style="font-size: 12px; border-bottom: 1px solid #dcdfe6;">
            <el-row>
                <el-col :span="2" style="text-align:left;">
                    <span style="font-size:18px;font-weight:bolder;color:#409EFF;">学生统计</span>
                </el-col>
                <el-col :span="1" :offset="21">
                    <el-dropdown class="header-setting">
                        <i class="el-icon-setting" style="margin: auto 5px auto 25px;font-size:20px;cursor: pointer;"></i>
                        <el-dropdown-menu slot="dropdown">
                            <el-dropdown-item>
                                <el-link :underline="false" href="/">系统主页</el-link>
                            </el-dropdown-item>
                            <el-dropdown-item>
                                <el-link :underline="false" href="" target="_blank">帮助中心</el-link>
                            </el-dropdown-item>
                            <el-dropdown-item>
                                <el-link :underline="false">退出登录</el-link>
                            </el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>
                </el-col>
            </el-row>
        </el-header>
        <el-main :style="windowInfo">
            <el-card>
                <div id="main1" style="width:100%;height:600px"></div>
            </el-card>
        </el-main>
    </el-container>
</template>
<script>
import { countStudent } from '../../api/countStudent';
export default {
    data() {
        return {
            windowInfo: {
                height: '',
                overflow: 'scroll'
            },
            categoryList: [],
            seriesDataList: [],
        }
    },
    mounted() {
        window.onresize = () => {
            window.removeEventListener('resize', this.getWindowInit())
        };
        this.getInfo();
    },
    destroyed() {
        window.removeEventListener('resize', this.getWindowInit());
    },
    methods: {
        //初始化窗口大小
        getWindowInit() {
            this.windowInfo.height = window.innerHeight - 60 + 'px';
        },
        //获取数据
        getInfo() {
            countStudent().then(res => {
                if (res.errcode == 0) {
                    let data = res.data;
                    data.forEach(item => {
                        this.categoryList.splice(this.categoryList.length, 0, item.parentName);
                        this.seriesDataList.splice(this.seriesDataList.length, 0, item.total);
                    })
                    this.drawEcharts();
                }
            })
        },
        //画图表
        drawEcharts() {
            let myChart = this.$echarts.init(document.getElementById("main1"));
            let option = {
                title: {
                    text: "统计班级的学生数量",
                },
                tooltip: {},
                legend: {
                    data: ["学生数量"],
                },
                xAxis: {
                    name: "所属班级",
                    data: this.categoryList,
                    axisLabel: {
                        interval: 0
                    }
                },
                yAxis: {
                    type: 'value'
                },
                series: [
                    {
                        name: "班级学生的数量",
                        type: "bar",
                        barWidth: '60%',
                        data: this.seriesDataList,
                        label: {
                            normal: {
                                show: true,
                                position: 'top'
                            }
                        }
                    },
                ],
            };
            // 使用刚指定的配置项和数据显示图表。
            myChart.setOption(option);
            // 点击事件
            myChart.on('click', function (param) {
                console.log('param', param);
            });
        },
    }
}
</script>
<style>
.el-container {
    width: 100%;
    height: 100%;
}

.el-container>.el-header {
    background-color: #fff;
    color: #000;
    line-height: 60px;
    height: 60px;
}

.el-container>.el-main {
    height: calc(100vh-60px);
    overflow: auto;
}
</style>
;