2024-01-03 11:48:54 -08:00
|
|
|
import { DataTableProps } from './DataTable';
|
2023-11-24 13:44:48 -08:00
|
|
|
import { GraphProps, GraphSeries } from './Graph';
|
|
|
|
|
2024-01-03 11:48:54 -08:00
|
|
|
export function isHeatmapData(data: DataTableProps['data']) {
|
|
|
|
if (data?.resultType === 'scalar' || data?.resultType === 'string' || !data?.result?.length || data?.result?.length < 2) {
|
2023-11-24 13:44:48 -08:00
|
|
|
return false;
|
|
|
|
}
|
2024-01-03 11:48:54 -08:00
|
|
|
// Type assertion to prevent TS2349 error.
|
|
|
|
const result = data.result as GraphProps['data']['result'];
|
2023-11-24 13:44:48 -08:00
|
|
|
const firstLabels = Object.keys(result[0].metric).filter((label) => label !== 'le');
|
|
|
|
return result.every(({ metric }) => {
|
|
|
|
const labels = Object.keys(metric).filter((label) => label !== 'le');
|
|
|
|
const allLabelsMatch = labels.every((label) => metric[label] === result[0].metric[label]);
|
|
|
|
return metric.le && labels.length === firstLabels.length && allLabelsMatch;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function prepareHeatmapData(buckets: GraphSeries[]) {
|
|
|
|
if (!buckets.every((a) => a.labels.le)) {
|
|
|
|
return buckets;
|
|
|
|
}
|
|
|
|
|
|
|
|
const sortedBuckets = buckets.sort((a, b) => promValueToNumber(a.labels.le) - promValueToNumber(b.labels.le));
|
|
|
|
const result: GraphSeries[] = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < sortedBuckets.length; i++) {
|
|
|
|
const values = [];
|
|
|
|
const { data, labels, color } = sortedBuckets[i];
|
|
|
|
|
|
|
|
for (const [timestamp, value] of data) {
|
|
|
|
const prevVal = sortedBuckets[i - 1]?.data.find((v) => v[0] === timestamp)?.[1] || 0;
|
|
|
|
const newVal = Number(value) - prevVal;
|
|
|
|
values.push([Number(timestamp), newVal]);
|
|
|
|
}
|
|
|
|
|
|
|
|
result.push({
|
|
|
|
data: values,
|
|
|
|
labels,
|
|
|
|
color,
|
|
|
|
index: i,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function promValueToNumber(s: string) {
|
|
|
|
switch (s) {
|
|
|
|
case 'NaN':
|
|
|
|
return NaN;
|
|
|
|
case 'Inf':
|
|
|
|
case '+Inf':
|
|
|
|
return Infinity;
|
|
|
|
case '-Inf':
|
|
|
|
return -Infinity;
|
|
|
|
default:
|
|
|
|
return parseFloat(s);
|
|
|
|
}
|
|
|
|
}
|