diff --git a/README.md b/README.md index 2f4f3f9..5fd93a5 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,13 @@ graph := chart.Chart{ graph.Render(chart.PNG, buffer) ``` +# 2 Y-Axis Charts + + ![](https://raw.githubusercontent.com/wcharczuk/go-chart/master/images/two_axis.png) + +It is also possible to draw series against 2 separate y-axis with their own ranges (usually good for comparison charts). +In order to map the series to an alternate axis make sure to set the `YAxis` property of the series to `YAxisSecondary`. + # Design Philosophy I wanted to make a charting library that used only native golang, that could be stood up on a server (i.e. it had built in fonts). diff --git a/images/two_axis.png b/images/two_axis.png new file mode 100644 index 0000000..7696841 Binary files /dev/null and b/images/two_axis.png differ diff --git a/style.go b/style.go index e4a2d5b..5ffe2f5 100644 --- a/style.go +++ b/style.go @@ -149,3 +149,35 @@ func (s Style) SVG(dpi float64) string { } return strings.Join([]string{strokeWidthText, strokeText, fillText, fontSizeText}, ";") } + +// SVGStroke returns the stroke components. +func (s Style) SVGStroke() Style { + return Style{ + StrokeColor: s.StrokeColor, + StrokeWidth: s.StrokeWidth, + } +} + +// SVGFill returns the fill components. +func (s Style) SVGFill() Style { + return Style{ + FillColor: s.FillColor, + } +} + +// SVGFillAndStroke returns the fill and stroke components. +func (s Style) SVGFillAndStroke() Style { + return Style{ + FillColor: s.FillColor, + StrokeColor: s.StrokeColor, + StrokeWidth: s.StrokeWidth, + } +} + +// SVGText returns just the text components of the style. +func (s Style) SVGText() Style { + return Style{ + FontColor: s.FontColor, + FontSize: s.FontSize, + } +} diff --git a/testserver/main.go b/testserver/main.go index 0080627..7e9134a 100644 --- a/testserver/main.go +++ b/testserver/main.go @@ -35,12 +35,12 @@ func chartHandler(rc *web.RequestContext) web.ControllerResult { Height: 400, XAxis: chart.XAxis{ Style: chart.Style{ - Show: false, + Show: true, }, }, YAxis: chart.YAxis{ Style: chart.Style{ - Show: false, + Show: true, }, Range: chart.Range{ Min: 0.0, @@ -49,7 +49,7 @@ func chartHandler(rc *web.RequestContext) web.ControllerResult { }, YAxisSecondary: chart.YAxis{ Style: chart.Style{ - Show: false, + Show: true, }, Range: chart.Range{ Min: 0.8, diff --git a/vector_renderer.go b/vector_renderer.go index 9c06522..3626875 100644 --- a/vector_renderer.go +++ b/vector_renderer.go @@ -77,28 +77,22 @@ func (vr *vectorRenderer) Close() { // Stroke draws the path with no fill. func (vr *vectorRenderer) Stroke() { - vr.s.FillColor = drawing.ColorTransparent - vr.s.FontColor = drawing.ColorTransparent - vr.drawPath() + vr.drawPath(vr.s.SVGStroke()) } // Fill draws the path with no stroke. func (vr *vectorRenderer) Fill() { - vr.s.StrokeColor = drawing.ColorTransparent - vr.s.StrokeWidth = 0 - vr.s.FontColor = drawing.ColorTransparent - vr.drawPath() + vr.drawPath(vr.s.SVGFill()) } // FillStroke draws the path with both fill and stroke. func (vr *vectorRenderer) FillStroke() { - vr.s.FontColor = drawing.ColorTransparent - vr.drawPath() + vr.drawPath(vr.s.SVGFillAndStroke()) } -func (vr *vectorRenderer) drawPath() { - vr.c.Path(strings.Join(vr.p, "\n"), vr.s.SVG(vr.dpi)) - vr.p = []string{} +func (vr *vectorRenderer) drawPath(s Style) { + vr.c.Path(strings.Join(vr.p, "\n"), s.SVG(vr.dpi)) + vr.p = []string{} // clear the path } // Circle implements the interface method. @@ -134,10 +128,8 @@ func (vr *vectorRenderer) svgFontFace() string { // Text draws a text blob. func (vr *vectorRenderer) Text(body string, x, y int) { - vr.s.FillColor = drawing.ColorTransparent - vr.s.StrokeColor = drawing.ColorTransparent - vr.s.StrokeWidth = 0 - vr.c.Text(x, y, body, vr.s.SVG(vr.dpi)+";"+vr.svgFontFace()) + s := vr.s.SVGText() + vr.c.Text(x, y, body, s.SVG(vr.dpi)+";"+vr.svgFontFace()) } // MeasureText uses the truetype font drawer to measure the width of text. diff --git a/yaxis.go b/yaxis.go index 2636d07..f4ed1f4 100644 --- a/yaxis.go +++ b/yaxis.go @@ -69,7 +69,9 @@ func (ya YAxis) generateTicksWithStep(ra Range, step float64, vf ValueFormatter) func (ya YAxis) Render(r Renderer, canvasBox Box, ra Range, axisType YAxisType, ticks []Tick) { r.SetStrokeColor(ya.Style.GetStrokeColor(DefaultAxisColor)) r.SetStrokeWidth(ya.Style.GetStrokeWidth(DefaultAxisLineWidth)) - r.SetFontColor(ya.Style.GetFontColor(DefaultAxisColor)) + + fontColor := ya.Style.GetFontColor(DefaultAxisColor) + r.SetFontColor(fontColor) fontSize := ya.Style.GetFontSize(DefaultFontSize) r.SetFontSize(fontSize)