From 0da2b41a9d89fb1068a9acd724b811841431691f Mon Sep 17 00:00:00 2001 From: Will Charczuk Date: Sat, 9 Jul 2016 10:27:47 -0700 Subject: [PATCH] you can now fill series. --- chart.go | 27 +++++++++++++++++++++++---- style.go | 12 +++++++----- testserver/main.go | 7 ++++++- vector_renderer.go | 14 ++++++++------ 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/chart.go b/chart.go index 5846bb9..9dd5465 100644 --- a/chart.go +++ b/chart.go @@ -333,24 +333,43 @@ func (c Chart) drawXAxisLabels(r Renderer, canvasBox Box, xrange Range) { } func (c Chart) drawSeries(r Renderer, canvasBox Box, index int, s Series, xrange, yrange Range) { - r.SetStrokeColor(s.GetStyle().GetStrokeColor(GetDefaultSeriesStrokeColor(index))) - r.SetStrokeWidth(s.GetStyle().GetStrokeWidth(DefaultStrokeWidth)) - if s.Len() == 0 { return } cx := canvasBox.Left cy := canvasBox.Top + cb := canvasBox.Bottom cw := canvasBox.Width v0x, v0y := s.GetValue(0) x0 := cw - xrange.Translate(v0x) y0 := yrange.Translate(v0y) - r.MoveTo(x0+cx, y0+cy) var vx, vy float64 var x, y int + + fill := s.GetStyle().GetFillColor() + if !ColorIsZero(fill) { + r.SetFillColor(fill) + r.MoveTo(x0+cx, y0+cy) + for i := 1; i < s.Len(); i++ { + vx, vy = s.GetValue(i) + x = cw - xrange.Translate(vx) + y = yrange.Translate(vy) + r.LineTo(x+cx, y+cy) + } + r.LineTo(x+cx, cb) + r.LineTo(x0+cx, cb) + r.Close() + r.Fill() + } + + stroke := s.GetStyle().GetStrokeColor(GetDefaultSeriesStrokeColor(index)) + r.SetStrokeColor(stroke) + r.SetStrokeWidth(s.GetStyle().GetStrokeWidth(DefaultStrokeWidth)) + + r.MoveTo(x0+cx, y0+cy) for i := 1; i < s.Len(); i++ { vx, vy = s.GetValue(i) x = cw - xrange.Translate(vx) diff --git a/style.go b/style.go index d3b6d5b..e0f5232 100644 --- a/style.go +++ b/style.go @@ -4,6 +4,8 @@ import ( "fmt" "image/color" "strings" + + "github.com/wcharczuk/go-chart/drawing" ) // Style is a simple style set. @@ -28,7 +30,7 @@ func (s Style) GetStrokeColor(defaults ...color.RGBA) color.RGBA { if len(defaults) > 0 { return defaults[0] } - return DefaultStrokeColor + return color.RGBA{} } return s.StrokeColor } @@ -39,7 +41,7 @@ func (s Style) GetFillColor(defaults ...color.RGBA) color.RGBA { if len(defaults) > 0 { return defaults[0] } - return DefaultFillColor + return color.RGBA{} } return s.FillColor } @@ -72,13 +74,13 @@ func (s Style) GetFontColor(defaults ...color.RGBA) color.RGBA { if len(defaults) > 0 { return defaults[0] } - return DefaultTextColor + return color.RGBA{} } return s.FontColor } // SVG returns the style as a svg style string. -func (s Style) SVG() string { +func (s Style) SVG(dpi float64) string { sw := s.StrokeWidth sc := s.StrokeColor fc := s.FillColor @@ -102,7 +104,7 @@ func (s Style) SVG() string { fontSizeText := "" if fs != 0 { - fontSizeText = "font-size:" + fmt.Sprintf("%.1fpx", fs) + fontSizeText = "font-size:" + fmt.Sprintf("%.1fpx", drawing.PointsToPixels(dpi, fs)) } if !ColorIsZero(fnc) { diff --git a/testserver/main.go b/testserver/main.go index 037f792..b4d01ad 100644 --- a/testserver/main.go +++ b/testserver/main.go @@ -1,6 +1,7 @@ package main import ( + "image/color" "log" "net/http" @@ -23,7 +24,8 @@ func chartHandler(rc *web.RequestContext) web.ControllerResult { c := chart.Chart{ Title: "A Test Chart", TitleStyle: chart.Style{ - Show: true, + Show: true, + FontSize: 26.0, }, Width: 640, Height: 480, @@ -43,6 +45,9 @@ func chartHandler(rc *web.RequestContext) web.ControllerResult { Name: "a", XValues: []float64{1.0, 2.0, 3.0, 4.0}, YValues: []float64{2.5, 5.0, 2.0, 3.3}, + Style: chart.Style{ + FillColor: color.RGBA{R: 0, G: 116, B: 217, A: 255}, + }, }, chart.ContinuousSeries{ Name: "b", diff --git a/vector_renderer.go b/vector_renderer.go index 83f1705..66d23bf 100644 --- a/vector_renderer.go +++ b/vector_renderer.go @@ -5,12 +5,12 @@ import ( "fmt" "image/color" "io" - "math" "strings" "golang.org/x/image/font" "github.com/golang/freetype/truetype" + "github.com/wcharczuk/go-chart/drawing" ) // SVG returns a new png/raster renderer. @@ -93,13 +93,13 @@ func (vr *vectorRenderer) FillStroke() { } func (vr *vectorRenderer) drawPath() { - vr.c.Path(strings.Join(vr.p, "\n"), vr.s.SVG()) + vr.c.Path(strings.Join(vr.p, "\n"), vr.s.SVG(vr.dpi)) vr.p = []string{} } // Circle implements the interface method. func (vr *vectorRenderer) Circle(radius float64, x, y int) { - vr.c.Circle(x, y, int(radius), vr.s.SVG()) + vr.c.Circle(x, y, int(radius), vr.s.SVG(vr.dpi)) } // SetFont implements the interface method. @@ -133,7 +133,7 @@ func (vr *vectorRenderer) Text(body string, x, y int) { vr.s.FillColor = color.RGBA{} vr.s.StrokeColor = color.RGBA{} vr.s.StrokeWidth = 0 - vr.c.Text(x, y, body, vr.s.SVG()+";"+vr.svgFontFace()) + vr.c.Text(x, y, body, vr.s.SVG(vr.dpi)+";"+vr.svgFontFace()) } // MeasureText uses the truetype font drawer to measure the width of text. @@ -145,8 +145,10 @@ func (vr *vectorRenderer) MeasureText(body string) (width, height int) { Size: vr.s.FontSize, }), } - width = vr.fc.MeasureString(body).Ceil() - height = int(math.Ceil(vr.s.FontSize)) + w := vr.fc.MeasureString(body).Ceil() + + width = int(drawing.PointsToPixels(vr.dpi, float64(w))) + height = int(drawing.PointsToPixels(vr.dpi, vr.s.FontSize)) } return }