forked from moira-alert/moira
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcurve.go
90 lines (80 loc) · 2.5 KB
/
curve.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package plotting
import (
"math"
"time"
"github.com/go-graphite/carbonapi/expr/types"
"github.com/wcharczuk/go-chart"
"github.com/moira-alert/moira"
)
// plotCurve is a single curve for given timeserie
type plotCurve struct {
timeStamps []time.Time
values []float64
}
// getCurveSeriesList returns curve series list
func getCurveSeriesList(metricsData []*types.MetricData, theme moira.PlotTheme) []chart.TimeSeries {
curveSeriesList := make([]chart.TimeSeries, 0)
for metricDataInd := range metricsData {
curveStyle, pointStyle := theme.GetSerieStyles(metricDataInd)
curveSeries := generatePlotCurves(metricsData[metricDataInd], curveStyle, pointStyle)
curveSeriesList = append(curveSeriesList, curveSeries...)
}
return curveSeriesList
}
// generatePlotCurves returns go-chart timeseries to generate plot curves
func generatePlotCurves(metricData *types.MetricData, curveStyle chart.Style, pointStyle chart.Style) []chart.TimeSeries {
curves := describePlotCurves(metricData)
curveSeries := make([]chart.TimeSeries, 0)
for _, curve := range curves {
var serieStyle chart.Style
if len(curve.values) > 1 {
serieStyle = curveStyle
} else {
serieStyle = pointStyle
}
curveSerie := chart.TimeSeries{
Name: metricData.Name,
YAxis: chart.YAxisSecondary,
Style: serieStyle,
XValues: curve.timeStamps,
YValues: curve.values,
}
curveSeries = append(curveSeries, curveSerie)
}
return curveSeries
}
// describePlotCurves returns parameters for required curves
func describePlotCurves(metricData *types.MetricData) []plotCurve {
curves := []plotCurve{{}}
curvesInd := 0
start, timeStamp := resolveFirstPoint(metricData)
for valInd := start; valInd < len(metricData.Values); valInd++ {
pointValue := metricData.Values[valInd]
if !math.IsNaN(pointValue) {
timeStampValue := moira.Int64ToTime(timeStamp)
curves[curvesInd].timeStamps = append(curves[curvesInd].timeStamps, timeStampValue)
curves[curvesInd].values = append(curves[curvesInd].values, pointValue)
} else {
if len(curves[curvesInd].values) > 0 {
curves = append(curves, plotCurve{})
curvesInd++
}
}
timeStamp += metricData.StepTime
}
return curves
}
// resolveFirstPoint returns first point coordinates
func resolveFirstPoint(metricData *types.MetricData) (int, int64) {
start := 0
startTime := metricData.StartTime
for _, metricVal := range metricData.Values {
if math.IsNaN(metricVal) {
start++
startTime += metricData.StepTime
} else {
break
}
}
return start, startTime
}