diff --git a/chart.go b/chart.go index 0d06a21..c32696f 100644 --- a/chart.go +++ b/chart.go @@ -95,6 +95,11 @@ func (c Chart) Render(rp RendererProvider, w io.Writer) error { xf, yf, yfa := c.getValueFormatters() xr, yr, yra = c.setRangeDomains(canvasBox, xr, yr, yra) + err = c.checkRanges(xr, yr, yra) + if err != nil { + return err + } + if c.hasAxes() { xt, yt, yta = c.getAxesTicks(r, xr, yr, yra, xf, yf, yfa) canvasBox = c.getAxisAdjustedCanvasBox(r, canvasBox, xr, yr, yra, xt, yt, yta) @@ -180,6 +185,23 @@ func (c Chart) getRanges() (xrange, yrange, yrangeAlt Range) { return } +func (c Chart) checkRanges(xr, yr, yra Range) error { + + if math.IsInf(xr.Delta(), 0) || math.IsNaN(xr.Delta()) { + return errors.New("Invalid (infinite or NaN) x-range delta") + } + if math.IsInf(yr.Delta(), 0) || math.IsNaN(yr.Delta()) { + return errors.New("Invalid (infinite or NaN) y-range delta") + } + if c.hasSecondarySeries() { + if math.IsInf(yra.Delta(), 0) || math.IsNaN(yra.Delta()) { + return errors.New("Invalid (infinite or NaN) y-secondary-range delta") + } + } + + return nil +} + func (c Chart) getDefaultCanvasBox() Box { dpt := c.Background.Padding.GetTop(DefaultBackgroundPadding.Top) dpl := c.Background.Padding.GetLeft(DefaultBackgroundPadding.Left) @@ -275,6 +297,15 @@ func (c Chart) hasAnnotationSeries() bool { return false } +func (c Chart) hasSecondarySeries() bool { + for _, s := range c.Series { + if s.GetYAxis() == YAxisSecondary { + return true + } + } + return false +} + func (c Chart) getAnnotationAdjustedCanvasBox(r Renderer, canvasBox Box, xr, yr, yra Range, xf, yf, yfa ValueFormatter) Box { annotationSeriesBox := canvasBox.Clone() for seriesIndex, s := range c.Series { diff --git a/yaxis.go b/yaxis.go index 36c6ccd..833ce08 100644 --- a/yaxis.go +++ b/yaxis.go @@ -37,14 +37,10 @@ func (ya YAxis) GetStyle() Style { // GetTicks returns the ticks for a series. It coalesces between user provided ticks and // generated ticks. func (ya YAxis) GetTicks(r Renderer, ra Range, defaults Style, vf ValueFormatter) []Tick { - var ticks []Tick if len(ya.Ticks) > 0 { - ticks = ya.Ticks - } else { - ticks = ya.generateTicks(r, ra, defaults, vf) + return ya.Ticks } - - return ticks + return ya.generateTicks(r, ra, defaults, vf) } func (ya YAxis) generateTicks(r Renderer, ra Range, defaults Style, vf ValueFormatter) []Tick { @@ -65,7 +61,8 @@ func (ya YAxis) getTickCount(r Renderer, ra Range, defaults Style, vf ValueForma //given the domain, figure out how many ticks we can draw ... label := vf(ra.Min) tb := r.MeasureText(label) - return int(math.Ceil(float64(ra.Domain) / float64(tb.Height()+DefaultMinimumTickVerticalSpacing))) + count := int(math.Ceil(float64(ra.Domain) / float64(tb.Height()+DefaultMinimumTickVerticalSpacing))) + return count } // GetGridLines returns the gridlines for the axis.