mirror of
https://github.com/grafana/grafana.git
synced 2025-02-14 01:23:32 -06:00
Histogram: Replace null values (#83195)
This commit is contained in:
parent
93fef224ae
commit
2540842c95
@ -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,
|
||||
],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user