package mathexp import ( "fmt" "math" "github.com/grafana/grafana-plugin-sdk-go/data" ) func Sum(v *data.Field) *float64 { var sum float64 for i := 0; i < v.Len(); i++ { if f, ok := v.At(i).(*float64); ok { if f == nil || math.IsNaN(*f) { nan := math.NaN() return &nan } sum += *f } } return &sum } func Avg(v *data.Field) *float64 { sum := Sum(v) f := *sum / float64(v.Len()) return &f } func Min(fv *data.Field) *float64 { var f float64 if fv.Len() == 0 { nan := math.NaN() return &nan } for i := 0; i < fv.Len(); i++ { if v, ok := fv.At(i).(*float64); ok { if v == nil || math.IsNaN(*v) { nan := math.NaN() return &nan } if i == 0 || *v < f { f = *v } } } return &f } func Max(fv *data.Field) *float64 { var f float64 if fv.Len() == 0 { nan := math.NaN() return &nan } for i := 0; i < fv.Len(); i++ { if v, ok := fv.At(i).(*float64); ok { if v == nil || math.IsNaN(*v) { nan := math.NaN() return &nan } if i == 0 || *v > f { f = *v } } } return &f } func Count(fv *data.Field) *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[1] switch rFunc { case "sum": f = Sum(fVec) case "mean": f = Avg(fVec) case "min": f = Min(fVec) case "max": f = Max(fVec) case "count": f = Count(fVec) default: return number, fmt.Errorf("reduction %v not implemented", rFunc) } number.SetValue(f) return number, nil }