diff --git a/packages/grafana-data/package.json b/packages/grafana-data/package.json index ef30090aa89..9794ab66cf6 100644 --- a/packages/grafana-data/package.json +++ b/packages/grafana-data/package.json @@ -49,6 +49,7 @@ "moment-timezone": "0.5.38", "ol": "7.1.0", "papaparse": "5.3.2", + "react-use": "17.4.0", "regenerator-runtime": "0.13.10", "rxjs": "7.5.7", "tinycolor2": "1.4.2", diff --git a/packages/grafana-data/src/field/fieldOverrides.ts b/packages/grafana-data/src/field/fieldOverrides.ts index 441635e69b8..6b2fbf31195 100644 --- a/packages/grafana-data/src/field/fieldOverrides.ts +++ b/packages/grafana-data/src/field/fieldOverrides.ts @@ -1,7 +1,11 @@ import { isNumber, set, unset, get, cloneDeep } from 'lodash'; +import { useMemo, useRef } from 'react'; +import usePrevious from 'react-use/lib/usePrevious'; -import { guessFieldTypeForField } from '../dataframe'; +import { compareArrayValues, compareDataFrameStructures, guessFieldTypeForField } from '../dataframe'; import { getTimeField } from '../dataframe/processDataFrame'; +import { PanelPlugin } from '../panel/PanelPlugin'; +import { GrafanaTheme2 } from '../themes'; import { asHexString } from '../themes/colorManipulator'; import { fieldMatchers, reduceField, ReducerID } from '../transformations'; import { @@ -16,11 +20,13 @@ import { FieldColorModeId, FieldConfig, FieldConfigPropertyItem, + FieldConfigSource, FieldOverrideContext, FieldType, InterpolateFunction, LinkModel, NumericRange, + PanelData, ScopedVars, TimeZone, ValueLinkConfig, @@ -503,3 +509,49 @@ export function applyRawFieldOverrides(data: DataFrame[]): DataFrame[] { return newData; } + +/** + * @internal + */ +export function useFieldOverrides( + plugin: PanelPlugin | undefined, + fieldConfig: FieldConfigSource | undefined, + data: PanelData | undefined, + timeZone: string, + theme: GrafanaTheme2, + replace: InterpolateFunction +): PanelData | undefined { + const fieldConfigRegistry = plugin?.fieldConfigRegistry; + const structureRev = useRef(0); + const prevSeries = usePrevious(data?.series); + + return useMemo(() => { + if (!fieldConfigRegistry || !fieldConfig || !data) { + return; + } + + const series = data?.series; + + if ( + data.structureRev == null && + series && + prevSeries && + !compareArrayValues(series, prevSeries, compareDataFrameStructures) + ) { + structureRev.current++; + } + + return { + structureRev: structureRev.current, + ...data, + series: applyFieldOverrides({ + data: series, + fieldConfig, + fieldConfigRegistry, + replaceVariables: replace, + theme, + timeZone, + }), + }; + }, [fieldConfigRegistry, fieldConfig, data, prevSeries, timeZone, theme, replace]); +} diff --git a/packages/grafana-data/src/field/index.ts b/packages/grafana-data/src/field/index.ts index 9bac21ccd8e..8ae807d42bc 100644 --- a/packages/grafana-data/src/field/index.ts +++ b/packages/grafana-data/src/field/index.ts @@ -12,7 +12,7 @@ export { } from './fieldColor'; export { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry'; export { sortThresholds, getActiveThreshold } from './thresholds'; -export { applyFieldOverrides, validateFieldConfig, applyRawFieldOverrides } from './fieldOverrides'; +export { applyFieldOverrides, validateFieldConfig, applyRawFieldOverrides, useFieldOverrides } from './fieldOverrides'; export { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy'; export { getFieldDisplayName, getFrameDisplayName } from './fieldState'; export { getScaleCalculator, getFieldConfigWithMinMax } from './scale'; diff --git a/public/app/features/panel/components/PanelRenderer.tsx b/public/app/features/panel/components/PanelRenderer.tsx index dacaf743639..bb221909c12 100644 --- a/public/app/features/panel/components/PanelRenderer.tsx +++ b/public/app/features/panel/components/PanelRenderer.tsx @@ -1,18 +1,13 @@ -import React, { useState, useMemo, useEffect, useRef } from 'react'; -import { usePrevious } from 'react-use'; +import React, { useState, useMemo, useEffect } from 'react'; import { - applyFieldOverrides, FieldConfigSource, getTimeZone, - PanelData, PanelPlugin, - compareArrayValues, - compareDataFrameStructures, PluginContextProvider, - ScopedVars, getPanelOptionsWithDefaults, OptionDefaults, + useFieldOverrides, } from '@grafana/data'; import { getTemplateSrv, PanelRendererProps } from '@grafana/runtime'; import { ErrorBoundaryAlert, useTheme2 } from '@grafana/ui'; @@ -37,10 +32,12 @@ export function PanelRenderer
(pr
fieldConfig = defaultFieldConfig,
} = props;
+ const theme = useTheme2();
+ const replace = useMemo(() => getTemplateSrv().replace, []);
const [plugin, setPlugin] = useState(syncGetPanelPlugin(pluginId));
const [error, setError] = useState (
});
}, [plugin, fieldConfig, options]);
}
-
-export function useFieldOverrides(
- plugin: PanelPlugin | undefined,
- fieldConfig: FieldConfigSource | undefined,
- data: PanelData | undefined,
- timeZone: string
-): PanelData | undefined {
- const fieldConfigRegistry = plugin?.fieldConfigRegistry;
- const theme = useTheme2();
- const structureRev = useRef(0);
- const prevSeries = usePrevious(data?.series);
-
- return useMemo(() => {
- if (!fieldConfigRegistry || !fieldConfig || !data) {
- return;
- }
-
- const series = data?.series;
-
- if (
- data.structureRev == null &&
- series &&
- prevSeries &&
- !compareArrayValues(series, prevSeries, compareDataFrameStructures)
- ) {
- structureRev.current++;
- }
-
- return {
- structureRev: structureRev.current,
- ...data,
- series: applyFieldOverrides({
- data: series,
- fieldConfig,
- fieldConfigRegistry,
- replaceVariables: (str: string, scopedVars?: ScopedVars) => {
- return getTemplateSrv().replace(str, scopedVars);
- },
- theme,
- timeZone,
- }),
- };
- }, [fieldConfigRegistry, fieldConfig, data, prevSeries, timeZone, theme]);
-}
diff --git a/public/app/features/scenes/components/VizPanel/VizPanelRenderer.tsx b/public/app/features/scenes/components/VizPanel/VizPanelRenderer.tsx
index 8877c8f0d22..9b418f3926a 100644
--- a/public/app/features/scenes/components/VizPanel/VizPanelRenderer.tsx
+++ b/public/app/features/scenes/components/VizPanel/VizPanelRenderer.tsx
@@ -1,10 +1,10 @@
-import React, { RefCallback } from 'react';
+import React, { RefCallback, useMemo } from 'react';
import { useMeasure } from 'react-use';
-import { PluginContextProvider } from '@grafana/data';
-import { PanelChrome, ErrorBoundaryAlert } from '@grafana/ui';
+import { PluginContextProvider, useFieldOverrides } from '@grafana/data';
+import { getTemplateSrv } from '@grafana/runtime';
+import { PanelChrome, ErrorBoundaryAlert, useTheme2 } from '@grafana/ui';
import { appEvents } from 'app/core/core';
-import { useFieldOverrides } from 'app/features/panel/components/PanelRenderer';
import { sceneGraph } from '../../core/sceneGraph';
import { SceneComponentProps } from '../../core/types';
@@ -16,6 +16,8 @@ import { VizPanel } from './VizPanel';
export function VizPanelRenderer({ model }: SceneComponentProps