mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[APM] Improves, smoothes shared pointer events across different charts (#135137)
* [APM] Improves, smoothes shared pointer events across different charts * fixes eslint dependency issue
This commit is contained in:
parent
e337b58f7f
commit
265c405f36
4 changed files with 52 additions and 23 deletions
|
@ -69,7 +69,7 @@ export function BreakdownChart({
|
|||
const history = useHistory();
|
||||
const chartTheme = useChartTheme();
|
||||
const { core } = useApmPluginContext();
|
||||
const { chartRef, setPointerEvent } = useChartPointerEventContext();
|
||||
const { chartRef, updatePointerEvent } = useChartPointerEventContext();
|
||||
const {
|
||||
query: { rangeFrom, rangeTo },
|
||||
} = useApmParams('/services/{serviceName}');
|
||||
|
@ -107,7 +107,7 @@ export function BreakdownChart({
|
|||
theme={chartTheme}
|
||||
xDomain={{ min, max }}
|
||||
flatLegend
|
||||
onPointerUpdate={setPointerEvent}
|
||||
onPointerUpdate={updatePointerEvent}
|
||||
externalPointerEvents={{
|
||||
tooltip: {
|
||||
visible: true,
|
||||
|
|
|
@ -86,7 +86,7 @@ export function TimeseriesChart({
|
|||
const history = useHistory();
|
||||
const { core } = useApmPluginContext();
|
||||
const { annotations } = useAnnotationsContext();
|
||||
const { setPointerEvent, chartRef } = useChartPointerEventContext();
|
||||
const { chartRef, updatePointerEvent } = useChartPointerEventContext();
|
||||
const theme = useTheme();
|
||||
const chartTheme = useChartTheme();
|
||||
const {
|
||||
|
@ -169,7 +169,7 @@ export function TimeseriesChart({
|
|||
},
|
||||
...chartTheme,
|
||||
]}
|
||||
onPointerUpdate={setPointerEvent}
|
||||
onPointerUpdate={updatePointerEvent}
|
||||
externalPointerEvents={{
|
||||
tooltip: { visible: true },
|
||||
}}
|
||||
|
|
|
@ -5,19 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, {
|
||||
createContext,
|
||||
Dispatch,
|
||||
ReactNode,
|
||||
SetStateAction,
|
||||
useState,
|
||||
} from 'react';
|
||||
import React, { createContext, ReactNode, useRef } from 'react';
|
||||
|
||||
import { PointerEvent } from '@elastic/charts';
|
||||
|
||||
export const UPDATE_POINTER_EVENT = 'updatePointerEvent';
|
||||
export const ChartPointerEventContext = createContext<{
|
||||
pointerEvent: PointerEvent | null;
|
||||
setPointerEvent: Dispatch<SetStateAction<PointerEvent | null>>;
|
||||
pointerEventTargetRef: React.MutableRefObject<EventTarget>;
|
||||
updatePointerEvent: (pointerEvent: PointerEvent) => void;
|
||||
} | null>(null);
|
||||
|
||||
export function ChartPointerEventContextProvider({
|
||||
|
@ -25,11 +20,19 @@ export function ChartPointerEventContextProvider({
|
|||
}: {
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const [pointerEvent, setPointerEvent] = useState<PointerEvent | null>(null);
|
||||
const pointerEventTargetRef = useRef(new EventTarget());
|
||||
const updatePointerEventRef = useRef((pointerEvent: PointerEvent) => {
|
||||
pointerEventTargetRef.current.dispatchEvent(
|
||||
new CustomEvent(UPDATE_POINTER_EVENT, { detail: pointerEvent })
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<ChartPointerEventContext.Provider
|
||||
value={{ pointerEvent, setPointerEvent }}
|
||||
value={{
|
||||
pointerEventTargetRef,
|
||||
updatePointerEvent: updatePointerEventRef.current,
|
||||
}}
|
||||
children={children}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -5,9 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import React, { useContext, useEffect, useCallback, useRef } from 'react';
|
||||
import { Chart } from '@elastic/charts';
|
||||
import { ChartPointerEventContext } from './chart_pointer_event_context';
|
||||
import { PointerEvent } from '@elastic/charts';
|
||||
import {
|
||||
ChartPointerEventContext,
|
||||
UPDATE_POINTER_EVENT,
|
||||
} from './chart_pointer_event_context';
|
||||
|
||||
export function useChartPointerEventContext() {
|
||||
const context = useContext(ChartPointerEventContext);
|
||||
|
@ -16,14 +20,36 @@ export function useChartPointerEventContext() {
|
|||
throw new Error('Missing ChartPointerEventContext provider');
|
||||
}
|
||||
|
||||
const { pointerEvent } = context;
|
||||
const { pointerEventTargetRef } = context;
|
||||
const chartRef = React.createRef<Chart>();
|
||||
const requestIdRef = useRef(0);
|
||||
const updatePointerEventHandler = useCallback(
|
||||
(event: Event) => {
|
||||
cancelAnimationFrame(requestIdRef.current);
|
||||
requestIdRef.current = requestAnimationFrame(() => {
|
||||
const pointerEvent = (
|
||||
event instanceof CustomEvent ? event.detail : null
|
||||
) as PointerEvent | null;
|
||||
if (chartRef.current && pointerEvent) {
|
||||
chartRef.current.dispatchExternalPointerEvent(pointerEvent);
|
||||
}
|
||||
});
|
||||
},
|
||||
[chartRef]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (pointerEvent && chartRef.current) {
|
||||
chartRef.current.dispatchExternalPointerEvent(pointerEvent);
|
||||
}
|
||||
}, [pointerEvent, chartRef]);
|
||||
|
||||
const pointerEventTarget = pointerEventTargetRef.current;
|
||||
pointerEventTarget.addEventListener(
|
||||
UPDATE_POINTER_EVENT,
|
||||
updatePointerEventHandler
|
||||
);
|
||||
return () => {
|
||||
pointerEventTarget.removeEventListener(
|
||||
UPDATE_POINTER_EVENT,
|
||||
updatePointerEventHandler
|
||||
);
|
||||
};
|
||||
}, [updatePointerEventHandler, pointerEventTargetRef]);
|
||||
return { ...context, chartRef };
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue