package mathexp import ( "fmt" "math" "github.com/grafana/grafana-plugin-sdk-go/data" ) func Sum(fv *Float64Field) *float64 { var sum float64 for i := 0; i < fv.Len(); i++ { f := fv.GetValue(i) if f == nil || math.IsNaN(*f) { nan := math.NaN() return &nan } sum += *f } return &sum } func Avg(fv *Float64Field) *float64 { sum := Sum(fv) f := *sum / float64(fv.Len()) return &f } func Min(fv *Float64Field) *float64 { var f float64 if fv.Len() == 0 { nan := math.NaN() return &nan } for i := 0; i < fv.Len(); i++ { v := fv.GetValue(i) if v == nil || math.IsNaN(*v) { nan := math.NaN() return &nan } if i == 0 || *v < f { f = *v } } return &f } func Max(fv *Float64Field) *float64 { var f float64 if fv.Len() == 0 { nan := math.NaN() return &nan } for i := 0; i < fv.Len(); i++ { v := fv.GetValue(i) if v == nil || math.IsNaN(*v) { nan := math.NaN() return &nan } if i == 0 || *v > f { f = *v } } return &f } func Count(fv *Float64Field) *float64 { f := float64(fv.Len()) return &f } // Reduce turns the Series into a Number based on the given reduction function func (s Series) Reduce(refID, rFunc string) (Number, error) { var l data.Labels if s.GetLabels() != nil { l = s.GetLabels().Copy() } number := NewNumber(refID, l) var f *float64 fVec := s.Frame.Fields[seriesTypeValIdx] floatField := Float64Field(*fVec) switch rFunc { case "sum": f = Sum(&floatField) case "mean": f = Avg(&floatField) case "min": f = Min(&floatField) case "max": f = Max(&floatField) case "count": f = Count(&floatField) default: return number, fmt.Errorf("reduction %v not implemented", rFunc) } number.SetValue(f) return number, nil }