场景
若依前后端分离版本地搭建开发环境并运行项目的教程:
若依前后端分离版手把手教你本地搭建环境并运行项目_BADAO_LIUMANG_QIZHI的博客-CSDN博客
在上面搭建架构的基础上,实现使用ElementUI的el-date-picker选择一段时间范围,
统计后台数据库中对应时间内的记录数并在柱状图中显示。
注:
博客:
BADAO_LIUMANG_QIZHI的博客_霸道流氓气质_CSDN博客-C#,SpringBoot,架构之路领域博主
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
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>