Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Commit

Permalink
Compute min and max from aggregated values (#19)
Browse files Browse the repository at this point in the history
* Compute min and max from aggregated values

Fixes #16 and #18

* Detect whether automatic min/max is set

* Refactor
  • Loading branch information
marcusolsson committed Jan 9, 2021
1 parent 7af7f0a commit 8aee92e
Showing 1 changed file with 30 additions and 3 deletions.
33 changes: 30 additions & 3 deletions src/bucket.ts
@@ -1,5 +1,5 @@
import * as d3 from 'd3';
import { TimeRange, dateTime, dateTimeParse, DisplayProcessor, Field } from '@grafana/data';
import { TimeRange, dateTime, dateTimeParse, DisplayProcessor, Field, getDisplayProcessor } from '@grafana/data';

export interface Point {
time: number;
Expand Down Expand Up @@ -123,22 +123,49 @@ export const bucketize = (
// Group and reduce values.
const groupedByMinutes = groupByMinutes(rowsWithinDailyInterval, customData.groupBy, timeZone);
const reducedMinutes = reduce(groupedByMinutes, calculations[customData.calculation]);
const points = groupByDay(reducedMinutes).flatMap(({ time, values }) =>

const aggregatedPoints = groupByDay(reducedMinutes).flatMap(({ time, values }) =>
values.map(({ time, value }) => ({
dayMillis: time,
bucketStartMillis: time,
value,
}))
);

recalculateMinMax(
valueField,
aggregatedPoints.map(({ value }) => value)
);

return {
numBuckets: Math.floor(minutesPerDay / customData.groupBy),
points: points,
points: aggregatedPoints,
valueField,
timeField,
};
};

// recalculateMinMax updates the field min and max to the extents of the
// aggregated values rather than the raw values.
//
// TODO: While this works, it feels like hacky. Is there a better way to do this?
const recalculateMinMax = (field: Field<number>, values: number[]) => {
// Future versions of Grafana will change how the min and max are calculated.
// For example, if Min or Max are set to auto, they will be undefined.
//
// Also, we should probably use getFieldConfigWithMinMax in the future:
// https://github.com/grafana/grafana/blob/097dcc456a617bc67c3d5134e22adc00ad5b79c5/packages/grafana-data/src/field/scale.ts#L68
const autoMin = !field.config.min || field.config.min === field.state?.calcs?.min;
const autoMax = !field.config.max || field.config.max === field.state?.calcs?.max;

if (autoMin) field.config.min = d3.min(values);
if (autoMax) field.config.max = d3.max(values);

field.display = getDisplayProcessor({
field: field,
});
};

// Lookup table for calculations.
const calculations: any = {
mean: (vals: number[]) => d3.mean(vals),
Expand Down

0 comments on commit 8aee92e

Please sign in to comment.