场景
若依前后端分离版本地搭建开发环境并运行项目的教程:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662
在上面搭建架构的基础上,实现使用ElementUI的el-date-picker选择一段时间范围,
统计后台数据库中对应时间内的记录数并在柱状图中显示。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
1、后台设计数据库,新建带时间字段的表
DROP TABLE IF EXISTS `bus_blog`; CREATE TABLE `bus_blog` ( `id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'id', `add_time` datetime(0) NOT NULL COMMENT '添加时间', `blog_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '名称', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '博客表' ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;
然后表中添加几条带时间的数据
2、使用若依自带的代码生成工具生成前后端代码和菜单数据。
在实体类中添加开始时间和结束时间两个字段,用来接收和传递时间范围字段
package com.ruoyi.system.domain; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.core.domain.BaseEntity; /** * 博客对象 bus_blog * * @author ruoyi * @date 2021-11-25 */ public class BusBlog extends BaseEntity { private static final long serialVersionUID = 1L; /** id */ private Long id; /** 添加时间 */ @JsonFormat(pattern = "yyyy-MM-dd") @Excel(name = "添加时间", width = 30, dateFormat = "yyyy-MM-dd") private Date addTime; /** 名称 */ @Excel(name = "名称") private String blogName; //开始时间 private String beginDate; //结束时间 private String endDate; public String getBeginDate() { return beginDate; } public void setBeginDate(String beginDate) { this.beginDate = beginDate; } public String getEndDate() { return endDate; } public void setEndDate(String endDate) { this.endDate = endDate; } public void setId(Long id) { this.id = id; } public Long getId() { return id; } public void setAddTime(Date addTime) { this.addTime = addTime; } public Date getAddTime() { return addTime; } public void setBlogName(String blogName) { this.blogName = blogName; } public String getBlogName() { return blogName; } @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) .append("id", getId()) .append("addTime", getAddTime()) .append("blogName", getBlogName()) .toString(); } }
3、修改Controller层的获取数据的接口
@GetMapping("/list") public AjaxResult list(BusBlog busBlog) { BusBlog indexModel=new BusBlog(); //构造返回数据,注意这里需要用LinkedHashMap Map<String,Integer> resultMap = new LinkedHashMap<String,Integer>(); if(null!= busBlog.getBeginDate() && null!= busBlog.getEndDate()) { //获取请求参数,开始时间和结束时间 indexModel.setBeginDate(busBlog.getBeginDate()); indexModel.setEndDate(busBlog.getBeginDate()); List<String> rangeData = new ArrayList<String>(); //查询数据库获取指定时间内的数据 rangeData = busBlogService.selectBlogCountByDate(busBlog); if (rangeData.size() >= 0) { // 日期格式化 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { // 起始日期 Date d1 = sdf.parse(busBlog.getBeginDate()); // 结束日期 Date d2 = sdf.parse(busBlog.getEndDate()); Date tmp = d1; Calendar dd = Calendar.getInstance(); dd.setTime(d1); while (tmp.getTime() < d2.getTime()) { int dayCount = 0; tmp = dd.getTime(); //获取查询的数据每天的档案数量 for (String oneDay:rangeData) { Date oneDayDate = sdf.parse(oneDay); if(oneDayDate.toString().equals(tmp.toString())) { dayCount++; } } resultMap.put(sdf.format(tmp),dayCount); // 天数加上1 dd.add(Calendar.DAY_OF_MONTH, 1); } System.out.println(resultMap); } catch (ParseException e) { e.printStackTrace(); } } } return AjaxResult.success(resultMap); }
4、Service层和mapper略过
都是如下返回格式和请求数据格式
public List<String> selectBlogCountByDate(BusBlog queryParam);
5、mapper.xml具体查询sql实现
<select id="selectBlogCountByDate" parameterType="BusBlog" resultType="java.lang.String"> SELECT add_time FROM bus_blog <where> <if test="beginDate != null"> AND date_format(add_time,'%y%m%d') >= date_format(#{beginDate},'%y%m%d') </if> <if test="endDate != null"> AND date_format(#{endDate},'%y%m%d') >= date_format(add_time,'%y%m%d') </if> </where>
6、最终后台返回的数据格式为
7、前端新建一个组件BarChartDateRange.vue用来显示柱状图
组件代码:
<template> <div :style="{ height: '300px', width: '300px' }" /> </template> <script> import echarts from "echarts"; require("echarts/theme/macarons"); // echarts theme import request from '@/utils/request' import { formatDate } from "@/utils/index"; export default { name: "BarChartDateRange", data() { return { chart: null, typeData: [ { product: "2021.11.23", 博客数: 20 }, { product: "2021.11.24", 博客数: 30 }, { product: "2021.11.25", 博客数: 35 }, { product: "2021.11.26", 博客数: 43 }, ], yAxisMax: 0, queryParam: { beginDate: null, endDate: null, }, }; }, created() { //默认开始时间为一周前 this.queryParam.beginDate = formatDate( new Date().getTime() - 60 * 1000 * 60 * 24 * 6 ); //默认结束时间时间当前时间 this.queryParam.endDate = formatDate(new Date().getTime()); this.getList().then((response) => { var res = response.data; if (res) { //清空柱状图的数据源 this.typeData = []; //遍历后台响应数据,构造柱状图数据源 for (var key in res) { this.typeData.push({ product: key, 博客数: res[key] }); } } this.initChart(this.typeData); }); }, mounted() {}, methods: { //调用后台接口查询数据 getList() { return request({ url: "/system/blog/list", method: "get", params: this.queryParam, }); }, //父组件调用子组件的该方法进行重新渲染柱状图 getSelectedRangeList(range) { var startDate = range[0]; var endDate = range[1]; this.queryParam.beginDate = startDate; this.queryParam.endDate = endDate; this.getList().then((response) => { var res = response.data; if (res) { this.typeData = []; for (var key in res) { this.typeData.push({ product: key, 博客数: res[key] }); } } this.initChart(this.typeData); }); }, initChart(typeData) { this.chart = echarts.init(this.$el, "macarons"); this.chart.setOption({ tooltip: { trigger: "axis", axisPointer: { // 坐标轴指示器,坐标轴触发有效 type: "shadow", // 默认为直线,可选为:'line' | 'shadow' }, }, grid: { top: 10, left: "2%", right: "2%", bottom: "3%", containLabel: true, }, legend: { //图例 data: ["博客数"], }, xAxis: [ { type: "category", axisPointer: { type: "shadow", }, axisLabel: { interval: 0, rotate: 40, }, }, ], yAxis: [ { type: "value", name: "单位:(条)", min: 0, max: 30, interval: 10, axisLabel: { formatter: "{value}", }, }, ], dataset: { source: typeData, }, series: [ { name: "博客数", type: "bar", barWidth: "40%", }, ], }); }, }, }; </script>
8、然后在主页面中引入该组件
import BarChartDateRange from "@/components/Echarts/BarChartDateRange"; export default { name: "Blog", components: { BarChartDateRange, },
并且在主页面添加时间范围选择组件
<div> <div> <BarChartDateRange ref="BarChartDateRange"></BarChartDateRange> </div> <div class="block"> <el-date-picker size="large" type="daterange" v-model="value1" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" @change="dateSelectChange" :value-format="dateFormat" > </el-date-picker> </div> </div>
设置时间选择组件的改变事件
@change="dateSelectChange"
实现该方法
/** 查询博客列表 */ dateSelectChange(val) { if (val) { var startDate = new Date(val[0]).getTime(); var endDate = new Date(val[1]).getTime(); debugger; if (endDate - startDate > 6 * 24 * 60 * 60 * 1000) { this.$message({ message: "所选时间范围不能大于7天", type: "warning", }); }else{ this.$refs.BarChartDateRange.getSelectedRangeList(val); } } },
获取选择的时间进行范围校验,然后通过
this.$refs.BarChartDateRange.getSelectedRangeList(val);
调用子组件的方法重新查询数据并渲染柱状图
子组件需要声明ref
<BarChartDateRange ref="BarChartDateRange"></BarChartDateRange>
在子组件中方法实现
//父组件调用子组件的该方法进行重新渲染柱状图 getSelectedRangeList(range) { var startDate = range[0]; var endDate = range[1]; this.queryParam.beginDate = startDate; this.queryParam.endDate = endDate; this.getList().then((response) => { var res = response.data; if (res) { this.typeData = []; for (var key in res) { this.typeData.push({ product: key, 博客数: res[key] }); } } this.initChart(this.typeData); }); },
9、柱状图组件完整示例代码
<template> <div :style="{ height: '300px', width: '300px' }" /> </template> <script> import echarts from "echarts"; require("echarts/theme/macarons"); // echarts theme import request from '@/utils/request' import { formatDate } from "@/utils/index"; export default { name: "BarChartDateRange", data() { return { chart: null, typeData: [ { product: "2021.11.23", 博客数: 20 }, { product: "2021.11.24", 博客数: 30 }, { product: "2021.11.25", 博客数: 35 }, { product: "2021.11.26", 博客数: 43 }, ], yAxisMax: 0, queryParam: { beginDate: null, endDate: null, }, }; }, created() { //默认开始时间为一周前 this.queryParam.beginDate = formatDate( new Date().getTime() - 60 * 1000 * 60 * 24 * 6 ); //默认结束时间时间当前时间 this.queryParam.endDate = formatDate(new Date().getTime()); this.getList().then((response) => { var res = response.data; if (res) { //清空柱状图的数据源 this.typeData = []; //遍历后台响应数据,构造柱状图数据源 for (var key in res) { this.typeData.push({ product: key, 博客数: res[key] }); } } this.initChart(this.typeData); }); }, mounted() {}, methods: { //调用后台接口查询数据 getList() { return request({ url: "/system/blog/list", method: "get", params: this.queryParam, }); }, //父组件调用子组件的该方法进行重新渲染柱状图 getSelectedRangeList(range) { var startDate = range[0]; var endDate = range[1]; this.queryParam.beginDate = startDate; this.queryParam.endDate = endDate; this.getList().then((response) => { var res = response.data; if (res) { this.typeData = []; for (var key in res) { this.typeData.push({ product: key, 博客数: res[key] }); } } this.initChart(this.typeData); }); }, initChart(typeData) { this.chart = echarts.init(this.$el, "macarons"); this.chart.setOption({ tooltip: { trigger: "axis", axisPointer: { // 坐标轴指示器,坐标轴触发有效 type: "shadow", // 默认为直线,可选为:'line' | 'shadow' }, }, grid: { top: 10, left: "2%", right: "2%", bottom: "3%", containLabel: true, }, legend: { //图例 data: ["博客数"], }, xAxis: [ { type: "category", axisPointer: { type: "shadow", }, axisLabel: { interval: 0, rotate: 40, }, }, ], yAxis: [ { type: "value", name: "单位:(条)", min: 0, max: 30, interval: 10, axisLabel: { formatter: "{value}", }, }, ], dataset: { source: typeData, }, series: [ { name: "博客数", type: "bar", barWidth: "40%", }, ], }); }, }, }; </script>
10、显示柱状图的父组件完整示例代码
<template> <div> <div> <BarChartDateRange ref="BarChartDateRange"></BarChartDateRange> </div> <div class="block"> <el-date-picker size="large" type="daterange" v-model="value1" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" @change="dateSelectChange" :value-format="dateFormat" > </el-date-picker> </div> </div> </template> <script> import BarChartDateRange from "@/components/Echarts/BarChartDateRange"; export default { name: "Blog", components: { BarChartDateRange, }, data() { return { value1: "", dateFormat: "yyyy-MM-dd", }; }, created() { }, methods: { /** 查询博客列表 */ dateSelectChange(val) { if (val) { var startDate = new Date(val[0]).getTime(); var endDate = new Date(val[1]).getTime(); debugger; if (endDate - startDate > 6 * 24 * 60 * 60 * 1000) { this.$message({ message: "所选时间范围不能大于7天", type: "warning", }); }else{ this.$refs.BarChartDateRange.getSelectedRangeList(val); } } }, }, }; </script>