// Plot draws the Line, implementing the plot.Plotter interface. func (rp *ResponsePlotter) Plot(da plot.DrawArea, plt *plot.Plot) { trX, trY := plt.Transforms(&da) start := float64(rp.Response.GetStartTime()) step := float64(rp.Response.GetStepTime()) absent := rp.Response.IsAbsent lines := make([][]plot.Point, 1) lines[0] = make([]plot.Point, 0, len(rp.Response.Values)) /* ikruglov * swithing between lineMode and looping inside * is more branch-prediction friendly i.e. potentially faster */ switch rp.lineMode { case "slope": currentLine := 0 lastAbsent := false for i, v := range rp.Response.Values { if absent[i] { lastAbsent = true } else if lastAbsent { currentLine++ lines = append(lines, make([]plot.Point, 1)) lines[currentLine][0] = plot.Point{X: trX(start + float64(i)*step), Y: trY(v)} lastAbsent = false } else { lines[currentLine] = append(lines[currentLine], plot.Point{X: trX(start + float64(i)*step), Y: trY(v)}) } } case "connected": for i, v := range rp.Response.Values { if absent[i] { continue } lines[0] = append(lines[0], plot.Point{X: trX(start + float64(i)*step), Y: trY(v)}) } case "drawAsInfinite": for i, v := range rp.Response.Values { if !absent[i] && v > 0 { infiniteLine := []plot.Point{ plot.Point{X: trX(start + float64(i)*step), Y: da.Y(1)}, plot.Point{X: trX(start + float64(i)*step), Y: da.Y(0)}, } lines = append(lines, infiniteLine) } } //case "staircase": // TODO default: panic("Unimplemented " + rp.lineMode) } da.StrokeLines(rp.LineStyle, lines...) }
func (g GlyphBoxes) Plot(da plot.DrawArea, plt *plot.Plot) { for _, b := range plt.GlyphBoxes(plt) { x := da.X(b.X) + b.Rect.Min.X y := da.Y(b.Y) + b.Rect.Min.Y da.StrokeLines(g.LineStyle, []plot.Point{ {x, y}, {x + b.Rect.Size.X, y}, {x + b.Rect.Size.X, y + b.Rect.Size.Y}, {x, y + b.Rect.Size.Y}, {x, y}, }) } }