Commit e50a75f2 by Torkel Ödegaard Committed by GitHub

Singlestat/Gauge/BarGauge: Improvements to decimals logic and added test dashboard (#18676)

* Singlevalue: Improvements to decimals logic and added test dashboard

* updated

* Fixed tests
parent 0f2a393e
import { MappingType, ValueMapping, DisplayProcessor, DisplayValue } from '@grafana/data';
import { getDisplayProcessor, getColorFromThreshold, getDecimalsForValue } from './displayProcessor';
import { getDisplayProcessor, getColorFromThreshold } from './displayProcessor';
function assertSame(input: any, processors: DisplayProcessor[], match: DisplayValue) {
processors.forEach(processor => {
......@@ -135,17 +134,16 @@ describe('Format value', () => {
});
it('should set auto decimals, 1 significant', () => {
const value = '1.23';
const value = 3.23;
const instance = getDisplayProcessor({ field: { decimals: null } });
expect(instance(value).text).toEqual('1.2');
expect(instance(value).text).toEqual('3.2');
});
it('should set auto decimals, 2 significant', () => {
const value = '0.0245';
const value = 0.0245;
const instance = getDisplayProcessor({ field: { decimals: null } });
expect(instance(value).text).toEqual('0.02');
expect(instance(value).text).toEqual('0.025');
});
it('should use override decimals', () => {
......@@ -164,20 +162,32 @@ describe('Format value', () => {
expect(instance(value).text).toEqual('1-20');
});
});
describe('getDecimalsForValue()', () => {
it('should calculate reasonable decimals precision for given value', () => {
expect(getDecimalsForValue(1.01)).toEqual({ decimals: 1, scaledDecimals: 4 });
expect(getDecimalsForValue(9.01)).toEqual({ decimals: 0, scaledDecimals: 2 });
expect(getDecimalsForValue(1.1)).toEqual({ decimals: 1, scaledDecimals: 4 });
expect(getDecimalsForValue(2)).toEqual({ decimals: 0, scaledDecimals: 2 });
expect(getDecimalsForValue(20)).toEqual({ decimals: 0, scaledDecimals: 1 });
expect(getDecimalsForValue(200)).toEqual({ decimals: 0, scaledDecimals: 0 });
expect(getDecimalsForValue(2000)).toEqual({ decimals: 0, scaledDecimals: 0 });
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 });
//
// Below is current behavior but I it's clearly not working great
//
it('with value 1000 and unit short', () => {
const value = 1000;
const instance = getDisplayProcessor({ field: { decimals: null, unit: 'short' } });
expect(instance(value).text).toEqual('1.000 K');
});
it('with value 1200 and unit short', () => {
const value = 1200;
const instance = getDisplayProcessor({ field: { decimals: null, unit: 'short' } });
expect(instance(value).text).toEqual('1.200 K');
});
it('with value 1250 and unit short', () => {
const value = 1250;
const instance = getDisplayProcessor({ field: { decimals: null, unit: 'short' } });
expect(instance(value).text).toEqual('1.250 K');
});
it('with value 10000000 and unit short', () => {
const value = 1000000;
const instance = getDisplayProcessor({ field: { decimals: null, unit: 'short' } });
expect(instance(value).text).toEqual('1.000 Mil');
});
});
......@@ -127,17 +127,31 @@ export function getColorFromThreshold(value: number, thresholds: Threshold[], th
return getColorFromHexRgbOrName(thresholds[0].color, themeType);
}
// function getSignificantDigitCount(n: number): number {
// // remove decimal and make positive
// n = Math.abs(parseInt(String(n).replace('.', ''), 10));
// if (n === 0) {
// return 0;
// }
//
// // kill the 0s at the end of n
// while (n !== 0 && n % 10 === 0) {
// n /= 10;
// }
//
// // get number of digits
// return Math.floor(Math.log(n) / Math.LN10) + 1;
// }
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);
let dec = -Math.floor(Math.log(value) / Math.LN10) + 1;
const magn = Math.pow(10, -dec);
const norm = delta / magn; // norm is between 1.0 and 10.0
const norm = value / magn; // norm is between 1.0 and 10.0
let size;
if (norm < 1.5) {
......@@ -158,7 +172,7 @@ export function getDecimalsForValue(value: number, decimalOverride?: DecimalCoun
size *= magn;
// reduce starting decimals if not needed
if (Math.floor(value) === value) {
if (value % 1 === 0) {
dec = 0;
}
......
......@@ -193,7 +193,7 @@ describe('SingleStatCtrl', () => {
singleStatScenario('When value to text mapping is specified', (ctx: TestContext) => {
ctx.setup(() => {
ctx.input = [{ target: 'test.cpu1', datapoints: [[9.9, 1]] }];
ctx.ctrl.panel.valueMaps = [{ value: '10', text: 'OK' }];
ctx.ctrl.panel.valueMaps = [{ value: '9.9', text: 'OK' }];
});
it('value should remain', () => {
......@@ -291,20 +291,16 @@ describe('SingleStatCtrl', () => {
singleStatScenario('When value to text mapping is specified', (ctx: TestContext) => {
ctx.setup(() => {
ctx.input = tableData;
ctx.input[0].rows[0] = [1492759673649, 'ignore1', 9.9, 'ignore2'];
ctx.input[0].rows[0] = [1492759673649, 'ignore1', 10, 'ignore2'];
ctx.ctrl.panel.mappingType = 2;
ctx.ctrl.panel.tableColumn = 'mean';
ctx.ctrl.panel.valueMaps = [{ value: '10', text: 'OK' }];
});
it('value should remain', () => {
expect(ctx.data.value).toBe(9.9);
expect(ctx.data.value).toBe(10);
});
// it('round should be rounded up', () => {
// expect(ctx.data.valueRounded).toBe(10);
// });
it('Should replace value with text', () => {
expect(ctx.data.display.text).toBe('OK');
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment