diff --git a/packages/grafana-data/src/field/fieldDisplay.ts b/packages/grafana-data/src/field/fieldDisplay.ts index 4ae028db8b1..65ef117b973 100644 --- a/packages/grafana-data/src/field/fieldDisplay.ts +++ b/packages/grafana-data/src/field/fieldDisplay.ts @@ -79,6 +79,7 @@ export interface GetFieldDisplayValuesOptions { replaceVariables: InterpolateFunction; sparkline?: boolean; // Calculate the sparkline theme: GrafanaTheme; + autoMinMax?: boolean; } export const DEFAULT_FIELD_DISPLAY_VALUES_LIMIT = 25; @@ -90,7 +91,7 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi const values: FieldDisplay[] = []; if (options.data) { - const data = applyFieldOverrides(options.data, fieldOptions, replaceVariables, options.theme); + const data = applyFieldOverrides(options); let hitLimit = false; const limit = fieldOptions.limit ? fieldOptions.limit : DEFAULT_FIELD_DISPLAY_VALUES_LIMIT; diff --git a/packages/grafana-data/src/field/fieldOverrides.test.ts b/packages/grafana-data/src/field/fieldOverrides.test.ts index 9aacc8e978a..d8cd2984f7c 100644 --- a/packages/grafana-data/src/field/fieldOverrides.test.ts +++ b/packages/grafana-data/src/field/fieldOverrides.test.ts @@ -2,8 +2,35 @@ import { setFieldConfigDefaults, findNumericFieldMinMax, applyFieldOverrides } f import { MutableDataFrame } from '../dataframe'; import { FieldConfig, FieldConfigSource, InterpolateFunction, GrafanaTheme } from '../types'; import { FieldMatcherID } from '../transformations'; +import { FieldDisplayOptions } from './fieldDisplay'; describe('FieldOverrides', () => { + const f0 = new MutableDataFrame(); + f0.add({ title: 'AAA', value: 100, value2: 1234 }, true); + f0.add({ title: 'BBB', value: -20 }, true); + f0.add({ title: 'CCC', value: 200, value2: 1000 }, true); + expect(f0.length).toEqual(3); + + // Hardcode the max value + f0.fields[1].config.max = 0; + f0.fields[1].config.decimals = 6; + + const src: FieldConfigSource = { + defaults: { + unit: 'xyz', + decimals: 2, + }, + overrides: [ + { + matcher: { id: FieldMatcherID.numeric }, + properties: [ + { path: 'decimals', value: 1 }, // Numeric + { path: 'title', value: 'Kittens' }, // Text + ], + }, + ], + }; + it('will merge FieldConfig with default values', () => { const field: FieldConfig = { min: 0, @@ -22,46 +49,20 @@ describe('FieldOverrides', () => { }); it('will apply field overrides', () => { - const f0 = new MutableDataFrame(); - f0.add({ title: 'AAA', value: 100, value2: 1234 }, true); - f0.add({ title: 'BBB', value: -20 }, true); - f0.add({ title: 'CCC', value: 200, value2: 1000 }, true); - expect(f0.length).toEqual(3); - - // Hardcode the max value - f0.fields[1].config.max = 0; - f0.fields[1].config.decimals = 6; - - const src: FieldConfigSource = { - defaults: { - unit: 'xyz', - decimals: 2, - }, - overrides: [ - { - matcher: { id: FieldMatcherID.numeric }, - properties: [ - { path: 'decimals', value: 1 }, // Numeric - { path: 'title', value: 'Kittens' }, // Text - ], - }, - ], - }; - - const data = applyFieldOverrides( - [f0], // the frame - src, // defaults + overrides - (undefined as any) as InterpolateFunction, - (undefined as any) as GrafanaTheme - )[0]; + const data = applyFieldOverrides({ + data: [f0], // the frame + fieldOptions: src as FieldDisplayOptions, // defaults + overrides + replaceVariables: (undefined as any) as InterpolateFunction, + theme: (undefined as any) as GrafanaTheme, + })[0]; const valueColumn = data.fields[1]; const config = valueColumn.config; // Keep max from the original setting expect(config.max).toEqual(0); - // Automatically pick the min value - expect(config.min).toEqual(-20); + // Don't Automatically pick the min value + expect(config.min).toEqual(undefined); // The default value applied expect(config.unit).toEqual('xyz'); @@ -72,6 +73,24 @@ describe('FieldOverrides', () => { // The override applied expect(config.decimals).toEqual(1); }); + + it('will apply set min/max when asked', () => { + const data = applyFieldOverrides({ + data: [f0], // the frame + fieldOptions: src as FieldDisplayOptions, // defaults + overrides + replaceVariables: (undefined as any) as InterpolateFunction, + theme: (undefined as any) as GrafanaTheme, + autoMinMax: true, + })[0]; + const valueColumn = data.fields[1]; + const config = valueColumn.config; + + // Keep max from the original setting + expect(config.max).toEqual(0); + + // Don't Automatically pick the min value + expect(config.min).toEqual(-20); + }); }); describe('Global MinMax', () => { diff --git a/packages/grafana-data/src/field/fieldOverrides.ts b/packages/grafana-data/src/field/fieldOverrides.ts index b5e6c58082e..71503f2ceb3 100644 --- a/packages/grafana-data/src/field/fieldOverrides.ts +++ b/packages/grafana-data/src/field/fieldOverrides.ts @@ -1,19 +1,11 @@ import set from 'lodash/set'; -import { - DynamicConfigValue, - FieldConfigSource, - FieldConfig, - InterpolateFunction, - GrafanaTheme, - DataFrame, - Field, - FieldType, -} from '../types'; +import { DynamicConfigValue, FieldConfig, InterpolateFunction, DataFrame, Field, FieldType } from '../types'; import { fieldMatchers, ReducerID, reduceField } from '../transformations'; import { FieldMatcher } from '../types/transformations'; import isNumber from 'lodash/isNumber'; import toNumber from 'lodash/toNumber'; import { getDisplayProcessor } from './displayProcessor'; +import { GetFieldDisplayValuesOptions } from './fieldDisplay'; interface OverrideProps { match: FieldMatcher; @@ -50,15 +42,13 @@ export function findNumericFieldMinMax(data: DataFrame[]): GlobalMinMax { /** * Return a copy of the DataFrame with all rules applied */ -export function applyFieldOverrides( - data: DataFrame[], - source: FieldConfigSource, - replaceVariables: InterpolateFunction, - theme: GrafanaTheme, - isUtc?: boolean -): DataFrame[] { +export function applyFieldOverrides(options: GetFieldDisplayValuesOptions): DataFrame[] { + if (!options.data) { + return []; + } + const source = options.fieldOptions; if (!source) { - return data; + return options.data; } let range: GlobalMinMax | undefined = undefined; @@ -76,7 +66,7 @@ export function applyFieldOverrides( } } - return data.map((frame, index) => { + return options.data.map((frame, index) => { let name = frame.name; if (!name) { name = `Series[${index}]`; @@ -98,17 +88,17 @@ export function applyFieldOverrides( config, field, data: frame, - replaceVariables, + replaceVariables: options.replaceVariables, }); } } } // Set the Min/Max value automatically - if (field.type === FieldType.number) { + if (options.autoMinMax && field.type === FieldType.number) { if (!isNumber(config.min) || !isNumber(config.max)) { if (!range) { - range = findNumericFieldMinMax(data); + range = findNumericFieldMinMax(options.data!); // Global value } if (!isNumber(config.min)) { config.min = range.min; @@ -129,8 +119,7 @@ export function applyFieldOverrides( processor: getDisplayProcessor({ type: field.type, config: config, - theme, - isUtc, + theme: options.theme, }), }; }); diff --git a/packages/grafana-ui/src/components/SingleStatShared/FieldPropertiesEditor.tsx b/packages/grafana-ui/src/components/SingleStatShared/FieldPropertiesEditor.tsx index ed830dfa531..9fb7d69df11 100644 --- a/packages/grafana-ui/src/components/SingleStatShared/FieldPropertiesEditor.tsx +++ b/packages/grafana-ui/src/components/SingleStatShared/FieldPropertiesEditor.tsx @@ -111,6 +111,7 @@ export const FieldPropertiesEditor: React.FC = ({ value, onChange, showMi onChange={onMinChange} onBlur={commitChanges} value={min} + placeholder="Auto" type="number" /> = ({ value, onChange, showMi onBlur={commitChanges} value={max} type="number" + placeholder="Auto" /> )} diff --git a/public/app/plugins/panel/bargauge/BarGaugePanel.tsx b/public/app/plugins/panel/bargauge/BarGaugePanel.tsx index 522dbfc56d1..800259389ec 100644 --- a/public/app/plugins/panel/bargauge/BarGaugePanel.tsx +++ b/public/app/plugins/panel/bargauge/BarGaugePanel.tsx @@ -57,6 +57,7 @@ export class BarGaugePanel extends PureComponent> { replaceVariables, theme: config.theme, data: data.series, + autoMinMax: true, }); }; diff --git a/public/app/plugins/panel/gauge/GaugePanel.tsx b/public/app/plugins/panel/gauge/GaugePanel.tsx index a88ec950cda..4eb6dd2538b 100644 --- a/public/app/plugins/panel/gauge/GaugePanel.tsx +++ b/public/app/plugins/panel/gauge/GaugePanel.tsx @@ -48,6 +48,7 @@ export class GaugePanel extends PureComponent> { replaceVariables, theme: config.theme, data: data.series, + autoMinMax: true, }); }; diff --git a/public/app/plugins/panel/stat/types.ts b/public/app/plugins/panel/stat/types.ts index d8139104a84..6686004e674 100644 --- a/public/app/plugins/panel/stat/types.ts +++ b/public/app/plugins/panel/stat/types.ts @@ -27,8 +27,6 @@ export const standardFieldDisplayOptions: FieldDisplayOptions = { values: false, calcs: [ReducerID.mean], defaults: { - min: 0, - max: 100, thresholds: [ { value: -Infinity, color: 'green' }, { value: 80, color: 'red' }, // 80%