增加cpu温度处理

This commit is contained in:
gaoyutao
2026-01-16 18:11:16 +08:00
parent d62fe4b99a
commit 4ed1a66466
14 changed files with 242 additions and 100 deletions
@@ -53,7 +53,7 @@ public class EchartsDataUtils {
return Math.round(microseconds / 1_000_000.0 * 100.0) / 100.0;
}
/**
* 构建ECharts图表数据(带时间补全和特殊值处理)- 修复版本
* 构建ECharts图表数据(带时间补全和特殊值处理)- 最终修复版本
*/
public static <T> Map<String, Object> buildEchartsDataAutoPadding(
List<T> list,
@@ -84,9 +84,6 @@ public class EchartsDataUtils {
.sorted(Comparator.comparing(timeExtractor))
.collect(Collectors.toList());
// 自动检测时间间隔
long timeInterval = detectTimeInterval(sortedList, timeExtractor);
// 获取数据实际的时间范围
Date actualStartTime = timeExtractor.apply(sortedList.get(0));
Date actualEndTime = timeExtractor.apply(sortedList.get(sortedList.size() - 1));
@@ -96,39 +93,13 @@ public class EchartsDataUtils {
long sparseInterval = totalTimeRange > 12L * 30 * 24 * 60 * 60 * 1000 ?
30L * 24 * 60 * 60 * 1000 : 2L * 24 * 60 * 60 * 1000;
// 生成完整的时间序列
List<Date> fullTimeSeries = new ArrayList<>();
// 1. 开始时间到数据开始时间(稀疏间隔)
if (startDate.before(actualStartTime)) {
List<Date> beforeSeries = generateSparseTimeSeries(startDate, actualStartTime, sparseInterval);
fullTimeSeries.addAll(beforeSeries);
}
// 2. 数据开始时间到数据结束时间 - 以第一个数据点的时间为基准生成序列
List<Date> dataSeries = generateTimeSeriesFromDataPoints(actualStartTime, actualEndTime,
timeInterval, actualStartTime);
fullTimeSeries.addAll(dataSeries);
// 3. 数据结束时间到结束时间(稀疏间隔)
if (actualEndTime.before(endDate)) {
// 从actualEndTime的下一个时间点开始
Calendar cal = Calendar.getInstance();
cal.setTime(actualEndTime);
cal.add(Calendar.MILLISECOND, (int)timeInterval);
Date nextAfterActualEnd = cal.getTime();
if (nextAfterActualEnd.before(endDate) || nextAfterActualEnd.equals(endDate)) {
List<Date> afterSeries = generateSparseTimeSeries(nextAfterActualEnd, endDate, sparseInterval);
fullTimeSeries.addAll(afterSeries);
}
}
// 去重并排序
fullTimeSeries = fullTimeSeries.stream()
.distinct()
.sorted()
.collect(Collectors.toList());
// 核心修改:生成X轴时间序列
List<Date> xAxisTimes = generateXAxisTimeSeries(
startDate, endDate,
actualStartTime, actualEndTime,
sortedList, timeExtractor,
sparseInterval
);
// 创建时间到数据的映射
Map<String, T> timeDataMap = new HashMap<>();
@@ -152,7 +123,7 @@ public class EchartsDataUtils {
dataExtractors.keySet().forEach(name ->
yData.put(name, new ArrayList<>()));
for (Date time : fullTimeSeries) {
for (Date time : xAxisTimes) {
// X轴数据
String timeStr = parseDateToStr(time);
xAxisData.add(timeStr);
@@ -177,7 +148,7 @@ public class EchartsDataUtils {
} else {
// 智能数据补全
if (isInDataRange) {
// 在数据时间范围内但该时间点无数据(数据缺失点)
// 在数据时间范围内但该时间点无数据
seriesData.add(getDefaultValue(name, fixedPercentile95Value, xAxisData.size()-1, hasRealData));
} else {
// 在数据时间范围外
@@ -200,37 +171,54 @@ public class EchartsDataUtils {
}
/**
* 从第一个数据点开始生成时间序列
* 生成X轴时间序列(核心方法)
* 策略:优先使用实际数据的时间点,然后在数据点之间按需补全
*/
private static List<Date> generateTimeSeriesFromDataPoints(Date start, Date end,
long interval, Date firstDataPoint) {
private static <T> List<Date> generateXAxisTimeSeries(
Date queryStart, Date queryEnd,
Date dataStart, Date dataEnd,
List<T> sortedList, Function<T, Date> timeExtractor,
long sparseInterval) {
List<Date> timeSeries = new ArrayList<>();
if (interval <= 0) {
interval = 300000L; // 默认5分钟
// 1. 查询开始时间到数据开始时间(稀疏间隔)
if (queryStart.before(dataStart)) {
List<Date> beforeSeries = generateTimeSeries(queryStart, dataStart, sparseInterval, false);
timeSeries.addAll(beforeSeries);
}
// 使用第一个数据点的时间作为基准
Calendar calendar = Calendar.getInstance();
calendar.setTime(firstDataPoint);
calendar.set(Calendar.MILLISECOND, 0);
// 2. 数据时间范围内的处理
if (sortedList != null && !sortedList.isEmpty()) {
// 优先使用实际数据的所有时间点
List<Date> dataTimePoints = sortedList.stream()
.map(timeExtractor)
.sorted()
.collect(Collectors.toList());
timeSeries.addAll(dataTimePoints);
// 从第一个数据点开始向前找,直到找到小于等于start的时间点
while (calendar.getTime().after(start)) {
calendar.add(Calendar.MILLISECOND, -(int)interval);
// 检测数据点之间的间隔,补全缺失的时间点
if (dataTimePoints.size() > 1) {
List<Date> filledSeries = fillMissingTimePoints(dataTimePoints);
timeSeries.addAll(filledSeries);
}
}
// 如果当前位置在start之前,前进一个间隔
if (calendar.getTime().before(start)) {
calendar.add(Calendar.MILLISECOND, (int)interval);
}
// 3. 数据结束时间到查询结束时间(稀疏间隔
if (dataEnd.before(queryEnd)) {
// 从数据结束时间的下一个稀疏间隔点开始
Calendar cal = Calendar.getInstance();
cal.setTime(dataEnd);
cal.add(Calendar.MILLISECOND, (int)sparseInterval);
Date nextAfterDataEnd = cal.getTime();
// 生成时间序列
while (!calendar.getTime().after(end)) {
timeSeries.add(calendar.getTime());
calendar.add(Calendar.MILLISECOND, (int)interval);
if (nextAfterDataEnd.before(queryEnd) || nextAfterDataEnd.equals(queryEnd)) {
List<Date> afterSeries = generateTimeSeries(nextAfterDataEnd, queryEnd, sparseInterval, false);
timeSeries.addAll(afterSeries);
}
}
// 去重、排序
return timeSeries.stream()
.distinct()
.sorted()
@@ -238,21 +226,103 @@ public class EchartsDataUtils {
}
/**
* 生成稀疏时间序列
* 补全缺失的时间点
* 在相邻数据点之间,如果间隔太大,插入中间点
*/
private static List<Date> generateSparseTimeSeries(Date start, Date end, long interval) {
private static List<Date> fillMissingTimePoints(List<Date> dataTimePoints) {
List<Date> filledPoints = new ArrayList<>();
if (dataTimePoints.size() < 2) {
return filledPoints;
}
// 检测常见间隔
long commonInterval = detectCommonInterval(dataTimePoints);
for (int i = 0; i < dataTimePoints.size() - 1; i++) {
Date current = dataTimePoints.get(i);
Date next = dataTimePoints.get(i + 1);
long diff = next.getTime() - current.getTime();
// 如果间隔大于常见间隔的1.5倍,说明中间有缺失
if (diff > commonInterval * 1.5) {
// 计算可以插入几个点
int pointsToInsert = (int) (diff / commonInterval) - 1;
Calendar cal = Calendar.getInstance();
cal.setTime(current);
for (int j = 1; j <= pointsToInsert; j++) {
cal.add(Calendar.MILLISECOND, (int)commonInterval);
Date insertedPoint = cal.getTime();
// 确保插入的点不晚于next
if (insertedPoint.before(next)) {
filledPoints.add(insertedPoint);
}
}
}
}
return filledPoints;
}
/**
* 检测常见时间间隔
*/
private static long detectCommonInterval(List<Date> timePoints) {
if (timePoints.size() < 2) {
return 300000L; // 默认5分钟
}
Map<Long, Integer> intervalCount = new HashMap<>();
for (int i = 1; i < timePoints.size(); i++) {
long interval = timePoints.get(i).getTime() - timePoints.get(i-1).getTime();
if (interval > 0) {
intervalCount.merge(interval, 1, Integer::sum);
}
}
if (intervalCount.isEmpty()) {
return 300000L;
}
return intervalCount.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse(300000L);
}
/**
* 生成时间序列
* @param alignToInterval 是否对齐到时间间隔
*/
private static List<Date> generateTimeSeries(Date start, Date end, long interval, boolean alignToInterval) {
List<Date> timeSeries = new ArrayList<>();
if (interval <= 0) {
interval = 2L * 24 * 60 * 60 * 1000; // 默认2天
interval = 300000L;
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(start);
calendar.set(Calendar.MILLISECOND, 0);
if (alignToInterval) {
// 对齐到间隔
long startMillis = calendar.getTimeInMillis();
long normalizedStart = (startMillis / interval) * interval;
calendar.setTimeInMillis(normalizedStart);
if (normalizedStart < startMillis) {
calendar.add(Calendar.MILLISECOND, (int)interval);
}
}
// 包含开始时间
timeSeries.add(calendar.getTime());
if (!calendar.getTime().after(end)) {
timeSeries.add(calendar.getTime());
}
while (true) {
calendar.add(Calendar.MILLISECOND, (int)interval);
@@ -262,10 +332,7 @@ public class EchartsDataUtils {
timeSeries.add(calendar.getTime());
}
return timeSeries.stream()
.distinct()
.sorted()
.collect(Collectors.toList());
return timeSeries;
}
/**
@@ -385,35 +385,27 @@ public class SpeedUtils {
}
public static String determineUnitByValue(Long value) {
if (value == null || value == 0) {
return "KB";
return "Kb";
}
// 注意:这里使用二进制单位(1024)
if (value >= 1024L * 1024 * 1024 * 1024) { // >= 1TB
return "TB";
} else if (value >= 1024L * 1024 * 1024) { // >= 1GB
return "GB";
if (value >= 1024L * 1024 * 1024) { // >= 1GB
return "Gb";
} else if (value >= 1024L * 1024) { // >= 1MB
return "MB";
return "Mb";
} else {
return "KB";
return "Kb";
}
}
// 工具方法:获取单位换算除数
public static BigDecimal get1024Divisor(String unit) {
switch (unit) {
case "GB":
case "Gb":
return new BigDecimal(1024L * 1024 * 1024); // 1GB = 1024^3
case "MB":
case "Mb":
return new BigDecimal(1024L * 1024); // 1MB = 1024^2
case "KB":
case "Kb":
return new BigDecimal(1024); // 1KB = 1024
case "TB":
case "Tb":
return new BigDecimal(1024L * 1024 * 1024 * 1024); // 1TB = 1024^4
default:
return new BigDecimal(1024); // 默认返回KB的除数
}