echats柱状图\折线图:数量级自动调整;动态设置多维度

通过构造echarts返回体EchartsData.class,在返回体内开发功能代码,实现echarts数据的改动。

特点:
1、y轴数据的数量级自动调整,使图表变化趋势更明显;
2、支持多维度数据【可以有1-N多个维度】

// EchartsData对象构造样例代码
List<String> xAxis = Arrays.asList("鲤鱼","草鱼","三文鱼","鳕鱼","龙利鱼","鲫鱼");
List<Object> barList = Arrays.asList("12345","2345","3456","4567","67891","7891");final EchartsData echartsData = new EchartsData("新增情况图表", xAxis).setFirstYAxis("总数", barList);
echartsData.setLineYAxis(“利用率(%)”, line1List);
// echartsData.setLineYAxis(“利用率_2”, line2List);
// ...
// echartsData.setLineYAxis(“利用率_N”, lineNList);

在这里插入图片描述

xxx
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.Getter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;/*** echarts 表格数据结构体*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@Getter // 规定了“不同图标类型的y坐标值”与y坐标系维度列表的对应关系,故不允许随意set
public class EchartsData extends HashMap<String, Object> {/*** 标题*/private final String title;/*** 横坐标值*/private final List<String> xAxis;/*** 多维纵坐标的维度名称列表* 按索引号,分别对应坐标值:barList、line1List、line2List* 若对应的坐标值列表List为空,则表示无数据*/private List<String> yAxisDimensionNameList;/*** 柱状图-纵坐标值* 元素可能为简单数据类型,* 也可能为DataWithItemStyleVO.class类型,用于标识该值的显示样式*/private List<Object> barList; // 柱状图
//    private List<String> line{0}List; // 折线图public EchartsData(String title, List<String> xAxis) {this.title = title;this.xAxis = xAxis;this.yAxisDimensionNameList = new ArrayList<>();// map对象,使用MapSerializer解析时,不会序列自身的属性put("title", this.title);put("xAxis", this.xAxis);put("yAxisDimensionNameList", this.yAxisDimensionNameList);}public EchartsData setFirstYAxis(String dimension, List<?> barList) {ParamException.isTrue(StringUtils.isBlank(dimension), "inputParam[dimension] should not be blank");if (CollectionUtils.isEmpty(barList)) {return this;}YAxis yAxis = balanceNum(dimension, barList);yAxisDimensionNameList.add(yAxis.getDimension());this.barList = yAxis.getDataList();put("barList", this.barList);return this;}public EchartsData setLineYAxis(String dimension, List<String> lineList) {ParamException.isTrue(StringUtils.isBlank(dimension), "inputParam[dimension] should not be blank");if (CollectionUtils.isEmpty(lineList)) {return this;}YAxis yAxis = balanceNum(dimension, lineList); // 不指定索引号add,避免覆盖原有元素yAxisDimensionNameList.add(yAxis.getDimension());int index = yAxisDimensionNameList.size() - 1;final String key = MessageFormat.format("line{0}List", index);put(key, yAxis.getDataList());return this;}private YAxis balanceNum(String sourceDimension, List<?> sourceList) {List<Object> targetList;String targetDimension;List<BigDecimal> tempNumList = new ArrayList<>();sourceList.forEach(data -> {String value;if (data instanceof DataWithItemStyleVO) {value = ((DataWithItemStyleVO) data).getValue();} else {value = String.valueOf(data);}// 非数字会报错final BigDecimal dNum = NumberUtil.parseStrToBigDecimal(value);tempNumList.add(dNum);});tempNumList.sort(BigDecimal::compareTo);final BigDecimal min = tempNumList.get(0);final int minLength = String.valueOf(min.intValue()).length();final BigDecimal max = tempNumList.get(tempNumList.size() - 1);final int maxLength = String.valueOf(max.intValue()).length();// 是否进行数值大小转换if (!sourceDimension.contains("率") // 为了避免调整百分数,双保险(部分字段的百分数值,没有带百分号。若数值本身的带百分号的minLength=1不会转换)。若是转化,单位会很奇怪,又是百分号、又是数量单位。&& maxLength >= minLength//  不可自动调整的数据如(为了避免调整百分数):88 vs 10; 987 vs 10; 101 vs 99&& (minLength > 2 || (minLength > 1 && (maxLength - minLength) > 1)) // 如:880 vs 100; 8800 vs 10) {targetList = new ArrayList<>();// 将最小值,处理成个位数。缩短无用y轴刻度,使y轴数值差异明显化// 若存在负数、小数:存在小数-因为整数位数为0故不会进行转化;存在负数-要求最小值即负数的位数比正数最大值位数短即可(否则转换后正数会小于0不符合所有值绝对值都大于零的预期)。int powerOfTen = minLength - 1;BigDecimal divisor = BigDecimal.valueOf(10).pow(powerOfTen); // 10的n次方。使得最小值为个位数for (int i = 0; i < sourceList.size(); i++) { // 不打乱原排序Object data = sourceList.get(i);DataWithItemStyleVO dataWithItemStyleVO = null;String value;if (data instanceof DataWithItemStyleVO) {dataWithItemStyleVO = (DataWithItemStyleVO) data;value = dataWithItemStyleVO.getValue();} else {value = String.valueOf(data);}final BigDecimal dNum = NumberUtil.parseStrToBigDecimal(value);final BigDecimal divide = dNum.divide(divisor);if (Objects.isNull(dataWithItemStyleVO)) {targetList.add(divide.toString());} else {targetList.add(new DataWithItemStyleVO(divide.toString(), dataWithItemStyleVO.getItemStyle()));}}// 追加转换后的单位NumCountUnitEnum unitEnum = NumCountUnitEnum.valueOf(powerOfTen);targetDimension = MessageFormat.format("{0}({1})", sourceDimension, unitEnum.getCountUnitName()); // 中文括号前端无法识别} else {// 数值小于1000,不做处理targetList = sourceList.stream().map(data -> (Object) data).collect(Collectors.toList());targetDimension = sourceDimension;}YAxis yaxis = new YAxis();yaxis.setDataList(targetList);yaxis.setDimension(targetDimension);return yaxis;}enum NumCountUnitEnum {ONE(0, "个"),TWO(1, "十"),THREE(2, "百"),FOUR(3, "千"),FIVE(4, "万"),SIX(5, "十万"),SEVEN(6, "百万"),EIGHT(7, "千万"),NINE(8, "亿"),;/*** 10的幂次*/private Integer powerOfTen;/*** 计数单位中文名*/private String countUnitName;NumCountUnitEnum(Integer powerOfTen, String countUnitName) {this.powerOfTen = powerOfTen;this.countUnitName = countUnitName;}public static NumCountUnitEnum valueOf(Integer powerOfTen) {ParamException.isTrue(Objects.isNull(powerOfTen), "invalid null powerOfTen");for (NumCountUnitEnum elem : values()) {if (powerOfTen.equals(elem.powerOfTen)) {return elem;}}throw new ParamException(String.format("invalid powerOfTen: [%s]", powerOfTen));}public Integer getPowerOfTen() {return powerOfTen;}public String getCountUnitName() {return countUnitName;}}@Dataclass YAxis {private String dimension;private List<Object> dataList;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/540716.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Yolo系列算法-理论部分-YOLOv5

