mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-25 03:16:53 +00:00
136 lines
3.4 KiB
TypeScript
136 lines
3.4 KiB
TypeScript
import { ChartData, ChartDataset } from 'chart.js';
|
|
import getLabelName from 'lib/getLabelName';
|
|
import { QueryData } from 'types/api/widgets/getQuery';
|
|
|
|
import convertIntoEpoc from './covertIntoEpoc';
|
|
import { colors } from './getRandomColor';
|
|
|
|
export const limit = 30;
|
|
|
|
const getChartData = ({
|
|
queryData,
|
|
createDataset,
|
|
isWarningLimit = false,
|
|
}: GetChartDataProps): {
|
|
data: ChartData;
|
|
isWarning: boolean;
|
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
} => {
|
|
const uniqueTimeLabels = new Set<number>();
|
|
queryData.forEach((data) => {
|
|
data.queryData.forEach((query) => {
|
|
query.values.forEach((value) => {
|
|
uniqueTimeLabels.add(value[0]);
|
|
});
|
|
});
|
|
});
|
|
|
|
const labels = Array.from(uniqueTimeLabels).sort((a, b) => a - b);
|
|
|
|
const response = queryData.map(
|
|
({ queryData, query: queryG, legend: legendG }) =>
|
|
queryData.map((e) => {
|
|
const { values = [], metric, legend, queryName } = e || {};
|
|
const labelNames = getLabelName(
|
|
metric,
|
|
queryName || queryG || '', // query
|
|
legend || legendG || '',
|
|
);
|
|
const dataValue = values?.map((e) => {
|
|
const [first = 0, second = ''] = e || [];
|
|
return {
|
|
first: new Date(parseInt(convertIntoEpoc(first * 1000), 10)), // converting in ms
|
|
second: Number(parseFloat(second)),
|
|
};
|
|
});
|
|
// Fill the missing data with null
|
|
const filledDataValues = Array.from(labels).map((e) => {
|
|
const td1 = new Date(parseInt(convertIntoEpoc(e * 1000), 10));
|
|
const data = dataValue.find((e1) => e1.first.getTime() === td1.getTime());
|
|
return (
|
|
data || {
|
|
first: new Date(parseInt(convertIntoEpoc(e * 1000), 10)),
|
|
second: null,
|
|
}
|
|
);
|
|
});
|
|
|
|
return {
|
|
label: labelNames !== 'undefined' ? labelNames : '',
|
|
first: filledDataValues.map((e) => e.first || 0),
|
|
second: filledDataValues.map((e) => e.second || 0),
|
|
};
|
|
}),
|
|
);
|
|
|
|
const modifiedData = response
|
|
.flat()
|
|
.sort((a, b) => {
|
|
const len = Math.min(a.second.length, b.second.length); // min length of both array
|
|
|
|
for (let i = 0; i < len; i += 1) {
|
|
const avearageOfArray = (arr: number[]): number =>
|
|
arr.reduce((a, b) => a + b, 0) / arr.length;
|
|
|
|
const diff = avearageOfArray(a.second) - avearageOfArray(b.second); // calculating the difference
|
|
|
|
if (diff !== 0) return diff;
|
|
}
|
|
|
|
return a.second.length - b.second.length;
|
|
})
|
|
.reverse();
|
|
|
|
const updatedSortedData = isWarningLimit
|
|
? modifiedData.slice(0, limit)
|
|
: modifiedData;
|
|
|
|
const allLabels = modifiedData.map((e) => e.label);
|
|
|
|
const updatedDataSet = updatedSortedData.map((e, index) => {
|
|
const datasetBaseConfig = {
|
|
index,
|
|
label: allLabels[index],
|
|
borderColor: colors[index % colors.length] || 'red',
|
|
data: e.second,
|
|
borderWidth: 1.5,
|
|
spanGaps: true,
|
|
animations: false,
|
|
showLine: true,
|
|
pointRadius: 0,
|
|
};
|
|
|
|
return createDataset
|
|
? createDataset(e.second, index, allLabels)
|
|
: datasetBaseConfig;
|
|
});
|
|
|
|
const updatedLabels = modifiedData.map((e) => e.first).flat();
|
|
|
|
const updatedData = {
|
|
datasets: updatedDataSet,
|
|
labels: updatedLabels,
|
|
};
|
|
|
|
return {
|
|
data: updatedData,
|
|
isWarning: isWarningLimit && (allLabels?.length || 0) > limit,
|
|
};
|
|
};
|
|
|
|
export interface GetChartDataProps {
|
|
queryData: {
|
|
query?: string;
|
|
legend?: string;
|
|
queryData: QueryData[];
|
|
}[];
|
|
createDataset?: (
|
|
element: (number | null)[],
|
|
index: number,
|
|
allLabels: string[],
|
|
) => ChartDataset;
|
|
isWarningLimit?: boolean;
|
|
}
|
|
|
|
export default getChartData;
|