From 4ba6889df8fb51f9147519a5d815841b4ddd0b9f Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Tue, 29 Aug 2023 11:35:18 -0500 Subject: [PATCH] FieldOverrides: Optimize doStandardCalcs() (#67881) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Torkel Ödegaard --- .../src/transformations/fieldReducer.test.ts | 21 ++++++++++++++++++- .../src/transformations/fieldReducer.ts | 11 ++++++---- .../transformers/groupBy.test.ts | 8 +++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/packages/grafana-data/src/transformations/fieldReducer.test.ts b/packages/grafana-data/src/transformations/fieldReducer.test.ts index f4cc0b6b178..c1d89c487a0 100644 --- a/packages/grafana-data/src/transformations/fieldReducer.test.ts +++ b/packages/grafana-data/src/transformations/fieldReducer.test.ts @@ -1,7 +1,7 @@ import { difference } from 'lodash'; import { createDataFrame, guessFieldTypeFromValue } from '../dataframe/processDataFrame'; -import { Field, FieldType } from '../types/index'; +import { Field, FieldType, NullValueMode } from '../types/index'; import { fieldReducers, ReducerID, reduceField } from './fieldReducer'; @@ -171,4 +171,23 @@ describe('Stats Calculators', () => { } } }); + + it('count should ignoreNulls by default', () => { + const someNulls = createField('x', [1, null, null, 1]); + expect(reduce(someNulls, ReducerID.count)).toEqual(2); + }); + + it('count should use fieldConfig nullValueMode.Ignore and not count nulls', () => { + const someNulls = createField('x', [1, null, null, 1]); + someNulls.config.nullValueMode = NullValueMode.Ignore; + + expect(reduce(someNulls, ReducerID.count)).toEqual(2); + }); + + it('count should use fieldConfig nullValueMode.Null and count nulls', () => { + const someNulls = createField('x', [1, null, null, 1]); + someNulls.config.nullValueMode = NullValueMode.Null; + + expect(reduce(someNulls, ReducerID.count)).toEqual(4); + }); }); diff --git a/packages/grafana-data/src/transformations/fieldReducer.ts b/packages/grafana-data/src/transformations/fieldReducer.ts index 103dc14309e..7d7927792fc 100644 --- a/packages/grafana-data/src/transformations/fieldReducer.ts +++ b/packages/grafana-data/src/transformations/fieldReducer.ts @@ -88,7 +88,9 @@ export function reduceField(options: ReduceFieldOptions): FieldCalcs { return (field.state.calcs = calcs); } - const { nullValueMode } = field.config; + // Default to Ignore for nullValueMode. + const { nullValueMode = NullValueMode.Ignore } = field.config; + const ignoreNulls = nullValueMode === NullValueMode.Ignore; const nullAsZero = nullValueMode === NullValueMode.AsZero; @@ -291,9 +293,8 @@ export function doStandardCalcs(field: Field, ignoreNulls: boolean, nullAsZero: }; const data = field.values; - calcs.count = ignoreNulls ? data.length : data.filter((val) => val != null).length; - const isNumberField = field.type === FieldType.number || FieldType.time; + const isNumberField = field.type === FieldType.number || field.type === FieldType.time; for (let i = 0; i < data.length; i++) { let currentValue = data[i]; @@ -304,7 +305,7 @@ export function doStandardCalcs(field: Field, ignoreNulls: boolean, nullAsZero: calcs.last = currentValue; - if (currentValue === null) { + if (currentValue == null) { if (ignoreNulls) { continue; } @@ -313,6 +314,8 @@ export function doStandardCalcs(field: Field, ignoreNulls: boolean, nullAsZero: } } + calcs.count++; + if (currentValue != null) { // null || undefined const isFirst = calcs.firstNotNull === null; diff --git a/packages/grafana-data/src/transformations/transformers/groupBy.test.ts b/packages/grafana-data/src/transformations/transformers/groupBy.test.ts index d0b07197ce0..8d049f63f52 100644 --- a/packages/grafana-data/src/transformations/transformers/groupBy.test.ts +++ b/packages/grafana-data/src/transformations/transformers/groupBy.test.ts @@ -83,7 +83,7 @@ describe('GroupBy transformer', () => { fields: [ { name: 'time', type: FieldType.time, values: [3000, 4000, 5000, 6000, 7000, 8000] }, { name: 'message', type: FieldType.string, values: ['one', 'two', 'two', 'three', 'three', 'three'] }, - { name: 'values', type: FieldType.string, values: [1, 2, 2, 3, 3, 3] }, + { name: 'values', type: FieldType.number, values: [1, 2, 2, 3, 3, 3] }, ], }); @@ -130,7 +130,7 @@ describe('GroupBy transformer', () => { fields: [ { name: 'time', type: FieldType.time, values: [3000, 4000, 5000, 6000, 7000, 8000] }, { name: 'message', type: FieldType.string, values: ['one', 'two', 'two', 'three', 'three', 'three'] }, - { name: 'values', type: FieldType.string, values: [1, 2, 2, 3, 3, 3] }, + { name: 'values', type: FieldType.number, values: [1, 2, 2, 3, 3, 3] }, ], }); @@ -194,7 +194,7 @@ describe('GroupBy transformer', () => { fields: [ { name: 'time', type: FieldType.time, values: [3000, 4000, 5000, 6000, 7000, 8000] }, { name: 'message', type: FieldType.string, values: ['one', 'two', 'two', 'three', 'three', 'three'] }, - { name: 'values', type: FieldType.string, values: [1, 2, 2, 3, 3, 3] }, + { name: 'values', type: FieldType.number, values: [1, 2, 2, 3, 3, 3] }, ], }), toDataFrame({ @@ -202,7 +202,7 @@ describe('GroupBy transformer', () => { fields: [ { name: 'time', type: FieldType.time, values: [3000, 4000, 5000, 6000, 7000, 8000] }, { name: 'message', type: FieldType.string, values: ['one', 'two', 'two', 'three', 'three', 'three'] }, - { name: 'values', type: FieldType.string, values: [0, 2, 5, 3, 3, 2] }, + { name: 'values', type: FieldType.number, values: [0, 2, 5, 3, 3, 2] }, ], }), ];