柱状图展示异步统计数据

2024-04-24 03:12

本文主要是介绍柱状图展示异步统计数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

PC端

 APP端

 Controller层

package com.cnpc.dj.party.controller;import com.alibaba.fastjson.JSONObject;
import com.cnpc.dj.common.JsonResult;
import com.cnpc.dj.common.context.BaseContextHandler;
import com.cnpc.dj.common.utils.DateUtils;
import com.cnpc.dj.party.common.ReturnExamEnum;
import com.cnpc.dj.party.service.GridDataStatisticService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/dataStatistic")
public class GridDataStatisticController {@Autowiredprivate GridDataStatisticService gridDataStatisticService ;@PostMapping("/doStatisticForGrid")public JsonResult<?> doStatisticForGrid(@RequestBody JSONObject requestBody) {// 检查入参合法性.BigDecimal orgId = requestBody.getBigDecimal("orgId");if (Objects.isNull(orgId)) {return JsonResult.error(ReturnExamEnum.GRID_ILLEGAL_ARGUMENT, "必要参数<orgId>未填写");}BigDecimal tenantId = BaseContextHandler.getDecimalTenantId();long beginTime = System.currentTimeMillis();log.info("\n[ {} ][ 网格员 - 数据统计任务 ]: 开始所有任务(当前租户ID: {} ).", DateUtils.format(new Date(beginTime), "yyyy年MM月dd日 HH时mm分ss秒 SSS毫秒"), tenantId);// 创建统计结果容器.JSONObject result = new JSONObject();// 创建异步统计任务: 调用各统计方法.CompletableFuture<?> task1 = gridDataStatisticService.gridNumberAsyncStatistic(tenantId, orgId, result);CompletableFuture<?> task2 = gridDataStatisticService.gridPersonNumberAsyncStatistic(tenantId, orgId, result);// 等待, 直到所有任务执行完毕.CompletableFuture.allOf(task1,task2).join();long endTime = System.currentTimeMillis();log.info("\n[ {} ][ 网格员 - 数据统计任务 ]: 所有任务完成, 总计耗时 {} 毫秒.", DateUtils.format(new Date(endTime), "yyyy年MM月dd日 HH时mm分ss秒 SSS毫秒"), endTime - beginTime);// 返回统计结果.return JsonResult.success(result);}
}

Service层 

package com.cnpc.dj.party.service;import com.alibaba.fastjson.JSONObject;
import com.cnpc.dj.common.utils.DateUtils;
import com.cnpc.dj.party.common.EChartsResult;
import com.cnpc.dj.party.common.KeyValuePair;
import com.cnpc.dj.party.repository.GridDataStatisticMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;@Service
@Slf4j
public class GridDataStatisticService {@Autowiredprivate GridDataStatisticMapper gridDataStatisticMapper;private static String convert(long timeMillis) {return DateUtils.format(new Date(timeMillis), "yyyy年MM月dd日 HH时mm分ss秒 SSS毫秒");}/*** 获取网格信息* @param orgId 入参: 组织ID.* @return 统计结果.*/@Asyncpublic CompletableFuture<?> gridNumberAsyncStatistic(BigDecimal tenantId, BigDecimal orgId, JSONObject parent) {long t0 = System.currentTimeMillis();log.info("\n[ {} ][ 网格情况 ][ 网格数量统计 ]: 任务开始.", convert(t0));// 查询数据库, 获取原始数据List<KeyValuePair<BigDecimal>> list = gridDataStatisticMapper.statisticGrid(tenantId, orgId);long t1 = System.currentTimeMillis();log.info("\n[ {} ][ 网格情况 ][ 网格数量统计 ]: 原始数据查询成功: 本步耗时 {} 毫秒, 总计耗时 {} 毫秒.", convert(t1),t1 - t0,t1 - t0);// 初始化查询结果容器.// 初始化查询结果容器.管理类,科研类,生产经营类,项目建设类,生产作业类,网格总数String[] mapEntry = {"Manage", "Scientific", "ProductionOperation", "ProjectBuild","FlowHomework", "GridTotal"};EChartsResult result = new EChartsResult();result.init(null, mapEntry, null);BigDecimal gridTotal = BigDecimal.ZERO;// 处理原始数据, 填充查询结果容器.for (KeyValuePair<BigDecimal> item : list) {if (Objects.nonNull(item.getKey())) {switch (item.getKey()) {case "1":result.addToMap(mapEntry[0], item.getValue());gridTotal = gridTotal.add(item.getValue());break;case "2":result.addToMap(mapEntry[1], item.getValue());gridTotal = gridTotal.add(item.getValue());break;case "3":result.addToMap(mapEntry[2], item.getValue());gridTotal = gridTotal.add(item.getValue());break;case "4":result.addToMap(mapEntry[3], item.getValue());gridTotal = gridTotal.add(item.getValue());break;default:result.addToMap(mapEntry[4], item.getValue());gridTotal = gridTotal.add(item.getValue());}}}result.addToMap(mapEntry[5], gridTotal);// 返回查询结果.parent.put("GridStatistic", result.getMap());long t2 = System.currentTimeMillis();log.info("\n[ {} ][ 网格情况 ][ 网格数量统计 ]: 数据处理完成, 任务结束: 本步耗时 {} 毫秒, 总计耗时 {} 毫秒.", convert(t2), t2 - t1,t2 - t0);return CompletableFuture.completedFuture(parent);}/*** 获取网格人员信息* @param orgId 入参: 组织ID.* @return 统计结果.*/@Asyncpublic CompletableFuture<?> gridPersonNumberAsyncStatistic(BigDecimal tenantId, BigDecimal orgId, JSONObject parent) {long t0 = System.currentTimeMillis();log.info("\n[ {} ][ 网格人员情况 ][ 网格人数统计 ]: 任务开始.", convert(t0));// 查询数据库, 获取原始数据List<KeyValuePair<BigDecimal>> list = gridDataStatisticMapper.statisticGridPerson(tenantId, orgId);long t1 = System.currentTimeMillis();log.info("\n[ {} ][ 网格人员情况 ][ 网格人数统计 ]: 原始数据查询成功: 本步耗时 {} 毫秒, 总计耗时 {} 毫秒.", convert(t1),t1 - t0,t1 - t0);// 初始化查询结果容器.// 初始化查询结果容器.管理类,科研类,生产经营类,项目建设类,生产作业类,网格人员总数String[] mapEntry = {"Manage", "Scientific", "ProductionOperation", "ProjectBuild","FlowHomework", "GridPersonTotal"};EChartsResult result = new EChartsResult();result.init(null, mapEntry, null);BigDecimal gridTotal = BigDecimal.ZERO;// 处理原始数据, 填充查询结果容器.for (KeyValuePair<BigDecimal> item : list) {if (Objects.nonNull(item.getKey())) {switch (item.getKey()) {case "1":result.addToMap(mapEntry[0], item.getValue());gridTotal = gridTotal.add(item.getValue());break;case "2":result.addToMap(mapEntry[1], item.getValue());gridTotal = gridTotal.add(item.getValue());break;case "3":result.addToMap(mapEntry[2], item.getValue());gridTotal = gridTotal.add(item.getValue());break;case "4":result.addToMap(mapEntry[3], item.getValue());gridTotal = gridTotal.add(item.getValue());break;default:result.addToMap(mapEntry[4], item.getValue());gridTotal = gridTotal.add(item.getValue());}}}result.addToMap(mapEntry[5], gridTotal);// 返回查询结果.parent.put("GridPersonStatistic", result.getMap());long t2 = System.currentTimeMillis();log.info("\n[ {} ][ 网格人员情况 ][ 网格人数统计 ]: 数据处理完成, 任务结束: 本步耗时 {} 毫秒, 总计耗时 {} 毫秒.", convert(t2), t2 - t1,t2 - t0);return CompletableFuture.completedFuture(parent);}
}

Mapper层

package com.cnpc.dj.party.repository;import com.cnpc.dj.party.common.KeyValuePair;
import org.apache.ibatis.annotations.Mapper;import java.math.BigDecimal;
import java.util.List;@Mapper
public interface GridDataStatisticMapper {/*** 统计网格数量* @param tenantId* @param orgId* @return K V*/List<KeyValuePair<BigDecimal>> statisticGrid(BigDecimal tenantId, BigDecimal orgId);/*** 统计网格人数* @param tenantId* @param orgId* @return K V*/List<KeyValuePair<BigDecimal>> statisticGridPerson(BigDecimal tenantId, BigDecimal orgId);
}

