From d78930a08f2f67a3c49cf70dc9372a0d1c9c6efc Mon Sep 17 00:00:00 2001 From: Will Charczuk Date: Sun, 10 Jul 2016 11:19:56 -0700 Subject: [PATCH] secondary axis works. --- chart.go | 12 ++++++-- testserver/main.go | 25 +++++++++++----- yaxis.go | 73 +++++++++++++++++++++++++++++++--------------- 3 files changed, 76 insertions(+), 34 deletions(-) diff --git a/chart.go b/chart.go index 7153f1a..47db2b6 100644 --- a/chart.go +++ b/chart.go @@ -155,6 +155,14 @@ func (c Chart) getRanges() (xrange, yrange, yrangeAlt Range) { yrange.Min = globalMinY yrange.Max = globalMaxY } + + if !c.YAxisSecondary.Range.IsZero() { + yrangeAlt.Min = c.YAxisSecondary.Range.Min + yrangeAlt.Max = c.YAxisSecondary.Range.Max + } else { + yrangeAlt.Min = globalMinYA + yrangeAlt.Max = globalMaxYA + } return } @@ -207,7 +215,7 @@ func (c Chart) getAxesTicks(r Renderer, xr, yr, yar Range, xf, yf, yfa ValueForm yticks = c.YAxis.GetTicks(r, yr, yf) } if c.YAxisSecondary.Style.Show { - yticksAlt = c.YAxisSecondary.GetTicks(r, yr, yf) + yticksAlt = c.YAxisSecondary.GetTicks(r, yar, yf) } return } @@ -348,7 +356,7 @@ func (c Chart) drawSeries(r Renderer, canvasBox Box, xrange, yrange, yrangeAlt R if s.GetYAxis() == YAxisPrimary { s.Render(r, canvasBox, xrange, yrange, c.getSeriesStyleDefaults(seriesIndex)) } else if s.GetYAxis() == YAxisSecondary { - s.Render(r, canvasBox, xrange, yrange, c.getSeriesStyleDefaults(seriesIndex)) + s.Render(r, canvasBox, xrange, yrangeAlt, c.getSeriesStyleDefaults(seriesIndex)) } } diff --git a/testserver/main.go b/testserver/main.go index 6b6372a..0cee661 100644 --- a/testserver/main.go +++ b/testserver/main.go @@ -20,11 +20,11 @@ func chartHandler(rc *web.RequestContext) web.ControllerResult { rc.Response.Header().Set("Content-Type", "image/svg+xml") } - s1x := []float64{1.0, 2.0, 3.0, 4.0} + s1x := []float64{2.0, 3.0, 4.0, 5.0} s1y := []float64{2.5, 5.0, 2.0, 3.3} - s2x := []float64{3.0, 4.0, 5.0, 6.0} - s2y := []float64{6.0, 5.0, 4.0, 1.0} + s2x := []float64{0.0, 0.5, 1.0, 1.5} + s2y := []float64{1.1, 1.2, 1.0, 1.3} c := chart.Chart{ Title: "A Test Chart", @@ -35,20 +35,27 @@ func chartHandler(rc *web.RequestContext) web.ControllerResult { Height: 400, XAxis: chart.XAxis{ Style: chart.Style{ - Show: true, - StrokeWidth: 1.0, + Show: true, }, }, YAxis: chart.YAxis{ Style: chart.Style{ - Show: true, - StrokeWidth: 1.0, + Show: true, }, Range: chart.Range{ Min: 0.0, Max: 7.0, }, }, + YAxisSecondary: chart.YAxis{ + Style: chart.Style{ + Show: true, + }, + Range: chart.Range{ + Min: 0.8, + Max: 1.5, + }, + }, Series: []chart.Series{ chart.ContinuousSeries{ Name: "a", @@ -57,6 +64,7 @@ func chartHandler(rc *web.RequestContext) web.ControllerResult { }, chart.ContinuousSeries{ Name: "b", + YAxis: chart.YAxisSecondary, XValues: s2x, YValues: s2y, }, @@ -75,7 +83,8 @@ func chartHandler(rc *web.RequestContext) web.ControllerResult { }, }, chart.AnnotationSeries{ - Name: "b - last value", + Name: "b - last value", + YAxis: chart.YAxisSecondary, Style: chart.Style{ Show: true, StrokeColor: chart.GetDefaultSeriesStrokeColor(1), diff --git a/yaxis.go b/yaxis.go index df64406..f2d7a3c 100644 --- a/yaxis.go +++ b/yaxis.go @@ -1,6 +1,7 @@ package chart import ( + "fmt" "math" "sort" ) @@ -54,6 +55,7 @@ func (ya YAxis) getTickStep(r Renderer, ra Range, vf ValueFormatter) float64 { func (ya YAxis) generateTicksWithStep(ra Range, step float64, vf ValueFormatter) []Tick { var ticks []Tick for cursor := ra.Min; cursor < ra.Max; cursor += step { + println("yaxis tick:", fmt.Sprintf("%.2f", cursor)) ticks = append(ticks, Tick{ Value: cursor, Label: vf(cursor), @@ -64,39 +66,62 @@ func (ya YAxis) generateTicksWithStep(ra Range, step float64, vf ValueFormatter) // Render renders the axis. func (ya YAxis) Render(r Renderer, canvasBox Box, ra Range, axisType YAxisType, ticks []Tick) { - var lx int - var tx int - if axisType == YAxisPrimary { - lx = canvasBox.Right - tx = canvasBox.Right + DefaultYAxisMargin - } else if axisType == YAxisSecondary { - lx = canvasBox.Left - tx = canvasBox.Left - DefaultYAxisMargin - } - r.SetStrokeColor(ya.Style.GetStrokeColor(DefaultAxisColor)) r.SetStrokeWidth(ya.Style.GetStrokeWidth(DefaultAxisLineWidth)) - - r.MoveTo(lx, canvasBox.Bottom) - r.LineTo(lx, canvasBox.Top) - r.Stroke() - r.SetFontColor(ya.Style.GetFontColor(DefaultAxisColor)) fontSize := ya.Style.GetFontSize(DefaultFontSize) r.SetFontSize(fontSize) sort.Sort(Ticks(ticks)) - for _, t := range ticks { - v := t.Value - ly := ra.Translate(v) + canvasBox.Top - th := int(fontSize) >> 1 - ty := ly + th + var lx int + var tx int + if axisType == YAxisPrimary { + lx = canvasBox.Right + tx = canvasBox.Right + DefaultYAxisMargin - r.Text(t.Label, tx, ty) - - r.MoveTo(lx, ly) - r.LineTo(lx+DefaultVerticalTickWidth, ly) + r.MoveTo(lx, canvasBox.Bottom) + r.LineTo(lx, canvasBox.Top) r.Stroke() + + for _, t := range ticks { + v := t.Value + ly := ra.Translate(v) + canvasBox.Top + + th := int(fontSize) >> 1 + ty := ly + th + + r.Text(t.Label, tx, ty) + + r.MoveTo(lx, ly) + r.LineTo(lx+DefaultVerticalTickWidth, ly) + r.Stroke() + } + } else if axisType == YAxisSecondary { + lx = canvasBox.Left + + r.MoveTo(lx, canvasBox.Bottom) + r.LineTo(lx, canvasBox.Top) + r.Stroke() + + for _, t := range ticks { + v := t.Value + ly := ra.Translate(v) + canvasBox.Top + + ptw, _ := r.MeasureText(t.Label) + + tw := ptw + th := int(fontSize) + + tx = lx - (int(tw) + (DefaultYAxisMargin >> 1)) + ty := ly + th>>1 + + r.Text(t.Label, tx, ty) + + r.MoveTo(lx, ly) + r.LineTo(lx-DefaultVerticalTickWidth, ly) + r.Stroke() + } } + }