mirror of
https://github.com/grafana/grafana.git
synced 2024-11-23 09:26:43 -06:00
Number formatting: only 0-trim decimals in y axis ticks. omit currency, locale units. (#57386)
This commit is contained in:
parent
45707ccf99
commit
0640eeef0a
@ -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.2');
|
||||
expect(disp.text).toEqual('1.20');
|
||||
expect(disp.suffix).toEqual(' K');
|
||||
});
|
||||
|
||||
@ -329,7 +329,7 @@ describe('Format value', () => {
|
||||
const value = 1500000;
|
||||
const instance = getDisplayProcessorFromConfig({ decimals: null, unit: 'short' });
|
||||
const disp = instance(value);
|
||||
expect(disp.text).toEqual('1.5');
|
||||
expect(disp.text).toEqual('1.50');
|
||||
expect(disp.suffix).toEqual(' Mil');
|
||||
});
|
||||
|
||||
@ -376,6 +376,53 @@ describe('Format value', () => {
|
||||
expect(disp.text).toEqual(value);
|
||||
});
|
||||
});
|
||||
|
||||
describe('number formatting for y axis ticks (dynamic decimals with trailing 0s trimming)', () => {
|
||||
// all these tests have non-null adjacentDecimals != null, which we only do durink axis tick formatting
|
||||
|
||||
it('should trim trailing zeros after decimal from fractional seconds when formatted as millis with adjacentDecimals=2', () => {
|
||||
const processor = getDisplayProcessorFromConfig({ unit: 's' }, FieldType.number);
|
||||
expect(processor(0.06, 2).text).toEqual('60');
|
||||
});
|
||||
|
||||
it('should trim trailing zeros after decimal from number', () => {
|
||||
const processor = getDisplayProcessorFromConfig({}, FieldType.number);
|
||||
expect(processor(1.2, 2).text).toEqual('1.2');
|
||||
|
||||
// dynamic!
|
||||
expect(processor(13.50008, 3).text).toEqual('13.5');
|
||||
});
|
||||
|
||||
it('should not attempt to trim zeros from currency*', () => {
|
||||
const processor = getDisplayProcessorFromConfig({ unit: 'currencyUSD' }, FieldType.number);
|
||||
expect(processor(1.2, 2).text).toEqual('1.20');
|
||||
});
|
||||
|
||||
it('should not attempt to trim zeros from bool', () => {
|
||||
const processor = getDisplayProcessorFromConfig({ unit: 'bool' }, FieldType.number);
|
||||
expect(processor(1, 2).text).toEqual('True');
|
||||
});
|
||||
|
||||
it('should not attempt to trim zeros from time', () => {
|
||||
const processor = getDisplayProcessorFromConfig({}, FieldType.time);
|
||||
expect(processor(1666402869517, 2).text).toEqual('2022-10-21 20:41:09');
|
||||
});
|
||||
|
||||
it('should not attempt to trim zeros from dateTimeAsUS', () => {
|
||||
const processor = getDisplayProcessorFromConfig({ unit: 'dateTimeAsUS' }, FieldType.number);
|
||||
expect(processor(1666402869517, 2).text).toEqual('10/21/2022 8:41:09 pm');
|
||||
});
|
||||
|
||||
it('should not attempt to trim zeros from locale', () => {
|
||||
const processor = getDisplayProcessorFromConfig({ unit: 'locale' }, FieldType.number);
|
||||
expect(processor(3500000, 2).text).toEqual('3,500,000');
|
||||
});
|
||||
|
||||
it('should not attempt to trim zeros when explicit decimals: 5', () => {
|
||||
const processor = getDisplayProcessorFromConfig({ decimals: 5 }, FieldType.number);
|
||||
expect(processor(35, 2).text).toEqual('35.00000');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Date display options', () => {
|
||||
|
@ -10,7 +10,7 @@ import { Field, FieldType } from '../types/dataFrame';
|
||||
import { DecimalCount, DisplayProcessor, DisplayValue } from '../types/displayValue';
|
||||
import { anyToNumber } from '../utils/anyToNumber';
|
||||
import { getValueMappingResult } from '../utils/valueMappings';
|
||||
import { getValueFormat, isBooleanUnit } from '../valueFormats/valueFormats';
|
||||
import { FormattedValue, getValueFormat, isBooleanUnit } from '../valueFormats/valueFormats';
|
||||
|
||||
import { getScaleCalculator } from './scale';
|
||||
|
||||
@ -72,16 +72,17 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP
|
||||
unit = 'string';
|
||||
}
|
||||
|
||||
const hasCurrencyUnit = unit?.startsWith('currency');
|
||||
const hasBoolUnit = unit === 'bool';
|
||||
const isNumType = field.type === FieldType.number;
|
||||
const isLocaleFormat = unit === 'locale';
|
||||
const shouldTrimTrailingDecimalZeros =
|
||||
!hasDateUnit && !hasBoolUnit && !isLocaleFormat && isNumType && config.decimals == null;
|
||||
const canTrimTrailingDecimalZeros =
|
||||
!hasDateUnit && !hasCurrencyUnit && !hasBoolUnit && !isLocaleFormat && isNumType && config.decimals == null;
|
||||
|
||||
const formatFunc = getValueFormat(unit || 'none');
|
||||
const scaleFunc = getScaleCalculator(field, options.theme);
|
||||
|
||||
return (value: any, decimals?: DecimalCount) => {
|
||||
return (value: any, adjacentDecimals?: DecimalCount) => {
|
||||
const { mappings } = config;
|
||||
const isStringUnit = unit === 'string';
|
||||
|
||||
@ -117,14 +118,18 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP
|
||||
|
||||
if (!Number.isNaN(numeric)) {
|
||||
if (text == null && !isBoolean(value)) {
|
||||
const v = formatFunc(numeric, decimals ?? config.decimals, null, options.timeZone, showMs);
|
||||
let v: FormattedValue;
|
||||
|
||||
// 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) {
|
||||
if (canTrimTrailingDecimalZeros && adjacentDecimals != null) {
|
||||
v = formatFunc(numeric, adjacentDecimals, 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 determined `adjacentDecimals` 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
|
||||
v.text = +v.text + '';
|
||||
} else {
|
||||
v = formatFunc(numeric, config.decimals, null, options.timeZone, showMs);
|
||||
}
|
||||
|
||||
text = v.text;
|
||||
|
@ -279,7 +279,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{
|
||||
label: customConfig.axisLabel,
|
||||
size: customConfig.axisWidth,
|
||||
placement: customConfig.axisPlacement ?? AxisPlacement.Auto,
|
||||
formatValue: (v, decimals) => formattedValueToString(fmt(v, config.decimals ?? decimals)),
|
||||
formatValue: (v, decimals) => formattedValueToString(fmt(v, decimals)),
|
||||
theme,
|
||||
grid: { show: customConfig.axisGridShow },
|
||||
decimals: field.config.decimals,
|
||||
|
@ -253,7 +253,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
||||
label: customConfig.axisLabel,
|
||||
size: customConfig.axisWidth,
|
||||
placement,
|
||||
formatValue: (v, decimals) => formattedValueToString(field.display!(v, field.config.decimals ?? decimals)),
|
||||
formatValue: (v, decimals) => formattedValueToString(field.display!(v, decimals)),
|
||||
theme,
|
||||
grid: { show: customConfig.axisGridShow },
|
||||
});
|
||||
|
@ -408,7 +408,7 @@ export function prepConfig(opts: PrepConfigOpts) {
|
||||
size: yAxisConfig.axisWidth || null,
|
||||
label: yAxisConfig.axisLabel,
|
||||
theme: theme,
|
||||
formatValue: (v, decimals) => formattedValueToString(dispY(v, yField.config.decimals ?? decimals)),
|
||||
formatValue: (v, decimals) => formattedValueToString(dispY(v, decimals)),
|
||||
splits: isOrdianalY
|
||||
? (self: uPlot) => {
|
||||
const meta = readHeatmapRowsCustomMeta(dataRef.current?.heatmap);
|
||||
|
@ -153,7 +153,7 @@ const prepConfig = (frame: DataFrame, theme: GrafanaTheme2) => {
|
||||
scaleKey: 'y',
|
||||
isTime: false,
|
||||
placement: AxisPlacement.Left,
|
||||
formatValue: (v, decimals) => formattedValueToString(dispY!(v, countField.config.decimals ?? decimals)),
|
||||
formatValue: (v, decimals) => formattedValueToString(dispY!(v, decimals)),
|
||||
//splits: config.xSplits,
|
||||
//values: config.xValues,
|
||||
//grid: false,
|
||||
|
Loading…
Reference in New Issue
Block a user