企业网站建设方案应该怎么做,上海建设摩托车,安安互联怎么上传网站,网站中的分享怎么做数据可视化插件echarts【前端】 前言版权开源推荐数据可视化插件echarts一、如何使用1.1 下载1.2 找到js文件1.3 入门使用1.4 我的使用 二、前后端交互#xff1a;入门demo2.1 前端htmljs 2.2 后端entitycontrollerservicemapper 三、前后端交互#xff1a;动态数据3.1 前端j… 数据可视化插件echarts【前端】 前言版权开源推荐数据可视化插件echarts一、如何使用1.1 下载1.2 找到js文件1.3 入门使用1.4 我的使用 二、前后端交互入门demo2.1 前端htmljs 2.2 后端entitycontrollerservicemapper 三、前后端交互动态数据3.1 前端js 3.2 后端service 四、前后端交互动态数据4.1 前端js 4.2 后端ChineseName注解EldDataDataService 五、测试扩展性5.0 开发说明5.1 测试结果5.2 Eld多加一个属性5.3 加入测试数据 六、注解优化6.0 开发说明6.1 测试结果6.2 前端6.2 后端ChineseNameEldDataDataService 七、实际项目开发EldDataConstant测试数据 最后 前言
2024-4-12 16:08:09
以下内容源自《【前端】》 仅供学习交流使用
版权
禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https://jsss-1.blog.csdn.net 禁止其他平台发布时删除以上此话
开源
日星月云 / echarts数据可视化
v1二、入门demo v2三、动态数据 v3四、动态数据 v4六、注解优化 v5七、项目开发
推荐
echarts入门教程超级详细带案例
数据可视化插件echarts
一、如何使用
1.1 下载
1从 npm 获取 npm install echarts --save 2从 CDN 获取 3从 GitHub 获取
1.2 找到js文件 在node_modules\echarts\dist中找到 echart.js或echarts.min,js 1.3 入门使用
!DOCTYPE html
htmlheadmeta charsetutf-8title/title!-- 01 导入js --script srcjs/echarts.js/script!-- 03 设置容器的样式 --style#container{width: 800px;height: 600px;}/style/headbody!-- 02 创建个容器 --div idcontainer/div/bodyscript//04 实例化echarts// 4.1 创建一个实例var echart echarts.init(document.getElementById(container))// 4.2 定义配置项var option {// 图表的标题title:{text:我的第一个图表},// 图表的提示tooltip:{},// 图例legend:{data:[睡眠时长]},// x轴线xAxis:{data:[周一,周二,周三,周四,周五,周六,周日]},// y轴线yAxis:{},// 设置数据series:[{// 数据名称name:睡眠时长,// 类型为柱状图type:bar,// 数据datadata:[8,10,4,5,9,4,8]}]}// 4.3 更新配置echart.setOption(option);// chart图表set设置 Option选项 data数据 type类型 bar条柱状条series系列数据 Axis轴线 xAxis水平轴线// legend传奇图例 tooltip 提示 init初始化 document文档/script/html
1.4 我的使用
下面的代码根据此代码修改
https://www.isqqw.com/?tline !DOCTYPE html
htmlheadmeta charsetutf-8title/title!-- 01 导入js --script srcjs/echarts.js/script!-- 03 设置容器的样式 --style#container{width: 800px;height: 600px;}/style/headbody!-- 02 创建个容器 --div idcontainer/div/bodyscript//实例化echarts// 1 创建一个实例var echart echarts.init(document.getElementById(container));let data1 [175, 160, 153, 121, 156]let data2 [200, 140, 205, 162, 175]let data3 []let data4 [13:00, 14:00, 15:00, 16:00, 17:00]data1.forEach((item1,index){if(item1data2[index]){data3.push({yAxis: item1, //标注的Y轴位置xAxis: data4[index], //标注的X轴位置value: item1 //标注的value值})}else{data3.push({yAxis: data2[index], //标注的Y轴位置xAxis: data4[index], //标注的X轴位置value: data2[index] //标注的value值})}})// 2 定义配置项var option {backgroundColor: white,grid: {top: 20%,left: 5%,right: 5%,bottom: 8%,containLabel: true},tooltip: {trigger: axis,borderWidth: 1,axisPointer: {type: shadow},extraCssText: z-index:2},legend: [{top: top,left: center,orient: horizontal,data: [进水量, 出水量],itemWidth: 15,itemHeight: 10,itemGap: 15,borderRadius: 4,textStyle: {color: #000,fontFamily: Alibaba PuHuiTi,fontSize: 14,fontWeight: 400}}],xAxis: {type: category,data: data4,axisLine: {show: false},axisTick: {show: false},axisLabel: {show: true,textStyle: {color: #393939 //X轴文字颜色}}},yAxis: [{type: value,name: ,nameTextStyle: {color: #000,fontFamily: Alibaba PuHuiTi,fontSize: 14,fontWeight: 600// padding: [0, 0, 0, 40], // 四个数字分别为上右下左与原位置距离},nameGap: 30, // 表现为上下位置axisLine: {show: true,lineStyle: {color: #eeeeee}},axisTick: {show: false},axisLabel: {color: #393939,fontSize: 14},splitLine: {show: true,lineStyle: {color: #eeeeee}}}],series: [{name: 进水量,type: line,showAllSymbol: true, //显示所有图形。//标记的图形为实心圆symbolSize: 8, //标记的大小itemStyle: {//折线拐点标志的样式color: white,borderWidth: 2,borderColor: #5470c6,normal: {color: #5470c6//拐点颜色}},lineStyle: {color: #5470c6},markPoint:{data: data3},data: data1},{name: 出水量,type: line,showAllSymbol: true, //显示所有图形。symbolSize: 8, //标记的大小itemStyle: {//折线拐点标志的样式color: white,borderWidth: 2,borderColor: #91cc75,normal: {color: #91cc75//拐点颜色}},lineStyle: {color: #91cc75},data: data2}]}// 3 更新配置echart.setOption(option);/script/html
二、前后端交互入门demo
2.1 前端
html div classdata-container/divjs
$(document).ready(function () {list();});function list() {$.ajax({type: GET,url: SERVER_PATH /data/list,xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}init(result.data);}});
}function init(dataLists) {//实例化echarts// 1 创建一个实例var echart echarts.init(document.querySelector(.data-container));//进水量let data1 dataLists.inWaterList;//出水量let data2 dataLists.outWaterList;//标注let data3 []//横轴时间let data4 dataLists.dateList;data1.forEach((item1, index) {if (item1 data2[index]) {data3.push({yAxis: item1, //标注的Y轴位置xAxis: data4[index], //标注的X轴位置value: item1 //标注的value值})} else {data3.push({yAxis: data2[index], //标注的Y轴位置xAxis: data4[index], //标注的X轴位置value: data2[index] //标注的value值})}})// 2 定义配置项var option {backgroundColor: white,grid: {top: 20%,left: 5%,right: 5%,bottom: 8%,containLabel: true},tooltip: {trigger: axis,borderWidth: 1,axisPointer: {type: shadow},extraCssText: z-index:2},legend: [{top: top,left: center,orient: horizontal,data: [进水量, 出水量],itemWidth: 15,itemHeight: 10,itemGap: 15,borderRadius: 4,textStyle: {color: #000,fontFamily: Alibaba PuHuiTi,fontSize: 14,fontWeight: 400}}],xAxis: {type: category,data: data4,axisLine: {show: false},axisTick: {show: false},axisLabel: {show: true,textStyle: {color: #393939 //X轴文字颜色}}},yAxis: [{type: value,name: ,nameTextStyle: {color: #000,fontFamily: Alibaba PuHuiTi,fontSize: 14,fontWeight: 600// padding: [0, 0, 0, 40], // 四个数字分别为上右下左与原位置距离},nameGap: 30, // 表现为上下位置axisLine: {show: true,lineStyle: {color: #eeeeee}},axisTick: {show: false},axisLabel: {color: #393939,fontSize: 14},splitLine: {show: true,lineStyle: {color: #eeeeee}}}],series: [{name: 进水量,type: line,showAllSymbol: true, //显示所有图形。//标记的图形为实心圆symbolSize: 8, //标记的大小itemStyle: {//折线拐点标志的样式color: white,borderWidth: 2,borderColor: #5470c6,normal: {color: #5470c6//拐点颜色}},lineStyle: {color: #5470c6},markPoint: {data: data3},data: data1},{name: 出水量,type: line,showAllSymbol: true, //显示所有图形。symbolSize: 8, //标记的大小itemStyle: {//折线拐点标志的样式color: white,borderWidth: 2,borderColor: #91cc75,normal: {color: #91cc75//拐点颜色}},lineStyle: {color: #91cc75},data: data2}]}// 3 更新配置echart.setOption(option);}2.2 后端
entity
lombok.Data
NoArgsConstructor
AllArgsConstructor
public class Data {Integer InWater;Integer OutWater;Date date;
}
controller GetMapping(/list)public ResponseModel getDataList(){HashMapString, Object search dataService.searchMap();return new ResponseModel(search);}service public HashMapString,Object searchMap(){HashMapString,Object mapnew HashMap();ListData dataList search();ListInteger inWaterList new ArrayList();ListInteger outWaterList new ArrayList();ListDate dateList new ArrayList();for(Data data : dataList){inWaterList.add(data.getInWater());outWaterList.add(data.getOutWater());dateList.add(data.getDate());}map.put(inWaterList,inWaterList);map.put(outWaterList,outWaterList);map.put(dateList,dateList);return map;}public ListData search() {return dataDao.list();}mapper
Select(SELECT * FROM test limit 20)ListData list();三、前后端交互动态数据 3.1 前端
js
$(document).ready(function () {list();});function list() {$.ajax({type: GET,url: SERVER_PATH /data/list,data: {userId: 1},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}init(result.data);}});
}function init(dataLists) {//实例化echarts// 1 创建一个实例var echart echarts.init(document.querySelector(.data-container));//进水量let data1 dataLists.rate1;//出水量let data2 dataLists.rate2;//横轴时间let data4 dataLists.date;//标注数据let data3 [];//只需修改以下对应let names[rate1,rate2];let datas[data1,data2];let colors[#5470c6,#91cc75]//动态生成下面的数据for(let i0;inames.length;i){data3.push([]);}datas.forEach((data, index) {data.forEach((item, i) {data3[index].push({yAxis: item, // 标注的Y轴位置xAxis: data4[i], // 标注的X轴位置value: item // 标注的value值});});});let seriesData[];for (var i 0; i datas.length; i) {seriesData.push({name: names[i],type: line,showAllSymbol: true, //显示所有图形。//标记的图形为实心圆symbolSize: 8, //标记的大小itemStyle: {//折线拐点标志的样式color: white,borderWidth: 2,borderColor: colors[i],normal: {color: colors[i]//拐点颜色}},lineStyle:{color: colors[i]},markPoint: {data: data3[i]},data: datas[i]});}// 2 定义配置项var option {backgroundColor: white,grid: {top: 20%,left: 5%,right: 5%,bottom: 8%,containLabel: true},tooltip: {trigger: axis,borderWidth: 1,axisPointer: {type: shadow},extraCssText: z-index:2,// formatter: function(params) {// var tooltipContent params[0].name br/; // 显示日期// params.forEach(function(param) {// tooltipContent param.seriesName : param.value br;// });// return tooltipContent;// }},legend: [{top: top,left: center,orient: horizontal,data: names,itemWidth: 15,itemHeight: 10,itemGap: 15,borderRadius: 4,textStyle: {color: #000,fontFamily: Alibaba PuHuiTi,fontSize: 14,fontWeight: 400}}],xAxis: {type: category,data: data4,axisLine: {show: false},axisTick: {show: false},axisLabel: {show: true,textStyle: {color: #393939 //X轴文字颜色}}},yAxis: [{type: value,name: ,nameTextStyle: {color: #000,fontFamily: Alibaba PuHuiTi,fontSize: 14,fontWeight: 600// padding: [0, 0, 0, 40], // 四个数字分别为上右下左与原位置距离},nameGap: 30, // 表现为上下位置axisLine: {show: true,lineStyle: {color: #eeeeee}},axisTick: {show: false},axisLabel: {color: #393939,fontSize: 14},splitLine: {show: true,lineStyle: {color: #eeeeee}}}],series: seriesData}// 3 更新配置echart.setOption(option);}
3.2 后端
service //返回数据链表public HashMapString,ArrayList searchMap(Integer userId){HashMapString,ArrayList mapnew HashMap();ListEldData dataList search(userId);ListString fieldNames new ArrayList();Class? dataClass EldData.class;// 获取 OldData 类的所有属性名Field[] fields dataClass.getDeclaredFields();for (Field field : fields) {fieldNames.add(field.getName());map.put(field.getName(),new ArrayList());}for (EldData data : dataList) {for (String fieldName : fieldNames) {ArrayListObject rowData map.get(fieldName);try {Field field dataClass.getDeclaredField(fieldName);field.setAccessible(true);rowData.add(field.get(data));} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}map.put(fieldName,rowData);}}return map;}//搜索数据public ListEldData search(Integer userId) {String key ELD_DATA userId;Set set redisTemplate.opsForZSet().reverseRange(key, 0, 19);// 获取分数最高的20个数据return set !null?new ArrayList(set):new ArrayList();}四、前后端交互动态数据
后端name根据注解ChineseName 前端颜色是随机生成的 hashMap导致没有顺序换成LinkedHashMap
在seachMap()中重新定义
// HashMapString,ArrayList mapnew HashMap();HashMapString,ArrayList mapnew LinkedHashMap();发现它是时间顺序是反这的 修改一下 //搜索数据
// public ListEldData search(Integer userId) {
// String key ELD_DATA userId;
// Set set redisTemplate.opsForZSet().reverseRange(key, 0, limit-1);// 获取分数最高的20个数据
//
// return set !null?new ArrayList(set):new ArrayList();
//
// }//搜索数据public ListEldData search(Integer userId) {String key ELD_DATA userId;Set set redisTemplate.opsForZSet().reverseRange(key, 0, limit-1);// 获取分数最高的limit个数据if(setnull){return new ArrayList();}ArrayListEldData resList new ArrayList(set);Collections.reverse(resList);return resList;}4.1 前端
js
变成真实登录的用户 而不是固定userId是1
$(document).ready(function () {list();});function list() {var idsessionStorage.getItem(id);$.ajax({type: GET,url: SERVER_PATH /data/list,data: {// userId: 1userId: id},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}init(result.data);}});
}function init(dataLists) {//实例化echarts// 1 创建一个实例var echart echarts.init(document.querySelector(.data-container));//横轴时间let datax dataLists.date;//标注数据let data0 [];//只需修改不需要展示的namevar noNeed[id,date];//原始数据的所有namelet keysObject.keys(dataLists);//只需添加足够的颜色// let colors[// #5470c6,#91cc75// ]//动态生成下面的数据不需要修改//随机生成相同数量的颜色let colorsgenerateRandomColors(keys.length);//名称和对应的数据let names []let datas [];keys.forEach((name) {if(!noNeed.includes(name)){names.push(name);datas.push(dataLists[name]);}});for(let i0;inames.length;i){data0.push([]);}datas.forEach((data, index) {data.forEach((item, i) {data0[index].push({yAxis: item, // 标注的Y轴位置xAxis: datax[i], // 标注的X轴位置value: item // 标注的value值});});});let seriesData[];for (var i 0; i datas.length; i) {seriesData.push({name: names[i],type: line,showAllSymbol: true, //显示所有图形。//标记的图形为实心圆symbolSize: 8, //标记的大小itemStyle: {//折线拐点标志的样式color: white,borderWidth: 2,borderColor: colors[i],normal: {color: colors[i]//拐点颜色}},lineStyle:{color: colors[i]},markPoint: {data: data0[i]},data: datas[i]});}// 2 定义配置项var option {backgroundColor: white,grid: {top: 20%,left: 5%,right: 5%,bottom: 8%,containLabel: true},tooltip: {trigger: axis,borderWidth: 1,axisPointer: {type: shadow},extraCssText: z-index:2,// formatter: function(params) {// var tooltipContent params[0].name br/; // 显示日期// params.forEach(function(param) {// tooltipContent param.seriesName : param.value br;// });// return tooltipContent;// }},legend: [{top: top,left: center,orient: horizontal,data: names,itemWidth: 15,itemHeight: 10,itemGap: 15,borderRadius: 4,textStyle: {color: #000,fontFamily: Alibaba PuHuiTi,fontSize: 14,fontWeight: 400}}],xAxis: {type: category,data: datax,axisLine: {show: false},axisTick: {show: false},axisLabel: {show: true,textStyle: {color: #393939 //X轴文字颜色}}},yAxis: [{type: value,name: ,nameTextStyle: {color: #000,fontFamily: Alibaba PuHuiTi,fontSize: 14,fontWeight: 600// padding: [0, 0, 0, 40], // 四个数字分别为上右下左与原位置距离},nameGap: 30, // 表现为上下位置axisLine: {show: true,lineStyle: {color: #eeeeee}},axisTick: {show: false},axisLabel: {color: #393939,fontSize: 14},splitLine: {show: true,lineStyle: {color: #eeeeee}}}],series: seriesData}// 3 更新配置echart.setOption(option);}function generateRandomColors(num) {let randomColors [];let characters 0123456789ABCDEF;for (let i 0; i num; i) {let color #;for (let j 0; j 6; j) {color characters[Math.floor(Math.random() * 16)];}randomColors.push(color);}return randomColors;
}4.2 后端
ChineseName注解
package com.jsss.echarts.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;Retention(RetentionPolicy.RUNTIME)
Target(ElementType.FIELD)
public interface ChineseName {String value();
}EldData
package com.jsss.echarts.entity;import com.jsss.echarts.annotation.ChineseName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;import java.sql.Date;
import java.util.Objects;Data
NoArgsConstructor
AllArgsConstructorpublic class EldData {ChineseName(id)String id;ChineseName(率1)Integer rate1;ChineseName(率2)Integer rate2;ChineseName(date)Date date;Overridepublic boolean equals(Object o) {if (this o) return true;if (o null || getClass() ! o.getClass()) return false;EldData eldData (EldData) o;return Objects.equals(id, eldData.id) Objects.equals(date, eldData.date);}Overridepublic int hashCode() {return Objects.hash(id, date);}Overridepublic String toString() {return EldData{ rate1 rate1 , rate2 rate2 , date date };}}
DataService
package com.jsss.echarts.service;import com.jsss.echarts.annotation.ChineseName;
import com.jsss.echarts.entity.EldData;
import com.jsss.utils.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;import java.lang.reflect.Field;
import java.util.*;Service
public class DataService implements Constant {AutowiredRedisTemplate redisTemplate;//返回数据链表public HashMapString,ArrayList searchMap(Integer userId){
// HashMapString,ArrayList mapnew HashMap();HashMapString,ArrayList mapnew LinkedHashMap();ListEldData dataList search(userId);ListString fieldNames new ArrayList();Class? dataClass EldData.class;// 获取 OldData 类的所有属性名Field[] fields dataClass.getDeclaredFields();for (Field field : fields) {fieldNames.add(field.getName());
// map.put(field.getName(),new ArrayList());map.put(field.getAnnotation(ChineseName.class).value(), new ArrayList());}for (EldData data : dataList) {for (String fieldName : fieldNames) {
// ArrayListObject rowData map.get(fieldName);try {Field field dataClass.getDeclaredField(fieldName);ArrayListObject rowData map.get(field.getAnnotation(ChineseName.class).value());field.setAccessible(true);rowData.add(field.get(data));map.put(field.getAnnotation(ChineseName.class).value(),rowData);} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}
// map.put(fieldName, rowData);}}return map;}//搜索数据
// public ListEldData search(Integer userId) {
// String key ELD_DATA userId;
// Set set redisTemplate.opsForZSet().reverseRange(key, 0, 19);// 获取分数最高的20个数据
//
// return set !null?new ArrayList(set):new ArrayList();
//
// }//搜索数据public ListEldData search(Integer userId) {String key ELD_DATA userId;Set set redisTemplate.opsForZSet().reverseRange(key, 0, limit-1);// 获取分数最高的limit个数据if(setnull){return new ArrayList();}ArrayListEldData resList new ArrayList(set);Collections.reverse(resList);return resList;}// 将数据存储到有序集合中分数为日期的时间戳public boolean addData(Integer userId, EldData data) {String key ELD_DATA userId;return redisTemplate.opsForZSet().add(key, data,data.getDate().getTime());}// 更新数据先删除数据后增加新数据public boolean updateData(Integer userId,EldData oldData,EldData newData) {long resremoveData(userId,oldData);if (res0){//没有旧数据就修改失败return false;}return addData(userId, newData);}// 删除指定的数据public long removeData(Integer userId, EldData data) {String key ELD_DATA userId;return redisTemplate.opsForZSet().remove(key, data);}}
五、测试扩展性
5.0 开发说明
后端
只需要更改EldData的属性就好了 并且添加对应注解
如果有一个属性没有注解会报错由于searchMap()中默认是所有属性都有此注解。
如果有属性不需要前端展示可以在前端noNeed中添加 也可以后端修改注解增加need属性增加代码逻辑 另外注解也可增加x轴属性 ChineseName(id)String id;ChineseName(率1)Integer rate1;ChineseName(率2)Integer rate2;ChineseName(率3)Integer rate3;ChineseName(date)Date date;
前端
修改横轴datax 怎么标注数据data0 以及不需要展示的name链表noNeed //横轴时间let datax dataLists.date;//标注数据let data0 [];//只需修改不需要展示的namevar noNeed[id,date];5.1 测试结果 5.2 Eld多加一个属性
package com.jsss.echarts.entity;import com.jsss.echarts.annotation.ChineseName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.sql.Date;
import java.util.Objects;Data
NoArgsConstructor
AllArgsConstructorpublic class EldData {ChineseName(id)String id;ChineseName(率1)Integer rate1;ChineseName(率2)Integer rate2;ChineseName(率3)Integer rate3;ChineseName(date)Date date;Overridepublic boolean equals(Object o) {if (this o) return true;if (o null || getClass() ! o.getClass()) return false;EldData eldData (EldData) o;return Objects.equals(id, eldData.id) Objects.equals(date, eldData.date);}Overridepublic int hashCode() {return Objects.hash(id, date);}}
5.3 加入测试数据
AutowiredRedisTemplate redisTemplate;AutowiredDataService dataService;Integer userId1;//清空数据Testpublic void restore() {String key ELD_DATA userId;redisTemplate.delete(key);testSearchMap();}Testpublic void testSearchMap(){HashMapString, ArrayList map dataService.searchMap(userId);System.out.println(map);}Testpublic void testValidAdd(){EldData eldDatanew EldData(Toolbox.getRandomString(),175,160,111,new Date(2024-1900,4-1,8));dataService.addData(userId,eldData);eldDatanew EldData(Toolbox.getRandomString(),160,140,121,new Date(2024-1900,4-1,9));dataService.addData(userId,eldData);eldDatanew EldData(Toolbox.getRandomString(),153,205,131,new Date(2024-1900,4-1,10));dataService.addData(userId,eldData);eldDatanew EldData(Toolbox.getRandomString(),121,162,141,new Date(2024-1900,4-1,11));dataService.addData(userId,eldData);eldDatanew EldData(Toolbox.getRandomString(),156,175,151,new Date(2024-1900,4-1,12));dataService.addData(userId,eldData);testSearchMap();}运行前端登录adminadmin用户
在加入测试数据
userId2
登录jsss123456也是可以的 2024-4-13 16:26:41
六、注解优化
6.0 开发说明
后端 在EldData中
如果某个属性需要前端展示就添加ChineseName注解 如果某个属性是横轴数据其value值就是datax
前端 不需要修改任何代码
public class EldData {ChineseName(率1)Integer rate1;ChineseName(率2)Integer rate2;//没有注解就不展示Integer rate3;//横轴的注解的值是dataxChineseName(datax)Date date;}6.1 测试结果
rate3没有注解 rate3添加注解
6.2 前端
对应的改一下这两个就行了 //横轴数据let datax dataLists.datax;//不需要展示的namevar noNeed[datax];6.2 后端
ChineseName
/*** 如果某个属性需要展示就添加ChineseName注解 br* 如果某个属性是横轴数据其value值是datax br*/
Retention(RetentionPolicy.RUNTIME)
Target(ElementType.FIELD)
public interface ChineseName {//中文nameString value();}EldData
redis判断是根据序列化的结果判断是否相同 equals和hashCode不起作用
package com.jsss.echarts.entity;import com.jsss.echarts.annotation.ChineseName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;import java.sql.Date;Data
NoArgsConstructor
AllArgsConstructor
ToString
public class EldData {ChineseName(率1)Integer rate1;ChineseName(率2)Integer rate2;//没有注解就不展示Integer rate3;//横轴的注解的值是dataxChineseName(datax)Date date;}
DataService //返回数据链表public HashMapString,ArrayList searchMap(Integer userId){HashMapString,ArrayList mapnew LinkedHashMap();ListEldData dataList search(userId);ListString fieldNames new ArrayList();Class? dataClass EldData.class;// 获取 OldData 类的所有被ChineseName注解的属性名Field[] fields dataClass.getDeclaredFields();for (Field field : fields) {//添加是否有注解的判断ChineseName chineseNameAnnotation field.getAnnotation(ChineseName.class);if (chineseNameAnnotation!null){fieldNames.add(field.getName());map.put(field.getAnnotation(ChineseName.class).value(), new ArrayList());}}for (EldData data : dataList) {for (String fieldName : fieldNames) {try {Field field dataClass.getDeclaredField(fieldName);field.setAccessible(true);ArrayListObject rowData map.get(field.getAnnotation(ChineseName.class).value());rowData.add(field.get(data));map.put(field.getAnnotation(ChineseName.class).value(),rowData);} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}}}return map;}//搜索数据public ListEldData search(Integer userId) {String key ELD_DATA userId;Set set redisTemplate.opsForZSet().reverseRange(key, 0, limit-1);// 获取分数最高的limit个数据if(setnull){return new ArrayList();}ArrayListEldData resList new ArrayList(set);Collections.reverse(resList);return resList;}七、实际项目开发
加入分栏就更好了
EldData
package com.jsss.echarts.entity;import com.jsss.echarts.annotation.ChineseName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;import java.sql.Date;/*** 字段名称 类型 字段说明 备注* p* HT Integer 通用-身高HT 单位:m* WT Integer 通用-体重WT 单位:kg* BMI Double 通用-身高体重指数BMI 正常范围 18.5~23.9超重24.0~27.9肥胖≥28.0* SBP Integer 血压-收缩压SBP 正常成年人的收缩压范围为90-140毫米汞柱mmHg。* DBP Integer 血压-舒张压DBP 正常成年人的舒张压范围为60-90毫米汞柱mmHg。* Hb Integer 血常规-血红蛋白Hb 正常成年人的正常范围为120-175克/升。* WBC Integer 血常规-白细胞计数WBC 正常成年人的白细胞计数范围为4-10 × 10^9/L。* PLT Integer 血常规-血小板计数PLT 正常成年人的血小板计数范围为100-300 × 10^9/L。* ALT Integer 肝功能-谷丙转氨酶ALT 正常成年人的ALT范围为10-40单位/升。* AST Integer 肝功能-谷草转氨酶AST 正常成年人的AST范围为10-35单位/升。* TBIL Double 肝功能-总胆红素TBIL 正常成年人的总胆红素范围为3.4-17.1毫摩尔/升。* BUN Double 肾功能-血尿素氮BUN 正常成年人的BUN范围为2.5-7.1毫摩尔/升。* Cr Integer 肾功能-血肌酐Cr 正常成年人的血肌酐范围为53-115微摩尔/升。* TC Double 血脂-总胆固醇TC 正常成年人的总胆固醇范围为3.1-5.2毫摩尔/升。* TG Double 血脂-甘油三酯TG 正常成年人的甘油三酯范围为0.4-1.7毫摩尔/升。* LDL_C Double 血脂-低密度脂蛋白胆固醇LDL-C 正常成年人的LDL-C范围为2.6-3.4毫摩尔/升。* FPG Double 血糖-空腹血糖FPG 正常成年人的空腹血糖范围为3.9-6.1毫摩尔/升。* twohPG Double 血糖-餐后2小时血糖2hPG 正常成年人的餐后2小时血糖范围为3.9-7.8毫摩尔/升。*/
Data
NoArgsConstructor
AllArgsConstructor
ToString
public class EldData {ChineseName(通用-身高(米))Integer HT;ChineseName(通用-体重(千克))Integer WT;ChineseName(通用-身高体重指数(千克/米2))Double BMI;ChineseName(血压-收缩压(毫米汞柱))Integer SBP;ChineseName(血压-舒张压(毫米汞柱))Integer DBP;ChineseName(血常规-血红蛋白(克/升))Integer Hb;ChineseName(血常规-白细胞计数(10^9/升))Integer WBC;ChineseName(血常规-血小板计数(10^9/升))Integer PLT;ChineseName(肝功能-谷丙转氨酶(单位/升))Integer ALT;ChineseName(肝功能-谷草转氨酶(单位/升))Integer AST;ChineseName(肝功能-总胆红素(毫摩尔/升))Double TBIL;ChineseName(肾功能-血尿素氮(毫摩尔/升))Double BUN;ChineseName(肾功能-血肌酐(微摩尔/升))Integer Cr;ChineseName(血脂-总胆固醇(毫摩尔/升))Double TC;ChineseName(血脂-甘油三酯(毫摩尔/升))Double TG;ChineseName(血脂-低密度脂蛋白胆固醇(毫摩尔/升))Double LDL_C;ChineseName(血糖-空腹血糖(毫摩尔/升))Double FPG;ChineseName(血糖-餐后2小时血糖(毫摩尔/升))Double twohPG;//横轴的注解的值是dataxChineseName(datax)Date date;}
Constant
package com.jsss.utils;import com.jsss.echarts.entity.EldData;import java.sql.Date;public interface Constant {/*** redis键老人的体检数据*/String ELD_DATA eld_data:;EldData MIN_DATAnew EldData(Integer.MIN_VALUE,Integer.MIN_VALUE,18.5,90,60,120,4,100,10,10,3.4,2.5,53,3.1,0.4,2.6,63.9,7.8,new Date(System.currentTimeMillis()));EldData MAX_DATAnew EldData(Integer.MAX_VALUE,Integer.MAX_VALUE,23.9,140,90,175,10,300,40,35,17.1,7.1,115,5.2,1.7,2.4,6.1,7.8,new Date(System.currentTimeMillis()));}
测试数据
package com.jsss.echarts;import com.jsss.echarts.entity.EldData;
import com.jsss.echarts.service.DataService;
import com.jsss.utils.Constant;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;SpringBootTest
public class EchartsTest implements Constant {AutowiredRedisTemplate redisTemplate;AutowiredDataService dataService;Integer userId1;Date datenew Date(2024-1900,4-1,14);Testpublic void test(){System.out.println(date);}//清空数据Testpublic void restore() {String key ELD_DATA userId;redisTemplate.delete(key);testSearchMap();}Testpublic void testSearchMap(){HashMapString, ArrayList map dataService.searchMap(userId);System.out.println(map);}Testpublic void testValidAdd(){EldData eldDatarandomData();eldData.setDate(new Date(2024-1900,4-1,8));dataService.addData(userId,eldData);eldDatarandomData();eldData.setDate(new Date(2024-1900,4-1,9));dataService.addData(userId,eldData);eldDatarandomData();eldData.setDate(new Date(2024-1900,4-1,10));dataService.addData(userId,eldData);eldDatarandomData();eldData.setDate(new Date(2024-1900,4-1,11));dataService.addData(userId,eldData);eldDatarandomData();eldData.setDate(new Date(2024-1900,4-1,12));dataService.addData(userId,eldData);testSearchMap();}EldData minDataMIN_DATA;EldData maxDataMAX_DATA;public EldData randomData(){EldData datanew EldData(randomInt(160,190), randomInt(45,80), randomDouble(minData.getBMI(),maxData.getBMI()),randomInt(minData.getSBP(),maxData.getSBP()),randomInt(minData.getDBP(),maxData.getDBP()),randomInt(minData.getHb(),maxData.getHb()),randomInt(minData.getWBC(),maxData.getWBC()),randomInt(minData.getPLT(),maxData.getPLT()),randomInt(minData.getALT(),maxData.getALT()),randomInt(minData.getAST(),maxData.getAST()),randomDouble(minData.getTBIL(),maxData.getTBIL()),randomDouble(minData.getBUN(),maxData.getBUN()),randomInt(minData.getCr(),maxData.getCr()),randomDouble(minData.getTC(),maxData.getTC()),randomDouble(minData.getTG(),maxData.getTG()),randomDouble(minData.getLDL_C(),maxData.getLDL_C()),randomDouble(minData.getFPG(),maxData.getFPG()),randomDouble(minData.getTwohPG(),maxData.getTwohPG()),new Date(System.currentTimeMillis()));return data;}public Integer randomInt(int min,int max){Random random new Random();return random.nextInt(max - min 1) min; // 生成 min 到 max 范围内的随机 int 数}public Double randomDouble(double min,double max){Random random new Random();return min (max - min) * random.nextDouble(); // 生成 min 到 max 范围内的随机 double 值}}
最后
2024-4-13 18:49:18
迎着日光月光星光直面风霜雨霜雪霜。