mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Field color: handling color changes when switching panel types (#28875)
* FieldColor: Per panel settings to filter out supported modes * Updates * Updated solution * Update panel plugin API for standard options support * Update FieldColorConfigSettings interface * Change color mode correctly when changing plugin type * Render only applicable color modes in field color config editor * Apply field config API changes * TS fixes Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
parent
2887f3f68b
commit
2ea4a36bf7
@ -24,6 +24,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
|
||||
{
|
||||
id: FieldColorModeId.Thresholds,
|
||||
name: 'From thresholds',
|
||||
isByValue: true,
|
||||
description: 'Derive colors from thresholds',
|
||||
getCalculator: (_field, theme) => {
|
||||
return (_value, _percent, threshold) => {
|
||||
|
@ -306,7 +306,6 @@ const processFieldConfigValue = (
|
||||
const currentConfig = get(destination, fieldConfigProperty.path);
|
||||
if (currentConfig === null || currentConfig === undefined) {
|
||||
const item = context.fieldConfigRegistry.getIfExists(fieldConfigProperty.id);
|
||||
// console.log(item);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
@ -120,8 +120,15 @@ export const booleanOverrideProcessor = (
|
||||
return value; // !!!! likely not !!!!
|
||||
};
|
||||
|
||||
export interface ColorFieldConfigSettings {
|
||||
allowUndefined?: boolean;
|
||||
textWhenUndefined?: string; // Pick Color
|
||||
disableNamedColors?: boolean;
|
||||
export interface FieldColorConfigSettings {
|
||||
/**
|
||||
* When switching to a visualization that does not support by value coloring then Grafana will
|
||||
* switch to a by series palette based color mode
|
||||
*/
|
||||
byValueSupport?: boolean;
|
||||
/**
|
||||
* When switching to a visualization that has this set to true then Grafana will change color mode
|
||||
* to from thresholds if it was set to a by series palette
|
||||
*/
|
||||
preferThresholdsMode?: boolean;
|
||||
}
|
||||
|
@ -9,11 +9,11 @@ describe('PanelPlugin', () => {
|
||||
standardFieldConfigEditorRegistry.setInit(() => {
|
||||
return [
|
||||
{
|
||||
id: 'min',
|
||||
id: FieldConfigProperty.Min,
|
||||
path: 'min',
|
||||
},
|
||||
{
|
||||
id: 'max',
|
||||
id: FieldConfigProperty.Max,
|
||||
path: 'max',
|
||||
},
|
||||
] as any;
|
||||
@ -210,15 +210,15 @@ describe('PanelPlugin', () => {
|
||||
expect(panel.fieldConfigRegistry.list()).toHaveLength(2);
|
||||
});
|
||||
|
||||
test('selected standard config', () => {
|
||||
test('disabling standard config properties', () => {
|
||||
const panel = new PanelPlugin(() => {
|
||||
return <div>Panel</div>;
|
||||
});
|
||||
|
||||
panel.useFieldConfig({
|
||||
standardOptions: [FieldConfigProperty.Min, FieldConfigProperty.Max],
|
||||
disableStandardOptions: [FieldConfigProperty.Min],
|
||||
});
|
||||
expect(panel.fieldConfigRegistry.list()).toHaveLength(2);
|
||||
expect(panel.fieldConfigRegistry.list()).toHaveLength(1);
|
||||
});
|
||||
|
||||
describe('default values', () => {
|
||||
@ -228,10 +228,9 @@ describe('PanelPlugin', () => {
|
||||
});
|
||||
|
||||
panel.useFieldConfig({
|
||||
standardOptions: [FieldConfigProperty.Max, FieldConfigProperty.Min],
|
||||
standardOptionsDefaults: {
|
||||
[FieldConfigProperty.Max]: 20,
|
||||
[FieldConfigProperty.Min]: 10,
|
||||
standardOptions: {
|
||||
[FieldConfigProperty.Max]: { defaultValue: 20 },
|
||||
[FieldConfigProperty.Min]: { defaultValue: 10 },
|
||||
},
|
||||
});
|
||||
|
||||
@ -247,17 +246,16 @@ describe('PanelPlugin', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should ignore defaults that are not specified as available properties', () => {
|
||||
it('should disable properties independently from the default values settings', () => {
|
||||
const panel = new PanelPlugin(() => {
|
||||
return <div>Panel</div>;
|
||||
});
|
||||
|
||||
panel.useFieldConfig({
|
||||
standardOptions: [FieldConfigProperty.Max],
|
||||
standardOptionsDefaults: {
|
||||
[FieldConfigProperty.Max]: 20,
|
||||
[FieldConfigProperty.Min]: 10,
|
||||
standardOptions: {
|
||||
[FieldConfigProperty.Max]: { defaultValue: 20 },
|
||||
},
|
||||
disableStandardOptions: [FieldConfigProperty.Min],
|
||||
});
|
||||
|
||||
expect(panel.fieldConfigRegistry.list()).toHaveLength(1);
|
||||
|
@ -15,33 +15,38 @@ import set from 'lodash/set';
|
||||
import { deprecationWarning } from '../utils';
|
||||
import { FieldConfigOptionsRegistry, standardFieldConfigEditorRegistry } from '../field';
|
||||
|
||||
type StandardOptionConfig = {
|
||||
defaultValue?: any;
|
||||
settings?: any;
|
||||
};
|
||||
|
||||
export interface SetFieldConfigOptionsArgs<TFieldConfigOptions = any> {
|
||||
/**
|
||||
* Array of standard field config properties
|
||||
* Configuration object of the standard field config properites
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* {
|
||||
* standardOptions: [FieldConfigProperty.Min, FieldConfigProperty.Max, FieldConfigProperty.Unit]
|
||||
* standardOptions: {
|
||||
* [FieldConfigProperty.Decimals]: {
|
||||
* defaultValue: 3
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
standardOptions?: FieldConfigProperty[];
|
||||
standardOptions?: Partial<Record<FieldConfigProperty, StandardOptionConfig>>;
|
||||
|
||||
/**
|
||||
* Object specifying standard option properties default values
|
||||
*
|
||||
* Array of standard field config properties that should not be available in the panel
|
||||
* @example
|
||||
* ```typescript
|
||||
* {
|
||||
* standardOptionsDefaults: {
|
||||
* [FieldConfigProperty.Min]: 20,
|
||||
* [FieldConfigProperty.Max]: 100
|
||||
* }
|
||||
* disableStandardOptions: [FieldConfigProperty.Min, FieldConfigProperty.Max, FieldConfigProperty.Unit]
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
standardOptionsDefaults?: Partial<Record<FieldConfigProperty, any>>;
|
||||
disableStandardOptions?: FieldConfigProperty[];
|
||||
|
||||
/**
|
||||
* Function that allows custom field config properties definition.
|
||||
@ -305,13 +310,13 @@ export class PanelPlugin<TOptions = any, TFieldConfigOptions extends object = an
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
useFieldConfig(config?: SetFieldConfigOptionsArgs<TFieldConfigOptions>) {
|
||||
useFieldConfig(config: SetFieldConfigOptionsArgs<TFieldConfigOptions> = {}) {
|
||||
// builder is applied lazily when custom field configs are accessed
|
||||
this._initConfigRegistry = () => {
|
||||
const registry = new FieldConfigOptionsRegistry();
|
||||
|
||||
// Add custom options
|
||||
if (config && config.useCustomConfig) {
|
||||
if (config.useCustomConfig) {
|
||||
const builder = new FieldConfigEditorBuilder<TFieldConfigOptions>();
|
||||
config.useCustomConfig(builder);
|
||||
|
||||
@ -326,21 +331,33 @@ export class PanelPlugin<TOptions = any, TFieldConfigOptions extends object = an
|
||||
}
|
||||
}
|
||||
|
||||
if (config && config.standardOptions) {
|
||||
for (const standardOption of config.standardOptions) {
|
||||
const standardEditor = standardFieldConfigEditorRegistry.get(standardOption);
|
||||
registry.register({
|
||||
...standardEditor,
|
||||
defaultValue:
|
||||
(config.standardOptionsDefaults && config.standardOptionsDefaults[standardOption]) ||
|
||||
standardEditor.defaultValue,
|
||||
});
|
||||
for (let fieldConfigProp of standardFieldConfigEditorRegistry.list()) {
|
||||
if (config.disableStandardOptions) {
|
||||
const isDisabled = config.disableStandardOptions.indexOf(fieldConfigProp.id as FieldConfigProperty) > -1;
|
||||
if (isDisabled) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
for (const fieldConfigProp of standardFieldConfigEditorRegistry.list()) {
|
||||
}
|
||||
if (config.standardOptions) {
|
||||
const customDefault: any = config.standardOptions[fieldConfigProp.id as FieldConfigProperty]?.defaultValue;
|
||||
const customSettings: any = config.standardOptions[fieldConfigProp.id as FieldConfigProperty]?.settings;
|
||||
if (customDefault) {
|
||||
fieldConfigProp = {
|
||||
...fieldConfigProp,
|
||||
defaultValue: customDefault,
|
||||
};
|
||||
}
|
||||
|
||||
if (customSettings) {
|
||||
fieldConfigProp = {
|
||||
...fieldConfigProp,
|
||||
settings: fieldConfigProp.settings ? { ...fieldConfigProp.settings, ...customSettings } : customSettings,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
registry.register(fieldConfigProp);
|
||||
}
|
||||
}
|
||||
|
||||
return registry;
|
||||
};
|
||||
|
@ -13,12 +13,10 @@ import {
|
||||
StringFieldConfigSettings,
|
||||
NumberFieldConfigSettings,
|
||||
SliderFieldConfigSettings,
|
||||
ColorFieldConfigSettings,
|
||||
identityOverrideProcessor,
|
||||
UnitFieldConfigSettings,
|
||||
unitOverrideProcessor,
|
||||
} from '../field';
|
||||
import { FieldColor } from '../types';
|
||||
|
||||
/**
|
||||
* Fluent API for declarative creation of field config option editors
|
||||
@ -104,9 +102,7 @@ export class FieldConfigEditorBuilder<TOptions> extends OptionsUIRegistryBuilder
|
||||
});
|
||||
}
|
||||
|
||||
addColorPicker<TSettings = any>(
|
||||
config: FieldConfigEditorConfig<TOptions, TSettings & ColorFieldConfigSettings, FieldColor>
|
||||
) {
|
||||
addColorPicker<TSettings = any>(config: FieldConfigEditorConfig<TOptions, TSettings, string>) {
|
||||
return this.addCustomEditor({
|
||||
...config,
|
||||
id: config.path,
|
||||
@ -203,9 +199,7 @@ export class PanelOptionsEditorBuilder<TOptions> extends OptionsUIRegistryBuilde
|
||||
});
|
||||
}
|
||||
|
||||
addColorPicker<TSettings = any>(
|
||||
config: PanelOptionsEditorConfig<TOptions, TSettings & ColorFieldConfigSettings, string>
|
||||
): this {
|
||||
addColorPicker<TSettings = any>(config: PanelOptionsEditorConfig<TOptions, TSettings, string>): this {
|
||||
return this.addCustomEditor({
|
||||
...config,
|
||||
id: config.path,
|
||||
|
@ -545,7 +545,7 @@ export function getBarGradient(props: Props, maxSize: number): string {
|
||||
return gradient + ')';
|
||||
}
|
||||
|
||||
if (mode.colors) {
|
||||
if (mode.isContinuous && mode.colors) {
|
||||
const scheme = mode.colors.map(item => getColorForTheme(item, theme));
|
||||
for (let i = 0; i < scheme.length; i++) {
|
||||
const color = scheme[i];
|
||||
|
@ -28,12 +28,6 @@ export const ColorValueEditor: React.FC<Props> = ({ value, onChange }) => {
|
||||
color={value ? getColorForTheme(value, theme) : theme.colors.formInputBorder}
|
||||
/>
|
||||
</div>
|
||||
{/* <div className={styles.colorText} onClick={showColorPicker}>
|
||||
{value ?? settings?.textWhenUndefined ?? 'Pick Color'}
|
||||
</div>
|
||||
{value && settings?.allowUndefined && (
|
||||
<Icon className={styles.trashIcon} name="trash-alt" onClick={() => onChange(undefined)} />
|
||||
)} */}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
|
@ -8,13 +8,14 @@ import {
|
||||
FieldColorMode,
|
||||
GrafanaTheme,
|
||||
getColorForTheme,
|
||||
FieldColorConfigSettings,
|
||||
} from '@grafana/data';
|
||||
import { Select } from '../Select/Select';
|
||||
import { ColorValueEditor } from './color';
|
||||
import { useStyles, useTheme } from '../../themes/ThemeContext';
|
||||
import { css } from 'emotion';
|
||||
|
||||
export const FieldColorEditor: React.FC<FieldConfigEditorProps<FieldColor | undefined, {}>> = ({
|
||||
export const FieldColorEditor: React.FC<FieldConfigEditorProps<FieldColor | undefined, FieldColorConfigSettings>> = ({
|
||||
value,
|
||||
onChange,
|
||||
item,
|
||||
@ -22,7 +23,11 @@ export const FieldColorEditor: React.FC<FieldConfigEditorProps<FieldColor | unde
|
||||
const theme = useTheme();
|
||||
const styles = useStyles(getStyles);
|
||||
|
||||
const options = fieldColorModeRegistry.list().map(mode => {
|
||||
const availableOptions = item.settings?.byValueSupport
|
||||
? fieldColorModeRegistry.list()
|
||||
: fieldColorModeRegistry.list().filter(m => !m.isByValue);
|
||||
|
||||
const options = availableOptions.map(mode => {
|
||||
let suffix = mode.isByValue ? ' (by value)' : '';
|
||||
|
||||
return {
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
identityOverrideProcessor,
|
||||
TimeZone,
|
||||
FieldColor,
|
||||
FieldColorConfigSettings,
|
||||
} from '@grafana/data';
|
||||
|
||||
import { Switch } from '../components/Switch/Switch';
|
||||
@ -204,15 +205,18 @@ export const getStandardFieldConfigs = () => {
|
||||
getItemsCount: value => (value ? value.length : 0),
|
||||
};
|
||||
|
||||
const color: FieldConfigPropertyItem<any, FieldColor | undefined, {}> = {
|
||||
const color: FieldConfigPropertyItem<any, FieldColor | undefined, FieldColorConfigSettings> = {
|
||||
id: 'color',
|
||||
path: 'color',
|
||||
name: 'Color scheme',
|
||||
description: 'Select palette, gradient or single color',
|
||||
editor: standardEditorsRegistry.get('fieldColor').editor as any,
|
||||
override: standardEditorsRegistry.get('fieldColor').editor as any,
|
||||
process: identityOverrideProcessor,
|
||||
shouldApply: () => true,
|
||||
settings: {
|
||||
byValueSupport: true,
|
||||
preferThresholdsMode: true,
|
||||
},
|
||||
category,
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,8 @@ import {
|
||||
standardFieldConfigEditorRegistry,
|
||||
PanelData,
|
||||
DataSourceInstanceSettings,
|
||||
FieldColorModeId,
|
||||
FieldColorConfigSettings,
|
||||
} from '@grafana/data';
|
||||
import { ComponentClass } from 'react';
|
||||
import { PanelQueryRunner } from './PanelQueryRunner';
|
||||
@ -55,7 +57,20 @@ export const mockStandardProperties = () => {
|
||||
shouldApply: () => true,
|
||||
};
|
||||
|
||||
return [unit, decimals, boolean];
|
||||
const fieldColor = {
|
||||
id: 'color',
|
||||
path: 'color',
|
||||
name: 'color',
|
||||
description: '',
|
||||
// @ts-ignore
|
||||
editor: () => null,
|
||||
// @ts-ignore
|
||||
override: () => null,
|
||||
process: identityOverrideProcessor,
|
||||
shouldApply: () => true,
|
||||
};
|
||||
|
||||
return [unit, decimals, boolean, fieldColor];
|
||||
};
|
||||
|
||||
standardFieldConfigEditorRegistry.setInit(() => mockStandardProperties());
|
||||
@ -147,10 +162,13 @@ describe('PanelModel', () => {
|
||||
});
|
||||
|
||||
panelPlugin.useFieldConfig({
|
||||
standardOptions: [FieldConfigProperty.Unit, FieldConfigProperty.Decimals],
|
||||
standardOptionsDefaults: {
|
||||
[FieldConfigProperty.Unit]: 'flop',
|
||||
[FieldConfigProperty.Decimals]: 2,
|
||||
standardOptions: {
|
||||
[FieldConfigProperty.Unit]: {
|
||||
defaultValue: 'flop',
|
||||
},
|
||||
[FieldConfigProperty.Decimals]: {
|
||||
defaultValue: 2,
|
||||
},
|
||||
},
|
||||
});
|
||||
model.pluginLoaded(panelPlugin);
|
||||
@ -239,6 +257,17 @@ describe('PanelModel', () => {
|
||||
describe('when changing panel type', () => {
|
||||
beforeEach(() => {
|
||||
const newPlugin = getPanelPlugin({ id: 'graph' });
|
||||
|
||||
newPlugin.useFieldConfig({
|
||||
standardOptions: {
|
||||
[FieldConfigProperty.Color]: {
|
||||
settings: {
|
||||
byThresholdsSupport: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
newPlugin.setPanelOptions(builder => {
|
||||
builder.addBooleanSwitch({
|
||||
name: 'Show thresholds labels',
|
||||
@ -285,6 +314,66 @@ describe('PanelModel', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when changing panel type to one that does not support by value color mode', () => {
|
||||
beforeEach(() => {
|
||||
model.fieldConfig.defaults.color = { mode: FieldColorModeId.Thresholds };
|
||||
|
||||
const newPlugin = getPanelPlugin({ id: 'graph' });
|
||||
newPlugin.useFieldConfig({
|
||||
standardOptions: {
|
||||
[FieldConfigProperty.Color]: {
|
||||
settings: {
|
||||
byValueSupport: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
model.editSourceId = 1001;
|
||||
model.changePlugin(newPlugin);
|
||||
model.alert = { id: 2 };
|
||||
});
|
||||
|
||||
it('should change color mode', () => {
|
||||
expect(model.fieldConfig.defaults.color.mode).toBe(FieldColorModeId.PaletteClassic);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when changing panel type from one not supporting by value color mode to one that supports it', () => {
|
||||
const prepareModel = (colorOptions?: FieldColorConfigSettings) => {
|
||||
const newModel = new PanelModel(modelJson);
|
||||
newModel.fieldConfig.defaults.color = { mode: FieldColorModeId.PaletteClassic };
|
||||
|
||||
const newPlugin = getPanelPlugin({ id: 'graph' });
|
||||
newPlugin.useFieldConfig({
|
||||
standardOptions: {
|
||||
[FieldConfigProperty.Color]: {
|
||||
settings: {
|
||||
byValueSupport: true,
|
||||
...colorOptions,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
newModel.editSourceId = 1001;
|
||||
newModel.changePlugin(newPlugin);
|
||||
newModel.alert = { id: 2 };
|
||||
return newModel;
|
||||
};
|
||||
|
||||
it('should keep supported mode', () => {
|
||||
const testModel = prepareModel();
|
||||
|
||||
expect(testModel.fieldConfig.defaults.color!.mode).toBe(FieldColorModeId.PaletteClassic);
|
||||
});
|
||||
|
||||
it('should change to thresholds mode when it prefers to', () => {
|
||||
const testModel = prepareModel({ preferThresholdsMode: true });
|
||||
expect(testModel.fieldConfig.defaults.color!.mode).toBe(FieldColorModeId.Thresholds);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when changing to react panel from angular panel', () => {
|
||||
let panelQueryRunner: any;
|
||||
|
||||
|
@ -12,6 +12,10 @@ import {
|
||||
DataQueryResponseData,
|
||||
DataTransformerConfig,
|
||||
eventFactory,
|
||||
FieldColorConfigSettings,
|
||||
FieldColorModeId,
|
||||
fieldColorModeRegistry,
|
||||
FieldConfigProperty,
|
||||
FieldConfigSource,
|
||||
PanelEvents,
|
||||
PanelPlugin,
|
||||
@ -322,7 +326,35 @@ export class PanelModel implements DataConfigSource {
|
||||
}
|
||||
});
|
||||
|
||||
this.fieldConfig = applyFieldConfigDefaults(this.fieldConfig, this.plugin!.fieldConfigDefaults);
|
||||
this.fieldConfig = applyFieldConfigDefaults(this.fieldConfig, plugin.fieldConfigDefaults);
|
||||
this.validateFieldColorMode(plugin);
|
||||
}
|
||||
|
||||
private validateFieldColorMode(plugin: PanelPlugin) {
|
||||
// adjust to prefered field color setting if needed
|
||||
const color = plugin.fieldConfigRegistry.getIfExists(FieldConfigProperty.Color);
|
||||
|
||||
if (color && color.settings) {
|
||||
const colorSettings = color.settings as FieldColorConfigSettings;
|
||||
const mode = fieldColorModeRegistry.getIfExists(this.fieldConfig.defaults.color?.mode);
|
||||
|
||||
// When no support fo value colors, use classic palette
|
||||
if (!colorSettings.byValueSupport) {
|
||||
if (!mode || mode.isByValue) {
|
||||
this.fieldConfig.defaults.color = { mode: FieldColorModeId.PaletteClassic };
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// When supporting value colors and prefering thresholds, use Thresholds mode.
|
||||
// Otherwise keep current mode
|
||||
if (colorSettings.byValueSupport && colorSettings.preferThresholdsMode) {
|
||||
if (!mode || !mode.isByValue) {
|
||||
this.fieldConfig.defaults.color = { mode: FieldColorModeId.Thresholds };
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pluginLoaded(plugin: PanelPlugin) {
|
||||
|
@ -12,11 +12,11 @@ import { axesEditorComponent } from './axes_editor';
|
||||
import config from 'app/core/config';
|
||||
import TimeSeries from 'app/core/time_series2';
|
||||
import { getProcessedDataFrames } from 'app/features/dashboard/state/runRequest';
|
||||
import { PanelEvents, PanelPlugin, DataFrame, FieldConfigProperty, getColorForTheme } from '@grafana/data';
|
||||
import { DataFrame, FieldConfigProperty, getColorForTheme, PanelEvents, PanelPlugin } from '@grafana/data';
|
||||
|
||||
import { GraphContextMenuCtrl } from './GraphContextMenuCtrl';
|
||||
import { graphPanelMigrationHandler } from './GraphMigrations';
|
||||
import { DataWarning, GraphPanelOptions, GraphFieldConfig } from './types';
|
||||
import { DataWarning, GraphFieldConfig, GraphPanelOptions } from './types';
|
||||
|
||||
import { auto } from 'angular';
|
||||
import { AnnotationsSrv } from 'app/features/annotations/all';
|
||||
@ -388,10 +388,14 @@ export class GraphCtrl extends MetricsPanelCtrl {
|
||||
// Use new react style configuration
|
||||
export const plugin = new PanelPlugin<GraphPanelOptions, GraphFieldConfig>(null)
|
||||
.useFieldConfig({
|
||||
standardOptions: [
|
||||
FieldConfigProperty.DisplayName,
|
||||
FieldConfigProperty.Unit,
|
||||
FieldConfigProperty.Links, // previously saved as dataLinks on options
|
||||
disableStandardOptions: [
|
||||
FieldConfigProperty.NoValue,
|
||||
FieldConfigProperty.Thresholds,
|
||||
FieldConfigProperty.Max,
|
||||
FieldConfigProperty.Min,
|
||||
FieldConfigProperty.Decimals,
|
||||
FieldConfigProperty.Color,
|
||||
FieldConfigProperty.Mappings,
|
||||
],
|
||||
})
|
||||
.setMigrationHandler(graphPanelMigrationHandler);
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { FieldConfigProperty, PanelPlugin } from '@grafana/data';
|
||||
import { PanelPlugin } from '@grafana/data';
|
||||
import { GraphPanel } from './GraphPanel';
|
||||
import { Options } from './types';
|
||||
|
||||
export const plugin = new PanelPlugin<Options>(GraphPanel)
|
||||
.useFieldConfig({ standardOptions: [FieldConfigProperty.Unit, FieldConfigProperty.Decimals] })
|
||||
.setPanelOptions(builder => {
|
||||
export const plugin = new PanelPlugin<Options>(GraphPanel).useFieldConfig().setPanelOptions(builder => {
|
||||
builder
|
||||
.addBooleanSwitch({
|
||||
path: 'graph.showBars',
|
||||
@ -60,4 +58,4 @@ export const plugin = new PanelPlugin<Options>(GraphPanel)
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,21 +1,20 @@
|
||||
import { FieldConfigProperty, PanelPlugin } from '@grafana/data';
|
||||
import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data';
|
||||
import { AxisSide, GraphCustomFieldConfig } from '@grafana/ui';
|
||||
import { GraphPanel } from './GraphPanel';
|
||||
import { Options } from './types';
|
||||
|
||||
export const plugin = new PanelPlugin<Options, GraphCustomFieldConfig>(GraphPanel)
|
||||
.useFieldConfig({
|
||||
standardOptions: [
|
||||
// FieldConfigProperty.Min,
|
||||
// FieldConfigProperty.Max,
|
||||
FieldConfigProperty.Color,
|
||||
FieldConfigProperty.Unit,
|
||||
FieldConfigProperty.DisplayName,
|
||||
FieldConfigProperty.Decimals,
|
||||
// NOT: FieldConfigProperty.Thresholds,
|
||||
FieldConfigProperty.Mappings,
|
||||
],
|
||||
|
||||
standardOptions: {
|
||||
[FieldConfigProperty.Color]: {
|
||||
settings: {
|
||||
byValueSupport: false,
|
||||
},
|
||||
defaultValue: {
|
||||
mode: FieldColorModeId.PaletteClassic,
|
||||
},
|
||||
},
|
||||
},
|
||||
useCustomConfig: builder => {
|
||||
builder
|
||||
.addBooleanSwitch({
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { sharedSingleStatMigrationHandler, BigValueTextMode } from '@grafana/ui';
|
||||
import { BigValueTextMode, sharedSingleStatMigrationHandler } from '@grafana/ui';
|
||||
import { PanelPlugin } from '@grafana/data';
|
||||
import { StatPanelOptions, addStandardDataReduceOptions } from './types';
|
||||
import { addStandardDataReduceOptions, StatPanelOptions } from './types';
|
||||
import { StatPanel } from './StatPanel';
|
||||
import { statPanelChangedHandler } from './StatMigrations';
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user