0


数据可视化插件echarts【前端】

数据可视化插件echarts【前端】

前言

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文件

在这里插入图片描述

  1. node_modules\echarts\dist

中找到

  1. echart.js

  1. echarts.min,js

在这里插入图片描述

1.3 入门使用

  1. <!DOCTYPEhtml><html><head><metacharset="utf-8"><title></title><!-- 01 导入js --><scriptsrc="js/echarts.js"></script><!-- 03 设置容器的样式 --><style>#container{width: 800px;height: 600px;}</style></head><body><!-- 02 创建个容器 --><divid="container"></div></body><script>//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 更新配置
  2. echart.setOption(option);// chart图表,set设置 Option选项 data数据 type类型 bar条(柱状条),series系列(数据) Axis轴线 xAxis水平轴线// legend传奇(图例) tooltip 提示 init初始化 document文档</script></html>

1.4 我的使用

下面的代码根据此代码修改

https://www.isqqw.com/?t=line

在这里插入图片描述

  1. <!DOCTYPEhtml><html><head><metacharset="utf-8"><title></title><!-- 01 导入js --><scriptsrc="js/echarts.js"></script><!-- 03 设置容器的样式 --><style>#container{width: 800px;height: 600px;}</style></head><body><!-- 02 创建个容器 --><divid="container"></div></body><script>//实例化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']
  2. data1.forEach((item1,index)=>{if(item1>data2[index]){
  3. data3.push({yAxis: item1,//标注的Y轴位置xAxis: data4[index],//标注的X轴位置value: item1 //标注的value值})}else{
  4. 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
  5. },data: data1
  6. },{name:'出水量',type:'line',showAllSymbol:true,//显示所有图形。symbolSize:8,//标记的大小itemStyle:{//折线拐点标志的样式color:'white',borderWidth:'2',borderColor:'#91cc75',normal:{color:'#91cc75'//拐点颜色}},lineStyle:{color:'#91cc75'},data: data2
  7. }]}// 3 更新配置
  8. echart.setOption(option);</script></html>

二、前后端交互:入门demo

2.1 前端

html
  1. <div class="data-container"></div>
js
  1. $(document).ready(function(){list();});functionlist(){
  2. $.ajax({type:"GET",url:SERVER_PATH+"/data/list",xhrFields:{withCredentials:true},success:function(result){if(result.status){alertBox(result.data.message);returnfalse;}init(result.data);}});}functioninit(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;
  3. data1.forEach((item1, index)=>{if(item1 > data2[index]){
  4. data3.push({yAxis: item1,//标注的Y轴位置xAxis: data4[index],//标注的X轴位置value: item1 //标注的value值})}else{
  5. 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
  6. },data: data1
  7. },{name:'出水量',type:'line',showAllSymbol:true,//显示所有图形。symbolSize:8,//标记的大小itemStyle:{//折线拐点标志的样式color:'white',borderWidth:'2',borderColor:'#91cc75',normal:{color:'#91cc75'//拐点颜色}},lineStyle:{color:'#91cc75'},data: data2
  8. }]}// 3 更新配置
  9. echart.setOption(option);}

2.2 后端

entity
  1. @lombok.Data@NoArgsConstructor@AllArgsConstructorpublicclassData{IntegerInWater;IntegerOutWater;Date date;}
controller
  1. @GetMapping("/list")publicResponseModelgetDataList(){HashMap<String,Object> search = dataService.searchMap();returnnewResponseModel(search);}
service
  1. publicHashMap<String,Object>searchMap(){HashMap<String,Object> map=newHashMap<>();List<Data> dataList =search();List<Integer> inWaterList =newArrayList<>();List<Integer> outWaterList =newArrayList<>();List<Date> dateList =newArrayList<>();for(Data data : dataList){
  2. inWaterList.add(data.getInWater());
  3. outWaterList.add(data.getOutWater());
  4. dateList.add(data.getDate());}
  5. map.put("inWaterList",inWaterList);
  6. map.put("outWaterList",outWaterList);
  7. map.put("dateList",dateList);return map;}publicList<Data>search(){return dataDao.list();}
mapper
  1. @Select("SELECT * FROM test limit 20")List<Data>list();

三、前后端交互:动态数据

在这里插入图片描述

3.1 前端

js
  1. $(document).ready(function (){list();});
  2. function list(){
  3. $.ajax({
  4. type:"GET",
  5. url:SERVER_PATH+"/data/list",
  6. data:{
  7. userId:1},
  8. xhrFields:{withCredentials:true},
  9. success: function (result){if(result.status){alertBox(result.data.message);returnfalse;}init(result.data);}});}
  10. function init(dataLists){//实例化echarts// 1 创建一个实例var echart = echarts.init(document.querySelector(".data-container"));//进水量
  11. let data1 = dataLists.rate1;//出水量
  12. let data2 = dataLists.rate2;//横轴时间
  13. let data4 = dataLists.date;//标注数据
  14. let data3 =[];//只需修改以下对应
  15. let names=["rate1","rate2"];
  16. let datas=[data1,data2];
  17. let colors=[
  18. '#5470c6','#91cc75'
  19. ]//动态生成下面的数据for(let i=0;i<names.length;i++){
  20. data3.push([]);}
  21. datas.forEach((data, index)=>{
  22. data.forEach((item, i)=>{
  23. data3[index].push({
  24. yAxis: item,// 标注的Y轴位置
  25. xAxis: data4[i],// 标注的X轴位置
  26. value: item // 标注的value值});});});
  27. let seriesData=[];for(var i =0; i < datas.length; i++){
  28. seriesData.push({
  29. name: names[i],
  30. type:'line',
  31. showAllSymbol:true,//显示所有图形。//标记的图形为实心圆
  32. symbolSize:8,//标记的大小
  33. itemStyle:{//折线拐点标志的样式
  34. color:'white',
  35. borderWidth:'2',
  36. borderColor: colors[i],
  37. normal:{
  38. color: colors[i]//拐点颜色}},
  39. lineStyle:{
  40. color: colors[i]},
  41. markPoint:{
  42. data: data3[i]},
  43. data: datas[i]});}// 2 定义配置项var option ={
  44. backgroundColor:'white',
  45. grid:{
  46. top:'20%',
  47. left:'5%',
  48. right:'5%',
  49. bottom:'8%',
  50. containLabel:true},
  51. tooltip:{
  52. trigger:'axis',
  53. borderWidth:1,
  54. axisPointer:{
  55. type:'shadow'},
  56. 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;// }},
  57. legend:[{
  58. top:'top',
  59. left:'center',
  60. orient: 'horizontal',
  61. data: names,
  62. itemWidth:15,
  63. itemHeight:10,
  64. itemGap:15,
  65. borderRadius:4,
  66. textStyle:{
  67. color:'#000',
  68. fontFamily: 'AlibabaPuHuiTi',
  69. fontSize:14,
  70. fontWeight:400}}],
  71. xAxis:{
  72. type: 'category',
  73. data: data4,
  74. axisLine:{
  75. show:false},
  76. axisTick:{
  77. show:false},
  78. axisLabel:{
  79. show:true,
  80. textStyle:{
  81. color: '#393939' //X轴文字颜色}}},
  82. yAxis:[{
  83. type:'value',
  84. name: '',
  85. nameTextStyle:{
  86. color:'#000',
  87. fontFamily: 'AlibabaPuHuiTi',
  88. fontSize:14,
  89. fontWeight:600// padding: [0, 0, 0, 40], // 四个数字分别为上右下左与原位置距离},
  90. nameGap:30,// 表现为上下位置
  91. axisLine:{
  92. show:true,
  93. lineStyle:{
  94. color: '#eeeeee'
  95. }},
  96. axisTick:{
  97. show:false},
  98. axisLabel:{
  99. color: '#393939',
  100. fontSize:14},
  101. splitLine:{
  102. show:true,
  103. lineStyle:{
  104. color: '#eeeeee'
  105. }}}],
  106. series: seriesData
  107. }// 3 更新配置
  108. echart.setOption(option);}

3.2 后端

service
  1. //返回数据链表publicHashMap<String,ArrayList>searchMap(Integer userId){HashMap<String,ArrayList> map=newHashMap<>();List<EldData> dataList =search(userId);List<String> fieldNames =newArrayList<>();Class<?> dataClass =EldData.class;// 获取 OldData 类的所有属性名Field[] fields = dataClass.getDeclaredFields();for(Field field : fields){
  2. fieldNames.add(field.getName());
  3. map.put(field.getName(),newArrayList<>());}for(EldData data : dataList){for(String fieldName : fieldNames){ArrayList<Object> rowData =map.get(fieldName);try{Field field = dataClass.getDeclaredField(fieldName);
  4. field.setAccessible(true);
  5. rowData.add(field.get(data));}catch(NoSuchFieldException|IllegalAccessException e){
  6. e.printStackTrace();}
  7. map.put(fieldName,rowData);}}return map;}//搜索数据publicList<EldData>search(Integer userId){String key=ELD_DATA+userId;Set set = redisTemplate.opsForZSet().reverseRange(key,0,19);// 获取分数最高的20个数据return set !=null?newArrayList<>(set):newArrayList<>();}

四、前后端交互:动态数据

后端name根据注解ChineseName
前端颜色是随机生成的

在这里插入图片描述
hashMap导致没有顺序,换成LinkedHashMap

在seachMap()中,重新定义

  1. // HashMap<String,ArrayList> map=new HashMap<>();HashMap<String,ArrayList> map=newLinkedHashMap<>();

在这里插入图片描述
发现它是时间顺序是反这的
修改一下

  1. //搜索数据// public List<EldData> 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<>();//// }//搜索数据publicList<EldData>search(Integer userId){String key=ELD_DATA+userId;Set set = redisTemplate.opsForZSet().reverseRange(key,0, limit-1);// 获取分数最高的limit个数据if(set==null){returnnewArrayList<>();}ArrayList<EldData> resList =newArrayList<>(set);Collections.reverse(resList);return resList;}

在这里插入图片描述

4.1 前端

js

变成真实登录的用户
而不是固定userId是1

  1. $(document).ready(function(){list();});functionlist(){var id=sessionStorage.getItem("id");
  2. $.ajax({type:"GET",url:SERVER_PATH+"/data/list",data:{// userId: 1userId: id
  3. },xhrFields:{withCredentials:true},success:function(result){if(result.status){alertBox(result.data.message);returnfalse;}init(result.data);}});}functioninit(dataLists){//实例化echarts// 1 创建一个实例var echart = echarts.init(document.querySelector(".data-container"));//横轴时间let datax = dataLists.date;//标注数据let data0 =[];//只需修改不需要展示的namevar noNeed=["id","date"];//原始数据的所有namelet keys=Object.keys(dataLists);//只需添加足够的颜色// let colors=[// '#5470c6','#91cc75'// ]//动态生成下面的数据,不需要修改//随机生成相同数量的颜色let colors=generateRandomColors(keys.length);//名称和对应的数据let names =[]let datas =[];
  4. keys.forEach((name)=>{if(!noNeed.includes(name)){
  5. names.push(name);
  6. datas.push(dataLists[name]);}});for(let i=0;i<names.length;i++){
  7. data0.push([]);}
  8. datas.forEach((data, index)=>{
  9. data.forEach((item, i)=>{
  10. data0[index].push({yAxis: item,// 标注的Y轴位置xAxis: datax[i],// 标注的X轴位置value: item // 标注的value值});});});let seriesData=[];for(var i =0; i < datas.length; i++){
  11. 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
  12. }// 3 更新配置
  13. echart.setOption(option);}functiongenerateRandomColors(num){let randomColors =[];let characters ='0123456789ABCDEF';for(let i =0; i < num; i++){let color ='#';for(let j =0; j <6; j++){
  14. color += characters[Math.floor(Math.random()*16)];}
  15. randomColors.push(color);}return randomColors;}

4.2 后端

ChineseName注解
  1. packagecom.jsss.echarts.annotation;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public@interfaceChineseName{Stringvalue();}
EldData
  1. packagecom.jsss.echarts.entity;importcom.jsss.echarts.annotation.ChineseName;importlombok.AllArgsConstructor;importlombok.Data;importlombok.EqualsAndHashCode;importlombok.NoArgsConstructor;importjava.sql.Date;importjava.util.Objects;@Data@NoArgsConstructor@AllArgsConstructorpublicclassEldData{@ChineseName("id")String id;@ChineseName("率1")Integer rate1;@ChineseName("率2")Integer rate2;@ChineseName("date")Date date;@Overridepublicbooleanequals(Object o){if(this== o)returntrue;if(o ==null||getClass()!= o.getClass())returnfalse;EldData eldData =(EldData) o;returnObjects.equals(id, eldData.id)&&Objects.equals(date, eldData.date);}@OverridepublicinthashCode(){returnObjects.hash(id, date);}@OverridepublicStringtoString(){return"EldData{"+"rate1="+ rate1 +", rate2="+ rate2 +", date="+ date +'}';}}
DataService
  1. packagecom.jsss.echarts.service;importcom.jsss.echarts.annotation.ChineseName;importcom.jsss.echarts.entity.EldData;importcom.jsss.utils.Constant;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.data.redis.serializer.StringRedisSerializer;importorg.springframework.stereotype.Service;importjava.lang.reflect.Field;importjava.util.*;@ServicepublicclassDataServiceimplementsConstant{@AutowiredRedisTemplate redisTemplate;//返回数据链表publicHashMap<String,ArrayList>searchMap(Integer userId){// HashMap<String,ArrayList> map=new HashMap<>();HashMap<String,ArrayList> map=newLinkedHashMap<>();List<EldData> dataList =search(userId);List<String> fieldNames =newArrayList<>();Class<?> dataClass =EldData.class;// 获取 OldData 类的所有属性名Field[] fields = dataClass.getDeclaredFields();for(Field field : fields){
  2. fieldNames.add(field.getName());// map.put(field.getName(),new ArrayList<>());
  3. map.put(field.getAnnotation(ChineseName.class).value(),newArrayList<>());}for(EldData data : dataList){for(String fieldName : fieldNames){// ArrayList<Object> rowData = map.get(fieldName);try{Field field = dataClass.getDeclaredField(fieldName);ArrayList<Object> rowData =map.get(field.getAnnotation(ChineseName.class).value());
  4. field.setAccessible(true);
  5. rowData.add(field.get(data));
  6. map.put(field.getAnnotation(ChineseName.class).value(),rowData);}catch(NoSuchFieldException|IllegalAccessException e){
  7. e.printStackTrace();}// map.put(fieldName, rowData);}}return map;}//搜索数据// public List<EldData> 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<>();//// }//搜索数据publicList<EldData>search(Integer userId){String key=ELD_DATA+userId;Set set = redisTemplate.opsForZSet().reverseRange(key,0, limit-1);// 获取分数最高的limit个数据if(set==null){returnnewArrayList<>();}ArrayList<EldData> resList =newArrayList<>(set);Collections.reverse(resList);return resList;}// 将数据存储到有序集合中,分数为日期的时间戳publicbooleanaddData(Integer userId,EldData data){String key=ELD_DATA+userId;return redisTemplate.opsForZSet().add(key, data,data.getDate().getTime());}// 更新数据,先删除数据,后增加新数据publicbooleanupdateData(Integer userId,EldData oldData,EldData newData){long res=removeData(userId,oldData);if(res==0){//没有旧数据,就修改失败returnfalse;}returnaddData(userId, newData);}// 删除指定的数据publiclongremoveData(Integer userId,EldData data){String key=ELD_DATA+userId;return redisTemplate.opsForZSet().remove(key, data);}}

五、测试扩展性

5.0 开发说明

后端:

只需要更改EldData的属性就好了
并且添加对应注解

如果有一个属性没有注解会报错,由于searchMap()中默认是所有属性都有此注解。

如果有属性不需要前端展示,可以在前端noNeed中添加
也可以后端修改注解,增加need属性,增加代码逻辑
另外:注解也可增加:x轴属性

  1. @ChineseName("id")String id;@ChineseName("率1")Integer rate1;@ChineseName("率2")Integer rate2;@ChineseName("率3")Integer rate3;@ChineseName("date")Date date;

前端:

修改横轴:

  1. datax

怎么标注数据:

  1. data0

以及不需要展示的

  1. name

链表:

  1. noNeed
  1. //横轴时间
  2. let datax = dataLists.date;
  3. //标注数据
  4. let data0 = [];
  5. //只需修改不需要展示的name
  6. var noNeed=["id","date"];

5.1 测试结果

在这里插入图片描述

5.2 Eld多加一个属性

  1. packagecom.jsss.echarts.entity;importcom.jsss.echarts.annotation.ChineseName;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importjava.sql.Date;importjava.util.Objects;@Data@NoArgsConstructor@AllArgsConstructorpublicclassEldData{@ChineseName("id")String id;@ChineseName("率1")Integer rate1;@ChineseName("率2")Integer rate2;@ChineseName("率3")Integer rate3;@ChineseName("date")Date date;@Overridepublicbooleanequals(Object o){if(this== o)returntrue;if(o ==null||getClass()!= o.getClass())returnfalse;EldData eldData =(EldData) o;returnObjects.equals(id, eldData.id)&&Objects.equals(date, eldData.date);}@OverridepublicinthashCode(){returnObjects.hash(id, date);}}

5.3 加入测试数据

  1. @AutowiredRedisTemplate redisTemplate;@AutowiredDataService dataService;Integer userId=1;//清空数据@Testpublicvoidrestore(){String key=ELD_DATA+userId;
  2. redisTemplate.delete(key);testSearchMap();}@TestpublicvoidtestSearchMap(){HashMap<String,ArrayList> map = dataService.searchMap(userId);System.out.println(map);}@TestpublicvoidtestValidAdd(){EldData eldData=newEldData(Toolbox.getRandomString(),175,160,111,newDate(2024-1900,4-1,8));
  3. dataService.addData(userId,eldData);
  4. eldData=newEldData(Toolbox.getRandomString(),160,140,121,newDate(2024-1900,4-1,9));
  5. dataService.addData(userId,eldData);
  6. eldData=newEldData(Toolbox.getRandomString(),153,205,131,newDate(2024-1900,4-1,10));
  7. dataService.addData(userId,eldData);
  8. eldData=newEldData(Toolbox.getRandomString(),121,162,141,newDate(2024-1900,4-1,11));
  9. dataService.addData(userId,eldData);
  10. eldData=newEldData(Toolbox.getRandomString(),156,175,151,newDate(2024-1900,4-1,12));
  11. dataService.addData(userId,eldData);testSearchMap();}

运行前端,登录admin:admin用户

在加入测试数据

userId=2

登录jsss:123456,也是可以的
在这里插入图片描述
2024-4-13 16:26:41

六、注解优化

6.0 开发说明

后端:
在EldData中

如果某个属性需要前端展示,就添加

  1. ChineseName

注解
如果某个属性是横轴数据,其

  1. value

值就是

  1. datax

前端:
不需要修改任何代码

  1. publicclassEldData{@ChineseName("率1")Integer rate1;@ChineseName("率2")Integer rate2;//没有注解,就不展示Integer rate3;//横轴的注解的值是datax@ChineseName("datax")Date date;}

6.1 测试结果

rate3没有注解
在这里插入图片描述
rate3添加注解
在这里插入图片描述

6.2 前端

对应的改一下这两个就行了

  1. //横轴数据let datax = dataLists.datax;//不需要展示的namevar noNeed=["datax"];

6.2 后端

ChineseName
  1. /**
  2. * 如果某个属性需要展示,就添加`ChineseName`注解 <br>
  3. * 如果某个属性是横轴数据,其`value`值是`datax` <br>
  4. */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public@interfaceChineseName{//中文nameStringvalue();}
EldData

redis判断是根据序列化的结果判断是否相同,
equals和hashCode不起作用

  1. packagecom.jsss.echarts.entity;importcom.jsss.echarts.annotation.ChineseName;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importlombok.ToString;importjava.sql.Date;@Data@NoArgsConstructor@AllArgsConstructor@ToStringpublicclassEldData{@ChineseName("率1")Integer rate1;@ChineseName("率2")Integer rate2;//没有注解,就不展示Integer rate3;//横轴的注解的值是datax@ChineseName("datax")Date date;}
DataService
  1. //返回数据链表publicHashMap<String,ArrayList>searchMap(Integer userId){HashMap<String,ArrayList> map=newLinkedHashMap<>();List<EldData> dataList =search(userId);List<String> fieldNames =newArrayList<>();Class<?> dataClass =EldData.class;// 获取 OldData 类的所有被ChineseName注解的属性名Field[] fields = dataClass.getDeclaredFields();for(Field field : fields){//添加是否有注解的判断ChineseName chineseNameAnnotation = field.getAnnotation(ChineseName.class);if(chineseNameAnnotation!=null){
  2. fieldNames.add(field.getName());
  3. map.put(field.getAnnotation(ChineseName.class).value(),newArrayList<>());}}for(EldData data : dataList){for(String fieldName : fieldNames){try{Field field = dataClass.getDeclaredField(fieldName);
  4. field.setAccessible(true);ArrayList<Object> rowData =map.get(field.getAnnotation(ChineseName.class).value());
  5. rowData.add(field.get(data));
  6. map.put(field.getAnnotation(ChineseName.class).value(),rowData);}catch(NoSuchFieldException|IllegalAccessException e){
  7. e.printStackTrace();}}}return map;}//搜索数据publicList<EldData>search(Integer userId){String key=ELD_DATA+userId;Set set = redisTemplate.opsForZSet().reverseRange(key,0, limit-1);// 获取分数最高的limit个数据if(set==null){returnnewArrayList<>();}ArrayList<EldData> resList =newArrayList<>(set);Collections.reverse(resList);return resList;}

七、实际项目开发

加入分栏就更好了
在这里插入图片描述

EldData

  1. packagecom.jsss.echarts.entity;importcom.jsss.echarts.annotation.ChineseName;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importlombok.ToString;importjava.sql.Date;/**
  2. * 字段名称 类型 字段说明 备注
  3. * <p>
  4. * HT Integer 通用-身高(HT) 单位:m
  5. * WT Integer 通用-体重(WT) 单位:kg
  6. * BMI Double 通用-身高体重指数(BMI) 正常范围 18.5~23.9,超重24.0~27.9,肥胖≥28.0
  7. * SBP Integer 血压-收缩压(SBP) 正常成年人的收缩压范围为90-140毫米汞柱(mmHg)。
  8. * DBP Integer 血压-舒张压(DBP) 正常成年人的舒张压范围为60-90毫米汞柱(mmHg)。
  9. * Hb Integer 血常规-血红蛋白(Hb) 正常成年人的正常范围为120-175克/升。
  10. * WBC Integer 血常规-白细胞计数(WBC) 正常成年人的白细胞计数范围为4-10 × 10^9/L。
  11. * PLT Integer 血常规-血小板计数(PLT) 正常成年人的血小板计数范围为100-300 × 10^9/L。
  12. * ALT Integer 肝功能-谷丙转氨酶(ALT) 正常成年人的ALT范围为10-40单位/升。
  13. * AST Integer 肝功能-谷草转氨酶(AST) 正常成年人的AST范围为10-35单位/升。
  14. * TBIL Double 肝功能-总胆红素(TBIL) 正常成年人的总胆红素范围为3.4-17.1毫摩尔/升。
  15. * BUN Double 肾功能-血尿素氮(BUN) 正常成年人的BUN范围为2.5-7.1毫摩尔/升。
  16. * Cr Integer 肾功能-血肌酐(Cr) 正常成年人的血肌酐范围为53-115微摩尔/升。
  17. * TC Double 血脂-总胆固醇(TC) 正常成年人的总胆固醇范围为3.1-5.2毫摩尔/升。
  18. * TG Double 血脂-甘油三酯(TG) 正常成年人的甘油三酯范围为0.4-1.7毫摩尔/升。
  19. * LDL_C Double 血脂-低密度脂蛋白胆固醇(LDL-C) 正常成年人的LDL-C范围为2.6-3.4毫摩尔/升。
  20. * FPG Double 血糖-空腹血糖(FPG) 正常成年人的空腹血糖范围为3.9-6.1毫摩尔/升。
  21. * twohPG Double 血糖-餐后2小时血糖(2hPG) 正常成年人的餐后2小时血糖范围为3.9-7.8毫摩尔/升。
  22. */@Data@NoArgsConstructor@AllArgsConstructor@ToStringpublicclassEldData{@ChineseName("通用-身高(米)")IntegerHT;@ChineseName("通用-体重(千克)")IntegerWT;@ChineseName("通用-身高体重指数(千克/米2)")DoubleBMI;@ChineseName("血压-收缩压(毫米汞柱)")IntegerSBP;@ChineseName("血压-舒张压(毫米汞柱)")IntegerDBP;@ChineseName("血常规-血红蛋白(克/升)")IntegerHb;@ChineseName("血常规-白细胞计数(10^9/升)")IntegerWBC;@ChineseName("血常规-血小板计数(10^9/升)")IntegerPLT;@ChineseName("肝功能-谷丙转氨酶(单位/升)")IntegerALT;@ChineseName("肝功能-谷草转氨酶(单位/升)")IntegerAST;@ChineseName("肝功能-总胆红素(毫摩尔/升)")DoubleTBIL;@ChineseName("肾功能-血尿素氮(毫摩尔/升)")DoubleBUN;@ChineseName("肾功能-血肌酐(微摩尔/升)")IntegerCr;@ChineseName("血脂-总胆固醇(毫摩尔/升)")DoubleTC;@ChineseName("血脂-甘油三酯(毫摩尔/升)")DoubleTG;@ChineseName("血脂-低密度脂蛋白胆固醇(毫摩尔/升)")DoubleLDL_C;@ChineseName("血糖-空腹血糖(毫摩尔/升)")DoubleFPG;@ChineseName("血糖-餐后2小时血糖(毫摩尔/升)")Double twohPG;//横轴的注解的值是datax@ChineseName("datax")Date date;}

Constant

  1. packagecom.jsss.utils;importcom.jsss.echarts.entity.EldData;importjava.sql.Date;publicinterfaceConstant{/**
  2. * redis键:老人的体检数据
  3. */StringELD_DATA="eld_data:";EldDataMIN_DATA=newEldData(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,newDate(System.currentTimeMillis()));EldDataMAX_DATA=newEldData(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,newDate(System.currentTimeMillis()));}

测试数据

  1. packagecom.jsss.echarts;importcom.jsss.echarts.entity.EldData;importcom.jsss.echarts.service.DataService;importcom.jsss.utils.Constant;importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.data.redis.core.RedisTemplate;importjava.sql.Date;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.Random;@SpringBootTestpublicclassEchartsTestimplementsConstant{@AutowiredRedisTemplate redisTemplate;@AutowiredDataService dataService;Integer userId=1;Date date=newDate(2024-1900,4-1,14);@Testpublicvoidtest(){System.out.println(date);}//清空数据@Testpublicvoidrestore(){String key=ELD_DATA+userId;
  2. redisTemplate.delete(key);testSearchMap();}@TestpublicvoidtestSearchMap(){HashMap<String,ArrayList> map = dataService.searchMap(userId);System.out.println(map);}@TestpublicvoidtestValidAdd(){EldData eldData=randomData();
  3. eldData.setDate(newDate(2024-1900,4-1,8));
  4. dataService.addData(userId,eldData);
  5. eldData=randomData();
  6. eldData.setDate(newDate(2024-1900,4-1,9));
  7. dataService.addData(userId,eldData);
  8. eldData=randomData();
  9. eldData.setDate(newDate(2024-1900,4-1,10));
  10. dataService.addData(userId,eldData);
  11. eldData=randomData();
  12. eldData.setDate(newDate(2024-1900,4-1,11));
  13. dataService.addData(userId,eldData);
  14. eldData=randomData();
  15. eldData.setDate(newDate(2024-1900,4-1,12));
  16. dataService.addData(userId,eldData);testSearchMap();}EldData minData=MIN_DATA;EldData maxData=MAX_DATA;publicEldDatarandomData(){EldData data=newEldData(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()),newDate(System.currentTimeMillis()));return data;}publicIntegerrandomInt(int min,int max){Random random =newRandom();return random.nextInt(max - min +1)+ min;// 生成 min 到 max 范围内的随机 int 数}publicDoublerandomDouble(double min,double max){Random random =newRandom();return min +(max - min)* random.nextDouble();// 生成 min 到 max 范围内的随机 double 值}}

最后

2024-4-13 18:49:18

迎着日光月光星光,直面风霜雨霜雪霜。


本文转载自: https://blog.csdn.net/qq_51625007/article/details/137684820
版权归原作者 日星月云 所有, 如有侵权,请联系我们删除。

“数据可视化插件echarts【前端】”的评论:

还没有评论