优化图形补0、null机制,优化监控看板接口
mtr监控策略相关接口
This commit is contained in:
+82
-21
@@ -54,13 +54,6 @@ public class EchartsDataUtils {
|
||||
}
|
||||
/**
|
||||
* 构建ECharts图表数据(带时间补全和特殊值处理)
|
||||
* @param list 原始数据列表
|
||||
* @param timeExtractor 时间字段提取函数
|
||||
* @param dataExtractors 数据提取器Map
|
||||
* @param startTime 开始时间字符串(格式:yyyy-MM-dd HH:mm:ss)
|
||||
* @param endTime 结束时间字符串(格式:yyyy-MM-dd HH:mm:ss)
|
||||
* @param <T> 数据类型泛型
|
||||
* @return 包含xData和yData的Map
|
||||
*/
|
||||
public static <T> Map<String, Object> buildEchartsDataAutoPadding(
|
||||
List<T> list,
|
||||
@@ -91,11 +84,44 @@ public class EchartsDataUtils {
|
||||
.sorted(Comparator.comparing(timeExtractor))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 自动检测时间间隔
|
||||
// 自动检测时间间隔(用于数据期间)
|
||||
long timeInterval = detectTimeInterval(sortedList, timeExtractor);
|
||||
|
||||
// 生成完整的时间序列
|
||||
List<Date> fullTimeSeries = generateTimeSeries(startDate, endDate, timeInterval);
|
||||
// 获取数据实际的时间范围
|
||||
Date actualStartTime = timeExtractor.apply(sortedList.get(0));
|
||||
Date actualEndTime = timeExtractor.apply(sortedList.get(sortedList.size() - 1));
|
||||
|
||||
// 计算稀疏间隔(用于数据期间外)
|
||||
long totalTimeRange = endDate.getTime() - startDate.getTime();
|
||||
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 = generateTimeSeries(startDate, actualStartTime, sparseInterval);
|
||||
fullTimeSeries.addAll(beforeSeries);
|
||||
}
|
||||
|
||||
// 2. 数据开始时间到数据结束时间(正常间隔)
|
||||
List<Date> dataSeries = generateTimeSeries(actualStartTime, actualEndTime, timeInterval);
|
||||
fullTimeSeries.addAll(dataSeries);
|
||||
|
||||
// 3. 数据结束时间到结束时间(稀疏间隔)
|
||||
if (actualEndTime.before(endDate)) {
|
||||
// 调整actualEndTime的下一个点开始,避免重复
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(actualEndTime);
|
||||
cal.setTimeInMillis(cal.getTimeInMillis() + timeInterval);
|
||||
Date nextAfterActualEnd = cal.getTime();
|
||||
|
||||
if (nextAfterActualEnd.before(endDate) || nextAfterActualEnd.equals(endDate)) {
|
||||
List<Date> afterSeries = generateTimeSeries(nextAfterActualEnd, endDate, sparseInterval);
|
||||
fullTimeSeries.addAll(afterSeries);
|
||||
}
|
||||
}
|
||||
|
||||
// 创建时间到数据的映射(考虑时间精度)
|
||||
Map<Long, T> timeDataMap = sortedList.stream()
|
||||
@@ -105,6 +131,12 @@ public class EchartsDataUtils {
|
||||
(a, b) -> a
|
||||
));
|
||||
|
||||
// 检测整个数据集中是否有真实数据
|
||||
boolean hasRealData = checkHasRealData(sortedList, dataExtractors);
|
||||
|
||||
// 特殊处理:查找percentile95的固定值
|
||||
Object fixedPercentile95Value = findFixedValueForPercentile95(sortedList, dataExtractors);
|
||||
|
||||
// 准备X轴和Y轴数据
|
||||
List<String> xAxisData = new ArrayList<>();
|
||||
Map<String, Object> yData = new LinkedHashMap<>();
|
||||
@@ -113,12 +145,6 @@ public class EchartsDataUtils {
|
||||
dataExtractors.keySet().forEach(name ->
|
||||
yData.put(name, new ArrayList<>()));
|
||||
|
||||
// 特殊处理:查找percentile95的固定值
|
||||
Object fixedPercentile95Value = findFixedValueForPercentile95(sortedList, dataExtractors);
|
||||
|
||||
// 检测整个数据集中是否有真实数据
|
||||
boolean hasRealData = checkHasRealData(sortedList, dataExtractors);
|
||||
|
||||
// 记录当前处理的时间点索引
|
||||
int timeIndex = 0;
|
||||
|
||||
@@ -126,6 +152,9 @@ public class EchartsDataUtils {
|
||||
// X轴数据
|
||||
xAxisData.add(parseDateToStr(time));
|
||||
|
||||
// 判断当前时间点是否在数据实际时间范围内
|
||||
boolean isInDataRange = !time.before(actualStartTime) && !time.after(actualEndTime);
|
||||
|
||||
// Y轴数据
|
||||
Long normalizedTime = normalizeTime(time, timeInterval);
|
||||
T item = timeDataMap.get(normalizedTime);
|
||||
@@ -138,11 +167,18 @@ public class EchartsDataUtils {
|
||||
List<Object> seriesData = (List<Object>) yData.get(name);
|
||||
|
||||
if (item != null) {
|
||||
// 有真实数据
|
||||
Object value = extractor.apply(item);
|
||||
seriesData.add(value != null ? value : getDefaultValue(name, fixedPercentile95Value, timeIndex, hasRealData));
|
||||
} else {
|
||||
// 智能数据补全
|
||||
seriesData.add(getDefaultValue(name, fixedPercentile95Value, timeIndex, hasRealData));
|
||||
if (isInDataRange) {
|
||||
// 在数据时间范围内但该时间点无数据:使用智能补全策略
|
||||
seriesData.add(getDefaultValue(name, fixedPercentile95Value, timeIndex, hasRealData));
|
||||
} else {
|
||||
// 在数据时间范围外(开始时间前或结束时间后):使用空数据补全策略
|
||||
seriesData.add(getEmptyDataDefaultValue(name, timeIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +197,23 @@ public class EchartsDataUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取空数据默认值(用于数据时间范围外的点)
|
||||
*/
|
||||
private static Object getEmptyDataDefaultValue(String metricName, int timeIndex) {
|
||||
// deployDevice特殊处理:始终补空字符串
|
||||
if ("deployDevice".equals(metricName)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 其他字段:第一个点补0,其他点补null
|
||||
if (timeIndex == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测整个数据集中是否有真实数据(非null)
|
||||
*/
|
||||
@@ -245,9 +298,17 @@ public class EchartsDataUtils {
|
||||
Date endDate = parseStringToDate(endTime);
|
||||
|
||||
if (startDate != null && endDate != null && !startDate.after(endDate)) {
|
||||
// 使用默认时间间隔生成完整时间序列
|
||||
long defaultInterval = 300000L; // 5分钟
|
||||
List<Date> fullTimeSeries = generateTimeSeries(startDate, endDate, defaultInterval);
|
||||
// 动态计算时间间隔
|
||||
long timeRange = endDate.getTime() - startDate.getTime();
|
||||
long interval;
|
||||
|
||||
if (timeRange > 12L * 30 * 24 * 60 * 60 * 1000) { // 超过12个月
|
||||
interval = 30L * 24 * 60 * 60 * 1000; // 每月1个点
|
||||
} else {
|
||||
interval = 2L * 24 * 60 * 60 * 1000; // 2天1个点
|
||||
}
|
||||
|
||||
List<Date> fullTimeSeries = generateTimeSeries(startDate, endDate, interval);
|
||||
|
||||
// 构建x轴数据
|
||||
List<String> xAxisData = new ArrayList<>();
|
||||
@@ -256,7 +317,7 @@ public class EchartsDataUtils {
|
||||
}
|
||||
result.put("xData", xAxisData);
|
||||
|
||||
// 构建y轴数据(空数据集:第一个点补0,其他点补null)
|
||||
// 构建y轴数据(空数据集)
|
||||
Map<String, Object> yData = new LinkedHashMap<>();
|
||||
int dataSize = xAxisData.size();
|
||||
dataNames.forEach(name -> {
|
||||
|
||||
Reference in New Issue
Block a user