diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx index d51dae088a..8ecd0c9cba 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx @@ -1,3 +1,4 @@ +import { ActiveElement, Chart, ChartData, ChartEvent } from 'chart.js'; import Graph from 'components/Graph'; import { METRICS_PAGE_QUERY_PARAM } from 'constants/query'; import ROUTES from 'constants/routes'; @@ -29,7 +30,29 @@ import { onGraphClickHandler, onViewTracePopupClick } from './util'; function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element { const { servicename } = useParams<{ servicename?: string }>(); const [selectedTimeStamp, setSelectedTimeStamp] = useState(0); + + const handleSetTimeStamp = useCallback((selectTime: number) => { + setSelectedTimeStamp(selectTime); + }, []); + const dispatch = useDispatch(); + const handleGraphClick = useCallback( + (type: string): ClickHandlerType => ( + ChartEvent: ChartEvent, + activeElements: ActiveElement[], + chart: Chart, + data: ChartData, + ): void => { + onGraphClickHandler(handleSetTimeStamp)( + ChartEvent, + activeElements, + chart, + data, + type, + ); + }, + [handleSetTimeStamp], + ); const { topOperations, @@ -82,14 +105,16 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element { const startTimestamp = Math.trunc(start); const endTimestamp = Math.trunc(end); - dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp])); + if (startTimestamp !== endTimestamp) { + dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp])); + } }, [dispatch], ); const onErrorTrackHandler = (timestamp: number): void => { const currentTime = timestamp; - const tPlusOne = timestamp + 1 * 60 * 1000; + const tPlusOne = timestamp + 60 * 1000; const urlParams = new URLSearchParams(); urlParams.set(METRICS_PAGE_QUERY_PARAM.startTime, currentTime.toString()); @@ -102,6 +127,52 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element { ); }; + const generalChartDataProperties = useCallback( + (title: string, colorIndex: number) => ({ + borderColor: colors[colorIndex], + label: title, + showLine: true, + borderWidth: 1.5, + spanGaps: true, + pointRadius: 2, + pointHoverRadius: 4, + }), + [], + ); + + const dataSets = useMemo( + () => [ + { + data: serviceOverview.map((e) => + parseFloat(convertToNanoSecondsToSecond(e.p99)), + ), + ...generalChartDataProperties('p99 Latency', 0), + }, + { + data: serviceOverview.map((e) => + parseFloat(convertToNanoSecondsToSecond(e.p95)), + ), + ...generalChartDataProperties('p95 Latency', 1), + }, + { + data: serviceOverview.map((e) => + parseFloat(convertToNanoSecondsToSecond(e.p50)), + ), + ...generalChartDataProperties('p50 Latency', 2), + }, + ], + [generalChartDataProperties, serviceOverview], + ); + + const data = useMemo( + () => ({ + datasets: dataSets, + labels: serviceOverview.map( + (e) => new Date(parseFloat(convertToNanoSecondsToSecond(e.timestamp))), + ), + }), + [serviceOverview, dataSets], + ); return ( <> @@ -122,58 +193,11 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element { Latency { - onGraphClickHandler(setSelectedTimeStamp)( - ChartEvent, - activeElements, - chart, - data, - 'Service', - ); - }} + animate={false} + onClickHandler={handleGraphClick('Service')} name="service_latency" type="line" - data={{ - datasets: [ - { - data: serviceOverview.map((e) => - parseFloat(convertToNanoSecondsToSecond(e.p99)), - ), - borderColor: colors[0], - label: 'p99 Latency', - showLine: true, - borderWidth: 1.5, - spanGaps: true, - pointRadius: 1.5, - }, - { - data: serviceOverview.map((e) => - parseFloat(convertToNanoSecondsToSecond(e.p95)), - ), - borderColor: colors[1], - label: 'p95 Latency', - showLine: true, - borderWidth: 1.5, - spanGaps: true, - pointRadius: 1.5, - }, - { - data: serviceOverview.map((e) => - parseFloat(convertToNanoSecondsToSecond(e.p50)), - ), - borderColor: colors[2], - label: 'p50 Latency', - showLine: true, - borderWidth: 1.5, - spanGaps: true, - pointRadius: 1.5, - }, - ], - labels: serviceOverview.map( - (e) => - new Date(parseFloat(convertToNanoSecondsToSecond(e.timestamp))), - ), - }} + data={data} yAxisUnit="ms" onDragSelect={onDragSelect} /> @@ -200,15 +224,7 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element { { - onGraphClickHandler(setSelectedTimeStamp)( - event, - element, - chart, - data, - 'Rate', - ); - }} + onClickHandler={handleGraphClick('Rate')} widget={operationPerSecWidget} yAxisUnit="ops" onDragSelect={onDragSelect} @@ -236,15 +252,7 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element { { - onGraphClickHandler(setSelectedTimeStamp)( - ChartEvent, - activeElements, - chart, - data, - 'Error', - ); - }} + onClickHandler={handleGraphClick('Error')} widget={errorPercentageWidget} yAxisUnit="%" onDragSelect={onDragSelect} @@ -267,4 +275,12 @@ interface DashboardProps { getWidgetQueryBuilder: (query: Widgets['query']) => Widgets; } +type ClickHandlerType = ( + ChartEvent: ChartEvent, + activeElements: ActiveElement[], + chart: Chart, + data: ChartData, + type?: string, +) => void; + export default Application; diff --git a/frontend/src/container/MetricsApplication/Tabs/util.ts b/frontend/src/container/MetricsApplication/Tabs/util.ts index a0e29e60fa..c030492aff 100644 --- a/frontend/src/container/MetricsApplication/Tabs/util.ts +++ b/frontend/src/container/MetricsApplication/Tabs/util.ts @@ -21,7 +21,7 @@ export function onViewTracePopupClick( ): VoidFunction { return (): void => { const currentTime = timestamp; - const tPlusOne = timestamp + 1 * 60 * 1000; + const tPlusOne = timestamp + 60 * 1000; const urlParams = new URLSearchParams(); urlParams.set(METRICS_PAGE_QUERY_PARAM.startTime, currentTime.toString()); @@ -36,7 +36,9 @@ export function onViewTracePopupClick( } export function onGraphClickHandler( - setSelectedTimeStamp: React.Dispatch>, + setSelectedTimeStamp: ( + n: number, + ) => void | React.Dispatch>, ) { return async ( event: ChartEvent, @@ -49,7 +51,7 @@ export function onGraphClickHandler( const points = chart.getElementsAtEventForMode( event.native, 'nearest', - { intersect: true }, + { intersect: false }, true, ); const id = `${from}_button`;