diff --git a/frontend/src/container/NewWidget/RightContainer/index.tsx b/frontend/src/container/NewWidget/RightContainer/index.tsx
index d8f650f083..023dd584b2 100644
--- a/frontend/src/container/NewWidget/RightContainer/index.tsx
+++ b/frontend/src/container/NewWidget/RightContainer/index.tsx
@@ -107,48 +107,8 @@ function RightContainer({
}
/>
- {/*
- Stacked Graphs :
- {
- setStacked((value) => !value);
- }}
- />
- */}
-
- {/*
Fill Opacity: */}
-
- {/* onChangeHandler(setOpacity, number.toString())}
- step={1}
- /> */}
-
- {/* Null/Zero values:
-
-
- {nullValueButtons.map((button) => (
-
- ))}
- */}
-
- Fill span gaps
+ Fill gaps
{
const container = document.createElement('div');
container.classList.add('tooltip-container');
+ const overlay = document.getElementById('overlay');
+ let tooltipCount = 0;
let tooltipTitle = '';
const formattedData: Record = {};
@@ -49,28 +51,40 @@ const generateTooltipContent = (
const { metric = {}, queryName = '', legend = '' } =
seriesList[index - 1] || {};
+ const value = data[index][idx];
const label = getLabelName(metric, queryName || '', legend || '');
- const value = data[index][idx] || 0;
- const tooltipValue = getToolTipValue(value, yAxisUnit);
+ if (value) {
+ const tooltipValue = getToolTipValue(value, yAxisUnit);
- const dataObj = {
- show: item.show || false,
- color: colors[(index - 1) % colors.length],
- label,
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- focus: item?._focus || false,
- value,
- tooltipValue,
- textContent: `${label} : ${tooltipValue}`,
- };
+ const dataObj = {
+ show: item.show || false,
+ color: colors[(index - 1) % colors.length],
+ label,
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ focus: item?._focus || false,
+ value,
+ tooltipValue,
+ textContent: `${label} : ${tooltipValue}`,
+ };
- formattedData[label] = dataObj;
+ tooltipCount += 1;
+ formattedData[label] = dataObj;
+ }
}
});
}
+ // Show tooltip only if atleast only series has a value at the hovered timestamp
+ if (tooltipCount <= 0) {
+ if (overlay && overlay.style.display === 'block') {
+ overlay.style.display = 'none';
+ }
+
+ return container;
+ }
+
const sortedData: Record<
string,
UplotTooltipDataProps
@@ -116,8 +130,6 @@ const generateTooltipContent = (
});
}
- const overlay = document.getElementById('overlay');
-
if (overlay && overlay.style.display === 'none') {
overlay.style.display = 'block';
}
diff --git a/frontend/src/lib/uPlotLib/utils/getUplotChartData.ts b/frontend/src/lib/uPlotLib/utils/getUplotChartData.ts
index be4bfb59e5..d1f5a7ffbc 100644
--- a/frontend/src/lib/uPlotLib/utils/getUplotChartData.ts
+++ b/frontend/src/lib/uPlotLib/utils/getUplotChartData.ts
@@ -1,44 +1,65 @@
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
+import { QueryData } from 'types/api/widgets/getQuery';
-// eslint-disable-next-line sonarjs/cognitive-complexity
-function fillMissingTimestamps(
- sortedTimestamps: number[],
- subsetArray: any[],
- fillSpans: boolean | undefined,
-): any[] {
- const filledArray = [];
+function getXAxisTimestamps(seriesList: QueryData[]): number[] {
+ const timestamps = new Set();
- let subsetIndex = 0;
- // eslint-disable-next-line no-restricted-syntax
- for (const timestamp of sortedTimestamps) {
- if (
- subsetIndex < subsetArray.length &&
- timestamp === subsetArray[subsetIndex][0]
- ) {
- // Timestamp is present in subsetArray
- const seriesPointData = subsetArray[subsetIndex];
+ seriesList.forEach((series: { values: [number, string][] }) => {
+ series.values.forEach((value) => {
+ timestamps.add(value[0]);
+ });
+ });
- if (
- seriesPointData &&
- Array.isArray(seriesPointData) &&
- seriesPointData.length > 0 &&
- seriesPointData[1] !== 'NaN'
- ) {
- filledArray.push(subsetArray[subsetIndex]);
- } else {
- const value = fillSpans ? 0 : null;
- filledArray.push([seriesPointData[0], value]);
- }
+ const timestampsArr: number[] | unknown[] = Array.from(timestamps) || [];
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ return timestampsArr.sort((a, b) => a - b);
+}
- subsetIndex += 1;
- } else {
- // Timestamp is missing in subsetArray, fill with [timestamp, 0]
+function fillMissingXAxisTimestamps(
+ timestampArr: number[],
+ data: any[],
+ fillSpans: boolean,
+): any {
+ // Generate a set of all timestamps in the range
+ const allTimestampsSet = new Set(timestampArr);
+ const processedData = JSON.parse(JSON.stringify(data));
+
+ // Fill missing timestamps with null values
+ processedData.forEach((entry: { values: (number | null)[][] }) => {
+ const existingTimestamps = new Set(entry.values.map((value) => value[0]));
+
+ const missingTimestamps = Array.from(allTimestampsSet).filter(
+ (timestamp) => !existingTimestamps.has(timestamp),
+ );
+
+ missingTimestamps.forEach((timestamp) => {
const value = fillSpans ? 0 : null;
- filledArray.push([timestamp, value]);
- }
- }
- return filledArray;
+ entry.values.push([timestamp, value]);
+ });
+
+ entry.values.forEach((v) => {
+ if (Number.isNaN(v[1])) {
+ const replaceValue = fillSpans ? 0 : null;
+ // eslint-disable-next-line no-param-reassign
+ v[1] = replaceValue;
+ } else if (v[1] !== null) {
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ // eslint-disable-next-line no-param-reassign
+ v[1] = parseFloat(v[1]);
+ }
+ });
+
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ entry.values.sort((a, b) => a[0] - b[0]);
+ });
+
+ return processedData.map((entry: { values: [number, string][] }) =>
+ entry.values.map((value) => value[1]),
+ );
}
export const getUPlotChartData = (
@@ -46,43 +67,12 @@ export const getUPlotChartData = (
fillSpans?: boolean,
): any[] => {
const seriesList = apiResponse?.data?.result || [];
- const uPlotData = [];
-
- // this helps us identify the series with the max number of values and helps define the x axis - timestamps
- const xSeries = seriesList.reduce(
- (maxObj, currentObj) =>
- currentObj.values.length > maxObj.values.length ? currentObj : maxObj,
- seriesList[0],
+ const timestampArr = getXAxisTimestamps(seriesList);
+ const yAxisValuesArr = fillMissingXAxisTimestamps(
+ timestampArr,
+ seriesList,
+ fillSpans || false,
);
- // sort seriesList
- for (let index = 0; index < seriesList.length; index += 1) {
- seriesList[index]?.values?.sort((a, b) => a[0] - b[0]);
- }
-
- const timestampArr = xSeries?.values?.map((v) => v[0]);
-
- // timestamp
- uPlotData.push(timestampArr);
-
- // for each series, push the values
- seriesList.forEach((series) => {
- const updatedSeries = fillMissingTimestamps(
- timestampArr,
- series?.values || [],
- fillSpans,
- );
-
- const seriesData =
- updatedSeries?.map((v) => {
- if (v[1] === null) {
- return v[1];
- }
- return parseFloat(v[1]);
- }) || [];
-
- uPlotData.push(seriesData);
- });
-
- return uPlotData;
+ return [timestampArr, ...yAxisValuesArr];
};
diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss
index 8efda895d4..6712b4c59a 100644
--- a/frontend/src/styles.scss
+++ b/frontend/src/styles.scss
@@ -42,6 +42,11 @@ body {
border-radius: 50%;
}
}
+
+ &.u-off {
+ text-decoration: line-through;
+ text-decoration-thickness: 3px;
+ }
}
}