grafana/data: Move useFieldOverrides from core (#60817)

* grafana/data: Move useFieldOverrides from core

* Update packages/grafana-data/src/field/fieldOverrides.ts

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>

* Review

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
Dominik Prokop 2023-01-02 02:27:48 -08:00 committed by GitHub
parent 6e89421544
commit 831e7697ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 59 deletions

View File

@ -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",

View File

@ -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]);
}

View File

@ -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';

View File

@ -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<P extends object = any, F extends object = any>(pr
fieldConfig = defaultFieldConfig,
} = props;
const theme = useTheme2();
const replace = useMemo(() => getTemplateSrv().replace, []);
const [plugin, setPlugin] = useState(syncGetPanelPlugin(pluginId));
const [error, setError] = useState<string | undefined>();
const optionsWithDefaults = useOptionDefaults(plugin, options, fieldConfig);
const dataWithOverrides = useFieldOverrides(plugin, optionsWithDefaults?.fieldConfig, data, timeZone);
const dataWithOverrides = useFieldOverrides(plugin, optionsWithDefaults?.fieldConfig, data, timeZone, theme, replace);
useEffect(() => {
// If we already have a plugin and it's correct one do nothing
@ -118,47 +115,3 @@ function useOptionDefaults<P extends object = any, F extends object = any>(
});
}, [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]);
}

View File

@ -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<VizPanel>) {
const { title, options, fieldConfig, pluginId, pluginLoadError, $data, placement } = model.useState();
const theme = useTheme2();
const replace = useMemo(() => getTemplateSrv().replace, []);
const [ref, { width, height }] = useMeasure();
const plugin = model.getPlugin();
const { data } = sceneGraph.getData(model).useState();
@ -31,7 +33,7 @@ export function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {
// Not sure we need to subscribe to this state
const timeZone = sceneGraph.getTimeRange(model).state.timeZone;
const dataWithOverrides = useFieldOverrides(plugin, fieldConfig, data, timeZone);
const dataWithOverrides = useFieldOverrides(plugin, fieldConfig, data, timeZone, theme, replace);
if (pluginLoadError) {
return <div>Failed to load plugin: {pluginLoadError}</div>;

View File

@ -4850,6 +4850,7 @@ __metadata:
react: 17.0.2
react-dom: 17.0.2
react-test-renderer: 17.0.2
react-use: 17.4.0
regenerator-runtime: 0.13.10
rimraf: 3.0.2
rollup: 2.79.1