diff --git a/annotation_series.go b/annotation_series.go index 9b383c9..3e97d82 100644 --- a/annotation_series.go +++ b/annotation_series.go @@ -6,7 +6,7 @@ import "math" type AnnotationSeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType Annotations []Value2 } @@ -21,7 +21,7 @@ func (as AnnotationSeries) GetStyle() Style { } // GetYAxis returns which YAxis the series draws on. -func (as AnnotationSeries) GetYAxis() YAxisType { +func (as AnnotationSeries) GetYAxis() yAxisType { return as.YAxis } diff --git a/axis.go b/axis.go index 1c6d272..e607cea 100644 --- a/axis.go +++ b/axis.go @@ -1,13 +1,24 @@ package chart +type tickPosition int + +const ( + // TickPositionUnset means to use the default tick position. + TickPositionUnset tickPosition = 0 + // TickPositionBetweenTicks draws the labels for a tick between the previous and current tick. + TickPositionBetweenTicks tickPosition = 1 + // TickPositionUnderTick draws the tick below the tick. + TickPositionUnderTick tickPosition = 2 +) + // YAxisType is a type of y-axis; it can either be primary or secondary. -type YAxisType int +type yAxisType int const ( // YAxisPrimary is the primary axis. - YAxisPrimary YAxisType = 0 + YAxisPrimary yAxisType = 0 // YAxisSecondary is the secondary axis. - YAxisSecondary YAxisType = 1 + YAxisSecondary yAxisType = 1 ) // Axis is a chart feature detailing what values happen where. diff --git a/bollinger_band_series.go b/bollinger_band_series.go index f74b489..6981d11 100644 --- a/bollinger_band_series.go +++ b/bollinger_band_series.go @@ -7,7 +7,7 @@ import "math" type BollingerBandsSeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType Period int K float64 @@ -27,7 +27,7 @@ func (bbs BollingerBandsSeries) GetStyle() Style { } // GetYAxis returns which YAxis the series draws on. -func (bbs BollingerBandsSeries) GetYAxis() YAxisType { +func (bbs BollingerBandsSeries) GetYAxis() yAxisType { return bbs.YAxis } diff --git a/continuous_series.go b/continuous_series.go index fe8d068..f3a00cf 100644 --- a/continuous_series.go +++ b/continuous_series.go @@ -5,7 +5,7 @@ type ContinuousSeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType XValues []float64 YValues []float64 @@ -44,7 +44,7 @@ func (cs ContinuousSeries) GetValueFormatters() (x, y ValueFormatter) { } // GetYAxis returns which YAxis the series draws on. -func (cs ContinuousSeries) GetYAxis() YAxisType { +func (cs ContinuousSeries) GetYAxis() yAxisType { return cs.YAxis } diff --git a/draw.go b/draw.go index 21d58df..eb9ec6a 100644 --- a/draw.go +++ b/draw.go @@ -62,8 +62,6 @@ func (d draw) BoundedSeries(r Renderer, canvasBox Box, xrange, yrange Range, sty drawOffsetIndex = drawOffsetIndexes[0] } - style.WriteToRenderer(r) - cb := canvasBox.Bottom cl := canvasBox.Left @@ -79,6 +77,7 @@ func (d draw) BoundedSeries(r Renderer, canvasBox Box, xrange, yrange Range, sty y2values := make([]float64, bbs.Len()) y2values[0] = v0y2 + style.GetFillAndStrokeOptions().WriteToRenderer(r) r.MoveTo(x0, y0) for i := 1; i < bbs.Len(); i++ { vx, vy1, vy2 = bbs.GetBoundedValue(i) diff --git a/ema_series.go b/ema_series.go index affadc1..991359f 100644 --- a/ema_series.go +++ b/ema_series.go @@ -9,7 +9,7 @@ const ( type EMASeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType Period int InnerSeries ValueProvider @@ -28,7 +28,7 @@ func (ema EMASeries) GetStyle() Style { } // GetYAxis returns which YAxis the series draws on. -func (ema EMASeries) GetYAxis() YAxisType { +func (ema EMASeries) GetYAxis() yAxisType { return ema.YAxis } diff --git a/examples/stock_analysis/main.go b/examples/stock_analysis/main.go index fd131ae..3f17025 100644 --- a/examples/stock_analysis/main.go +++ b/examples/stock_analysis/main.go @@ -43,7 +43,8 @@ func drawChart(res http.ResponseWriter, req *http.Request) { graph := chart.Chart{ XAxis: chart.XAxis{ - Style: chart.Style{Show: true}, + Style: chart.Style{Show: true}, + TickPosition: chart.TickPositionBetweenTicks, }, YAxis: chart.YAxis{ Style: chart.Style{Show: true}, diff --git a/histogram_series.go b/histogram_series.go index 0542c1a..351fe94 100644 --- a/histogram_series.go +++ b/histogram_series.go @@ -6,7 +6,7 @@ package chart type HistogramSeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType InnerSeries ValueProvider } @@ -21,7 +21,7 @@ func (hs HistogramSeries) GetStyle() Style { } // GetYAxis returns which yaxis the series is mapped to. -func (hs HistogramSeries) GetYAxis() YAxisType { +func (hs HistogramSeries) GetYAxis() yAxisType { return hs.YAxis } diff --git a/linear_regression_series.go b/linear_regression_series.go index a33a0b1..06c8c4e 100644 --- a/linear_regression_series.go +++ b/linear_regression_series.go @@ -5,7 +5,7 @@ package chart type LinearRegressionSeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType Window int Offset int @@ -28,7 +28,7 @@ func (lrs LinearRegressionSeries) GetStyle() Style { } // GetYAxis returns which YAxis the series draws on. -func (lrs LinearRegressionSeries) GetYAxis() YAxisType { +func (lrs LinearRegressionSeries) GetYAxis() yAxisType { return lrs.YAxis } diff --git a/macd_series.go b/macd_series.go index b3b80c0..d0aa51c 100644 --- a/macd_series.go +++ b/macd_series.go @@ -14,7 +14,7 @@ const ( type MACDSeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType InnerSeries ValueProvider PrimaryPeriod int @@ -56,7 +56,7 @@ func (macd MACDSeries) GetStyle() Style { } // GetYAxis returns which YAxis the series draws on. -func (macd MACDSeries) GetYAxis() YAxisType { +func (macd MACDSeries) GetYAxis() yAxisType { return macd.YAxis } @@ -109,7 +109,7 @@ func (macd *MACDSeries) ensureChildSeries() { type MACDSignalSeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType InnerSeries ValueProvider PrimaryPeriod int @@ -150,7 +150,7 @@ func (macds MACDSignalSeries) GetStyle() Style { } // GetYAxis returns which YAxis the series draws on. -func (macds MACDSignalSeries) GetYAxis() YAxisType { +func (macds MACDSignalSeries) GetYAxis() yAxisType { return macds.YAxis } @@ -200,7 +200,7 @@ func (macds *MACDSignalSeries) Render(r Renderer, canvasBox Box, xrange, yrange type MACDLineSeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType InnerSeries ValueProvider PrimaryPeriod int @@ -223,7 +223,7 @@ func (macdl MACDLineSeries) GetStyle() Style { } // GetYAxis returns which YAxis the series draws on. -func (macdl MACDLineSeries) GetYAxis() YAxisType { +func (macdl MACDLineSeries) GetYAxis() yAxisType { return macdl.YAxis } diff --git a/series.go b/series.go index 6145dcb..879f24b 100644 --- a/series.go +++ b/series.go @@ -3,7 +3,7 @@ package chart // Series is an alias to Renderable. type Series interface { GetName() string - GetYAxis() YAxisType + GetYAxis() yAxisType GetStyle() Style Render(r Renderer, canvasBox Box, xrange, yrange Range, s Style) } diff --git a/sma_series.go b/sma_series.go index a7e0034..dd8aed9 100644 --- a/sma_series.go +++ b/sma_series.go @@ -9,7 +9,7 @@ const ( type SMASeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType Period int InnerSeries ValueProvider @@ -26,7 +26,7 @@ func (sma SMASeries) GetStyle() Style { } // GetYAxis returns which YAxis the series draws on. -func (sma SMASeries) GetYAxis() YAxisType { +func (sma SMASeries) GetYAxis() yAxisType { return sma.YAxis } diff --git a/time_series.go b/time_series.go index df779eb..8869cac 100644 --- a/time_series.go +++ b/time_series.go @@ -7,7 +7,7 @@ type TimeSeries struct { Name string Style Style - YAxis YAxisType + YAxis yAxisType XValues []time.Time YValues []float64 @@ -50,7 +50,7 @@ func (ts TimeSeries) GetValueFormatters() (x, y ValueFormatter) { } // GetYAxis returns which YAxis the series draws on. -func (ts TimeSeries) GetYAxis() YAxisType { +func (ts TimeSeries) GetYAxis() yAxisType { return ts.YAxis } diff --git a/xaxis.go b/xaxis.go index b229008..31013e7 100644 --- a/xaxis.go +++ b/xaxis.go @@ -13,6 +13,8 @@ type XAxis struct { Range Range Ticks []Tick + TickPosition tickPosition + GridLines []GridLine GridMajorStyle Style GridMinorStyle Style @@ -28,6 +30,17 @@ func (xa XAxis) GetStyle() Style { return xa.Style } +// GetTickPosition returns the tick position option for the axis. +func (xa XAxis) GetTickPosition(defaults ...tickPosition) tickPosition { + if xa.TickPosition == TickPositionUnset { + if len(defaults) > 0 { + return defaults[0] + } + return TickPositionUnderTick + } + return xa.TickPosition +} + // GetTicks returns the ticks for a series. // The coalesce priority is: // - User Supplied Ticks (i.e. Ticks array on the axis itself). @@ -82,25 +95,48 @@ func (xa XAxis) Measure(r Renderer, canvasBox Box, ra Range, defaults Style, tic // Render renders the axis func (xa XAxis) Render(r Renderer, canvasBox Box, ra Range, defaults Style, ticks []Tick) { - xa.Style.InheritFrom(defaults).WriteToRenderer(r) + tickStyle := xa.Style.InheritFrom(defaults) + tickStyle.GetStrokeOptions().WriteToRenderer(r) r.MoveTo(canvasBox.Left, canvasBox.Bottom) r.LineTo(canvasBox.Right, canvasBox.Bottom) r.Stroke() sort.Sort(Ticks(ticks)) - for _, t := range ticks { + tp := xa.GetTickPosition() + + var tx, ty int + for index, t := range ticks { v := t.Value lx := ra.Translate(v) tb := r.MeasureText(t.Label) - tx := canvasBox.Left + lx - ty := canvasBox.Bottom + DefaultXAxisMargin + tb.Height() - r.Text(t.Label, tx-tb.Width()>>1, ty) + tx = canvasBox.Left + lx + ty = canvasBox.Bottom + DefaultXAxisMargin + tb.Height() + + tickStyle.GetStrokeOptions().WriteToRenderer(r) r.MoveTo(tx, canvasBox.Bottom) r.LineTo(tx, canvasBox.Bottom+DefaultVerticalTickHeight) r.Stroke() + + switch tp { + case TickPositionUnderTick: + tickStyle.GetTextOptions().WriteToRenderer(r) + r.Text(t.Label, tx-tb.Width()>>1, ty) + case TickPositionBetweenTicks: + if index > 0 { + llx := ra.Translate(ticks[index-1].Value) + ltx := canvasBox.Left + llx + Draw.TextWithin(r, t.Label, Box{ + Left: ltx, + Right: tx, + Top: canvasBox.Bottom + DefaultXAxisMargin, + Bottom: canvasBox.Bottom + DefaultXAxisMargin + tb.Height(), + }, tickStyle.InheritFrom(Style{TextHorizontalAlign: TextHorizontalAlignCenter})) + } + } + } if xa.GridMajorStyle.Show || xa.GridMinorStyle.Show { diff --git a/yaxis.go b/yaxis.go index b9c16d3..de9cc3a 100644 --- a/yaxis.go +++ b/yaxis.go @@ -13,7 +13,7 @@ type YAxis struct { Zero GridLine - AxisType YAxisType + AxisType yAxisType ValueFormatter ValueFormatter Range Range