Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 62 additions & 25 deletions src/components/charts/TimeSeriesChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import ReactECharts, { EChartsOption } from 'echarts-for-react';
import { format } from 'date-fns';
import { parseDate } from '../../lib/daterange';
import React, { useState, useEffect, memo, useRef } from 'react';
import React, { useState, useEffect, memo, useRef, useCallback } from 'react';
import { getBackendSrv } from '@grafana/runtime';
import { getBackendUrl } from '../../constants';
const formatNumber = (num: number) => {
Expand All @@ -25,7 +25,13 @@ function lessThan3Day(startTs: number, endTs: number) {
const whoAmI = "timeseries-chart";

// Create the base component
function TimeSeriesChartBase(params: {
function TimeSeriesChartBase({
startDate,
endDate,
whoChanged,
currentTable,
onDateRangeSelect
}: {
startDate: string
endDate: string
whoChanged: string
Expand All @@ -43,17 +49,39 @@ function TimeSeriesChartBase(params: {
endTs: 0
});

// Add throttling timer ref
const throttleTimerRef = useRef<NodeJS.Timeout | null>(null);

// Throttled version of onDateRangeSelect
const throttledDateRangeSelect = useCallback((newStartDate: string, newEndDate: string) => {
if (throttleTimerRef.current) {
clearTimeout(throttleTimerRef.current);
}

throttleTimerRef.current = setTimeout(() => {
onDateRangeSelect?.(newStartDate, newEndDate, whoAmI);
}, 150); // 150ms throttle
}, [onDateRangeSelect]);

// Cleanup throttle timer
useEffect(() => {
return () => {
if (throttleTimerRef.current) {
clearTimeout(throttleTimerRef.current);
}
};
}, []);

if (params.currentTable == null) {
useEffect(() => {
if (currentTable == null) {
return;
}
if (params.currentTable === "") {
if (currentTable === "") {
return;
}

const startTs = parseDate(params.startDate);
const endTs = parseDate(params.endDate);
const startTs = parseDate(startDate);
const endTs = parseDate(endDate);

dataRangeRef.current = { startTs, endTs };

Expand All @@ -65,7 +93,7 @@ function TimeSeriesChartBase(params: {
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify({ query: "", startDate: startTs, endDate: endTs, tableName: params.currentTable }),
data: JSON.stringify({ query: "", startDate: startTs, endDate: endTs, tableName: currentTable }),
showErrorAlert: false
}).subscribe({
next: (resp) => {
Expand All @@ -82,8 +110,7 @@ function TimeSeriesChartBase(params: {
}
});


}, [params.startDate, params.endDate, params.currentTable]);
}, [startDate, endDate, currentTable]);

if (loading) {
return null;
Expand Down Expand Up @@ -258,11 +285,7 @@ function TimeSeriesChartBase(params: {

dataRangeRef.current = { startTs, endTs };

params.onDateRangeSelect?.(
startDate,
endDate,
whoAmI
);
throttledDateRangeSelect(startDate, endDate);
}
}
}}
Expand All @@ -271,32 +294,46 @@ function TimeSeriesChartBase(params: {
);
}

// Create a custom comparison function for memo
// Optimize the comparison function for memo
const arePropsEqual = (prevProps: any, nextProps: any) => {
const prevStartTs = parseDate(prevProps.startDate);
const prevEndTs = parseDate(prevProps.endDate);
const nextStartTs = parseDate(nextProps.startDate);
const nextEndTs = parseDate(nextProps.endDate);
// Quick equality check for identical objects
if (prevProps === nextProps) {
return true;
}

// If table changed, must re-render
if (prevProps.currentTable !== nextProps.currentTable) {
return false
return false;
}

// If change came from another component, must re-render
if (nextProps.whoChanged !== whoAmI) {
return false;
}

// If the new date range is within the old one, don't re-render
const prevStartTs = parseDate(prevProps.startDate);
const prevEndTs = parseDate(prevProps.endDate);
const nextStartTs = parseDate(nextProps.startDate);
const nextEndTs = parseDate(nextProps.endDate);

// If dates are exactly the same, don't re-render
if (prevStartTs === nextStartTs && prevEndTs === nextEndTs) {
return true;
}

// If new range is within old range, don't re-render
if (nextStartTs >= prevStartTs && nextEndTs <= prevEndTs) {
return true; // props are equal, don't re-render
return true;
}

// If the date range is exactly the same, don't re-render
if (prevStartTs === nextStartTs && prevEndTs === nextEndTs) {
// If the difference is less than 1 second, don't re-render
const startDiff = Math.abs(nextStartTs - prevStartTs);
const endDiff = Math.abs(nextEndTs - prevEndTs);
if (startDiff < 1000 && endDiff < 1000) {
return true;
}

return false; // props are different, allow re-render
return false;
};

// Export the memoized component
Expand Down
Loading