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(); 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 label = allLabels[index]; const datasetBaseConfig = { index, label, 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;