 Mapper.xml层

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.cnpc.dj.party.repository.GridDataStatisticMapper"><resultMap id="KeyValuePair" type="com.cnpc.dj.party.common.KeyValuePair"><result column="K" property="key" jdbcType="VARCHAR" javaType="java.lang.String"/><result column="V" property="value" jdbcType="INTEGER" javaType="java.math.BigDecimal"/></resultMap><select id="statisticGrid" parameterType="java.math.BigDecimal" resultMap="KeyValuePair">SELECT G.GRID_CLASS k,COUNT(*)     vFROM ZHONGHY_ONLINE_ANSWERS.DJ_GRID GWHERE G.IS_DELETE = '0'AND  G.ORG_CODE IN (SELECT o.ORG_CODEFROM ZHONGHY_BASIC_INFO.DJ_ORG OWHERE o.is_delete = '0'AND o.is_del_org = '0'AND o.tenant_id = #{tenantId, jdbcType=DECIMAL}AND !REGEXP_LIKE(o.org_code, '^(000.001|000.002)')CONNECT BY PRIOR o.id = o.parent_idSTART WITH o.id = #{orgId, jdbcType=DECIMAL})GROUP BY G.GRID_CLASSORDER BY G.GRID_CLASS</select><select id="statisticGridPerson" parameterType="java.math.BigDecimal" resultMap="KeyValuePair">SELECT G.GRID_CLASS k,COUNT(*)     vFROM ZHONGHY_ONLINE_ANSWERS.DJ_GRID_RANGE RLEFT JOIN ZHONGHY_ONLINE_ANSWERS.DJ_GRID GON R.GRID_ID = G.ID AND R.IS_DELETE = '0'WHERE G.IS_DELETE = '0'AND G.ORG_CODE IN (SELECT o.ORG_CODEFROM ZHONGHY_BASIC_INFO.DJ_ORG OWHERE o.is_delete = '0'AND o.is_del_org = '0'AND o.tenant_id = #{tenantId, jdbcType=DECIMAL}AND !REGEXP_LIKE(o.org_code, '^(000.001|000.002)')CONNECT BY PRIOR o.id = o.parent_idSTART WITH o.id = #{orgId, jdbcType=DECIMAL})GROUP BY G.GRID_CLASSORDER BY G.GRID_CLASS</select>
</mapper>

