mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
@@ -49,6 +49,7 @@
|
|||||||
"moment-timezone": "0.5.38",
|
"moment-timezone": "0.5.38",
|
||||||
"ol": "7.1.0",
|
"ol": "7.1.0",
|
||||||
"papaparse": "5.3.2",
|
"papaparse": "5.3.2",
|
||||||
|
"react-use": "17.4.0",
|
||||||
"regenerator-runtime": "0.13.10",
|
"regenerator-runtime": "0.13.10",
|
||||||
"rxjs": "7.5.7",
|
"rxjs": "7.5.7",
|
||||||
"tinycolor2": "1.4.2",
|
"tinycolor2": "1.4.2",
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { isNumber, set, unset, get, cloneDeep } from 'lodash';
|
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 { getTimeField } from '../dataframe/processDataFrame';
|
||||||
|
import { PanelPlugin } from '../panel/PanelPlugin';
|
||||||
|
import { GrafanaTheme2 } from '../themes';
|
||||||
import { asHexString } from '../themes/colorManipulator';
|
import { asHexString } from '../themes/colorManipulator';
|
||||||
import { fieldMatchers, reduceField, ReducerID } from '../transformations';
|
import { fieldMatchers, reduceField, ReducerID } from '../transformations';
|
||||||
import {
|
import {
|
||||||
@@ -16,11 +20,13 @@ import {
|
|||||||
FieldColorModeId,
|
FieldColorModeId,
|
||||||
FieldConfig,
|
FieldConfig,
|
||||||
FieldConfigPropertyItem,
|
FieldConfigPropertyItem,
|
||||||
|
FieldConfigSource,
|
||||||
FieldOverrideContext,
|
FieldOverrideContext,
|
||||||
FieldType,
|
FieldType,
|
||||||
InterpolateFunction,
|
InterpolateFunction,
|
||||||
LinkModel,
|
LinkModel,
|
||||||
NumericRange,
|
NumericRange,
|
||||||
|
PanelData,
|
||||||
ScopedVars,
|
ScopedVars,
|
||||||
TimeZone,
|
TimeZone,
|
||||||
ValueLinkConfig,
|
ValueLinkConfig,
|
||||||
@@ -503,3 +509,49 @@ export function applyRawFieldOverrides(data: DataFrame[]): DataFrame[] {
|
|||||||
|
|
||||||
return newData;
|
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]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export {
|
|||||||
} from './fieldColor';
|
} from './fieldColor';
|
||||||
export { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry';
|
export { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry';
|
||||||
export { sortThresholds, getActiveThreshold } from './thresholds';
|
export { sortThresholds, getActiveThreshold } from './thresholds';
|
||||||
export { applyFieldOverrides, validateFieldConfig, applyRawFieldOverrides } from './fieldOverrides';
|
export { applyFieldOverrides, validateFieldConfig, applyRawFieldOverrides, useFieldOverrides } from './fieldOverrides';
|
||||||
export { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy';
|
export { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy';
|
||||||
export { getFieldDisplayName, getFrameDisplayName } from './fieldState';
|
export { getFieldDisplayName, getFrameDisplayName } from './fieldState';
|
||||||
export { getScaleCalculator, getFieldConfigWithMinMax } from './scale';
|
export { getScaleCalculator, getFieldConfigWithMinMax } from './scale';
|
||||||
|
|||||||
@@ -1,18 +1,13 @@
|
|||||||
import React, { useState, useMemo, useEffect, useRef } from 'react';
|
import React, { useState, useMemo, useEffect } from 'react';
|
||||||
import { usePrevious } from 'react-use';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
applyFieldOverrides,
|
|
||||||
FieldConfigSource,
|
FieldConfigSource,
|
||||||
getTimeZone,
|
getTimeZone,
|
||||||
PanelData,
|
|
||||||
PanelPlugin,
|
PanelPlugin,
|
||||||
compareArrayValues,
|
|
||||||
compareDataFrameStructures,
|
|
||||||
PluginContextProvider,
|
PluginContextProvider,
|
||||||
ScopedVars,
|
|
||||||
getPanelOptionsWithDefaults,
|
getPanelOptionsWithDefaults,
|
||||||
OptionDefaults,
|
OptionDefaults,
|
||||||
|
useFieldOverrides,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { getTemplateSrv, PanelRendererProps } from '@grafana/runtime';
|
import { getTemplateSrv, PanelRendererProps } from '@grafana/runtime';
|
||||||
import { ErrorBoundaryAlert, useTheme2 } from '@grafana/ui';
|
import { ErrorBoundaryAlert, useTheme2 } from '@grafana/ui';
|
||||||
@@ -37,10 +32,12 @@ export function PanelRenderer<P extends object = any, F extends object = any>(pr
|
|||||||
fieldConfig = defaultFieldConfig,
|
fieldConfig = defaultFieldConfig,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const theme = useTheme2();
|
||||||
|
const replace = useMemo(() => getTemplateSrv().replace, []);
|
||||||
const [plugin, setPlugin] = useState(syncGetPanelPlugin(pluginId));
|
const [plugin, setPlugin] = useState(syncGetPanelPlugin(pluginId));
|
||||||
const [error, setError] = useState<string | undefined>();
|
const [error, setError] = useState<string | undefined>();
|
||||||
const optionsWithDefaults = useOptionDefaults(plugin, options, fieldConfig);
|
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(() => {
|
useEffect(() => {
|
||||||
// If we already have a plugin and it's correct one do nothing
|
// 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]);
|
}, [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]);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import React, { RefCallback } from 'react';
|
import React, { RefCallback, useMemo } from 'react';
|
||||||
import { useMeasure } from 'react-use';
|
import { useMeasure } from 'react-use';
|
||||||
|
|
||||||
import { PluginContextProvider } from '@grafana/data';
|
import { PluginContextProvider, useFieldOverrides } from '@grafana/data';
|
||||||
import { PanelChrome, ErrorBoundaryAlert } from '@grafana/ui';
|
import { getTemplateSrv } from '@grafana/runtime';
|
||||||
|
import { PanelChrome, ErrorBoundaryAlert, useTheme2 } from '@grafana/ui';
|
||||||
import { appEvents } from 'app/core/core';
|
import { appEvents } from 'app/core/core';
|
||||||
import { useFieldOverrides } from 'app/features/panel/components/PanelRenderer';
|
|
||||||
|
|
||||||
import { sceneGraph } from '../../core/sceneGraph';
|
import { sceneGraph } from '../../core/sceneGraph';
|
||||||
import { SceneComponentProps } from '../../core/types';
|
import { SceneComponentProps } from '../../core/types';
|
||||||
@@ -16,6 +16,8 @@ import { VizPanel } from './VizPanel';
|
|||||||
|
|
||||||
export function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {
|
export function VizPanelRenderer({ model }: SceneComponentProps<VizPanel>) {
|
||||||
const { title, options, fieldConfig, pluginId, pluginLoadError, $data, placement } = model.useState();
|
const { title, options, fieldConfig, pluginId, pluginLoadError, $data, placement } = model.useState();
|
||||||
|
const theme = useTheme2();
|
||||||
|
const replace = useMemo(() => getTemplateSrv().replace, []);
|
||||||
const [ref, { width, height }] = useMeasure();
|
const [ref, { width, height }] = useMeasure();
|
||||||
const plugin = model.getPlugin();
|
const plugin = model.getPlugin();
|
||||||
const { data } = sceneGraph.getData(model).useState();
|
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
|
// Not sure we need to subscribe to this state
|
||||||
const timeZone = sceneGraph.getTimeRange(model).state.timeZone;
|
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) {
|
if (pluginLoadError) {
|
||||||
return <div>Failed to load plugin: {pluginLoadError}</div>;
|
return <div>Failed to load plugin: {pluginLoadError}</div>;
|
||||||
|
|||||||
@@ -4850,6 +4850,7 @@ __metadata:
|
|||||||
react: 17.0.2
|
react: 17.0.2
|
||||||
react-dom: 17.0.2
|
react-dom: 17.0.2
|
||||||
react-test-renderer: 17.0.2
|
react-test-renderer: 17.0.2
|
||||||
|
react-use: 17.4.0
|
||||||
regenerator-runtime: 0.13.10
|
regenerator-runtime: 0.13.10
|
||||||
rimraf: 3.0.2
|
rimraf: 3.0.2
|
||||||
rollup: 2.79.1
|
rollup: 2.79.1
|
||||||
|
|||||||
Reference in New Issue
Block a user