diff --git a/annotation_series.go b/annotation_series.go index b9b9e2b..770fa81 100644 --- a/annotation_series.go +++ b/annotation_series.go @@ -66,6 +66,7 @@ func (as AnnotationSeries) Render(r Renderer, canvasBox Box, xrange, yrange Rang if as.Style.Show { style := as.Style.WithDefaultsFrom(Style{ Font: defaults.Font, + FontColor: DefaultTextColor, FillColor: DefaultAnnotationFillColor, FontSize: DefaultAnnotationFontSize, StrokeColor: defaults.StrokeColor, diff --git a/chart.go b/chart.go index e0cd5f4..ed6b8e2 100644 --- a/chart.go +++ b/chart.go @@ -24,7 +24,9 @@ type Chart struct { YAxis YAxis YAxisSecondary YAxis - Font *truetype.Font + Font *truetype.Font + defaultFont *truetype.Font + Series []Series Elements []Renderable } @@ -41,15 +43,27 @@ func (c Chart) GetDPI(defaults ...float64) float64 { } // GetFont returns the text font. -func (c Chart) GetFont() (*truetype.Font, error) { +func (c Chart) GetFont() *truetype.Font { if c.Font == nil { - f, err := GetDefaultFont() - if err != nil { - return nil, err - } - return f, nil + return c.defaultFont } - return c.Font, nil + return c.Font +} + +// GetWidth returns the chart width or the default value. +func (c Chart) GetWidth() int { + if c.Width == 0 { + return DefaultChartWidth + } + return c.Width +} + +// GetHeight returns the chart height or the default value. +func (c Chart) GetHeight() int { + if c.Height == 0 { + return DefaultChartHeight + } + return c.Height } // Render renders the chart with the given renderer to the given io.Writer. @@ -59,17 +73,18 @@ func (c Chart) Render(rp RendererProvider, w io.Writer) error { } c.YAxisSecondary.AxisType = YAxisSecondary - r, err := rp(c.Width, c.Height) + r, err := rp(c.GetWidth(), c.GetHeight()) if err != nil { return err } - font, err := c.GetFont() - if err != nil { - return err + if c.Font == nil { + defaultFont, err := GetDefaultFont() + if err != nil { + return err + } + c.defaultFont = defaultFont } - c.Font = font - r.SetFont(font) r.SetDPI(c.GetDPI(DefaultDPI)) c.drawBackground(r) @@ -114,21 +129,23 @@ func (c Chart) getRanges() (xrange, yrange, yrangeAlt Range) { var minya, maxya float64 = math.MaxFloat64, 0 for _, s := range c.Series { - seriesAxis := s.GetYAxis() - if vp, isValueProvider := s.(ValueProvider); isValueProvider { - seriesLength := vp.Len() - for index := 0; index < seriesLength; index++ { - vx, vy := vp.GetValue(index) + if s.GetStyle().IsZero() || s.GetStyle().Show { + seriesAxis := s.GetYAxis() + if vp, isValueProvider := s.(ValueProvider); isValueProvider { + seriesLength := vp.Len() + for index := 0; index < seriesLength; index++ { + vx, vy := vp.GetValue(index) - minx = math.Min(minx, vx) - maxx = math.Max(maxx, vx) + minx = math.Min(minx, vx) + maxx = math.Max(maxx, vx) - if seriesAxis == YAxisPrimary { - miny = math.Min(miny, vy) - maxy = math.Max(maxy, vy) - } else if seriesAxis == YAxisSecondary { - minya = math.Min(minya, vy) - maxya = math.Max(maxya, vy) + if seriesAxis == YAxisPrimary { + miny = math.Min(miny, vy) + maxy = math.Max(maxy, vy) + } else if seriesAxis == YAxisSecondary { + minya = math.Min(minya, vy) + maxya = math.Max(maxya, vy) + } } } } @@ -172,8 +189,8 @@ func (c Chart) getDefaultCanvasBox() Box { return Box{ Top: dpt, Left: dpl, - Right: c.Width - dpr, - Bottom: c.Height - dpb, + Right: c.GetWidth() - dpr, + Bottom: c.GetHeight() - dpb, } } @@ -222,15 +239,15 @@ func (c Chart) getAxesTicks(r Renderer, xr, yr, yar Range, xf, yf, yfa ValueForm func (c Chart) getAxisAdjustedCanvasBox(r Renderer, canvasBox Box, xr, yr, yra Range, xticks, yticks, yticksAlt []Tick) Box { axesOuterBox := canvasBox.Clone() if c.XAxis.Style.Show { - axesBounds := c.XAxis.Measure(r, canvasBox, xr, xticks) + axesBounds := c.XAxis.Measure(r, canvasBox, xr, c.styleDefaultsAxis(), xticks) axesOuterBox = axesOuterBox.Grow(axesBounds) } if c.YAxis.Style.Show { - axesBounds := c.YAxis.Measure(r, canvasBox, yr, yticks) + axesBounds := c.YAxis.Measure(r, canvasBox, yr, c.styleDefaultsAxis(), yticks) axesOuterBox = axesOuterBox.Grow(axesBounds) } if c.YAxisSecondary.Style.Show { - axesBounds := c.YAxisSecondary.Measure(r, canvasBox, yra, yticksAlt) + axesBounds := c.YAxisSecondary.Measure(r, canvasBox, yra, c.styleDefaultsAxis(), yticksAlt) axesOuterBox = axesOuterBox.Grow(axesBounds) } @@ -250,7 +267,7 @@ func (c Chart) setRangeDomains(canvasBox Box, xr, yr, yra Range) (xr2, yr2, yra2 func (c Chart) hasAnnotationSeries() bool { for _, s := range c.Series { if as, isAnnotationSeries := s.(AnnotationSeries); isAnnotationSeries { - if as.Style.Show { + if as.Style.IsZero() || as.Style.Show { return true } } @@ -262,8 +279,8 @@ func (c Chart) getAnnotationAdjustedCanvasBox(r Renderer, canvasBox Box, xr, yr, annotationSeriesBox := canvasBox.Clone() for seriesIndex, s := range c.Series { if as, isAnnotationSeries := s.(AnnotationSeries); isAnnotationSeries { - if as.Style.Show { - style := c.seriesStyleDefaults(seriesIndex) + if as.Style.IsZero() || as.Style.Show { + style := c.styleDefaultsSeries(seriesIndex) var annotationBounds Box if as.YAxis == YAxisPrimary { annotationBounds = as.Measure(r, canvasBox, xr, yr, style) @@ -280,7 +297,7 @@ func (c Chart) getAnnotationAdjustedCanvasBox(r Renderer, canvasBox Box, xr, yr, } func (c Chart) drawBackground(r Renderer) { - DrawBox(r, Box{Right: c.Width, Bottom: c.Height}, c.Canvas.WithDefaultsFrom(Style{ + DrawBox(r, c.asBox(), c.Canvas.WithDefaultsFrom(Style{ FillColor: DefaultBackgroundColor, StrokeColor: DefaultBackgroundStrokeColor, StrokeWidth: DefaultStrokeWidth, @@ -297,27 +314,29 @@ func (c Chart) drawCanvas(r Renderer, canvasBox Box) { func (c Chart) drawAxes(r Renderer, canvasBox Box, xrange, yrange, yrangeAlt Range, xticks, yticks, yticksAlt []Tick) { if c.XAxis.Style.Show { - c.XAxis.Render(r, canvasBox, xrange, xticks) + c.XAxis.Render(r, canvasBox, xrange, c.styleDefaultsAxis(), xticks) } if c.YAxis.Style.Show { - c.YAxis.Render(r, canvasBox, yrange, yticks) + c.YAxis.Render(r, canvasBox, yrange, c.styleDefaultsAxis(), yticks) } if c.YAxisSecondary.Style.Show { - c.YAxisSecondary.Render(r, canvasBox, yrangeAlt, yticksAlt) + c.YAxisSecondary.Render(r, canvasBox, yrangeAlt, c.styleDefaultsAxis(), yticksAlt) } } func (c Chart) drawSeries(r Renderer, canvasBox Box, xrange, yrange, yrangeAlt Range, s Series, seriesIndex int) { - if s.GetYAxis() == YAxisPrimary { - s.Render(r, canvasBox, xrange, yrange, c.seriesStyleDefaults(seriesIndex)) - } else if s.GetYAxis() == YAxisSecondary { - s.Render(r, canvasBox, xrange, yrangeAlt, c.seriesStyleDefaults(seriesIndex)) + if s.GetStyle().IsZero() || s.GetStyle().Show { + if s.GetYAxis() == YAxisPrimary { + s.Render(r, canvasBox, xrange, yrange, c.styleDefaultsSeries(seriesIndex)) + } else if s.GetYAxis() == YAxisSecondary { + s.Render(r, canvasBox, xrange, yrangeAlt, c.styleDefaultsSeries(seriesIndex)) + } } } func (c Chart) drawTitle(r Renderer) { if len(c.Title) > 0 && c.TitleStyle.Show { - r.SetFont(c.TitleStyle.GetFont(c.Font)) + r.SetFont(c.TitleStyle.GetFont(c.GetFont())) r.SetFontColor(c.TitleStyle.GetFontColor(DefaultTextColor)) titleFontSize := c.TitleStyle.GetFontSize(DefaultTitleFontSize) r.SetFontSize(titleFontSize) @@ -327,23 +346,32 @@ func (c Chart) drawTitle(r Renderer) { textWidth := textBox.Width() textHeight := textBox.Height() - titleX := (c.Width >> 1) - (textWidth >> 1) + titleX := (c.GetWidth() >> 1) - (textWidth >> 1) titleY := c.TitleStyle.Padding.GetTop(DefaultTitleTop) + textHeight r.Text(c.Title, titleX, titleY) } } -func (c Chart) seriesStyleDefaults(seriesIndex int) Style { +func (c Chart) styleDefaultsSeries(seriesIndex int) Style { strokeColor := GetDefaultSeriesStrokeColor(seriesIndex) return Style{ StrokeColor: strokeColor, StrokeWidth: DefaultStrokeWidth, - Font: c.Font, + Font: c.GetFont(), FontSize: DefaultFontSize, } } -func (c Chart) asBox() Box { - return Box{Right: c.Width, Bottom: c.Height} +func (c Chart) styleDefaultsAxis() Style { + return Style{ + Font: c.GetFont(), + FontSize: DefaultAxisFontSize, + StrokeColor: DefaultAxisColor, + StrokeWidth: DefaultAxisLineWidth, + } +} + +func (c Chart) asBox() Box { + return Box{Right: c.GetWidth(), Bottom: c.GetHeight()} } diff --git a/chart_test.go b/chart_test.go index 372611a..4705b02 100644 --- a/chart_test.go +++ b/chart_test.go @@ -8,6 +8,121 @@ import ( "github.com/blendlabs/go-assert" ) +func TestChartGetDPI(t *testing.T) { + assert := assert.New(t) + + unset := Chart{} + assert.Equal(DefaultDPI, unset.GetDPI()) + assert.Equal(192, unset.GetDPI(192)) + + set := Chart{DPI: 128} + assert.Equal(128, set.GetDPI()) + assert.Equal(128, set.GetDPI(192)) +} + +func TestChartGetFont(t *testing.T) { + assert := assert.New(t) + + f, err := GetDefaultFont() + assert.Nil(err) + + unset := Chart{} + assert.Nil(unset.GetFont()) + + set := Chart{Font: f} + assert.NotNil(set.GetFont()) +} + +func TestChartGetWidth(t *testing.T) { + assert := assert.New(t) + + unset := Chart{} + assert.Equal(DefaultChartWidth, unset.GetWidth()) + + set := Chart{Width: DefaultChartWidth + 10} + assert.Equal(DefaultChartWidth+10, set.GetWidth()) +} + +func TestChartGetHeight(t *testing.T) { + assert := assert.New(t) + + unset := Chart{} + assert.Equal(DefaultChartHeight, unset.GetHeight()) + + set := Chart{Height: DefaultChartHeight + 10} + assert.Equal(DefaultChartHeight+10, set.GetHeight()) +} + +func TestChartGetRanges(t *testing.T) { + assert := assert.New(t) + + c := Chart{ + Series: []Series{ + ContinuousSeries{ + XValues: []float64{-2.0, -1.0, 0, 1.0, 2.0}, + YValues: []float64{1.0, 2.0, 3.0, 4.0, 4.5}, + }, + ContinuousSeries{ + XValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0}, + YValues: []float64{-2.1, -1.0, 0, 1.0, 2.0}, + }, + ContinuousSeries{ + YAxis: YAxisSecondary, + XValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0}, + YValues: []float64{10.0, 11.0, 12.0, 13.0, 14.0}, + }, + }, + } + + xrange, yrange, yrangeAlt := c.getRanges() + assert.Equal(-2.0, xrange.Min) + assert.Equal(5.0, xrange.Max) + + assert.Equal(-2.1, yrange.Min) + assert.Equal(4.5, yrange.Max) + + assert.Equal(10.0, yrangeAlt.Min) + assert.Equal(14.0, yrangeAlt.Max) + + cSet := Chart{ + XAxis: XAxis{ + Range: Range{Min: 9.8, Max: 19.8}, + }, + YAxis: YAxis{ + Range: Range{Min: 9.9, Max: 19.9}, + }, + YAxisSecondary: YAxis{ + Range: Range{Min: 9.7, Max: 19.7}, + }, + Series: []Series{ + ContinuousSeries{ + XValues: []float64{-2.0, -1.0, 0, 1.0, 2.0}, + YValues: []float64{1.0, 2.0, 3.0, 4.0, 4.5}, + }, + ContinuousSeries{ + XValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0}, + YValues: []float64{-2.1, -1.0, 0, 1.0, 2.0}, + }, + ContinuousSeries{ + YAxis: YAxisSecondary, + XValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0}, + YValues: []float64{10.0, 11.0, 12.0, 13.0, 14.0}, + }, + }, + } + + xr2, yr2, yra2 := cSet.getRanges() + assert.Equal(9.8, xr2.Min) + assert.Equal(19.8, xr2.Max) + + assert.Equal(9.9, yr2.Min) + assert.Equal(19.9, yr2.Max) + + assert.Equal(9.7, yra2.Min) + assert.Equal(19.7, yra2.Max) +} + +// TestChartSingleSeries is more of a sanity check than anything. func TestChartSingleSeries(t *testing.T) { assert := assert.New(t) now := time.Now() diff --git a/drawing_helpers.go b/drawing_helpers.go index 732c7d9..c73d822 100644 --- a/drawing_helpers.go +++ b/drawing_helpers.go @@ -32,8 +32,7 @@ func DrawLineSeries(r Renderer, canvasBox Box, xrange, yrange Range, s Style, vs r.Fill() } - stroke := s.GetStrokeColor() - r.SetStrokeColor(stroke) + r.SetStrokeColor(s.GetStrokeColor()) r.SetStrokeWidth(s.GetStrokeWidth(DefaultStrokeWidth)) r.MoveTo(x0, y0) @@ -48,8 +47,13 @@ func DrawLineSeries(r Renderer, canvasBox Box, xrange, yrange Range, s Style, vs // MeasureAnnotation measures how big an annotation would be. func MeasureAnnotation(r Renderer, canvasBox Box, s Style, lx, ly int, label string) Box { + r.SetFillColor(s.GetFillColor(DefaultAnnotationFillColor)) + r.SetStrokeColor(s.GetStrokeColor()) + r.SetStrokeWidth(s.GetStrokeWidth()) r.SetFont(s.GetFont()) + r.SetFontColor(s.GetFontColor(DefaultTextColor)) r.SetFontSize(s.GetFontSize(DefaultAnnotationFontSize)) + textBox := r.MeasureText(label) textWidth := textBox.Width() textHeight := textBox.Height() @@ -76,8 +80,10 @@ func MeasureAnnotation(r Renderer, canvasBox Box, s Style, lx, ly int, label str // DrawAnnotation draws an anotation with a renderer. func DrawAnnotation(r Renderer, canvasBox Box, s Style, lx, ly int, label string) { - r.SetFont(s.GetFont()) - r.SetFontSize(s.GetFontSize(DefaultAnnotationFontSize)) + r.SetFillColor(s.GetFillColor(DefaultAnnotationFillColor)) + r.SetStrokeColor(s.GetStrokeColor()) + r.SetStrokeWidth(s.GetStrokeWidth()) + textBox := r.MeasureText(label) textWidth := textBox.Width() halfTextHeight := textBox.Height() >> 1 @@ -102,11 +108,6 @@ func DrawAnnotation(r Renderer, canvasBox Box, s Style, lx, ly int, label string lbx := lx + DefaultAnnotationDeltaWidth lby := ly + (pb + halfTextHeight) - //draw the shape... - r.SetFillColor(s.GetFillColor(DefaultAnnotationFillColor)) - r.SetStrokeColor(s.GetStrokeColor()) - r.SetStrokeWidth(s.GetStrokeWidth()) - r.MoveTo(lx, ly) r.LineTo(ltx, lty) r.LineTo(rtx, rty) @@ -116,7 +117,10 @@ func DrawAnnotation(r Renderer, canvasBox Box, s Style, lx, ly int, label string r.Close() r.FillStroke() + r.SetFont(s.GetFont()) r.SetFontColor(s.GetFontColor(DefaultTextColor)) + r.SetFontSize(s.GetFontSize(DefaultAnnotationFontSize)) + r.Text(label, textX, textY) } @@ -125,6 +129,7 @@ func DrawBox(r Renderer, b Box, s Style) { r.SetFillColor(s.GetFillColor()) r.SetStrokeColor(s.GetStrokeColor(DefaultStrokeColor)) r.SetStrokeWidth(s.GetStrokeWidth(DefaultStrokeWidth)) + r.MoveTo(b.Left, b.Top) r.LineTo(b.Right, b.Top) r.LineTo(b.Right, b.Bottom) @@ -135,17 +140,18 @@ func DrawBox(r Renderer, b Box, s Style) { // DrawText draws text with a given style. func DrawText(r Renderer, text string, x, y int, s Style) { - r.SetFillColor(s.GetFillColor()) + r.SetFillColor(s.GetFillColor(DefaultTextColor)) r.SetStrokeColor(s.GetStrokeColor()) r.SetStrokeWidth(s.GetStrokeWidth()) r.SetFont(s.GetFont()) r.SetFontSize(s.GetFontSize()) + r.Text(text, x, y) } // DrawTextCentered draws text with a given style centered. func DrawTextCentered(r Renderer, text string, x, y int, s Style) { - r.SetFillColor(s.GetFillColor()) + r.SetFillColor(s.GetFillColor(DefaultTextColor)) r.SetStrokeColor(s.GetStrokeColor()) r.SetStrokeWidth(s.GetStrokeWidth()) r.SetFont(s.GetFont()) diff --git a/series.go b/series.go index aae51fb..75c4e63 100644 --- a/series.go +++ b/series.go @@ -3,5 +3,6 @@ package chart // Series is an alias to Renderable. type Series interface { GetYAxis() YAxisType + GetStyle() Style Render(r Renderer, canvasBox Box, xrange, yrange Range, s Style) } diff --git a/xaxis.go b/xaxis.go index 1a2a525..d1ef328 100644 --- a/xaxis.go +++ b/xaxis.go @@ -71,41 +71,16 @@ func (xa XAxis) GetGridLines(ticks []Tick) []GridLine { if len(xa.GridLines) > 0 { return xa.GridLines } - return xa.generateGridLines(ticks) -} - -func (xa XAxis) generateGridLines(ticks []Tick) []GridLine { - var gl []GridLine - isMinor := false - minorStyle := Style{ - StrokeColor: DefaultGridLineColor.WithAlpha(100), - StrokeWidth: 1.0, - } - majorStyle := Style{ - StrokeColor: DefaultGridLineColor, - StrokeWidth: 1.0, - } - for _, t := range ticks { - s := majorStyle - if isMinor { - s = minorStyle - } - gl = append(gl, GridLine{ - Style: s, - IsMinor: isMinor, - IsVertical: true, - Value: t.Value, - }) - isMinor = !isMinor - } - return gl + return GenerateGridLines(ticks, true) } // Measure returns the bounds of the axis. -func (xa XAxis) Measure(r Renderer, canvasBox Box, ra Range, ticks []Tick) Box { - defaultFont, _ := GetDefaultFont() - r.SetFont(xa.Style.GetFont(defaultFont)) - r.SetFontSize(xa.Style.GetFontSize(DefaultFontSize)) +func (xa XAxis) Measure(r Renderer, canvasBox Box, ra Range, defaults Style, ticks []Tick) Box { + r.SetStrokeColor(xa.Style.GetStrokeColor(defaults.StrokeColor)) + r.SetStrokeWidth(xa.Style.GetStrokeWidth(defaults.StrokeWidth)) + r.SetFont(xa.Style.GetFont(defaults.GetFont())) + r.SetFontColor(xa.Style.GetFontColor(DefaultAxisColor)) + r.SetFontSize(xa.Style.GetFontSize(defaults.GetFontSize())) sort.Sort(Ticks(ticks)) @@ -133,19 +108,17 @@ func (xa XAxis) Measure(r Renderer, canvasBox Box, ra Range, ticks []Tick) Box { } // Render renders the axis -func (xa XAxis) Render(r Renderer, canvasBox Box, ra Range, ticks []Tick) { - tickFontSize := xa.Style.GetFontSize(DefaultFontSize) - - r.SetStrokeColor(xa.Style.GetStrokeColor(DefaultAxisColor)) - r.SetStrokeWidth(xa.Style.GetStrokeWidth(DefaultAxisLineWidth)) +func (xa XAxis) Render(r Renderer, canvasBox Box, ra Range, defaults Style, ticks []Tick) { + r.SetStrokeColor(xa.Style.GetStrokeColor(defaults.StrokeColor)) + r.SetStrokeWidth(xa.Style.GetStrokeWidth(defaults.StrokeWidth)) + r.SetFont(xa.Style.GetFont(defaults.GetFont())) + r.SetFontColor(xa.Style.GetFontColor(DefaultAxisColor)) + r.SetFontSize(xa.Style.GetFontSize(defaults.GetFontSize())) r.MoveTo(canvasBox.Left, canvasBox.Bottom) r.LineTo(canvasBox.Right, canvasBox.Bottom) r.Stroke() - r.SetFontColor(xa.Style.GetFontColor(DefaultAxisColor)) - r.SetFontSize(tickFontSize) - sort.Sort(Ticks(ticks)) for _, t := range ticks { diff --git a/yaxis.go b/yaxis.go index 4213875..5193b4e 100644 --- a/yaxis.go +++ b/yaxis.go @@ -75,10 +75,12 @@ func (ya YAxis) GetGridLines(ticks []Tick) []GridLine { } // Measure returns the bounds of the axis. -func (ya YAxis) Measure(r Renderer, canvasBox Box, ra Range, ticks []Tick) Box { - defaultFont, _ := GetDefaultFont() - r.SetFont(ya.Style.GetFont(defaultFont)) - r.SetFontSize(ya.Style.GetFontSize(DefaultFontSize)) +func (ya YAxis) Measure(r Renderer, canvasBox Box, ra Range, defaults Style, ticks []Tick) Box { + r.SetStrokeColor(ya.Style.GetStrokeColor(defaults.StrokeColor)) + r.SetStrokeWidth(ya.Style.GetStrokeWidth(defaults.StrokeWidth)) + r.SetFont(ya.Style.GetFont(defaults.GetFont())) + r.SetFontColor(ya.Style.GetFontColor(DefaultAxisColor)) + r.SetFontSize(ya.Style.GetFontSize(defaults.GetFontSize())) sort.Sort(Ticks(ticks)) @@ -120,14 +122,12 @@ func (ya YAxis) Measure(r Renderer, canvasBox Box, ra Range, ticks []Tick) Box { } // Render renders the axis. -func (ya YAxis) Render(r Renderer, canvasBox Box, ra Range, ticks []Tick) { - r.SetStrokeColor(ya.Style.GetStrokeColor(DefaultAxisColor)) - r.SetStrokeWidth(ya.Style.GetStrokeWidth(DefaultAxisLineWidth)) - - fontColor := ya.Style.GetFontColor(DefaultAxisColor) - r.SetFontColor(fontColor) - fontSize := ya.Style.GetFontSize(DefaultFontSize) - r.SetFontSize(fontSize) +func (ya YAxis) Render(r Renderer, canvasBox Box, ra Range, defaults Style, ticks []Tick) { + r.SetStrokeColor(ya.Style.GetStrokeColor(defaults.StrokeColor)) + r.SetStrokeWidth(ya.Style.GetStrokeWidth(defaults.StrokeWidth)) + r.SetFont(ya.Style.GetFont(defaults.GetFont())) + r.SetFontColor(ya.Style.GetFontColor(DefaultAxisColor)) + r.SetFontSize(ya.Style.GetFontSize(defaults.GetFontSize())) sort.Sort(Ticks(ticks))