소스 검색

Units: Correctly use the override decimals (#16413)

Fixes bugs introduced in PR #14716 and #15146 also restores unit tests that where lost in the
move from kbn units to @grafana/ui units

Fixes #16068
Fixes #16373
Torkel Ödegaard 6 년 전
부모
커밋
8a4a6b4dc1

+ 4 - 2
packages/grafana-ui/src/types/displayValue.ts

@@ -6,7 +6,9 @@ export interface DisplayValue {
   fontSize?: string;
 }
 
+export type DecimalCount = number | null | undefined;
+
 export interface DecimalInfo {
-  decimals: number;
-  scaledDecimals: number;
+  decimals: DecimalCount;
+  scaledDecimals: DecimalCount;
 }

+ 7 - 0
packages/grafana-ui/src/utils/displayValue.test.ts

@@ -158,6 +158,12 @@ describe('Format value', () => {
     expect(instance(value).text).toEqual('0.02');
   });
 
+  it('should use override decimals', () => {
+    const value = 100030303;
+    const instance = getDisplayProcessor({ decimals: 2, unit: 'bytes' });
+    expect(instance(value).text).toEqual('95.40 MiB');
+  });
+
   it('should return mapped value if there are matching value mappings', () => {
     const valueMappings: ValueMapping[] = [
       { id: 0, operator: '', text: '1-20', type: MappingType.RangeToText, from: '1', to: '20' },
@@ -182,5 +188,6 @@ describe('getDecimalsForValue()', () => {
     expect(getDecimalsForValue(20000)).toEqual({ decimals: 0, scaledDecimals: -2 });
     expect(getDecimalsForValue(200000)).toEqual({ decimals: 0, scaledDecimals: -3 });
     expect(getDecimalsForValue(200000000)).toEqual({ decimals: 0, scaledDecimals: -6 });
+    expect(getDecimalsForValue(100, 2)).toEqual({ decimals: 2, scaledDecimals: null });
   });
 });

+ 16 - 15
packages/grafana-ui/src/utils/displayValue.ts

@@ -8,8 +8,15 @@ import { getMappedValue } from './valueMappings';
 import { getColorFromHexRgbOrName } from './namedColorsPalette';
 
 // Types
-import { Threshold, ValueMapping, DecimalInfo, DisplayValue, GrafanaTheme, GrafanaThemeType } from '../types';
-import { DecimalCount } from './valueFormats/valueFormats';
+import {
+  Threshold,
+  ValueMapping,
+  DecimalInfo,
+  DisplayValue,
+  GrafanaTheme,
+  GrafanaThemeType,
+  DecimalCount,
+} from '../types';
 
 export type DisplayProcessor = (value: any) => DisplayValue;
 
@@ -69,18 +76,7 @@ export function getDisplayProcessor(options?: DisplayValueOptions): DisplayProce
 
       if (!isNaN(numeric)) {
         if (shouldFormat && !_.isBoolean(value)) {
-          let decimals;
-          let scaledDecimals = 0;
-
-          if (!options.decimals) {
-            const decimalInfo = getDecimalsForValue(value);
-
-            decimals = decimalInfo.decimals;
-            scaledDecimals = decimalInfo.scaledDecimals;
-          } else {
-            decimals = options.decimals;
-          }
-
+          const { decimals, scaledDecimals } = getDecimalsForValue(value, options.decimals);
           text = formatFunc(numeric, decimals, scaledDecimals, options.isUtc);
         }
         if (thresholds && thresholds.length > 0) {
@@ -159,7 +155,12 @@ export function getColorFromThreshold(value: number, thresholds: Threshold[], th
   return getColorFromHexRgbOrName(thresholds[0].color, themeType);
 }
 
-export function getDecimalsForValue(value: number): DecimalInfo {
+export function getDecimalsForValue(value: number, decimalOverride?: DecimalCount): DecimalInfo {
+  if (_.isNumber(decimalOverride)) {
+    // It's important that scaledDecimals is null here
+    return { decimals: decimalOverride, scaledDecimals: null };
+  }
+
   const delta = value / 2;
   let dec = -Math.floor(Math.log(delta) / Math.LN10);
 

+ 2 - 1
packages/grafana-ui/src/utils/valueFormats/arithmeticFormatters.ts

@@ -1,4 +1,5 @@
-import { toFixed, DecimalCount } from './valueFormats';
+import { toFixed } from './valueFormats';
+import { DecimalCount } from '../../types';
 
 export function toPercent(size: number, decimals: DecimalCount) {
   if (size === null) {

+ 2 - 1
packages/grafana-ui/src/utils/valueFormats/dateTimeFormatters.ts

@@ -1,4 +1,5 @@
-import { toFixed, toFixedScaled, DecimalCount } from './valueFormats';
+import { toFixed, toFixedScaled } from './valueFormats';
+import { DecimalCount } from '../../types';
 import moment from 'moment';
 
 interface IntervalsInSeconds {

+ 2 - 1
packages/grafana-ui/src/utils/valueFormats/symbolFormatters.ts

@@ -1,4 +1,5 @@
-import { scaledUnits, DecimalCount } from './valueFormats';
+import { scaledUnits } from './valueFormats';
+import { DecimalCount } from '../../types';
 
 export function currency(symbol: string) {
   const units = ['', 'K', 'M', 'B', 'T'];

+ 29 - 0
packages/grafana-ui/src/utils/valueFormats/valueFormats.test.ts

@@ -0,0 +1,29 @@
+import { toFixed, getValueFormat } from './valueFormats';
+
+describe('kbn.toFixed and negative decimals', () => {
+  it('should treat as zero decimals', () => {
+    const str = toFixed(186.123, -2);
+    expect(str).toBe('186');
+  });
+});
+
+describe('kbn ms format when scaled decimals is null do not use it', () => {
+  it('should use specified decimals', () => {
+    const str = getValueFormat('ms')(10000086.123, 1, null);
+    expect(str).toBe('2.8 hour');
+  });
+});
+
+describe('kbn kbytes format when scaled decimals is null do not use it', () => {
+  it('should use specified decimals', () => {
+    const str = getValueFormat('kbytes')(10000000, 3, null);
+    expect(str).toBe('9.537 GiB');
+  });
+});
+
+describe('kbn deckbytes format when scaled decimals is null do not use it', () => {
+  it('should use specified decimals', () => {
+    const str = getValueFormat('deckbytes')(10000000, 3, null);
+    expect(str).toBe('10.000 GB');
+  });
+});

+ 1 - 2
packages/grafana-ui/src/utils/valueFormats/valueFormats.ts

@@ -1,6 +1,5 @@
 import { getCategories } from './categories';
-
-export type DecimalCount = number | null | undefined;
+import { DecimalCount } from '../../types';
 
 export type ValueFormatter = (
   value: number,