mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Feature/mathandreduce (#41608)
* Added new math functions: round, ceil, floor * Added a new reduce function: last.
This commit is contained in:
committed by
GitHub
parent
5d0bc9e933
commit
9fc0aee02b
@@ -53,6 +53,21 @@ var builtins = map[string]parse.Func{
|
||||
VariantReturn: true,
|
||||
F: isNumber,
|
||||
},
|
||||
"round": {
|
||||
Args: []parse.ReturnType{parse.TypeVariantSet},
|
||||
VariantReturn: true,
|
||||
F: round,
|
||||
},
|
||||
"ceil": {
|
||||
Args: []parse.ReturnType{parse.TypeVariantSet},
|
||||
VariantReturn: true,
|
||||
F: ceil,
|
||||
},
|
||||
"floor": {
|
||||
Args: []parse.ReturnType{parse.TypeVariantSet},
|
||||
VariantReturn: true,
|
||||
F: floor,
|
||||
},
|
||||
}
|
||||
|
||||
// abs returns the absolute value for each result in NumberSet, SeriesSet, or Scalar
|
||||
@@ -253,3 +268,42 @@ func perNullableFloat(e *State, val Value, floatF func(x *float64) *float64) (Va
|
||||
|
||||
return newVal, nil
|
||||
}
|
||||
|
||||
// round returns the rounded value for each result in NumberSet, SeriesSet, or Scalar
|
||||
func round(e *State, varSet Results) (Results, error) {
|
||||
newRes := Results{}
|
||||
for _, res := range varSet.Values {
|
||||
newVal, err := perFloat(e, res, math.Round)
|
||||
if err != nil {
|
||||
return newRes, err
|
||||
}
|
||||
newRes.Values = append(newRes.Values, newVal)
|
||||
}
|
||||
return newRes, nil
|
||||
}
|
||||
|
||||
// ceil returns the rounded up value for each result in NumberSet, SeriesSet, or Scalar
|
||||
func ceil(e *State, varSet Results) (Results, error) {
|
||||
newRes := Results{}
|
||||
for _, res := range varSet.Values {
|
||||
newVal, err := perFloat(e, res, math.Ceil)
|
||||
if err != nil {
|
||||
return newRes, err
|
||||
}
|
||||
newRes.Values = append(newRes.Values, newVal)
|
||||
}
|
||||
return newRes, nil
|
||||
}
|
||||
|
||||
// floor returns the rounded down value for each result in NumberSet, SeriesSet, or Scalar
|
||||
func floor(e *State, varSet Results) (Results, error) {
|
||||
newRes := Results{}
|
||||
for _, res := range varSet.Values {
|
||||
newVal, err := perFloat(e, res, math.Floor)
|
||||
if err != nil {
|
||||
return newRes, err
|
||||
}
|
||||
newRes.Values = append(newRes.Values, newVal)
|
||||
}
|
||||
return newRes, nil
|
||||
}
|
||||
|
||||
@@ -69,6 +69,17 @@ func Count(fv *Float64Field) *float64 {
|
||||
return &f
|
||||
}
|
||||
|
||||
func Last(fv *Float64Field) *float64 {
|
||||
var f float64
|
||||
if fv.Len() == 0 {
|
||||
f = math.NaN()
|
||||
return &f
|
||||
}
|
||||
v := fv.GetValue(fv.Len() - 1)
|
||||
f = *v
|
||||
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
|
||||
@@ -90,6 +101,8 @@ func (s Series) Reduce(refID, rFunc string) (Number, error) {
|
||||
f = Max(&floatField)
|
||||
case "count":
|
||||
f = Count(&floatField)
|
||||
case "last":
|
||||
f = Last(&floatField)
|
||||
default:
|
||||
return number, fmt.Errorf("reduction %v not implemented", rFunc)
|
||||
}
|
||||
|
||||
@@ -214,6 +214,19 @@ func TestSeriesReduce(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "last empty series",
|
||||
red: "last",
|
||||
varToReduce: "A",
|
||||
vars: seriesEmpty,
|
||||
errIs: require.NoError,
|
||||
resultsIs: require.Equal,
|
||||
results: Results{
|
||||
[]Value{
|
||||
makeNumber("", nil, NaN),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
Reference in New Issue
Block a user