func marshalPNG(r *http.Request, results []*metricData) []byte { p, err := plot.New() if err != nil { panic(err) } // set bg/fg colors bgcolor := string2Color(getString(r.FormValue("bgcolor"), "black")) p.BackgroundColor = bgcolor fgcolorstr := getString(r.FormValue("fgcolor"), "white") fgcolor := string2Color(fgcolorstr) p.Title.Color = fgcolor p.X.LineStyle.Color = fgcolor p.Y.LineStyle.Color = fgcolor p.X.Tick.LineStyle.Color = fgcolor p.Y.Tick.LineStyle.Color = fgcolor p.X.Tick.Label.Color = fgcolor p.Y.Tick.Label.Color = fgcolor p.X.Label.Color = fgcolor p.Y.Label.Color = fgcolor p.Legend.Color = fgcolor // set grid grid := plotter.NewGrid() grid.Vertical.Color = fgcolor grid.Horizontal.Color = fgcolor p.Add(grid) // line mode (ikruglow) TODO check values lineMode := getString(r.FormValue("lineMode"), "slope") // width and height width := getFloat64(r.FormValue("width"), 330) height := getFloat64(r.FormValue("height"), 250) // need different timeMarker's based on step size p.Title.Text = r.FormValue("title") p.X.Tick.Marker = NewTimeMarker(results[0].GetStepTime()) hideLegend := getBool(r.FormValue("hideLegend"), false) graphOnly := getBool(r.FormValue("graphOnly"), false) if graphOnly { p.HideAxes() } if len(results) == 1 && results[0].color == "" { results[0].color = fgcolorstr } var lines []plot.Plotter for i, r := range results { l := NewResponsePlotter(r) l.LineStyle.Color = fgcolor // consolidate datapoints l.maybeConsolidateData(width) if r.drawAsInfinite { l.lineMode = "drawAsInfinite" } else { l.lineMode = lineMode } if r.color != "" { l.Color = string2Color(r.color) } else { l.Color = plotutil.Color(i) } lines = append(lines, l) if !graphOnly && !hideLegend { p.Legend.Add(r.GetName(), l) } } p.Add(lines...) p.Y.Max *= 1.05 p.Y.Min *= 0.95 writerTo, err := p.WriterTo(vg.Points(width), vg.Points(height), "png") var buffer bytes.Buffer if _, err := writerTo.WriteTo(&buffer); err != nil { panic(err) } return buffer.Bytes() }