0. 写在前面 YOLO系列博客&#xff0c;紧接上一篇Yolo系列算法-理论部分-YOLOv4-CSDN博客 1. YOLOv5-美而全的产品 YOLOv5的诞生&#xff0c;直接将目标检测算法向终局推进&#xff0c;Ultralytics团队在COCO数据集上预训练的目标检测架构和模型直接开源&#xff0c;其中包含了…

世纪互联版Microsoft 365应用无法跳转正确登录门户

很多购买世纪互联&#xff08;国内版&#xff09;Microsoft 365&#xff08;Office 365&#xff09;的用户有时候会遇到在Office应用登录账号时&#xff0c;登陆页面跳转到国际版Microsoft Entra ID&#xff08;Azure AD&#xff09;页面&#xff08;没有备案号&#xff09;&am…

Supervisor,一个超酷的 Python 库!

大家好&#xff0c;今天为大家分享一个超酷的 Python 库 - supervisor。 Github地址&#xff1a;https://github.com/Supervisor/supervisor 在大型项目中&#xff0c;经常需要管理多个进程&#xff0c;确保它们能够稳定运行并协同工作。Python提供了许多工具和库来帮助实现进…

LeetCode438题(无敌双指针——滑动窗口)

找到字符串中所有字母异位词 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 示例 1: 输入: s "…

HTML案例-2.标签综合练习

目录 效果 知识点 1.图像标签 2.链接标签 3.锚点定位 4.base标签 源码 页面1 页面2 效果 知识点 1.图像标签 <img src="图像URL" /> 单标签 属性 属性值 描述 src URL 图像的路径 alt 文本

如何实现固定公网地址远程SSH连接Linux Deepin系统

文章目录 前言1. 开启SSH服务2. Deppin安装Cpolar3. 配置ssh公网地址4. 公网远程SSH连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 前言 Deepin操作系统是一个基于Debian的Linux操作系统&#xff0c;专注于使用者对日常办公、学习、生活和娱乐的操作体验的极致&#xff0…

(网络安全)一款强大的逆向分析工具,开源!

工具介绍 Ghidra 是由美国国家安全局&#xff08;NSA&#xff09;研究部门开发的软件逆向工程&#xff08;SRE&#xff09;套件&#xff0c;用于支持网络安全任务。包括一套功能齐全的高端软件分析工具&#xff0c;使用户能够在各种平台(Windows、Mac OS和Linux)分析编译后的代…

Unity PS5开发 天坑篇 之 申请开发者与硬件部署01

腾了好几天终于把PS5开发机调试部署成功, 希望能帮到国内的开发者, 主机游戏PlayStation/Nintendo Switch都是比较闭塞的&#xff0c;开发者账号是必须的。 开发环境有两个部分&#xff0c;一是DEV Kit 开发机, TEST Kit测试机两部分组成&#xff0c;二是Unity的支持库(安装后…

高并发缓存策略大揭秘:面试必备的缓存更新模式解析

在高并发场景中&#xff0c;缓存能抵挡大量数据库查询&#xff0c;减少数据库压力&#xff0c;对于缓存更新通常有以下几种模式可以选择&#xff1a; cache asideread/write throughwrite behind caching cache aside模式 Cache-aside模式是一种常用的用于管理缓存的模式。它…

【Python】进阶学习:一文了解NotImplementedError的作用

【Python】进阶学习&#xff1a;一文了解NotImplementedError的作用 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望…

springboot+ssm基于vue.js的客户关系Crm管理系统

系统包含两种角色&#xff1a;管理员、用户&#xff0c;主要功能如下。 ide工具&#xff1a;IDEA 或者eclipse 编程语言: java 数据库: mysql5.7 框架&#xff1a;ssmspringboot都有 前端&#xff1a;vue.jsElementUI 详细技术&#xff1a;springbootSSMvueMYSQLMAVEN 数据库…

LCR144翻转二叉树(力扣简单题,Java,递归+非递归)

目录 题目描述&#xff1a; 递归代码1&#xff1a; 递归代码2&#xff1a; 非递归代码&#xff08;层次遍历&#xff09;&#xff1a; 题目描述&#xff1a; 给定一棵二叉树的根节点 root&#xff0c;请左右翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a;…