場景
若依前后端分離版本地搭建開發環境並運行項目的教程:
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>