Browse Source

ydata改成多个数据

master
review512jwy@163.com 1 month ago
parent
commit
7ef0631145
  1. 4
      dongjian-dashboard-back-model/src/main/java/com/dongjian/dashboard/back/vo/device/LineData.java
  2. 4
      dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/CommonOpt.java
  3. 195
      dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/LineDataHourAggregator.java

4
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<Object> xData = new ArrayList<>();
@Schema(description = "Y-axis data", example = "[]")
private List<Object> yData = new ArrayList<>();
private Map<String, List<Object>> yData = new HashMap<>();
}

4
dongjian-dashboard-back-service/src/main/java/com/dongjian/dashboard/back/service/common/CommonOpt.java

@ -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);

195
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<Object> xData = lineData.getXData();
List<Object> yData = lineData.getYData();
Map<String, List<Object>> yDataMap = lineData.getYData();
if (xData == null || yData == null || xData.size() != yData.size()) {
if (xData == null || yDataMap == null || yDataMap.isEmpty()) {
return;
}
// hour -> List<Double>
Map<String, List<Double>> hourMap = new TreeMap<>();
// hour -> index
Map<String, Integer> hourIndexMap = new TreeMap<>();
Map<String, Map<String, List<Double>>> 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<String, List<Object>> 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<Object> newX = new ArrayList<>();
List<Object> newY = new ArrayList<>();
Map<String, List<Object>> newY = new HashMap<>();
for (Map.Entry<String, List<Double>> 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<String, List<Double>> seriesMap = hourValueMap.get(hourKey);
if (seriesMap == null) {
continue;
}
newY.add(avg);
for (Map.Entry<String, List<Double>> 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<Object> xData = lineData.getXData();
List<Object> yData = lineData.getYData();
Map<String, List<Object>> 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<String, Map<String, Object>> valueMap = new HashMap<>();
// 现有数据转 Map
Map<String, Double> 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<String, List<Object>> e : yDataMap.entrySet()) {
valueMap
.computeIfAbsent(time, k -> new HashMap<>())
.put(e.getKey(), e.getValue().get(i));
}
}
// 日本“今天”
LocalDate todayJst = LocalDate.now(JST);
List<Object> newX = new ArrayList<>(48);
List<Object> newY = new ArrayList<>(48);
// 日本当天 00:00
LocalDateTime start = todayJst.atStartOfDay();
Map<String, List<Object>> 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<String, Object> 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<Object> xData = lineData.getXData();
List<Object> yData = lineData.getYData();
Map<String, List<Object>> yDataMap = lineData.getYData();
if (xData == null || yData == null || xData.size() != yData.size()) {
if (xData == null || yDataMap == null) {
return;
}
// halfHour -> List<Double>
Map<String, List<Double>> halfHourMap = new TreeMap<>();
Map<String, Map<String, List<Double>>> 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<String, List<Object>> 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<Object> newX = new ArrayList<>();
List<Object> newY = new ArrayList<>();
Map<String, List<Object>> newY = new HashMap<>();
for (Map.Entry<String, List<Double>> entry : halfHourMap.entrySet()) {
for (Map.Entry<String, Map<String, List<Double>>> entry : halfHourMap.entrySet()) {
newX.add(entry.getKey());
double avg = entry.getValue()
.stream()
.mapToDouble(Double::doubleValue)
.average()
.orElse(0);
newY.add(avg);
for (Map.Entry<String, List<Double>> 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<Object> xData = lineData.getXData();
List<Object> yData = lineData.getYData();
Map<String, List<Object>> yDataMap = lineData.getYData();
if (xData == null || yData == null || xData.size() != yData.size()) {
if (xData == null || yDataMap == null) {
return;
}
// halfHour -> lastValue
Map<String, Double> halfHourLastMap = new TreeMap<>();
Map<String, Map<String, Object>> 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<String, List<Object>> 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<Object> newX = new ArrayList<>();
List<Object> newY = new ArrayList<>();
Map<String, List<Object>> newY = new HashMap<>();
for (Map.Entry<String, Double> entry : halfHourLastMap.entrySet()) {
for (Map.Entry<String, Map<String, Object>> entry : halfHourLastMap.entrySet()) {
newX.add(entry.getKey());
newY.add(entry.getValue());
for (Map.Entry<String, Object> e : entry.getValue().entrySet()) {
newY.computeIfAbsent(e.getKey(), k -> new ArrayList<>()).add(e.getValue());
}
}
lineData.setXData(newX);

Loading…
Cancel
Save