From 7eac79b5f80f9206dab60ea711cdd04cc664411c Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Thu, 20 Oct 2022 17:56:21 -0500 Subject: [PATCH] Number formatting: Strip trailing zeros after decimal point when decimals=auto (#57373) --- .../src/field/displayProcessor.test.ts | 11 +++++++++-- .../grafana-data/src/field/displayProcessor.ts | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/grafana-data/src/field/displayProcessor.test.ts b/packages/grafana-data/src/field/displayProcessor.test.ts index 94262f14b43..77415af38c1 100644 --- a/packages/grafana-data/src/field/displayProcessor.test.ts +++ b/packages/grafana-data/src/field/displayProcessor.test.ts @@ -305,7 +305,7 @@ describe('Format value', () => { const value = 1200; const instance = getDisplayProcessorFromConfig({ decimals: null, unit: 'short' }); const disp = instance(value); - expect(disp.text).toEqual('1.20'); + expect(disp.text).toEqual('1.2'); expect(disp.suffix).toEqual(' K'); }); @@ -329,10 +329,17 @@ describe('Format value', () => { const value = 1500000; const instance = getDisplayProcessorFromConfig({ decimals: null, unit: 'short' }); const disp = instance(value); - expect(disp.text).toEqual('1.50'); + expect(disp.text).toEqual('1.5'); expect(disp.suffix).toEqual(' Mil'); }); + it('with value 15000000 and unit locale', () => { + const value = 1500000; + const instance = getDisplayProcessorFromConfig({ decimals: null, unit: 'locale' }); + const disp = instance(value); + expect(disp.text).toEqual('1,500,000'); + }); + it('with value 128000000 and unit bytes', () => { const value = 1280000125; const instance = getDisplayProcessorFromConfig({ decimals: null, unit: 'bytes' }); diff --git a/packages/grafana-data/src/field/displayProcessor.ts b/packages/grafana-data/src/field/displayProcessor.ts index b5d967afaf6..055ad7baa89 100644 --- a/packages/grafana-data/src/field/displayProcessor.ts +++ b/packages/grafana-data/src/field/displayProcessor.ts @@ -72,6 +72,12 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP unit = 'string'; } + const hasBoolUnit = unit === 'bool'; + const isNumType = field.type === FieldType.number; + const isLocaleFormat = unit === 'locale'; + const shouldTrimTrailingDecimalZeros = + !hasDateUnit && !hasBoolUnit && !isLocaleFormat && isNumType && config.decimals == null; + const formatFunc = getValueFormat(unit || 'none'); const scaleFunc = getScaleCalculator(field, options.theme); @@ -109,9 +115,18 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP } } - if (!isNaN(numeric)) { + if (!Number.isNaN(numeric)) { if (text == null && !isBoolean(value)) { const v = formatFunc(numeric, decimals ?? config.decimals, null, options.timeZone, showMs); + + // if no explicit decimals config, we strip trailing zeros e.g. 60.00 -> 60 + // this is needed because we may have determined the minimum required `decimals` for y tick increments based on + // e.g. 'seconds' field unit (0.15s, 0.20s, 0.25s), but then formatFunc decided to return milli or nanos (150, 200, 250) + // so we end up with excess precision: 150.00, 200.00, 250.00 + if (shouldTrimTrailingDecimalZeros) { + v.text = +v.text + ''; + } + text = v.text; suffix = v.suffix; prefix = v.prefix;