fix: it has been fixed of difficult to click on metrics graph points (#2207)

* fix: it has been fixed of difficult to click on metrics graph points

* fix: resolve conflict

* fix: changed hover point & memoized the passed props

* fix: memo from develop

* fix: add condition for end and start stamps

* chore: type position is updated

---------

Co-authored-by: palashgdev <palashgdev@gmail.com>
This commit is contained in:
Kolesnyk Anton 2023-02-15 07:20:39 +02:00 committed by GitHub
parent 45cb1eb38f
commit 05076968c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 91 additions and 73 deletions

View File

@ -1,3 +1,4 @@
import { ActiveElement, Chart, ChartData, ChartEvent } from 'chart.js';
import Graph from 'components/Graph'; import Graph from 'components/Graph';
import { METRICS_PAGE_QUERY_PARAM } from 'constants/query'; import { METRICS_PAGE_QUERY_PARAM } from 'constants/query';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
@ -29,7 +30,29 @@ import { onGraphClickHandler, onViewTracePopupClick } from './util';
function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element { function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element {
const { servicename } = useParams<{ servicename?: string }>(); const { servicename } = useParams<{ servicename?: string }>();
const [selectedTimeStamp, setSelectedTimeStamp] = useState<number>(0); const [selectedTimeStamp, setSelectedTimeStamp] = useState<number>(0);
const handleSetTimeStamp = useCallback((selectTime: number) => {
setSelectedTimeStamp(selectTime);
}, []);
const dispatch = useDispatch(); 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 { const {
topOperations, topOperations,
@ -82,14 +105,16 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element {
const startTimestamp = Math.trunc(start); const startTimestamp = Math.trunc(start);
const endTimestamp = Math.trunc(end); const endTimestamp = Math.trunc(end);
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp])); if (startTimestamp !== endTimestamp) {
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
}
}, },
[dispatch], [dispatch],
); );
const onErrorTrackHandler = (timestamp: number): void => { const onErrorTrackHandler = (timestamp: number): void => {
const currentTime = timestamp; const currentTime = timestamp;
const tPlusOne = timestamp + 1 * 60 * 1000; const tPlusOne = timestamp + 60 * 1000;
const urlParams = new URLSearchParams(); const urlParams = new URLSearchParams();
urlParams.set(METRICS_PAGE_QUERY_PARAM.startTime, currentTime.toString()); 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 ( return (
<> <>
<Row gutter={24}> <Row gutter={24}>
@ -122,58 +193,11 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element {
<GraphTitle>Latency</GraphTitle> <GraphTitle>Latency</GraphTitle>
<GraphContainer> <GraphContainer>
<Graph <Graph
onClickHandler={(ChartEvent, activeElements, chart, data): void => { animate={false}
onGraphClickHandler(setSelectedTimeStamp)( onClickHandler={handleGraphClick('Service')}
ChartEvent,
activeElements,
chart,
data,
'Service',
);
}}
name="service_latency" name="service_latency"
type="line" type="line"
data={{ data={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))),
),
}}
yAxisUnit="ms" yAxisUnit="ms"
onDragSelect={onDragSelect} onDragSelect={onDragSelect}
/> />
@ -200,15 +224,7 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element {
<FullView <FullView
name="operations_per_sec" name="operations_per_sec"
fullViewOptions={false} fullViewOptions={false}
onClickHandler={(event, element, chart, data): void => { onClickHandler={handleGraphClick('Rate')}
onGraphClickHandler(setSelectedTimeStamp)(
event,
element,
chart,
data,
'Rate',
);
}}
widget={operationPerSecWidget} widget={operationPerSecWidget}
yAxisUnit="ops" yAxisUnit="ops"
onDragSelect={onDragSelect} onDragSelect={onDragSelect}
@ -236,15 +252,7 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element {
<FullView <FullView
name="error_percentage_%" name="error_percentage_%"
fullViewOptions={false} fullViewOptions={false}
onClickHandler={(ChartEvent, activeElements, chart, data): void => { onClickHandler={handleGraphClick('Error')}
onGraphClickHandler(setSelectedTimeStamp)(
ChartEvent,
activeElements,
chart,
data,
'Error',
);
}}
widget={errorPercentageWidget} widget={errorPercentageWidget}
yAxisUnit="%" yAxisUnit="%"
onDragSelect={onDragSelect} onDragSelect={onDragSelect}
@ -267,4 +275,12 @@ interface DashboardProps {
getWidgetQueryBuilder: (query: Widgets['query']) => Widgets; getWidgetQueryBuilder: (query: Widgets['query']) => Widgets;
} }
type ClickHandlerType = (
ChartEvent: ChartEvent,
activeElements: ActiveElement[],
chart: Chart,
data: ChartData,
type?: string,
) => void;
export default Application; export default Application;

View File

@ -21,7 +21,7 @@ export function onViewTracePopupClick(
): VoidFunction { ): VoidFunction {
return (): void => { return (): void => {
const currentTime = timestamp; const currentTime = timestamp;
const tPlusOne = timestamp + 1 * 60 * 1000; const tPlusOne = timestamp + 60 * 1000;
const urlParams = new URLSearchParams(); const urlParams = new URLSearchParams();
urlParams.set(METRICS_PAGE_QUERY_PARAM.startTime, currentTime.toString()); urlParams.set(METRICS_PAGE_QUERY_PARAM.startTime, currentTime.toString());
@ -36,7 +36,9 @@ export function onViewTracePopupClick(
} }
export function onGraphClickHandler( export function onGraphClickHandler(
setSelectedTimeStamp: React.Dispatch<React.SetStateAction<number>>, setSelectedTimeStamp: (
n: number,
) => void | React.Dispatch<React.SetStateAction<number>>,
) { ) {
return async ( return async (
event: ChartEvent, event: ChartEvent,
@ -49,7 +51,7 @@ export function onGraphClickHandler(
const points = chart.getElementsAtEventForMode( const points = chart.getElementsAtEventForMode(
event.native, event.native,
'nearest', 'nearest',
{ intersect: true }, { intersect: false },
true, true,
); );
const id = `${from}_button`; const id = `${from}_button`;