mirror of
https://github.com/grafana/grafana.git
synced 2024-11-24 18:00:31 -06:00
Transformations: Add standard deviation and variance reducers (#52769)
Co-authored-by: Selva <selvavm@hotmail.com> Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
This commit is contained in:
parent
a1c6147374
commit
5df6a95045
@ -10,7 +10,7 @@ weight: 1100
|
||||
|
||||
# Reference: Calculation types
|
||||
|
||||
Refer to the following list of calculations you can perform in Grafana. You can find these calculations in the **Transform** tab and in the bar gauge, gauge, and stat visualizations.
|
||||
The following table contains a list of calculations you can perform in Grafana. You can find these calculations in the **Transform** tab and in the bar gauge, gauge, and stat visualizations.
|
||||
|
||||
| Calculation | Description |
|
||||
| :----------------- | :-------------------------------------------------------- |
|
||||
@ -25,6 +25,8 @@ Refer to the following list of calculations you can perform in Grafana. You can
|
||||
| First (not null) | First, not null value in a field |
|
||||
| Max | Maximum value of a field |
|
||||
| Mean | Mean value of all values in a field |
|
||||
| Variance | Variance of all values in a field |
|
||||
| StdDev | Standard deviation of all values in a field |
|
||||
| Min | Minimum value of a field |
|
||||
| Min (above zero) | Minimum, positive value of a field |
|
||||
| Range | Difference between maximum and minimum values of a field |
|
||||
|
@ -80,11 +80,13 @@ describe('Stats Calculators', () => {
|
||||
it('should get non standard stats', () => {
|
||||
const stats = reduceField({
|
||||
field: basicTable.fields[0],
|
||||
reducers: [ReducerID.distinctCount, ReducerID.changeCount],
|
||||
reducers: [ReducerID.distinctCount, ReducerID.changeCount, ReducerID.variance, ReducerID.stdDev],
|
||||
});
|
||||
|
||||
expect(stats.distinctCount).toEqual(2);
|
||||
expect(stats.changeCount).toEqual(1);
|
||||
expect(stats.variance).toEqual(25);
|
||||
expect(stats.stdDev).toEqual(5);
|
||||
});
|
||||
|
||||
it('should calculate step', () => {
|
||||
|
@ -10,6 +10,8 @@ export enum ReducerID {
|
||||
min = 'min',
|
||||
logmin = 'logmin',
|
||||
mean = 'mean',
|
||||
variance = 'variance',
|
||||
stdDev = 'stdDev',
|
||||
last = 'last',
|
||||
first = 'first',
|
||||
count = 'count',
|
||||
@ -152,6 +154,20 @@ export const fieldReducers = new Registry<FieldReducerInfo>(() => [
|
||||
{ id: ReducerID.min, name: 'Min', description: 'Minimum Value', standard: true },
|
||||
{ id: ReducerID.max, name: 'Max', description: 'Maximum Value', standard: true },
|
||||
{ id: ReducerID.mean, name: 'Mean', description: 'Average Value', standard: true, aliasIds: ['avg'] },
|
||||
{
|
||||
id: ReducerID.variance,
|
||||
name: 'Variance',
|
||||
description: 'Variance of all values in a field',
|
||||
standard: false,
|
||||
reduce: calculateStdDev,
|
||||
},
|
||||
{
|
||||
id: ReducerID.stdDev,
|
||||
name: 'StdDev',
|
||||
description: 'Standard deviation of all values in a field',
|
||||
standard: false,
|
||||
reduce: calculateStdDev,
|
||||
},
|
||||
{
|
||||
id: ReducerID.sum,
|
||||
name: 'Total',
|
||||
@ -419,6 +435,33 @@ function calculateLastNotNull(field: Field, ignoreNulls: boolean, nullAsZero: bo
|
||||
return { lastNotNull: null };
|
||||
}
|
||||
|
||||
/** Calculates standard deviation and variance */
|
||||
function calculateStdDev(field: Field, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
||||
// Only support number fields
|
||||
if (!(field.type === FieldType.number || field.type === FieldType.time)) {
|
||||
return { variance: 0, stdDev: 0 };
|
||||
}
|
||||
|
||||
let squareSum = 0;
|
||||
let runningMean = 0;
|
||||
let runningNonNullCount = 0;
|
||||
const data = field.values;
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const currentValue = data.get(i);
|
||||
if (currentValue != null) {
|
||||
runningNonNullCount++;
|
||||
let _oldMean = runningMean;
|
||||
runningMean += (currentValue - _oldMean) / runningNonNullCount;
|
||||
squareSum += (currentValue - _oldMean) * (currentValue - runningMean);
|
||||
}
|
||||
}
|
||||
if (runningNonNullCount > 0) {
|
||||
const variance = squareSum / runningNonNullCount;
|
||||
return { variance, stdDev: Math.sqrt(variance) };
|
||||
}
|
||||
return { variance: 0, stdDev: 0 };
|
||||
}
|
||||
|
||||
function calculateChangeCount(field: Field, ignoreNulls: boolean, nullAsZero: boolean): FieldCalcs {
|
||||
const data = field.values;
|
||||
let count = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user