From 78cbfa62bcd685d4833619ba13c66ff88b144469 Mon Sep 17 00:00:00 2001 From: Will Charczuk Date: Mon, 9 Jan 2017 17:57:45 -0800 Subject: [PATCH] can just supply inverted ranges. --- axis.go | 5 ++++- continuous_range.go | 2 +- range.go | 2 +- tick.go | 11 ++++----- tick_test.go | 55 ++++++++++++++++++++++++++++++++++++++++----- xaxis.go | 8 +------ yaxis.go | 12 +++------- 7 files changed, 66 insertions(+), 29 deletions(-) diff --git a/axis.go b/axis.go index 6fd0a60..54e4d36 100644 --- a/axis.go +++ b/axis.go @@ -25,12 +25,15 @@ const ( // Axis is a chart feature detailing what values happen where. type Axis interface { GetName() string + SetName(name string) + GetStyle() Style + SetStyle(style Style) GetTicks() []Tick GenerateTicks(r Renderer, ra Range, vf ValueFormatter) []Tick - // GetGridLines returns the gridlines for the axis. + // GenerateGridLines returns the gridlines for the axis. GetGridLines(ticks []Tick) []GridLine // Measure should return an absolute box for the axis. diff --git a/continuous_range.go b/continuous_range.go index d119649..8a8e853 100644 --- a/continuous_range.go +++ b/continuous_range.go @@ -56,7 +56,7 @@ func (r *ContinuousRange) SetDomain(domain int) { // String returns a simple string for the ContinuousRange. func (r ContinuousRange) String() string { - return fmt.Sprintf("ContinuousRange [%.2f,%.2f] => %d", r.Min, r.Max, r.Domain) + return fmt.Sprintf("ContinuousRange [%.2f,%.2f] => %f", r.Min, r.Max, r.Domain) } // Translate maps a given value into the ContinuousRange space. diff --git a/range.go b/range.go index 9cea1fb..a816fda 100644 --- a/range.go +++ b/range.go @@ -20,7 +20,7 @@ type Stringable interface { String() string } -// Range is a +// Range is a common interface for a range of values. type Range interface { Stringable IsZeroable diff --git a/tick.go b/tick.go index c00cba0..138d15c 100644 --- a/tick.go +++ b/tick.go @@ -49,17 +49,18 @@ func GenerateContinuousTicks(r Renderer, ra Range, isVertical bool, style Style, style.GetTextOptions().WriteToRenderer(r) labelBox := r.MeasureText(minLabel) - var tickSize int + var tickSize float64 if isVertical { - tickSize = labelBox.Height() + DefaultMinimumTickVerticalSpacing + tickSize = float64(labelBox.Height() + DefaultMinimumTickVerticalSpacing) } else { - tickSize = labelBox.Width() + DefaultMinimumTickHorizontalSpacing + tickSize = float64(labelBox.Width() + DefaultMinimumTickHorizontalSpacing) } - domainRemainder := (ra.GetDomain()) - (tickSize * 2) + domain := float64(ra.GetDomain()) + domainRemainder := domain - (tickSize * 2) intermediateTickCount := int(math.Floor(float64(domainRemainder) / float64(tickSize))) - rangeDelta := max - min + rangeDelta := math.Abs(max - min) tickStep := rangeDelta / float64(intermediateTickCount) roundTo := Math.GetRoundToForDelta(rangeDelta) / 10 diff --git a/tick_test.go b/tick_test.go index 1b69ded..0ea3a88 100644 --- a/tick_test.go +++ b/tick_test.go @@ -1,12 +1,57 @@ package chart -/* -func TestGenerateTicksWithStep(t *testing.T) { +import ( + "testing" + + assert "github.com/blendlabs/go-assert" +) + +func TestGenerateContinuousTicks(t *testing.T) { assert := assert.New(t) + f, err := GetDefaultFont() + assert.Nil(err) + r, err := PNG(1024, 1024) + assert.Nil(err) + r.SetFont(f) - ticks := GenerateContinuousTicksWithStep(&ContinuousRange{Min: 1.0, Max: 10.0, Domain: 100}, 1.0, FloatValueFormatter, false) - assert.Len(ticks, 10) + ra := &ContinuousRange{ + Min: 0.0, + Max: 10.0, + Domain: 256, + } + + vf := FloatValueFormatter + + ticks := GenerateContinuousTicks(r, ra, false, Style{}, vf) + assert.NotEmpty(ticks) + assert.Len(ticks, 11) + assert.Equal(0.0, ticks[0].Value) + assert.Equal(10, ticks[len(ticks)-1].Value) +} + +func TestGenerateContinuousTicksDescending(t *testing.T) { + assert := assert.New(t) + + f, err := GetDefaultFont() + assert.Nil(err) + + r, err := PNG(1024, 1024) + assert.Nil(err) + r.SetFont(f) + + ra := &ContinuousRange{ + Min: 10.0, + Max: 0.0, + Domain: 256, + } + + vf := FloatValueFormatter + + ticks := GenerateContinuousTicks(r, ra, false, Style{}, vf) + assert.NotEmpty(ticks) + assert.Len(ticks, 11) + assert.Equal(10.0, ticks[0].Value) + assert.Equal(0.0, ticks[len(ticks)-1].Value) } -*/ diff --git a/xaxis.go b/xaxis.go index 0728e9b..c090d22 100644 --- a/xaxis.go +++ b/xaxis.go @@ -1,9 +1,6 @@ package chart -import ( - "math" - "sort" -) +import "math" // XAxis represents the horizontal axis. type XAxis struct { @@ -71,7 +68,6 @@ func (xa XAxis) GetGridLines(ticks []Tick) []GridLine { // Measure returns the bounds of the axis. func (xa XAxis) Measure(r Renderer, canvasBox Box, ra Range, defaults Style, ticks []Tick) Box { tickStyle := xa.TickStyle.InheritFrom(xa.Style.InheritFrom(defaults)) - sort.Sort(Ticks(ticks)) tp := xa.GetTickPosition() @@ -124,8 +120,6 @@ func (xa XAxis) Render(r Renderer, canvasBox Box, ra Range, defaults Style, tick r.LineTo(canvasBox.Right, canvasBox.Bottom) r.Stroke() - sort.Sort(Ticks(ticks)) - tp := xa.GetTickPosition() var tx, ty int diff --git a/yaxis.go b/yaxis.go index da3a559..dce43db 100644 --- a/yaxis.go +++ b/yaxis.go @@ -1,9 +1,6 @@ package chart -import ( - "math" - "sort" -) +import "math" // YAxis is a veritcal rule of the range. // There can be (2) y-axes; a primary and secondary. @@ -15,7 +12,8 @@ type YAxis struct { Zero GridLine - AxisType YAxisType + AxisType YAxisType + Ascending bool ValueFormatter ValueFormatter Range Range @@ -74,8 +72,6 @@ func (ya YAxis) GetGridLines(ticks []Tick) []GridLine { // Measure returns the bounds of the axis. func (ya YAxis) Measure(r Renderer, canvasBox Box, ra Range, defaults Style, ticks []Tick) Box { - sort.Sort(Ticks(ticks)) - var tx int if ya.AxisType == YAxisPrimary { tx = canvasBox.Right + DefaultYAxisMargin @@ -128,8 +124,6 @@ func (ya YAxis) Render(r Renderer, canvasBox Box, ra Range, defaults Style, tick tickStyle := ya.TickStyle.InheritFrom(ya.Style.InheritFrom(defaults)) tickStyle.WriteToRenderer(r) - sort.Sort(Ticks(ticks)) - sw := tickStyle.GetStrokeWidth(defaults.StrokeWidth) var lx int