introduces the Range interface (instead of a concrete type).

This commit is contained in:
Will Charczuk 2016-07-21 14:11:27 -07:00
parent 8af50213c3
commit b0934ee2e3
27 changed files with 331 additions and 172 deletions

101
chart.go
View file

@ -137,7 +137,7 @@ func (c Chart) getRanges() (xrange, yrange, yrangeAlt Range) {
var miny, maxy float64 = math.MaxFloat64, 0
var minya, maxya float64 = math.MaxFloat64, 0
hasSecondaryAxis := false
seriesMappedToSecondaryAxis := false
// note: a possible future optimization is to not scan the series values if
// all axis are represented by either custom ticks or custom ranges.
@ -162,7 +162,7 @@ func (c Chart) getRanges() (xrange, yrange, yrangeAlt Range) {
minya = math.Min(minya, vy2)
maxya = math.Max(maxya, vy1)
maxya = math.Max(maxya, vy2)
hasSecondaryAxis = true
seriesMappedToSecondaryAxis = true
}
}
} else if vp, isValueProvider := s.(ValueProvider); isValueProvider {
@ -179,27 +179,40 @@ func (c Chart) getRanges() (xrange, yrange, yrangeAlt Range) {
} else if seriesAxis == YAxisSecondary {
minya = math.Min(minya, vy)
maxya = math.Max(maxya, vy)
hasSecondaryAxis = true
seriesMappedToSecondaryAxis = true
}
}
}
}
}
if xrange == nil {
xrange = &ContinuousRange{}
}
if yrange == nil {
yrange = &ContinuousRange{}
}
if yrangeAlt == nil {
yrangeAlt = &ContinuousRange{}
}
if len(c.XAxis.Ticks) > 0 {
tickMin, tickMax := math.MaxFloat64, 0.0
for _, t := range c.XAxis.Ticks {
tickMin = math.Min(tickMin, t.Value)
tickMax = math.Max(tickMax, t.Value)
}
xrange.Min = tickMin
xrange.Max = tickMax
} else if !c.XAxis.Range.IsZero() {
xrange.Min = c.XAxis.Range.Min
xrange.Max = c.XAxis.Range.Max
xrange.SetMin(tickMin)
xrange.SetMax(tickMax)
} else if c.XAxis.Range != nil && !c.XAxis.Range.IsZero() {
xrange.SetMin(c.XAxis.Range.GetMin())
xrange.SetMax(c.XAxis.Range.GetMax())
} else {
xrange.Min = minx
xrange.Max = maxx
xrange.SetMin(minx)
xrange.SetMax(maxx)
}
if len(c.YAxis.Ticks) > 0 {
@ -208,15 +221,20 @@ func (c Chart) getRanges() (xrange, yrange, yrangeAlt Range) {
tickMin = math.Min(tickMin, t.Value)
tickMax = math.Max(tickMax, t.Value)
}
yrange.Min = tickMin
yrange.Max = tickMax
} else if !c.YAxis.Range.IsZero() {
yrange.Min = c.YAxis.Range.Min
yrange.Max = c.YAxis.Range.Max
yrange.SetMin(tickMin)
yrange.SetMax(tickMax)
} else if c.YAxis.Range != nil && !c.YAxis.Range.IsZero() {
yrange.SetMin(c.YAxis.Range.GetMin())
yrange.SetMax(c.YAxis.Range.GetMax())
} else {
yrange.Min = miny
yrange.Max = maxy
yrange.Min, yrange.Max = yrange.GetRoundedRangeBounds()
yrange.SetMin(miny)
yrange.SetMax(maxy)
delta := yrange.GetDelta()
roundTo := GetRoundToForDelta(delta)
rmin, rmax := RoundDown(yrange.GetMin(), roundTo), RoundUp(yrange.GetMax(), roundTo)
yrange.SetMin(rmin)
yrange.SetMax(rmax)
}
if len(c.YAxisSecondary.Ticks) > 0 {
@ -225,30 +243,34 @@ func (c Chart) getRanges() (xrange, yrange, yrangeAlt Range) {
tickMin = math.Min(tickMin, t.Value)
tickMax = math.Max(tickMax, t.Value)
}
yrangeAlt.Min = tickMin
yrangeAlt.Max = tickMax
} else if !c.YAxisSecondary.Range.IsZero() {
yrangeAlt.Min = c.YAxisSecondary.Range.Min
yrangeAlt.Max = c.YAxisSecondary.Range.Max
} else if hasSecondaryAxis {
yrangeAlt.Min = minya
yrangeAlt.Max = maxya
yrangeAlt.Min, yrangeAlt.Max = yrangeAlt.GetRoundedRangeBounds()
yrangeAlt.SetMin(tickMin)
yrangeAlt.SetMax(tickMax)
} else if c.YAxisSecondary.Range != nil && !c.YAxisSecondary.Range.IsZero() {
yrangeAlt.SetMin(c.YAxisSecondary.Range.GetMin())
yrangeAlt.SetMax(c.YAxisSecondary.Range.GetMax())
} else if seriesMappedToSecondaryAxis {
yrangeAlt.SetMin(minya)
yrangeAlt.SetMax(maxya)
delta := yrangeAlt.GetDelta()
roundTo := GetRoundToForDelta(delta)
rmin, rmax := RoundDown(yrangeAlt.GetMin(), roundTo), RoundUp(yrangeAlt.GetMax(), roundTo)
yrangeAlt.SetMin(rmin)
yrangeAlt.SetMax(rmax)
}
return
}
func (c Chart) checkRanges(xr, yr, yra Range) error {
if math.IsInf(xr.Delta(), 0) || math.IsNaN(xr.Delta()) {
if math.IsInf(xr.GetDelta(), 0) || math.IsNaN(xr.GetDelta()) || xr.GetDelta() == 0 {
return errors.New("Invalid (infinite or NaN) x-range delta")
}
if math.IsInf(yr.Delta(), 0) || math.IsNaN(yr.Delta()) {
if math.IsInf(yr.GetDelta(), 0) || math.IsNaN(yr.GetDelta()) || yr.GetDelta() == 0 {
return errors.New("Invalid (infinite or NaN) y-range delta")
}
if c.hasSecondarySeries() {
if math.IsInf(yra.Delta(), 0) || math.IsNaN(yra.Delta()) {
if math.IsInf(yra.GetDelta(), 0) || math.IsNaN(yra.GetDelta()) || yra.GetDelta() == 0 {
return errors.New("Invalid (infinite or NaN) y-secondary-range delta")
}
}
@ -320,14 +342,11 @@ func (c Chart) getAxisAdjustedCanvasBox(r Renderer, canvasBox Box, xr, yr, yra R
return canvasBox.OuterConstrain(c.Box(), axesOuterBox)
}
func (c Chart) setRangeDomains(canvasBox Box, xr, yr, yra Range) (xr2, yr2, yra2 Range) {
xr2.Min, xr2.Max = xr.Min, xr.Max
xr2.Domain = canvasBox.Width()
yr2.Min, yr2.Max = yr.Min, yr.Max
yr2.Domain = canvasBox.Height()
yra2.Min, yra2.Max = yra.Min, yra.Max
yra2.Domain = canvasBox.Height()
return
func (c Chart) setRangeDomains(canvasBox Box, xr, yr, yra Range) (Range, Range, Range) {
xr.SetDomain(canvasBox.Width())
yr.SetDomain(canvasBox.Height())
yra.SetDomain(canvasBox.Height())
return xr, yr, yra
}
func (c Chart) hasAnnotationSeries() bool {
@ -372,7 +391,7 @@ func (c Chart) getAnnotationAdjustedCanvasBox(r Renderer, canvasBox Box, xr, yr,
}
func (c Chart) getBackgroundStyle() Style {
return c.Background.WithDefaultsFrom(c.styleDefaultsBackground())
return c.Background.InheritFrom(c.styleDefaultsBackground())
}
func (c Chart) drawBackground(r Renderer) {
@ -383,7 +402,7 @@ func (c Chart) drawBackground(r Renderer) {
}
func (c Chart) getCanvasStyle() Style {
return c.Canvas.WithDefaultsFrom(c.styleDefaultsCanvas())
return c.Canvas.InheritFrom(c.styleDefaultsCanvas())
}
func (c Chart) drawCanvas(r Renderer, canvasBox Box) {