From 7ef0631145378fc3809d4a09d80f9d2cf57b5f97 Mon Sep 17 00:00:00 2001 From: "review512jwy@163.com" <“review512jwy@163.com”> Date: Fri, 23 Jan 2026 22:59:01 +0800 Subject: [PATCH] =?UTF-8?q?ydata=E6=94=B9=E6=88=90=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/back/vo/device/LineData.java | 4 +- .../back/service/common/CommonOpt.java | 28 +-- .../common/LineDataHourAggregator.java | 195 +++++++++--------- 3 files changed, 110 insertions(+), 117 deletions(-) diff --git a/dongjian-dashboard-back-model/src/main/java/com/dongjian/dashboard/back/vo/device/LineData.java b/dongjian-dashboard-back-model/src/main/java/com/dongjian/dashboard/back/vo/device/LineData.java index 2f7f2ad..6938200 100644 --- a/dongjian-dashboard-back-model/src/main/java/com/dongjian/dashboard/back/vo/device/LineData.java +++ b/dongjian-dashboard-back-model/src/main/java/com/dongjian/dashboard/back/vo/device/LineData.java @@ -4,7 +4,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Data public class LineData { @@ -16,6 +18,6 @@ public class LineData { private List xData = new ArrayList<>(); @Schema(description = "Y-axis data", example = "[]") - private List yData = new ArrayList<>(); + private Map> yData = new HashMap<>(); } diff --git a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/CommonOpt.java b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/CommonOpt.java index 0931806..e88bdd7 100644 --- a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/CommonOpt.java +++ b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/CommonOpt.java @@ -39,13 +39,13 @@ import org.springframework.stereotype.Component; import com.dongjian.dashboard.back.util.CommonUtil; -/** +/** * @author Mr.Jiang -* @time 2022年5月28日 上午7:41:40 +* @time 2022年5月28日 上午7:41:40 */ @Component public class CommonOpt { - + private static Logger logger = LoggerFactory.getLogger(CommonOpt.class); public enum ExtractStrategy { @@ -61,7 +61,7 @@ public class CommonOpt { @Value("${spring.datasource.url}") private String dbUrl; - + @Autowired private BasicCompanyMapperExt basicCompanyMapperExt; @Autowired @@ -75,13 +75,13 @@ public class CommonOpt { @Autowired private MsgLanguageChange msgLanguageChange; - + /** * 根据自身企业ID获取子企业ID的list,list包含自身ID - * + * * @param companyId 自身ID - * + * * @return */ public List getSelfAndSubCompanyId(Long companyId) { @@ -91,7 +91,7 @@ public class CommonOpt { return idsList; } - + private void collectChildIds(List idsList, String parentCompanyIds) { Map searchChildMap = new HashMap(); searchChildMap.put("companyIds", parentCompanyIds); @@ -103,14 +103,14 @@ public class CommonOpt { } } - + /** * 过滤掉不属于targetCompany和它子企业的ID - * + * * @param targetCompanyId 指定企业ID - * + * * @param needProcessedCompanyIds 需要被处理的企业ID - * + * */ public List filterCompanyIds(Long targetCompanyId, String needProcessedCompanyIds) { List selfAndSubCompanyList = getSelfAndSubCompanyId(targetCompanyId); @@ -444,7 +444,7 @@ public class CommonOpt { } while (result.next()); lineData.getXData().addAll(xDataList); - lineData.getYData().addAll(yDataList); + lineData.getYData().put("common", yDataList); } catch (Exception e) { logger.error("Error processing result set", e); @@ -492,7 +492,7 @@ public class CommonOpt { } while (result.next()); lineData.getXData().addAll(xDataList); - lineData.getYData().addAll(yDataList); + lineData.getYData().put("common", yDataList); } catch (Exception e) { logger.error("Error processing result set", e); diff --git a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/LineDataHourAggregator.java b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/LineDataHourAggregator.java index 7cff13b..e191ee8 100644 --- a/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/LineDataHourAggregator.java +++ b/dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/LineDataHourAggregator.java @@ -22,43 +22,51 @@ public class LineDataHourAggregator { public static void aggregateByHour(LineData lineData) { List xData = lineData.getXData(); - List yData = lineData.getYData(); + Map> yDataMap = lineData.getYData(); - if (xData == null || yData == null || xData.size() != yData.size()) { + if (xData == null || yDataMap == null || yDataMap.isEmpty()) { return; } - // hour -> List - Map> hourMap = new TreeMap<>(); + // hour -> index + Map hourIndexMap = new TreeMap<>(); + Map>> hourValueMap = new TreeMap<>(); for (int i = 0; i < xData.size(); i++) { String timeStr = String.valueOf(xData.get(i)); - Object yVal = yData.get(i); - - if (yVal == null) { - continue; - } - LocalDateTime time = LocalDateTime.parse(timeStr, INPUT_FMT); String hourKey = time.format(HOUR_FMT); - hourMap.computeIfAbsent(hourKey, k -> new ArrayList<>()).add(Double.parseDouble(String.valueOf(yVal))); + hourIndexMap.putIfAbsent(hourKey, hourIndexMap.size()); + + for (Map.Entry> entry : yDataMap.entrySet()) { + Object yVal = entry.getValue().get(i); + if (yVal == null) { + continue; + } + + hourValueMap + .computeIfAbsent(hourKey, k -> new HashMap<>()) + .computeIfAbsent(entry.getKey(), k -> new ArrayList<>()) + .add(Double.parseDouble(String.valueOf(yVal))); + } } - // 重新构建 xData / yData List newX = new ArrayList<>(); - List newY = new ArrayList<>(); + Map> newY = new HashMap<>(); - for (Map.Entry> entry : hourMap.entrySet()) { - newX.add(entry.getKey()); + for (String hourKey : hourIndexMap.keySet()) { + newX.add(hourKey); - double avg = entry.getValue() - .stream() - .mapToDouble(Double::doubleValue) - .average() - .orElse(0); + Map> seriesMap = hourValueMap.get(hourKey); + if (seriesMap == null) { + continue; + } - newY.add(avg); + for (Map.Entry> e : seriesMap.entrySet()) { + double avg = e.getValue().stream().mapToDouble(Double::doubleValue).average().orElse(0); + newY.computeIfAbsent(e.getKey(), k -> new ArrayList<>()).add(avg); + } } lineData.setXData(newX); @@ -72,38 +80,42 @@ public class LineDataHourAggregator { public static void fillTodayHalfHourPointsJST(LineData lineData) { List xData = lineData.getXData(); - List yData = lineData.getYData(); + Map> yDataMap = lineData.getYData(); - if (xData == null || yData == null || xData.size() != yData.size()) { + if (xData == null || yDataMap == null) { return; } ZoneId JST = ZoneId.of("Asia/Tokyo"); + LocalDate todayJst = LocalDate.now(JST); + LocalDateTime start = todayJst.atStartOfDay(); + + // 原数据转 Map:time -> series -> value + Map> valueMap = new HashMap<>(); - // 现有数据转 Map - Map valueMap = new HashMap<>(); for (int i = 0; i < xData.size(); i++) { - valueMap.put( - String.valueOf(xData.get(i)), - Double.parseDouble(String.valueOf(yData.get(i))) - ); + String time = String.valueOf(xData.get(i)); + for (Map.Entry> e : yDataMap.entrySet()) { + valueMap + .computeIfAbsent(time, k -> new HashMap<>()) + .put(e.getKey(), e.getValue().get(i)); + } } - // 日本“今天” - LocalDate todayJst = LocalDate.now(JST); - List newX = new ArrayList<>(48); - List newY = new ArrayList<>(48); - - // 日本当天 00:00 - LocalDateTime start = todayJst.atStartOfDay(); + Map> newY = new HashMap<>(); for (int i = 0; i < 48; i++) { - LocalDateTime timePoint = start.plusMinutes(i * 30); - String key = timePoint.format(INPUT_FMT); - + LocalDateTime t = start.plusMinutes(i * 30); + String key = t.format(INPUT_FMT); newX.add(key); - newY.add(valueMap.getOrDefault(key, null)); + + Map seriesValues = valueMap.get(key); + for (String series : yDataMap.keySet()) { + newY + .computeIfAbsent(series, k -> new ArrayList<>()) + .add(seriesValues == null ? null : seriesValues.get(series)); + } } lineData.setXData(newX); @@ -119,54 +131,42 @@ public class LineDataHourAggregator { public static void aggregateAverageByHalfHour(LineData lineData) { List xData = lineData.getXData(); - List yData = lineData.getYData(); + Map> yDataMap = lineData.getYData(); - if (xData == null || yData == null || xData.size() != yData.size()) { + if (xData == null || yDataMap == null) { return; } - // halfHour -> List - Map> halfHourMap = new TreeMap<>(); + Map>> halfHourMap = new TreeMap<>(); for (int i = 0; i < xData.size(); i++) { - String timeStr = String.valueOf(xData.get(i)); - Object yVal = yData.get(i); - - if (yVal == null) { - continue; - } + LocalDateTime time = LocalDateTime.parse(String.valueOf(xData.get(i)), INPUT_FMT); - LocalDateTime time = LocalDateTime.parse(timeStr, INPUT_FMT); + int minute = time.getMinute() < 30 ? 0 : 30; + LocalDateTime halfHourTime = time.withMinute(minute).withSecond(0).withNano(0); + String key = halfHourTime.format(INPUT_FMT); - int minute = time.getMinute(); - int halfHourMinute = minute < 30 ? 0 : 30; + for (Map.Entry> e : yDataMap.entrySet()) { + Object yVal = e.getValue().get(i); + if (yVal == null) continue; - LocalDateTime halfHourTime = time - .withMinute(halfHourMinute) - .withSecond(0) - .withNano(0); - - String halfHourKey = halfHourTime.format(INPUT_FMT); - - halfHourMap - .computeIfAbsent(halfHourKey, k -> new ArrayList<>()) - .add(Double.parseDouble(String.valueOf(yVal))); + halfHourMap + .computeIfAbsent(key, k -> new HashMap<>()) + .computeIfAbsent(e.getKey(), k -> new ArrayList<>()) + .add(Double.parseDouble(String.valueOf(yVal))); + } } - // 重新构建 xData / yData List newX = new ArrayList<>(); - List newY = new ArrayList<>(); + Map> newY = new HashMap<>(); - for (Map.Entry> entry : halfHourMap.entrySet()) { + for (Map.Entry>> entry : halfHourMap.entrySet()) { newX.add(entry.getKey()); - double avg = entry.getValue() - .stream() - .mapToDouble(Double::doubleValue) - .average() - .orElse(0); - - newY.add(avg); + for (Map.Entry> e : entry.getValue().entrySet()) { + double avg = e.getValue().stream().mapToDouble(Double::doubleValue).average().orElse(0); + newY.computeIfAbsent(e.getKey(), k -> new ArrayList<>()).add(avg); + } } lineData.setXData(newX); @@ -180,49 +180,40 @@ public class LineDataHourAggregator { public static void aggregateLastByHalfHour(LineData lineData) { List xData = lineData.getXData(); - List yData = lineData.getYData(); + Map> yDataMap = lineData.getYData(); - if (xData == null || yData == null || xData.size() != yData.size()) { + if (xData == null || yDataMap == null) { return; } - // halfHour -> lastValue - Map halfHourLastMap = new TreeMap<>(); + Map> halfHourLastMap = new TreeMap<>(); for (int i = 0; i < xData.size(); i++) { - String timeStr = String.valueOf(xData.get(i)); - Object yVal = yData.get(i); - - if (yVal == null) { - continue; - } - - LocalDateTime time = LocalDateTime.parse(timeStr, INPUT_FMT); - - int minute = time.getMinute(); - int halfHourMinute = minute < 30 ? 0 : 30; + LocalDateTime time = LocalDateTime.parse(String.valueOf(xData.get(i)), INPUT_FMT); - LocalDateTime halfHourTime = time - .withMinute(halfHourMinute) - .withSecond(0) - .withNano(0); + int minute = time.getMinute() < 30 ? 0 : 30; + LocalDateTime halfHourTime = time.withMinute(minute).withSecond(0).withNano(0); + String key = halfHourTime.format(INPUT_FMT); - String halfHourKey = halfHourTime.format(INPUT_FMT); + for (Map.Entry> e : yDataMap.entrySet()) { + Object yVal = e.getValue().get(i); + if (yVal == null) continue; - // 同一个半小时,后面的会覆盖前面的 → 自然就是“最后一条” - halfHourLastMap.put( - halfHourKey, - Double.parseDouble(String.valueOf(yVal)) - ); + halfHourLastMap + .computeIfAbsent(key, k -> new HashMap<>()) + .put(e.getKey(), yVal); + } } - // 重新构建 xData / yData List newX = new ArrayList<>(); - List newY = new ArrayList<>(); + Map> newY = new HashMap<>(); - for (Map.Entry entry : halfHourLastMap.entrySet()) { + for (Map.Entry> entry : halfHourLastMap.entrySet()) { newX.add(entry.getKey()); - newY.add(entry.getValue()); + + for (Map.Entry e : entry.getValue().entrySet()) { + newY.computeIfAbsent(e.getKey(), k -> new ArrayList<>()).add(e.getValue()); + } } lineData.setXData(newX);