前情提要:本次Echarts數據可視化基于圖書管理系統(tǒng)設計
一、Echarts
Echarts是一個開源的可視化圖表庫,由百度前端技術部開發(fā)維護。它基于JavaScript語言實現,通過簡單的配置即可生成豐富多樣的圖表,包括柱狀圖、折線圖、餅圖等等。Echarts支持各種數據格式,如JSON、XML、CSV等,同時也提供了強大的交互功能,可以讓用戶在圖表上進行縮放、平移、標記等操作。Echarts還有豐富的擴展插件和主題,方便用戶根據不同需求進行自定義定制。Echarts的優(yōu)點在于使用簡單、靈活性高、可定制性強,并且提供了完善的文檔和API參考,方便開發(fā)人員快速上手和開發(fā)。
二、前端(Vue+Echarts)
Echarts下載:npm i echarts -S
HomeView.vue(完整代碼)
<template>
<div>
<div style="margin: 20px 0">
<el-select class="input" v-model="timeRange" placeholder="請選擇" @change="load">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<el-card>
<div id="line" style="width: 100%; height: 400px"></div>
</el-card>
</div>
</template>
<script>
import Cookies from 'js-cookie'
import request from "@/utils/request";
import * as echarts from 'echarts'
const option = {
title: {
text: '圖書借還統(tǒng)計'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['借書數量', '還書數量']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [] //從后臺動態(tài)獲取
},
yAxis: {
type: 'value'
},
series: [
{
name: '借書數量',
type: 'line',
stack: 'Total',
smooth: true,
data: [] //從后臺動態(tài)獲取
},
{
name: '還書數量',
type: 'line',
smooth: true,
data: [] //從后臺動態(tài)獲取
}
]
}
export default {
data() {
return {
admin: Cookies.get('admin') ? JSON.parse(Cookies.get('admin')) : {},
lineBox: null,
timeRange: 'week',
options: [
{label: '最近一周', value: 'week'},
{label: '最近一個月', value: 'month'},
{label: '最近兩個月', value: 'month2'},
{label: '最近三個月', value: 'month3'},
]
}
},
mounted() { // 等頁面元素全部初始化好才開始加載mounth()函數
this.load()
},
methods: {
load() {
if (!this.lineBox) {
this.lineBox = echarts.init(document.getElementById('line')) //初始化echarts容器
}
//從后臺獲取數據
request.get('/borrow/lineCharts/' + this.timeRange).then(res => {
option.xAxis.data = res.data.date
option.series[0].data = res.data.borrow
option.series[1].data = res.data.retur
this.lineBox.setOption(option) //設置容器的屬性值,當數據重新發(fā)生變化時,一定要重新setOption()
})
}
}
}
</script>
<style>
.input {
width: 300px;
}
</style>
1、導入echarts
import * as echarts from 'echarts'
2、原始的option代碼
option = {
title: {
text: 'Stacked Line'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
name: 'Email',
type: 'line',
stack: 'Total',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: 'Union Ads',
type: 'line',
stack: 'Total',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: 'Video Ads',
type: 'line',
stack: 'Total',
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: 'Direct',
type: 'line',
stack: 'Total',
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: 'Search Engine',
type: 'line',
stack: 'Total',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
};
3、修改
目錄:
text: '圖書借還統(tǒng)計
折線:
legend: {
data: ['借書數量', '還書數量']
},
橫坐標:
xAxis: {
type: 'category',
boundaryGap: false,
data: []
},
縱坐標:
yAxis: {
type: 'value'
},
series(與相應折線legend對應)
series: [
{
name: '借書數量',
type: 'line',
stack: 'Total',
smooth: true,
data: []
},
{
name: '還書數量',
type: 'line',
stack: 'Total',
smooth: true,
data: []
}
]
4、定義echart圖標對應的dom元素
html
<el-card>
<div id="line" style="width: 100%; height: 400px"></div>
</el-card>
5、定義echarts容器
js
data() {
return {
lineBox: null,
}
}
6、根據時間范圍加載最新的數據
html
<div style="margin: 20px 0">
<el-select class="input" v-model="timeRange" placeholder="請選擇" @change="load">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
js
mounted() { // 等頁面元素全部初始化好才開始加載mounth()函數
this.load()
},
methods: {
load() {
if (!this.lineBox) {
this.lineBox = echarts.init(document.getElementById('line')) //初始化echarts容器
}
//從后臺獲取數據
request.get('/borrow/lineCharts/' + this.timeRange).then(res => {
option.xAxis.data = res.data.date
option.series[0].data = res.data.borrow
option.series[1].data = res.data.retur
this.lineBox.setOption(option) //設置容器的屬性值,當數據重新發(fā)生變化時,一定要重新setOption()
})
}
}
三、后端(SpringBoot+MyBatis)
1、請求接口2、返回前端的數據
BorrowController.java
//timeRange:week、month、month2、month3
@GetMapping("/lineCharts/{timeRange}")
public Result lineCharts(@PathVariable String timeRange) {
return Result.success(borrowService.getCountByTimeRange(timeRange));
}
IBorrowService.java
Map<String, Object> getCountByTimeRange(String timeRange);
BorrowService.java
導入
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
Java工具類庫Hutool 提供的方法:
DateUtil.rangeToList() 返回從開始時間到結束時間的一個時間范圍 返回類型 List < DateTime >
DateUtil.offsetDay() 計算時間的一個工具方法 返回類型 DateTime
通過自定義函數 datetimeToDateStr() 把 DateTime類型 的 List 轉換成一個 String類型 的 List
原因是前端里 “data”:[ ]、“return”:[ ]、“borrow”:[ ] 數組存儲的是String類型的元素
@Override
public Map<String, Object> getCountByTimeRange(String timeRange) {
Map<String, Object> map = new HashMap<>();
Date today = new Date();
List<DateTime> dateRange;
switch (timeRange) {
case "week":
dateRange = DateUtil.rangeToList(DateUtil.offsetDay(today, -6), today, DateField.DAY_OF_WEEK);
break;
case "month":
dateRange = DateUtil.rangeToList(DateUtil.offsetDay(today, -29), today, DateField.DAY_OF_MONTH);
break;
case "month2":
dateRange = DateUtil.rangeToList(DateUtil.offsetDay(today, -59), today, DateField.DAY_OF_MONTH);
break;
case "month3":
dateRange = DateUtil.rangeToList(DateUtil.offsetDay(today, -89), today, DateField.DAY_OF_MONTH);
break;
default:
dateRange = new ArrayList<>();
}
List<String> dateStrRange = datetimeToDateStr(dateRange);
map.put("date", dateStrRange); // x軸的時間日期數據生成完畢
//1 borrow 2 retrun
//getCountByTimeRange:不會統(tǒng)計數據庫沒有的日期,比如沒有2022.11.4,他不會返回 **data=2022-11-04,count=0**
List<BorrowReturCountPO> borrowCount = borrowMapper.getCountByTimeRange(timeRange, 1);
List<BorrowReturCountPO> returnCount = borrowMapper.getCountByTimeRange(timeRange, 2);
map.put("borrow", countList(borrowCount, dateStrRange));
map.put("retur", countList(returnCount, dateStrRange));
return map;
}
注意:
getCountByTimeRange sql語句:不會統(tǒng)計數據庫沒有的日期,比如沒有2022.11.4,他不會返回 data=2022-11-04,count=0 這個數據,所以又寫countList()函數對在統(tǒng)計數據庫時其中不存在的數據進行處理
datetimeToDateStr()函數
把 DateTime類型 的 List 轉換成一個 String類型 的 List
private List<String> datetimeToDateStr(List<DateTime> dateTimeList) {
List<String> list = CollUtil.newArrayList();
if (CollUtil.isEmpty(dateTimeList)) {
return list;
}
for (DateTime dateTime : dateTimeList) {
String date = DateUtil.formatDate(dateTime);
list.add(date);
}
return list;
}
countList()函數
1、對在統(tǒng)計數據庫時其中不存在的數據進行處理
2、.map(BorrowReturCountPO::getCount) 取出對象里的count值
3、有就取出,沒有就.orElse(0)對沒匹配的數據返回 0文章來源:http://www.zghlxwxcb.cn/news/detail-474899.html
private List<Integer> countList(List<BorrowReturCountPO> countPOList, List<String> dateRange) {
List<Integer> list = CollUtil.newArrayList();
if (CollUtil.isEmpty(countPOList)) {
return list;
}
for (String date : dateRange) {
Integer count = countPOList.stream().filter(countPO -> date.equals(countPO.getDate()))
.map(BorrowReturCountPO::getCount).findFirst().orElse(0);
list.add(count);
}
/* "date": [
"2023-06-01",
"2023-06-02",
"2023-06-03",
"2023-06-04",
"2023-06-05",
"2023-06-06",
"2023-06-07"
],
"retur": [
0,
0,
0,
0,
0,
0,
2
],
"borrow": [
0,
0,
0,
0,
0,
0,
3
]*/
return list;
}
BorrowReturCountPO(自定義類封裝)
@Data
public class BorrowReturCountPO {
private String date;
private Integer count;
}
BorrowMapper.java
List<BorrowReturCountPO> getCountByTimeRange(@Param("timeRange") String timeRange, @Param("type") int type); // 1 borrow 2 return
Borrow.xml
1、DATE_FORMAT(createtime,‘%Y-%m-%d’) :把DateTime類型的數據格式化為 yyyy-MM-dd
2、getCountByTimeRange sql語句:如果是1查 borrow表,2查 return表
3、DATE_SUB(NOW(),INTERVAL 1 WEEK) :數據庫進行時間計算的函數(對當前的時間減去一周)文章來源地址http://www.zghlxwxcb.cn/news/detail-474899.html
<select id="getCountByTimeRange" resultType="com.example.springboot.mapper.po.BorrowReturCountPO">
select count(id) as count, DATE_FORMAT(createtime,'%Y-%m-%d') as date from
<if test="type == 1">
borrow
</if>
<if test="type == 2">
retur
</if>
where
<choose>
<when test="timeRange == 'week'">
createtime >= DATE_SUB(NOW(),INTERVAL 1 WEEK)
</when>
<when test="timeRange == 'month'">
createtime >= DATE_SUB(NOW(),INTERVAL 1 MONTH)
</when>
<when test="timeRange == 'month2'">
createtime >= DATE_SUB(NOW(),INTERVAL 2 MONTH)
</when>
<when test="timeRange == 'month3'">
createtime >= DATE_SUB(NOW(),INTERVAL 3 MONTH)
</when>
<otherwise>
createtime > now()
</otherwise>
</choose>
group by date
</select>
到了這里,關于項目中的Echarts圖表統(tǒng)計的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!