Skip to content
Merged
Show file tree
Hide file tree
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
12 changes: 12 additions & 0 deletions packages/scenes/src/components/VizPanel/VizPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ export interface VizPanelState<TOptions = {}, TFieldConfig = {}> extends SceneOb
*/
extendPanelContext?: (vizPanel: VizPanel, context: PanelContext) => void;

/**
* @internal
* experimental / temporary
*
* clears field.values arrays of previous/stale/retained series and annotations frames in PanelData
*
* see https://github.com/facebook/react/issues/36176
* see https://github.com/grafana/grafana/pull/121682
* see https://github.com/grafana/grafana/pull/120190
**/
_UNSAFE_clearPreviousFieldValues?: boolean;

/**
* Sets panel chrome collapsed state
*/
Expand Down
54 changes: 51 additions & 3 deletions packages/scenes/src/components/VizPanel/VizPanelRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { Trans } from '@grafana/i18n';
import React, { RefCallback, useCallback, useEffect, useLayoutEffect, useMemo } from 'react';
import { useMeasure } from 'react-use';
import React, { RefCallback, useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react';
import { useMeasure, usePrevious } from 'react-use';

// @ts-ignore
import { AlertState, GrafanaTheme2, PanelData, PluginContextProvider, SetPanelAttentionEvent } from '@grafana/data';
import {
AlertState,
DataFrame,
GrafanaTheme2,
PanelData,
PluginContextProvider,
SetPanelAttentionEvent,
} from '@grafana/data';

import { getAppEvents } from '@grafana/runtime';
import { PanelChrome, ErrorBoundaryAlert, PanelContextProvider, Tooltip, useStyles2, Icon } from '@grafana/ui';
Expand Down Expand Up @@ -37,6 +44,7 @@ export function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {
collapsible,
collapsed,
_renderCounter = 0,
_UNSAFE_clearPreviousFieldValues = false,
} = model.useState();
const [ref, { width, height }] = useMeasure();
const appEvents = useMemo(() => getAppEvents(), []);
Expand Down Expand Up @@ -85,6 +93,11 @@ export function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {
const dataObject = sceneGraph.getData(model);

const rawData = dataObject.useState();

const { series, annotations } = _UNSAFE_clearPreviousFieldValues ? rawData.data ?? {} : {};
useClearPreviousData(series);
useClearPreviousData(annotations);

const dataWithSeriesLimit = useDataWithSeriesLimit(rawData.data, seriesLimit, seriesLimitShowAll);
const dataWithFieldConfig = model.applyFieldConfig(dataWithSeriesLimit);
const sceneTimeRange = sceneGraph.getTimeRange(model);
Expand Down Expand Up @@ -305,6 +318,41 @@ export function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {
);
}

function useClearPreviousData(data?: DataFrame[]) {
// this holds all value arrays from all series or anno frames
// so we can empty any previous ones that no longer appear in current data
// why? because React fiber: https://github.com/facebook/react/issues/36176
const prevVals = useRef<Set<any[]>>();
const currVals = useRef<Set<any[]>>();
prevVals.current ??= new Set();
currVals.current ??= new Set();

const currFrames = data;
const prevFrames = usePrevious(currFrames);

if (currFrames != null && currFrames !== prevFrames) {
// populate new
currVals.current.clear();

for (let i = 0; i < currFrames.length; i++) {
let fields = currFrames[i].fields;

for (let j = 0; j < fields.length; j++) {
currVals.current.add(fields[j].values);
}
}

// empty out all prev not seen in new
prevVals.current.forEach((vals) => {
if (!currVals.current!.has(vals)) {
vals.length = 0;
}
});
prevVals.current.clear();
prevVals.current = new Set(currVals.current);
}
}

function useDataWithSeriesLimit(data: PanelData | undefined, seriesLimit?: number, showAllSeries?: boolean) {
return useMemo(() => {
if (!data?.series || !seriesLimit || showAllSeries) {
Expand Down
Loading