  公共类EChartsResult

package com.cnpc.dj.party.common;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.math.BigDecimal;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedList;/*** 陕西信合 - 数据统计.*/
public class EChartsResult {public static final Comparator<? super Entry> VALUE_ASC = Comparator.comparing(Entry::getValue);public static final Comparator<? super Entry> VALUE_DESC = (Entry o1, Entry o2) -> o2.getValue().compareTo(o1.getValue());private Comparator<? super Entry> comparator;private LinkedHashMap<String, Entry> entryMap;private LinkedHashMap<String, BigDecimal> valueMap;private BigDecimal total;public void init(String[] names, String[] keys, Comparator<? super Entry> comparator) {// 初始化EntryMapif (names != null && names.length > 0) {this.entryMap = new LinkedHashMap<>(names.length);for (String name : names) {this.entryMap.put(name, new Entry(name, BigDecimal.ZERO, null));}}// 初始化ValueMapif (keys != null && keys.length > 0) {this.valueMap = new LinkedHashMap<>(keys.length);for (String key : keys) {this.valueMap.put(key, BigDecimal.ZERO);}}// 设置Comparatorthis.comparator = comparator;}public void setComparator(Comparator<? super Entry> comparator) {this.comparator = comparator;}public void addToList(String name, BigDecimal value) {if (this.entryMap == null) {this.entryMap = new LinkedHashMap<>();}if (this.entryMap.containsKey(name)) {this.entryMap.get(name).addValue(value);} else {this.entryMap.put(name, new Entry(name, value, null));}}public void addToMap(String key, BigDecimal value) {if (this.valueMap == null) {this.valueMap = new LinkedHashMap<>();}this.valueMap.put(key, this.valueMap.containsKey(key)? this.valueMap.get(key).add(value): value);}public void calculate() {this.calculateTotal();this.calculatePercent();}public void calculate(BigDecimal total) {this.calculateTotal();this.calculatePercent(total);}private void calculateTotal() {if (this.entryMap != null) {// 初始化Total.this.total = BigDecimal.ZERO;// 累加求和.for (Entry entry : this.entryMap.values()) {this.total = this.total.add(entry.getValue());}}}private void calculatePercent() {if (this.entryMap != null) {// 若Total未初始化, 则先计算Total.if (this.total == null) {this.calculateTotal();}// 遍历EntryMap的所有项目, 计算百分比.this.entryMap.values().forEach(entry -> entry.calculatePercent(this.total));}}private void calculatePercent(BigDecimal total) {if (this.entryMap != null) {// 遍历EntryMap的所有项目, 计算百分比.this.entryMap.values().forEach(entry -> entry.calculatePercent(total));}}public void buildMap() {this.calculate();LinkedList<Entry> list = this.getList();if (list != null) {for (Entry entry : list) {this.addToMap(entry.getName(), entry.getValue());this.addToMap(entry.getName() + "Percent", entry.getPercent());}this.addToMap("Total", this.total);}}public LinkedList<Entry> getList() {if (this.entryMap != null) {LinkedList<Entry> list = new LinkedList<>(this.entryMap.values());if (this.comparator != null) {list.sort(this.comparator);}return list;}return null;}public LinkedHashMap<String, BigDecimal> getMap() {return this.valueMap;}public BigDecimal getTotal() {return this.total;}/*** ECharts 统计列表项.** @author wangzijie05@cnpc.com.cn* @since 2019-03-15*/@Data@NoArgsConstructor@AllArgsConstructorpublic class Entry {private String name;private BigDecimal value;private BigDecimal percent;void addValue(BigDecimal augend) {this.value = this.value.add(augend);}void calculatePercent(BigDecimal total) {if (BigDecimal.ZERO.equals(total)) {this.percent = BigDecimal.ZERO;} else {this.percent = this.value.abs().divide(total, 10, BigDecimal.ROUND_HALF_UP);}}}
}

