108 lines
1.8 KiB
Go
108 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
|
|
"gonum.org/v1/plot"
|
|
"gonum.org/v1/plot/plotter"
|
|
"gonum.org/v1/plot/plotutil"
|
|
"gonum.org/v1/plot/vg"
|
|
"gonum.org/v1/plot/vg/draw"
|
|
"gonum.org/v1/plot/vg/vgsvg"
|
|
)
|
|
|
|
type statSheet struct {
|
|
Values []float64
|
|
Ok bool
|
|
}
|
|
|
|
type provider struct {
|
|
Current int
|
|
Values [3600]statSheet
|
|
Fetch func() []float64
|
|
|
|
NoVals int
|
|
ValTags []string
|
|
|
|
Name string
|
|
Y string
|
|
}
|
|
|
|
func (p *provider) Run() {
|
|
tick := time.NewTicker(time.Second)
|
|
|
|
for {
|
|
<-tick.C
|
|
|
|
vals := p.Fetch()
|
|
// fmt.Println("tick", p.Name, vals)
|
|
|
|
p.Values[p.Current] = statSheet{vals, true}
|
|
p.Current++
|
|
|
|
if p.Current >= 3600 {
|
|
p.Current = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
var xypool = sync.Pool{
|
|
New: func() interface{} {
|
|
return make(plotter.XYs, 3600)
|
|
},
|
|
}
|
|
|
|
func (prov *provider) Render(w http.ResponseWriter, r *http.Request) {
|
|
p := plot.New()
|
|
p.Legend.Top = true
|
|
p.Title.Text = prov.Name
|
|
p.X.Label.Text = "Time (seconds)"
|
|
p.Y.Label.Text = prov.Y
|
|
|
|
var points = make([]plotter.XYs, prov.NoVals)
|
|
var allocs = make([]plotter.XYs, prov.NoVals)
|
|
defer func() {
|
|
for _, x := range allocs {
|
|
xypool.Put(x)
|
|
}
|
|
}()
|
|
for i := range points {
|
|
alloc := xypool.Get().(plotter.XYs)
|
|
points[i] = alloc
|
|
allocs[i] = alloc
|
|
}
|
|
for i, x := range prov.Values {
|
|
if !x.Ok {
|
|
for yi := range points {
|
|
points[yi] = points[yi][:i]
|
|
}
|
|
break
|
|
}
|
|
for yi, y := range x.Values {
|
|
points[yi][i] = plotter.XY{
|
|
Y: y,
|
|
X: float64(i),
|
|
}
|
|
}
|
|
}
|
|
|
|
for i, x := range points {
|
|
line, err := plotter.NewLine(x)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
line.Color = plotutil.Color(i)
|
|
line.Dashes = plotutil.Dashes(i)
|
|
p.Add(line)
|
|
p.Legend.Add(prov.ValTags[i], line)
|
|
}
|
|
|
|
canv := vgsvg.New(vg.Millimeter*290, vg.Millimeter*200)
|
|
p.Draw(draw.New(canv))
|
|
|
|
w.Header().Set("content-type", "image/svg+xml")
|
|
canv.WriteTo(w)
|
|
}
|