Scale/offset

This commit is contained in:
Alexander Zobnin
2021-05-25 16:24:32 +03:00
parent addd86d7cd
commit d3888329cb
5 changed files with 140 additions and 71 deletions

View File

@@ -2,6 +2,7 @@ package datasource
import ( import (
"fmt" "fmt"
"strconv"
"github.com/alexanderzobnin/grafana-zabbix/pkg/gtime" "github.com/alexanderzobnin/grafana-zabbix/pkg/gtime"
"github.com/alexanderzobnin/grafana-zabbix/pkg/timeseries" "github.com/alexanderzobnin/grafana-zabbix/pkg/timeseries"
@@ -18,6 +19,8 @@ var funcMap map[string]DataProcessingFunc
func init() { func init() {
funcMap = map[string]DataProcessingFunc{ funcMap = map[string]DataProcessingFunc{
"groupBy": applyGroupBy, "groupBy": applyGroupBy,
"scale": applyScale,
"offset": applyOffset,
} }
} }
@@ -53,6 +56,28 @@ func applyGroupBy(series timeseries.TimeSeries, params ...string) (timeseries.Ti
return s, nil return s, nil
} }
func applyScale(series timeseries.TimeSeries, params ...string) (timeseries.TimeSeries, error) {
pFactor := params[0]
factor, err := strconv.ParseFloat(pFactor, 64)
if err != nil {
return nil, err
}
transformFunc := timeseries.TransformScale(factor)
return series.Transform(transformFunc), nil
}
func applyOffset(series timeseries.TimeSeries, params ...string) (timeseries.TimeSeries, error) {
pOffset := params[0]
offset, err := strconv.ParseFloat(pOffset, 64)
if err != nil {
return nil, err
}
transformFunc := timeseries.TransformOffset(offset)
return series.Transform(transformFunc), nil
}
func getAggFunc(agg string) timeseries.AggFunc { func getAggFunc(agg string) timeseries.AggFunc {
switch agg { switch agg {
case "avg": case "avg":

View File

@@ -0,0 +1,80 @@
package timeseries
import (
"math"
"sort"
)
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
}
}
return &sum
}
func AggMax(points []TimePoint) *float64 {
var max *float64 = nil
for _, p := range points {
if p.Value != nil {
if max == nil {
max = p.Value
} else if *p.Value > *max {
max = p.Value
}
}
}
return max
}
func AggMin(points []TimePoint) *float64 {
var min *float64 = nil
for _, p := range points {
if p.Value != nil {
if min == nil {
min = p.Value
} else if *p.Value < *min {
min = p.Value
}
}
}
return min
}
func AggCount(points []TimePoint) *float64 {
count := float64(len(points))
return &count
}
func AggFirst(points []TimePoint) *float64 {
return points[0].Value
}
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
}

View File

@@ -31,3 +31,5 @@ type TimeSeriesMeta struct {
} }
type AggFunc = func(points []TimePoint) *float64 type AggFunc = func(points []TimePoint) *float64
type TransformFunc = func(point TimePoint) TimePoint

View File

@@ -74,78 +74,11 @@ func (ts TimeSeries) GroupBy(interval time.Duration, aggFunc AggFunc) TimeSeries
return groupedSeries return groupedSeries
} }
func AggAvg(points []TimePoint) *float64 { func (ts TimeSeries) Transform(transformFunc TransformFunc) TimeSeries {
sum := AggSum(points) for i, p := range ts {
avg := *sum / float64(len(points)) ts[i] = transformFunc(p)
return &avg
}
func AggSum(points []TimePoint) *float64 {
var sum float64 = 0
for _, p := range points {
if p.Value != nil {
sum += *p.Value
} }
} return ts
return &sum
}
func AggMax(points []TimePoint) *float64 {
var max *float64 = nil
for _, p := range points {
if p.Value != nil {
if max == nil {
max = p.Value
} else if *p.Value > *max {
max = p.Value
}
}
}
return max
}
func AggMin(points []TimePoint) *float64 {
var min *float64 = nil
for _, p := range points {
if p.Value != nil {
if min == nil {
min = p.Value
} else if *p.Value < *min {
min = p.Value
}
}
}
return min
}
func AggCount(points []TimePoint) *float64 {
count := float64(len(points))
return &count
}
func AggFirst(points []TimePoint) *float64 {
return points[0].Value
}
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. // Aligns point's time stamps according to provided interval.

View File

@@ -0,0 +1,29 @@
package timeseries
func TransformScale(factor float64) TransformFunc {
return func(point TimePoint) TimePoint {
return transformScale(point, factor)
}
}
func TransformOffset(offset float64) TransformFunc {
return func(point TimePoint) TimePoint {
return transformOffset(point, offset)
}
}
func transformScale(point TimePoint, factor float64) TimePoint {
if point.Value != nil {
newValue := *point.Value * factor
point.Value = &newValue
}
return point
}
func transformOffset(point TimePoint, offset float64) TimePoint {
if point.Value != nil {
newValue := *point.Value + offset
point.Value = &newValue
}
return point
}