 公共类KeyValuePair

package com.cnpc.dj.party.common;import lombok.Data;@Data
public class KeyValuePair<T> {private String key;private T value;}

 postman测试

这篇关于柱状图展示异步统计数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/930609

相关文章

Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题

《Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题》在爬虫工程里,“HTTPS”是绕不开的话题,HTTPS为传输加密提供保护,同时也给爬虫带来证书校验、... 目录一、核心问题与优先级检查(先问三件事)二、基础示例:requests 与证书处理三、高并发选型:

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

C#异步编程ConfigureAwait的使用小结

《C#异步编程ConfigureAwait的使用小结》本文介绍了异步编程在GUI和服务器端应用的优势,详细的介绍了async和await的关键作用,通过实例解析了在UI线程正确使用await.Conf... 异步编程是并发的一种形式,它有两大好处:对于面向终端用户的GUI程序,提高了响应能力对于服务器端应

C# async await 异步编程实现机制详解

《C#asyncawait异步编程实现机制详解》async/await是C#5.0引入的语法糖,它基于**状态机(StateMachine)**模式实现,将异步方法转换为编译器生成的状态机类,本... 目录一、async/await 异步编程实现机制1.1 核心概念1.2 编译器转换过程1.3 关键组件解析

如何在Java Spring实现异步执行(详细篇)

《如何在JavaSpring实现异步执行(详细篇)》Spring框架通过@Async、Executor等实现异步执行,提升系统性能与响应速度,支持自定义线程池管理并发,本文给大家介绍如何在Sprin... 目录前言1. 使用 @Async 实现异步执行1.1 启用异步执行支持1.2 创建异步方法1.3 调用

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

Python 异步编程 asyncio简介及基本用法

《Python异步编程asyncio简介及基本用法》asyncio是Python的一个库,用于编写并发代码,使用协程、任务和Futures来处理I/O密集型和高延迟操作,本文给大家介绍Python... 目录1、asyncio是什么IO密集型任务特征2、怎么用1、基本用法2、关键字 async1、async

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构