Histogram: Replace null values (#83195)

This commit is contained in:
Adela Almasan 2024-02-26 21:25:26 -06:00 committed by GitHub
parent 93fef224ae
commit 2540842c95
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 129 additions and 16 deletions

View File

@ -22,6 +22,14 @@ describe('histogram frames frames', () => {
fields: [{ name: 'C', type: FieldType.number, values: [5, 6, 7, 8, 9] }],
});
const series3 = toDataFrame({
fields: [{ name: 'D', type: FieldType.number, values: [1, 2, 3, null, null] }],
});
const series4 = toDataFrame({
fields: [{ name: 'E', type: FieldType.number, values: [4, 5, null, 6, null], config: { noValue: '0' } }],
});
const out = histogramFieldsToFrame(buildHistogram([series1, series2])!);
expect(
out.fields.map((f) => ({
@ -188,5 +196,87 @@ describe('histogram frames frames', () => {
},
]
`);
// NULLs filtering test
const out3 = histogramFieldsToFrame(buildHistogram([series3])!);
expect(
out3.fields.map((f) => ({
name: f.name,
values: f.values,
}))
).toMatchInlineSnapshot(`
[
{
"name": "xMin",
"values": [
1,
2,
3,
],
},
{
"name": "xMax",
"values": [
2,
3,
4,
],
},
{
"name": "D",
"values": [
1,
1,
1,
],
},
]
`);
// noValue nulls test
const out4 = histogramFieldsToFrame(buildHistogram([series4])!);
expect(
out4.fields.map((f) => ({
name: f.name,
values: f.values,
config: f.config,
}))
).toMatchInlineSnapshot(`
[
{
"config": {},
"name": "xMin",
"values": [
0,
4,
5,
6,
],
},
{
"config": {},
"name": "xMax",
"values": [
1,
5,
6,
7,
],
},
{
"config": {
"noValue": "0",
"unit": undefined,
},
"name": "E",
"values": [
2,
1,
1,
1,
],
},
]
`);
});
});

View File

@ -8,6 +8,7 @@ import { roundDecimals } from '../../utils';
import { DataTransformerID } from './ids';
import { AlignedData, join } from './joinDataFrames';
import { nullToValueField } from './nulls/nullToValue';
import { transformationsVariableSupport } from './utils';
/**
@ -334,6 +335,26 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
let bucketCount = options?.bucketCount ?? DEFAULT_BUCKET_COUNT;
let bucketOffset = options?.bucketOffset ?? 0;
// replace or filter nulls from numeric fields
frames = frames.map((frame) => {
return {
...frame,
fields: frame.fields.map((field) => {
if (field.type === FieldType.number) {
const noValue = Number(field.config.noValue);
if (!Number.isNaN(noValue)) {
field = nullToValueField(field, noValue);
} else {
field = { ...field, values: field.values.filter((v) => v != null) };
}
}
return field;
}),
};
});
// if bucket size is auto, try to calc from all numeric fields
if (!bucketSize || bucketSize < 0) {
let allValues: number[] = [];
@ -347,8 +368,6 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
}
}
allValues = allValues.filter((v) => v != null);
allValues.sort((a, b) => a - b);
let smallestDelta = Infinity;

View File

@ -1,27 +1,31 @@
import { DataFrame } from '../../../types';
import { DataFrame, Field } from '../../../types';
export function nullToValue(frame: DataFrame) {
return {
...frame,
fields: frame.fields.map((field) => {
const noValue = +field.config?.noValue!;
const noValue = Number(field.config.noValue);
if (!Number.isNaN(noValue)) {
const transformedVals = field.values.slice();
for (let i = 0; i < transformedVals.length; i++) {
if (transformedVals[i] === null) {
transformedVals[i] = noValue;
}
}
return {
...field,
values: transformedVals,
};
return nullToValueField(field, noValue);
} else {
return field;
}
}),
};
}
export function nullToValueField(field: Field, noValue: number) {
const transformedVals = field.values.slice();
for (let i = 0; i < transformedVals.length; i++) {
if (transformedVals[i] === null) {
transformedVals[i] = noValue;
}
}
return {
...field,
values: transformedVals,
};
}