diff --git a/chart.go b/chart.go index 8cfe17e..0b282c3 100644 --- a/chart.go +++ b/chart.go @@ -199,20 +199,21 @@ func (c Chart) drawSeries(r Renderer, s Series) { return } - v0 := s.GetValue(0) - x0 := xrange.Translate(v0.X) - y0 := yrange.Translate(v0.Y) + v0x, v0y := s.GetValue(0) + x0 := xrange.Translate(v0x) + y0 := yrange.Translate(v0y) r.MoveTo(x0, y0) - var v Point + var vx interface{} + var vy float64 var x, y int for index := 0; index < s.Len(); index++ { - v = s.GetValue(0) - x = xrange.Translate(v.X) - y = yrange.Translate(v.Y) + vx, vy = s.GetValue(index) + x = xrange.Translate(vx) + y = yrange.Translate(vy) r.LineTo(x, y) } - r.FillStroke() + r.Stroke() } func (c Chart) drawTitle(r Renderer) error { diff --git a/raster_renderer.go b/raster_renderer.go index 8d5ccab..9c5fa36 100644 --- a/raster_renderer.go +++ b/raster_renderer.go @@ -34,46 +34,55 @@ type rasterRenderer struct { // SetStrokeColor implements the interface method. func (rr *rasterRenderer) SetStrokeColor(c color.RGBA) { + println("SetStrokeColor") rr.gc.SetStrokeColor(c) } // SetFillColor implements the interface method. func (rr *rasterRenderer) SetFillColor(c color.RGBA) { + println("SetFillColor") rr.gc.SetFillColor(c) } // SetLineWidth implements the interface method. func (rr *rasterRenderer) SetLineWidth(width int) { + println("SetLineWidth", width) rr.gc.SetLineWidth(float64(width)) } // MoveTo implements the interface method. func (rr *rasterRenderer) MoveTo(x, y int) { + println("MoveTo", x, y) rr.gc.MoveTo(float64(x), float64(y)) } // LineTo implements the interface method. func (rr *rasterRenderer) LineTo(x, y int) { + println("LineTo", x, y) rr.gc.LineTo(float64(x), float64(y)) } // Close implements the interface method. func (rr *rasterRenderer) Close() { + println("Close") rr.gc.Close() } // Stroke implements the interface method. func (rr *rasterRenderer) Stroke() { + println("Stroke") rr.gc.Stroke() } // FillStroke implements the interface method. func (rr *rasterRenderer) FillStroke() { + println("FillStroke") rr.gc.FillStroke() } // Circle implements the interface method. func (rr *rasterRenderer) Circle(radius float64, x, y int) { + println("Circle", radius, x, y) xf := float64(x) yf := float64(y) rr.gc.MoveTo(xf-radius, yf) //9 @@ -87,29 +96,34 @@ func (rr *rasterRenderer) Circle(radius float64, x, y int) { // SetFont implements the interface method. func (rr *rasterRenderer) SetFont(f *truetype.Font) { + println("SetFont") rr.font = f rr.gc.SetFont(f) } // SetFontSize implements the interface method. func (rr *rasterRenderer) SetFontSize(size float64) { + println("SetFontSize", size) rr.fontSize = size rr.gc.SetFontSize(size) } // SetFontColor implements the interface method. func (rr *rasterRenderer) SetFontColor(c color.RGBA) { + println("SetFontColor") rr.fontColor = c rr.gc.SetStrokeColor(c) } // Text implements the interface method. func (rr *rasterRenderer) Text(body string, x, y int) { + println("Text", body, x, y) rr.gc.CreateStringPath(body, float64(x), float64(y)) } // MeasureText implements the interface method. func (rr *rasterRenderer) MeasureText(body string) int { + println("MeasureText", body) if rr.fc == nil && rr.font != nil { rr.fc = &font.Drawer{ Face: truetype.NewFace(rr.font, &truetype.Options{ @@ -127,5 +141,6 @@ func (rr *rasterRenderer) MeasureText(body string) int { // Save implements the interface method. func (rr *rasterRenderer) Save(w io.Writer) error { + println("Save") return png.Encode(w, rr.i) } diff --git a/series.go b/series.go index ec7cf8d..7575629 100644 --- a/series.go +++ b/series.go @@ -7,7 +7,7 @@ type Series interface { GetName() string GetStyle() Style Len() int - GetValue(index int) Point + GetValue(index int) (interface{}, float64) GetXRange(domain int) Range GetYRange(domain int) Range @@ -48,8 +48,8 @@ func (ts TimeSeries) GetYRange(domain int) Range { } // GetValue gets a value at a given index. -func (ts TimeSeries) GetValue(index int) Point { - return Point{X: float64(ts.XValues[index].Unix()), Y: ts.YValues[index]} +func (ts TimeSeries) GetValue(index int) (interface{}, float64) { + return ts.XValues[index], ts.YValues[index] } // ContinousSeries represents a line on a chart. @@ -77,8 +77,8 @@ func (cs ContinousSeries) Len() int { } // GetValue gets a value at a given index. -func (cs ContinousSeries) GetValue(index int) Point { - return Point{X: cs.XValues[index], Y: cs.YValues[index]} +func (cs ContinousSeries) GetValue(index int) (interface{}, float64) { + return cs.XValues[index], cs.YValues[index] } // GetXRange returns the x range. diff --git a/series_test.go b/series_test.go index 58a733f..01ff492 100644 --- a/series_test.go +++ b/series_test.go @@ -1 +1,56 @@ package chart + +import ( + "testing" + "time" + + "github.com/blendlabs/go-assert" +) + +func TestTimeSeriesGetValue(t *testing.T) { + assert := assert.New(t) + + ts := TimeSeries{ + Name: "Test", + XValues: []time.Time{ + time.Now().AddDate(0, 0, -5), + time.Now().AddDate(0, 0, -4), + time.Now().AddDate(0, 0, -3), + time.Now().AddDate(0, 0, -2), + time.Now().AddDate(0, 0, -1), + }, + YValues: []float64{ + 1.0, 2.0, 3.0, 4.0, 5.0, + }, + } + + x0, y0 := ts.GetValue(0) + assert.NotZero(x0) + assert.Equal(1.0, y0) +} + +func TestTimeSeriesRanges(t *testing.T) { + assert := assert.New(t) + + ts := TimeSeries{ + Name: "Test", + XValues: []time.Time{ + time.Now().AddDate(0, 0, -5), + time.Now().AddDate(0, 0, -4), + time.Now().AddDate(0, 0, -3), + time.Now().AddDate(0, 0, -2), + time.Now().AddDate(0, 0, -1), + }, + YValues: []float64{ + 1.0, 2.0, 3.0, 4.0, 5.0, + }, + } + + xrange := ts.GetXRange(1000) + x0 := xrange.Translate(time.Now().AddDate(0, 0, -3)) + assert.Equal(500, x0) + + yrange := ts.GetYRange(400) + y0 := yrange.Translate(3.0) + assert.Equal(200, y0) +}