SpringBoot+Vue2+Echarts实现图表的统计
一、需求
该功能是为了实现在对学生分班的人数统计下,所作出的相应调整。Echarts图表在实际项目中也有使用。
二、具体实现
1、数据库设计
班级表:classes
字段名 | 类型 | 长度 | 小数点 | 是否允许为空 | 是否为主键 | 说明 |
---|---|---|---|---|---|---|
cid | int | 0 | 0 | 否 | 是 | 主键,自增 |
cname | varchar | 255 | 0 | 是 | 否 | 班级名称 |
学生表:student
字段名 | 类型 | 长度 | 小数点 | 是否允许为空 | 是否为主键 | 说明 |
---|---|---|---|---|---|---|
sid | int | 0 | 0 | 否 | 是 | 主键,自增 |
name | varchar | 255 | 0 | 是 | 否 | 姓名 |
sex | int | 0 | 0 | 是 | 否 | 性别 |
age | int | 0 | 0 | 是 | 否 | 年龄 |
address | varchar | 255 | 0 | 是 | 否 | 地址 |
cid | int | 0 | 0 | 是 | 否 | 所属班级 |
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>