mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
GraphNG: Fix issues with plugins not retrieving plot instance (#29585)
* Fix issues with plugins not retrieving plot instance * Review
This commit is contained in:
parent
4e0ad50102
commit
563478ece7
@ -23,10 +23,6 @@ export const UPlotChart: React.FC<PlotProps> = props => {
|
||||
props.config
|
||||
);
|
||||
const getPlotInstance = useCallback(() => {
|
||||
if (!plotInstance.current) {
|
||||
throw new Error("Plot hasn't initialised yet");
|
||||
}
|
||||
|
||||
return plotInstance.current;
|
||||
}, []);
|
||||
|
||||
@ -72,13 +68,15 @@ export const UPlotChart: React.FC<PlotProps> = props => {
|
||||
|
||||
// Memoize plot context
|
||||
const plotCtx = useMemo(() => {
|
||||
return buildPlotContext(Boolean(plotInstance.current), canvasRef, props.data, registerPlugin, getPlotInstance);
|
||||
return buildPlotContext(canvasRef, props.data, registerPlugin, getPlotInstance);
|
||||
}, [plotInstance, canvasRef, props.data, registerPlugin, getPlotInstance]);
|
||||
|
||||
return (
|
||||
<PlotContext.Provider value={plotCtx}>
|
||||
<div ref={plotCtx.canvasRef} data-testid="uplot-main-div" />
|
||||
{props.children}
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div ref={plotCtx.canvasRef} data-testid="uplot-main-div" />
|
||||
{props.children}
|
||||
</div>
|
||||
</PlotContext.Provider>
|
||||
);
|
||||
};
|
||||
|
@ -21,8 +21,7 @@ interface PlotPluginsContextType {
|
||||
}
|
||||
|
||||
interface PlotContextType extends PlotPluginsContextType {
|
||||
isPlotReady: boolean;
|
||||
getPlotInstance: () => uPlot;
|
||||
getPlotInstance: () => uPlot | undefined;
|
||||
getSeries: () => Series[];
|
||||
getCanvas: () => PlotCanvasContextType;
|
||||
canvasRef: any;
|
||||
@ -127,28 +126,31 @@ export const usePlotData = (): PlotDataAPI => {
|
||||
};
|
||||
|
||||
export const buildPlotContext = (
|
||||
isPlotReady: boolean,
|
||||
canvasRef: any,
|
||||
data: AlignedFrameWithGapTest,
|
||||
registerPlugin: any,
|
||||
getPlotInstance: () => uPlot
|
||||
getPlotInstance: () => uPlot | undefined
|
||||
): PlotContextType => {
|
||||
return {
|
||||
isPlotReady,
|
||||
canvasRef,
|
||||
data,
|
||||
registerPlugin,
|
||||
getPlotInstance,
|
||||
getSeries: () => getPlotInstance().series,
|
||||
getCanvas: () => ({
|
||||
width: getPlotInstance().width,
|
||||
height: getPlotInstance().height,
|
||||
plot: {
|
||||
width: getPlotInstance().bbox.width / window.devicePixelRatio,
|
||||
height: getPlotInstance().bbox.height / window.devicePixelRatio,
|
||||
top: getPlotInstance().bbox.top / window.devicePixelRatio,
|
||||
left: getPlotInstance().bbox.left / window.devicePixelRatio,
|
||||
},
|
||||
}),
|
||||
getSeries: () => getPlotInstance()!.series,
|
||||
getCanvas: () => {
|
||||
const plotInstance = getPlotInstance()!;
|
||||
const bbox = plotInstance.bbox;
|
||||
const pxRatio = window.devicePixelRatio;
|
||||
return {
|
||||
width: plotInstance.width,
|
||||
height: plotInstance.height,
|
||||
plot: {
|
||||
width: bbox.width / pxRatio,
|
||||
height: bbox.height / pxRatio,
|
||||
top: bbox.top / pxRatio,
|
||||
left: bbox.left / pxRatio,
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -18,8 +18,7 @@ export function EventsCanvas<T>({ id, events, renderEventMarker, mapEventToXYCoo
|
||||
|
||||
const eventMarkers = useMemo(() => {
|
||||
const markers: React.ReactNode[] = [];
|
||||
|
||||
if (!plotCtx.isPlotReady || events.length === 0) {
|
||||
if (!plotCtx.getPlotInstance() || events.length === 0) {
|
||||
return markers;
|
||||
}
|
||||
|
||||
@ -41,9 +40,9 @@ export function EventsCanvas<T>({ id, events, renderEventMarker, mapEventToXYCoo
|
||||
}
|
||||
|
||||
return <>{markers}</>;
|
||||
}, [events, renderEventMarker, renderToken, plotCtx.isPlotReady]);
|
||||
}, [events, renderEventMarker, renderToken, plotCtx]);
|
||||
|
||||
if (!plotCtx.isPlotReady) {
|
||||
if (!plotCtx.getPlotInstance()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,9 @@ interface XYCanvasProps {}
|
||||
*/
|
||||
export const XYCanvas: React.FC<XYCanvasProps> = ({ children }) => {
|
||||
const plotContext = usePlotContext();
|
||||
const plotInstance = plotContext.getPlotInstance();
|
||||
|
||||
if (!plotContext.isPlotReady) {
|
||||
if (!plotInstance) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -20,8 +21,8 @@ export const XYCanvas: React.FC<XYCanvasProps> = ({ children }) => {
|
||||
className={css`
|
||||
position: absolute;
|
||||
overflow: visible;
|
||||
left: ${plotContext.getPlotInstance().bbox.left / window.devicePixelRatio}px;
|
||||
top: ${plotContext.getPlotInstance().bbox.top / window.devicePixelRatio}px;
|
||||
left: ${plotInstance.bbox.left / window.devicePixelRatio}px;
|
||||
top: ${plotInstance.bbox.top / window.devicePixelRatio}px;
|
||||
`}
|
||||
>
|
||||
{children}
|
||||
|
@ -75,7 +75,7 @@ export const SelectionPlugin: React.FC<SelectionPluginProps> = ({ onSelect, onDi
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (!plotCtx.isPlotReady || !children || !selection) {
|
||||
if (!plotCtx.getPlotInstance() || !children || !selection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({ mode = 'single', t
|
||||
return (
|
||||
<CursorPlugin id={pluginId}>
|
||||
{({ focusedSeriesIdx, focusedPointIdx, coords }) => {
|
||||
if (!plotContext.isPlotReady) {
|
||||
if (!plotContext.getPlotInstance()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ export const AnnotationsPlugin: React.FC<AnnotationsPluginProps> = ({ annotation
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (plotCtx.isPlotReady) {
|
||||
if (plotCtx.getPlotInstance()) {
|
||||
const views: Array<DataFrameView<AnnotationsDataFrameViewDTO>> = [];
|
||||
|
||||
for (const frame of annotations) {
|
||||
@ -41,7 +41,7 @@ export const AnnotationsPlugin: React.FC<AnnotationsPluginProps> = ({ annotation
|
||||
|
||||
annotationsRef.current = views;
|
||||
}
|
||||
}, [plotCtx.isPlotReady, annotations]);
|
||||
}, [plotCtx, annotations]);
|
||||
|
||||
useEffect(() => {
|
||||
const unregister = plotCtx.registerPlugin({
|
||||
@ -93,13 +93,14 @@ export const AnnotationsPlugin: React.FC<AnnotationsPluginProps> = ({ annotation
|
||||
|
||||
const mapAnnotationToXYCoords = useCallback(
|
||||
(annotation: AnnotationsDataFrameViewDTO) => {
|
||||
if (!annotation.time) {
|
||||
const plotInstance = plotCtx.getPlotInstance();
|
||||
if (!annotation.time || !plotInstance) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
x: plotCtx.getPlotInstance().valToPos(annotation.time / 1000, 'x'),
|
||||
y: plotCtx.getPlotInstance().bbox.height / window.devicePixelRatio + 4,
|
||||
x: plotInstance.valToPos(annotation.time, 'x'),
|
||||
y: plotInstance.bbox.height / window.devicePixelRatio + 4,
|
||||
};
|
||||
},
|
||||
[plotCtx.getPlotInstance]
|
||||
|
@ -42,7 +42,7 @@ export const ExemplarsPlugin: React.FC<ExemplarsPluginProps> = ({ exemplars, tim
|
||||
|
||||
// THIS EVENT ONLY MOCKS EXEMPLAR Y VALUE!!!! TO BE REMOVED WHEN WE GET CORRECT EXEMPLARS SHAPE VIA PROPS
|
||||
useEffect(() => {
|
||||
if (plotCtx.isPlotReady) {
|
||||
if (plotCtx.getPlotInstance()) {
|
||||
const mocks: DataFrame[] = [];
|
||||
|
||||
for (const frame of exemplars) {
|
||||
@ -61,18 +61,19 @@ export const ExemplarsPlugin: React.FC<ExemplarsPluginProps> = ({ exemplars, tim
|
||||
|
||||
setExemplarsMock(mocks);
|
||||
}
|
||||
}, [plotCtx.isPlotReady, exemplars]);
|
||||
}, [plotCtx, exemplars]);
|
||||
|
||||
const mapExemplarToXYCoords = useCallback(
|
||||
(exemplar: ExemplarsDataFrameViewDTO) => {
|
||||
if (!exemplar.time) {
|
||||
const plotInstance = plotCtx.getPlotInstance();
|
||||
if (!exemplar.time || !plotInstance) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
x: plotCtx.getPlotInstance().valToPos(exemplar.time / 1000, 'x'),
|
||||
x: plotInstance.valToPos(exemplar.time / 1000, 'x'),
|
||||
// exemplar.y is a temporary mock for an examplar. This Needs to be calculated according to examplar scale!
|
||||
y: Math.floor((exemplar.y * plotCtx.getPlotInstance().bbox.height) / window.devicePixelRatio),
|
||||
y: Math.floor((exemplar.y * plotInstance.bbox.height) / window.devicePixelRatio),
|
||||
};
|
||||
},
|
||||
[plotCtx.getPlotInstance]
|
||||
|
Loading…
Reference in New Issue
Block a user