diff --git a/pkg/datasource/functions.go b/pkg/datasource/functions.go index aec2176..94c1420 100644 --- a/pkg/datasource/functions.go +++ b/pkg/datasource/functions.go @@ -61,6 +61,12 @@ func getAggFunc(agg string) timeseries.AggFunc { return timeseries.AggMax case "min": return timeseries.AggMin + case "sum": + return timeseries.AggSum + case "median": + return timeseries.AggMedian + case "count": + return timeseries.AggCount case "first": return timeseries.AggFirst case "last": diff --git a/pkg/timeseries/timeseries.go b/pkg/timeseries/timeseries.go index 578ee1a..962be01 100644 --- a/pkg/timeseries/timeseries.go +++ b/pkg/timeseries/timeseries.go @@ -75,14 +75,19 @@ func (ts TimeSeries) GroupBy(interval time.Duration, aggFunc AggFunc) TimeSeries } func AggAvg(points []TimePoint) *float64 { + sum := AggSum(points) + avg := *sum / float64(len(points)) + return &avg +} + +func AggSum(points []TimePoint) *float64 { var sum float64 = 0 for _, p := range points { if p.Value != nil { sum += *p.Value } } - avg := sum / float64(len(points)) - return &avg + return &sum } func AggMax(points []TimePoint) *float64 { @@ -113,6 +118,11 @@ func AggMin(points []TimePoint) *float64 { return min } +func AggCount(points []TimePoint) *float64 { + count := float64(len(points)) + return &count +} + func AggFirst(points []TimePoint) *float64 { return points[0].Value } @@ -121,6 +131,23 @@ func AggLast(points []TimePoint) *float64 { return points[len(points)-1].Value } +func AggMedian(points []TimePoint) *float64 { + values := make([]float64, 0) + for _, p := range points { + if p.Value != nil { + values = append(values, *p.Value) + } + } + if len(values) == 0 { + return nil + } + + values = sort.Float64Slice(values) + medianIndex := int(math.Floor(float64(len(values)) / 2)) + median := values[medianIndex] + return &median +} + // Aligns point's time stamps according to provided interval. func (ts TimeSeries) Align(interval time.Duration) TimeSeries { if interval <= 0 || ts.Len() < 2 {