forked from bosun-monitor/bosun
-
Notifications
You must be signed in to change notification settings - Fork 1
/
chart.go
91 lines (83 loc) · 2.44 KB
/
chart.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
91
package sched
import (
"image"
"image/color"
"image/png"
"io"
"bosun.org/_third_party/github.com/MiniProfiler/go/miniprofiler"
"bosun.org/_third_party/github.com/ajstarks/svgo"
"bosun.org/_third_party/github.com/bradfitz/slice"
"bosun.org/_third_party/github.com/vdobler/chart"
"bosun.org/_third_party/github.com/vdobler/chart/imgg"
"bosun.org/_third_party/github.com/vdobler/chart/svgg"
"bosun.org/cmd/bosun/expr"
)
var chartColors = []color.Color{
color.NRGBA{0x37, 0x7e, 0xb8, 0xff},
color.NRGBA{0x4d, 0xaf, 0x4a, 0xff},
color.NRGBA{0x98, 0x4e, 0xa3, 0xff},
color.NRGBA{0xff, 0x7f, 0x00, 0xff},
color.NRGBA{0xa6, 0x56, 0x28, 0xff},
color.NRGBA{0xf7, 0x81, 0xbf, 0xff},
color.NRGBA{0x99, 0x99, 0x99, 0xff},
color.NRGBA{0xe4, 0x1a, 0x1c, 0xff},
}
// Autostyle styles a chart series.
func Autostyle(i int) chart.Style {
c := chartColors[i%len(chartColors)]
s := chart.Symbol[i%len(chart.Symbol)]
return chart.Style{
Symbol: s,
SymbolSize: .5,
SymbolColor: c,
LineStyle: chart.SolidLine,
LineWidth: 1,
LineColor: c,
}
}
var white = color.RGBA{0xff, 0xff, 0xff, 0xff}
func (s *Schedule) ExprSVG(t miniprofiler.Timer, w io.Writer, width, height int, unit string, res []*expr.Result) error {
ch, err := s.ExprGraph(t, unit, res)
if err != nil {
return err
}
g := svg.New(w)
g.StartviewUnit(100, 100, "%", 0, 0, width, height)
g.Rect(0, 0, width, height, "fill: #ffffff")
sgr := svgg.AddTo(g, 0, 0, width, height, "", 12, white)
ch.Plot(sgr)
g.End()
return nil
}
func (s *Schedule) ExprPNG(t miniprofiler.Timer, w io.Writer, width, height int, unit string, res []*expr.Result) error {
ch, err := s.ExprGraph(t, unit, res)
if err != nil {
return err
}
g := image.NewRGBA(image.Rectangle{Min: image.ZP, Max: image.Pt(width, height)})
sgr := imgg.AddTo(g, 0, 0, width, height, white, nil, nil)
ch.Plot(sgr)
return png.Encode(w, g)
}
func (s *Schedule) ExprGraph(t miniprofiler.Timer, unit string, res []*expr.Result) (chart.Chart, error) {
c := chart.ScatterChart{
Key: chart.Key{Pos: "itl"},
YRange: chart.Range{Label: unit},
}
c.XRange.Time = true
for ri, r := range res {
rv := r.Value.(expr.Series)
pts := make([]chart.EPoint, len(rv))
idx := 0
for k, v := range rv {
pts[idx].X = float64(k.Unix())
pts[idx].Y = v
idx++
}
slice.Sort(pts, func(i, j int) bool {
return pts[i].X < pts[j].X
})
c.AddData(r.Group.String(), pts, chart.PlotStyleLinesPoints, Autostyle(ri))
}
return &c, nil
}