diff --git a/_examples/axes/output.png b/_examples/axes/output.png index 8b44578..61c376c 100644 Binary files a/_examples/axes/output.png and b/_examples/axes/output.png differ diff --git a/_examples/bar_chart/output.png b/_examples/bar_chart/output.png index 8b1c702..ced62f1 100644 Binary files a/_examples/bar_chart/output.png and b/_examples/bar_chart/output.png differ diff --git a/_examples/custom_padding/main.go b/_examples/custom_padding/main.go index 199a8e7..95ec57c 100644 --- a/_examples/custom_padding/main.go +++ b/_examples/custom_padding/main.go @@ -5,6 +5,7 @@ import ( "github.com/wcharczuk/go-chart" "github.com/wcharczuk/go-chart/drawing" + "github.com/wcharczuk/go-chart/seq" ) func drawChart(res http.ResponseWriter, req *http.Request) { @@ -30,8 +31,8 @@ func drawChart(res http.ResponseWriter, req *http.Request) { }, Series: []chart.Series{ chart.ContinuousSeries{ - XValues: chart.Sequence.Float64(1.0, 100.0), - YValues: chart.Sequence.Random(100.0, 256.0), + XValues: seq.Wrap(seq.NewLinear().WithStart(1.0).WithEnd(100.0)).Array(), + YValues: seq.Wrap(seq.NewRandom().WithLen(100).WithAverage(256)).Array(), }, }, } @@ -57,8 +58,8 @@ func drawChartDefault(res http.ResponseWriter, req *http.Request) { }, Series: []chart.Series{ chart.ContinuousSeries{ - XValues: chart.Sequence.Float64(1.0, 100.0), - YValues: chart.Sequence.Random(100.0, 256.0), + XValues: seq.Wrap(seq.NewLinear().WithStart(1.0).WithEnd(100.0)).Array(), + YValues: seq.Wrap(seq.NewRandom().WithLen(100).WithAverage(256)).Array(), }, }, } diff --git a/bollinger_band_series.go b/bollinger_band_series.go index 9173825..9dbd3b8 100644 --- a/bollinger_band_series.go +++ b/bollinger_band_series.go @@ -3,7 +3,7 @@ package chart import ( "fmt" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" ) // BollingerBandsSeries draws bollinger bands for an inner series. @@ -17,7 +17,7 @@ type BollingerBandsSeries struct { K float64 InnerSeries ValuesProvider - valueBuffer *sequence.Buffer + valueBuffer *seq.Buffer } // GetName returns the name of the time series. @@ -67,7 +67,7 @@ func (bbs *BollingerBandsSeries) GetBoundedValues(index int) (x, y1, y2 float64) return } if bbs.valueBuffer == nil || index == 0 { - bbs.valueBuffer = sequence.NewBufferWithCapacity(bbs.GetPeriod()) + bbs.valueBuffer = seq.NewBufferWithCapacity(bbs.GetPeriod()) } if bbs.valueBuffer.Len() >= bbs.GetPeriod() { bbs.valueBuffer.Dequeue() @@ -76,8 +76,8 @@ func (bbs *BollingerBandsSeries) GetBoundedValues(index int) (x, y1, y2 float64) bbs.valueBuffer.Enqueue(py) x = px - ay := sequence.Seq{Provider: bbs.valueBuffer}.Average() - std := sequence.Seq{Provider: bbs.valueBuffer}.StdDev() + ay := seq.New(bbs.valueBuffer).Average() + std := seq.New(bbs.valueBuffer).StdDev() y1 = ay + (bbs.GetK() * std) y2 = ay - (bbs.GetK() * std) @@ -96,15 +96,15 @@ func (bbs *BollingerBandsSeries) GetBoundedLastValues() (x, y1, y2 float64) { startAt = 0 } - vb := sequence.NewBufferWithCapacity(period) + vb := seq.NewBufferWithCapacity(period) for index := startAt; index < seriesLength; index++ { xn, yn := bbs.InnerSeries.GetValues(index) vb.Enqueue(yn) x = xn } - ay := sequence.Seq{Provider: vb}.Average() - std := sequence.Seq{Provider: vb}.StdDev() + ay := seq.Seq{Provider: vb}.Average() + std := seq.Seq{Provider: vb}.StdDev() y1 = ay + (bbs.GetK() * std) y2 = ay - (bbs.GetK() * std) diff --git a/bollinger_band_series_test.go b/bollinger_band_series_test.go index b591848..8801220 100644 --- a/bollinger_band_series_test.go +++ b/bollinger_band_series_test.go @@ -6,15 +6,15 @@ import ( "testing" "github.com/blendlabs/go-assert" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" ) func TestBollingerBandSeries(t *testing.T) { assert := assert.New(t) s1 := mockValuesProvider{ - X: sequence.Values(1.0, 100.0), - Y: sequence.RandomValuesWithAverage(1024, 100), + X: seq.Range(1.0, 100.0), + Y: seq.RandomValuesWithAverage(1024, 100), } bbs := &BollingerBandsSeries{ @@ -38,8 +38,8 @@ func TestBollingerBandLastValue(t *testing.T) { assert := assert.New(t) s1 := mockValuesProvider{ - X: sequence.Values(1.0, 100.0), - Y: sequence.Values(1.0, 100.0), + X: seq.Range(1.0, 100.0), + Y: seq.Range(1.0, 100.0), } bbs := &BollingerBandsSeries{ diff --git a/chart_test.go b/chart_test.go index 6a04793..90a3c19 100644 --- a/chart_test.go +++ b/chart_test.go @@ -10,7 +10,7 @@ import ( "github.com/blendlabs/go-assert" "github.com/wcharczuk/go-chart/drawing" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" ) func TestChartGetDPI(t *testing.T) { @@ -392,8 +392,8 @@ func TestChartRegressionBadRangesByUser(t *testing.T) { }, Series: []Series{ ContinuousSeries{ - XValues: sequence.Values(1.0, 10.0), - YValues: sequence.Values(1.0, 10.0), + XValues: seq.Range(1.0, 10.0), + YValues: seq.Range(1.0, 10.0), }, }, } @@ -408,8 +408,8 @@ func TestChartValidatesSeries(t *testing.T) { c := Chart{ Series: []Series{ ContinuousSeries{ - XValues: sequence.Values(1.0, 10.0), - YValues: sequence.Values(1.0, 10.0), + XValues: seq.Range(1.0, 10.0), + YValues: seq.Range(1.0, 10.0), }, }, } @@ -419,7 +419,7 @@ func TestChartValidatesSeries(t *testing.T) { c = Chart{ Series: []Series{ ContinuousSeries{ - XValues: sequence.Values(1.0, 10.0), + XValues: seq.Range(1.0, 10.0), }, }, } @@ -505,8 +505,8 @@ func TestChartE2ELine(t *testing.T) { }, Series: []Series{ ContinuousSeries{ - XValues: sequence.ValuesWithStep(0, 4, 1), - YValues: sequence.ValuesWithStep(0, 4, 1), + XValues: seq.RangeWithStep(0, 4, 1), + YValues: seq.RangeWithStep(0, 4, 1), }, }, } @@ -550,8 +550,8 @@ func TestChartE2ELineWithFill(t *testing.T) { StrokeColor: drawing.ColorBlue, FillColor: drawing.ColorRed, }, - XValues: sequence.ValuesWithStep(0, 4, 1), - YValues: sequence.ValuesWithStep(0, 4, 1), + XValues: seq.RangeWithStep(0, 4, 1), + YValues: seq.RangeWithStep(0, 4, 1), }, }, } diff --git a/concat_series_test.go b/concat_series_test.go index 1f15339..3856e0a 100644 --- a/concat_series_test.go +++ b/concat_series_test.go @@ -4,25 +4,25 @@ import ( "testing" assert "github.com/blendlabs/go-assert" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" ) func TestConcatSeries(t *testing.T) { assert := assert.New(t) s1 := ContinuousSeries{ - XValues: sequence.Values(1.0, 10.0), - YValues: sequence.Values(1.0, 10.0), + XValues: seq.Range(1.0, 10.0), + YValues: seq.Range(1.0, 10.0), } s2 := ContinuousSeries{ - XValues: sequence.Values(11, 20.0), - YValues: sequence.Values(10.0, 1.0), + XValues: seq.Range(11, 20.0), + YValues: seq.Range(10.0, 1.0), } s3 := ContinuousSeries{ - XValues: sequence.Values(21, 30.0), - YValues: sequence.Values(1.0, 10.0), + XValues: seq.Range(21, 30.0), + YValues: seq.Range(1.0, 10.0), } cs := ConcatSeries([]Series{s1, s2, s3}) diff --git a/continuous_series_test.go b/continuous_series_test.go index 828493c..89af981 100644 --- a/continuous_series_test.go +++ b/continuous_series_test.go @@ -5,7 +5,7 @@ import ( "testing" assert "github.com/blendlabs/go-assert" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" ) func TestContinuousSeries(t *testing.T) { @@ -13,8 +13,8 @@ func TestContinuousSeries(t *testing.T) { cs := ContinuousSeries{ Name: "Test Series", - XValues: sequence.Values(1.0, 10.0), - YValues: sequence.Values(1.0, 10.0), + XValues: seq.Range(1.0, 10.0), + YValues: seq.Range(1.0, 10.0), } assert.Equal("Test Series", cs.GetName()) @@ -54,20 +54,20 @@ func TestContinuousSeriesValidate(t *testing.T) { cs := ContinuousSeries{ Name: "Test Series", - XValues: sequence.Values(1.0, 10.0), - YValues: sequence.Values(1.0, 10.0), + XValues: seq.Range(1.0, 10.0), + YValues: seq.Range(1.0, 10.0), } assert.Nil(cs.Validate()) cs = ContinuousSeries{ Name: "Test Series", - XValues: sequence.Values(1.0, 10.0), + XValues: seq.Range(1.0, 10.0), } assert.NotNil(cs.Validate()) cs = ContinuousSeries{ Name: "Test Series", - YValues: sequence.Values(1.0, 10.0), + YValues: seq.Range(1.0, 10.0), } assert.NotNil(cs.Validate()) } diff --git a/ema_series_test.go b/ema_series_test.go index 4b08570..e2867d0 100644 --- a/ema_series_test.go +++ b/ema_series_test.go @@ -4,11 +4,11 @@ import ( "testing" "github.com/blendlabs/go-assert" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" ) var ( - emaXValues = sequence.Values(1.0, 50.0) + emaXValues = seq.Range(1.0, 50.0) emaYValues = []float64{ 1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3, 2, diff --git a/histogram_series_test.go b/histogram_series_test.go index 0c7e6c0..744ebe1 100644 --- a/histogram_series_test.go +++ b/histogram_series_test.go @@ -4,7 +4,7 @@ import ( "testing" assert "github.com/blendlabs/go-assert" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" ) func TestHistogramSeries(t *testing.T) { @@ -12,8 +12,8 @@ func TestHistogramSeries(t *testing.T) { cs := ContinuousSeries{ Name: "Test Series", - XValues: sequence.Values(1.0, 20.0), - YValues: sequence.Values(10.0, -10.0), + XValues: seq.Range(1.0, 20.0), + YValues: seq.Range(10.0, -10.0), } hs := HistogramSeries{ diff --git a/linear_regression_series.go b/linear_regression_series.go index 1ff2dc4..13c3cb0 100644 --- a/linear_regression_series.go +++ b/linear_regression_series.go @@ -3,7 +3,7 @@ package chart import ( "fmt" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" util "github.com/wcharczuk/go-chart/util" ) @@ -107,14 +107,14 @@ func (lrs *LinearRegressionSeries) computeCoefficients() { p := float64(endIndex - startIndex) - xvalues := sequence.NewBufferWithCapacity(lrs.Len()) + xvalues := seq.NewBufferWithCapacity(lrs.Len()) for index := startIndex; index < endIndex; index++ { x, _ := lrs.InnerSeries.GetValues(index) xvalues.Enqueue(x) } - lrs.avgx = sequence.Seq{Provider: xvalues}.Average() - lrs.stddevx = sequence.Seq{Provider: xvalues}.StdDev() + lrs.avgx = seq.Seq{Provider: xvalues}.Average() + lrs.stddevx = seq.Seq{Provider: xvalues}.StdDev() var sumx, sumy, sumxx, sumxy float64 for index := startIndex; index < endIndex; index++ { diff --git a/linear_regression_series_test.go b/linear_regression_series_test.go index c26934b..c24dff0 100644 --- a/linear_regression_series_test.go +++ b/linear_regression_series_test.go @@ -4,7 +4,7 @@ import ( "testing" assert "github.com/blendlabs/go-assert" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" ) func TestLinearRegressionSeries(t *testing.T) { @@ -12,8 +12,8 @@ func TestLinearRegressionSeries(t *testing.T) { mainSeries := ContinuousSeries{ Name: "A test series", - XValues: sequence.Values(1.0, 100.0), - YValues: sequence.Values(1.0, 100.0), + XValues: seq.Range(1.0, 100.0), + YValues: seq.Range(1.0, 100.0), } linRegSeries := &LinearRegressionSeries{ @@ -34,8 +34,8 @@ func TestLinearRegressionSeriesDesc(t *testing.T) { mainSeries := ContinuousSeries{ Name: "A test series", - XValues: sequence.Values(100.0, 1.0), - YValues: sequence.Values(100.0, 1.0), + XValues: seq.Range(100.0, 1.0), + YValues: seq.Range(100.0, 1.0), } linRegSeries := &LinearRegressionSeries{ @@ -56,8 +56,8 @@ func TestLinearRegressionSeriesWindowAndOffset(t *testing.T) { mainSeries := ContinuousSeries{ Name: "A test series", - XValues: sequence.Values(100.0, 1.0), - YValues: sequence.Values(100.0, 1.0), + XValues: seq.Range(100.0, 1.0), + YValues: seq.Range(100.0, 1.0), } linRegSeries := &LinearRegressionSeries{ diff --git a/market_hours_range.go b/market_hours_range.go index 19ccf0f..de32e8c 100644 --- a/market_hours_range.go +++ b/market_hours_range.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" "github.com/wcharczuk/go-chart/util" ) @@ -115,31 +115,31 @@ func (mhr MarketHoursRange) GetMarketClose() time.Time { // GetTicks returns the ticks for the range. // This is to override the default continous ticks that would be generated for the range. func (mhr *MarketHoursRange) GetTicks(r Renderer, defaults Style, vf ValueFormatter) []Tick { - times := sequence.Time.MarketHours(mhr.Min, mhr.Max, mhr.GetMarketOpen(), mhr.GetMarketClose(), mhr.GetHolidayProvider()) + times := seq.Time.MarketHours(mhr.Min, mhr.Max, mhr.GetMarketOpen(), mhr.GetMarketClose(), mhr.GetHolidayProvider()) timesWidth := mhr.measureTimes(r, defaults, vf, times) if timesWidth <= mhr.Domain { return mhr.makeTicks(vf, times) } - times = sequence.Time.MarketHourQuarters(mhr.Min, mhr.Max, mhr.GetMarketOpen(), mhr.GetMarketClose(), mhr.GetHolidayProvider()) + times = seq.Time.MarketHourQuarters(mhr.Min, mhr.Max, mhr.GetMarketOpen(), mhr.GetMarketClose(), mhr.GetHolidayProvider()) timesWidth = mhr.measureTimes(r, defaults, vf, times) if timesWidth <= mhr.Domain { return mhr.makeTicks(vf, times) } - times = sequence.Time.MarketDayCloses(mhr.Min, mhr.Max, mhr.GetMarketOpen(), mhr.GetMarketClose(), mhr.GetHolidayProvider()) + times = seq.Time.MarketDayCloses(mhr.Min, mhr.Max, mhr.GetMarketOpen(), mhr.GetMarketClose(), mhr.GetHolidayProvider()) timesWidth = mhr.measureTimes(r, defaults, vf, times) if timesWidth <= mhr.Domain { return mhr.makeTicks(vf, times) } - times = sequence.Time.MarketDayAlternateCloses(mhr.Min, mhr.Max, mhr.GetMarketOpen(), mhr.GetMarketClose(), mhr.GetHolidayProvider()) + times = seq.Time.MarketDayAlternateCloses(mhr.Min, mhr.Max, mhr.GetMarketOpen(), mhr.GetMarketClose(), mhr.GetHolidayProvider()) timesWidth = mhr.measureTimes(r, defaults, vf, times) if timesWidth <= mhr.Domain { return mhr.makeTicks(vf, times) } - times = sequence.Time.MarketDayMondayCloses(mhr.Min, mhr.Max, mhr.GetMarketOpen(), mhr.GetMarketClose(), mhr.GetHolidayProvider()) + times = seq.Time.MarketDayMondayCloses(mhr.Min, mhr.Max, mhr.GetMarketOpen(), mhr.GetMarketClose(), mhr.GetHolidayProvider()) timesWidth = mhr.measureTimes(r, defaults, vf, times) if timesWidth <= mhr.Domain { return mhr.makeTicks(vf, times) diff --git a/sequence/array.go b/seq/array.go similarity index 95% rename from sequence/array.go rename to seq/array.go index bf870bd..08479c2 100644 --- a/sequence/array.go +++ b/seq/array.go @@ -1,4 +1,4 @@ -package sequence +package seq // NewArray creates a new array. func NewArray(values ...float64) Array { diff --git a/sequence/buffer.go b/seq/buffer.go similarity index 98% rename from sequence/buffer.go rename to seq/buffer.go index 7f61449..be7c32e 100644 --- a/sequence/buffer.go +++ b/seq/buffer.go @@ -1,4 +1,4 @@ -package sequence +package seq import ( "fmt" @@ -47,7 +47,7 @@ func NewBufferWithCapacity(capacity int) *Buffer { // Buffer is a fifo datastructure that is backed by a pre-allocated array. // Instead of allocating a whole new node object for each element, array elements are re-used (which saves GC churn). // Enqueue can be O(n), Dequeue is generally O(1). -// Buffer implements `sequence.Provider` +// Buffer implements `seq.Provider` type Buffer struct { array []float64 head int @@ -61,7 +61,7 @@ func (b *Buffer) Len() int { return b.size } -// GetValue implements sequence provider. +// GetValue implements seq provider. func (b *Buffer) GetValue(index int) float64 { effectiveIndex := (b.head + index) % len(b.array) return b.array[effectiveIndex] diff --git a/sequence/buffer_test.go b/seq/buffer_test.go similarity index 99% rename from sequence/buffer_test.go rename to seq/buffer_test.go index 6c9d20b..19fd64d 100644 --- a/sequence/buffer_test.go +++ b/seq/buffer_test.go @@ -1,4 +1,4 @@ -package sequence +package seq import ( "testing" diff --git a/sequence/linear.go b/seq/linear.go similarity index 63% rename from sequence/linear.go rename to seq/linear.go index e17526f..699a5ac 100644 --- a/sequence/linear.go +++ b/seq/linear.go @@ -1,18 +1,18 @@ -package sequence +package seq -// Values returns the array values of a linear sequence with a given start, end and optional step. -func Values(start, end float64) []float64 { +// Range returns the array values of a linear seq with a given start, end and optional step. +func Range(start, end float64) []float64 { return Seq{NewLinear().WithStart(start).WithEnd(end).WithStep(1.0)}.Array() } -// ValuesWithStep returns the array values of a linear sequence with a given start, end and optional step. -func ValuesWithStep(start, end, step float64) []float64 { +// RangeWithStep returns the array values of a linear seq with a given start, end and optional step. +func RangeWithStep(start, end, step float64) []float64 { return Seq{NewLinear().WithStart(start).WithEnd(end).WithStep(step)}.Array() } // NewLinear returns a new linear generator. func NewLinear() *Linear { - return &Linear{} + return &Linear{step: 1.0} } // Linear is a stepwise generator. @@ -22,7 +22,22 @@ type Linear struct { step float64 } -// Len returns the number of elements in the sequence. +// Start returns the start value. +func (lg Linear) Start() float64 { + return lg.start +} + +// End returns the end value. +func (lg Linear) End() float64 { + return lg.end +} + +// Step returns the step value. +func (lg Linear) Step() float64 { + return lg.step +} + +// Len returns the number of elements in the seq. func (lg Linear) Len() int { if lg.start < lg.end { return int((lg.end-lg.start)/lg.step) + 1 diff --git a/seq/linear_test.go b/seq/linear_test.go new file mode 100644 index 0000000..70c5719 --- /dev/null +++ b/seq/linear_test.go @@ -0,0 +1,48 @@ +package seq + +import ( + "testing" + + assert "github.com/blendlabs/go-assert" +) + +func TestRange(t *testing.T) { + assert := assert.New(t) + + values := Range(1, 100) + assert.Len(values, 100) + assert.Equal(1, values[0]) + assert.Equal(100, values[99]) +} + +func TestRangeWithStep(t *testing.T) { + assert := assert.New(t) + + values := RangeWithStep(0, 100, 5) + assert.Equal(100, values[20]) + assert.Len(values, 21) +} + +func TestRangeReversed(t *testing.T) { + assert := assert.New(t) + + values := Range(10.0, 1.0) + assert.Equal(10, len(values)) + assert.Equal(10.0, values[0]) + assert.Equal(1.0, values[9]) +} + +func TestValuesRegression(t *testing.T) { + assert := assert.New(t) + + // note; this assumes a 1.0 step is implicitly set in the constructor. + linearProvider := NewLinear().WithStart(1.0).WithEnd(100.0) + assert.Equal(1, linearProvider.Start()) + assert.Equal(100, linearProvider.End()) + assert.Equal(100, linearProvider.Len()) + + values := Seq{Provider: linearProvider}.Array() + assert.Len(values, 100) + assert.Equal(1.0, values[0]) + assert.Equal(100, values[99]) +} diff --git a/sequence/random.go b/seq/random.go similarity index 84% rename from sequence/random.go rename to seq/random.go index bbdb2df..72fc8ef 100644 --- a/sequence/random.go +++ b/seq/random.go @@ -1,4 +1,4 @@ -package sequence +package seq import ( "math" @@ -16,14 +16,14 @@ func RandomValuesWithAverage(average float64, count int) []float64 { return Seq{NewRandom().WithAverage(average).WithLen(count)}.Array() } -// NewRandom creates a new random sequence. +// NewRandom creates a new random seq. func NewRandom() *Random { return &Random{ rnd: rand.New(rand.NewSource(time.Now().Unix())), } } -// Random is a random number sequence generator. +// Random is a random number seq generator. type Random struct { rnd *rand.Rand scale *float64 @@ -55,12 +55,22 @@ func (r *Random) WithLen(length int) *Random { return r } +// Scale returns the scale. +func (r Random) Scale() *float64 { + return r.scale +} + // WithScale sets the scale and returns the Random. func (r *Random) WithScale(scale float64) *Random { r.scale = &scale return r } +// Average returns the average. +func (r Random) Average() *float64 { + return r.average +} + // WithAverage sets the average and returns the Random. func (r *Random) WithAverage(average float64) *Random { r.average = &average diff --git a/seq/random_test.go b/seq/random_test.go new file mode 100644 index 0000000..30261c0 --- /dev/null +++ b/seq/random_test.go @@ -0,0 +1,18 @@ +package seq + +import ( + "testing" + + assert "github.com/blendlabs/go-assert" +) + +func TestRandomRegression(t *testing.T) { + assert := assert.New(t) + + randomProvider := NewRandom().WithLen(100).WithAverage(256) + assert.Equal(100, randomProvider.Len()) + assert.Equal(256, *randomProvider.Average()) + + randomValues := New(randomProvider).Array() + assert.Len(randomValues, 100) +} diff --git a/sequence/sequence.go b/seq/sequence.go similarity index 85% rename from sequence/sequence.go rename to seq/sequence.go index fe1663e..dfc369a 100644 --- a/sequence/sequence.go +++ b/seq/sequence.go @@ -1,27 +1,32 @@ -package sequence +package seq import ( "math" "sort" ) -// New returns a new sequence. -func New(values ...float64) Seq { +// New wraps a provider with a seq. +func New(provider Provider) Seq { + return Seq{Provider: provider} +} + +// Values returns a new seq composed of a given set of values. +func Values(values ...float64) Seq { return Seq{Provider: Array(values)} } -// Provider is a provider for values for a sequence. +// Provider is a provider for values for a seq. type Provider interface { Len() int GetValue(int) float64 } -// Seq is a utility wrapper for sequence providers. +// Seq is a utility wrapper for seq providers. type Seq struct { Provider } -// Array enumerates the sequence into a slice. +// Array enumerates the seq into a slice. func (s Seq) Array() (output []float64) { if s.Len() == 0 { return @@ -42,7 +47,7 @@ func (s Seq) Each(mapfn func(int, float64)) { } // Map applies the `mapfn` to all values in the value provider, -// returning a new sequence. +// returning a new seq. func (s Seq) Map(mapfn func(i int, v float64) float64) Seq { output := make([]float64, s.Len()) for i := 0; i < s.Len(); i++ { @@ -51,7 +56,7 @@ func (s Seq) Map(mapfn func(i int, v float64) float64) Seq { return Seq{Array(output)} } -// FoldLeft collapses a sequence from left to right. +// FoldLeft collapses a seq from left to right. func (s Seq) FoldLeft(mapfn func(i int, v0, v float64) float64) (v0 float64) { if s.Len() == 0 { return 0 @@ -68,7 +73,7 @@ func (s Seq) FoldLeft(mapfn func(i int, v0, v float64) float64) (v0 float64) { return } -// FoldRight collapses a sequence from right to left. +// FoldRight collapses a seq from right to left. func (s Seq) FoldRight(mapfn func(i int, v0, v float64) float64) (v0 float64) { if s.Len() == 0 { return 0 @@ -85,7 +90,7 @@ func (s Seq) FoldRight(mapfn func(i int, v0, v float64) float64) (v0 float64) { return } -// Min returns the minimum value in the sequence. +// Min returns the minimum value in the seq. func (s Seq) Min() float64 { if s.Len() == 0 { return 0 @@ -101,7 +106,7 @@ func (s Seq) Min() float64 { return min } -// Max returns the maximum value in the sequence. +// Max returns the maximum value in the seq. func (s Seq) Max() float64 { if s.Len() == 0 { return 0 @@ -137,8 +142,8 @@ func (s Seq) MinMax() (min, max float64) { return } -// Sort returns the sequence sorted in ascending order. -// This fully enumerates the sequence. +// Sort returns the seq sorted in ascending order. +// This fully enumerates the seq. func (s Seq) Sort() Seq { if s.Len() == 0 { return s @@ -148,7 +153,7 @@ func (s Seq) Sort() Seq { return Seq{Provider: Array(values)} } -// Median returns the median or middle value in the sorted sequence. +// Median returns the median or middle value in the sorted seq. func (s Seq) Median() (median float64) { l := s.Len() if l == 0 { diff --git a/sequence/sequence_test.go b/seq/sequence_test.go similarity index 96% rename from sequence/sequence_test.go rename to seq/sequence_test.go index e9927b4..33f8458 100644 --- a/sequence/sequence_test.go +++ b/seq/sequence_test.go @@ -1,4 +1,4 @@ -package sequence +package seq import ( "testing" @@ -85,7 +85,7 @@ func TestSequenceVariance(t *testing.T) { func TestSequenceNormalize(t *testing.T) { assert := assert.New(t) - normalized := New(1, 2, 3, 4, 5).Normalize().Array() + normalized := Values(1, 2, 3, 4, 5).Normalize().Array() assert.NotEmpty(normalized) assert.Len(normalized, 5) diff --git a/sequence/time.go b/seq/time.go similarity index 97% rename from sequence/time.go rename to seq/time.go index 7cf0083..79ef02a 100644 --- a/sequence/time.go +++ b/seq/time.go @@ -1,4 +1,4 @@ -package sequence +package seq import ( "time" @@ -6,12 +6,12 @@ import ( "github.com/wcharczuk/go-chart/util" ) -// Time is a utility singleton with helper functions for time sequence generation. +// Time is a utility singleton with helper functions for time seq generation. var Time timeSequence type timeSequence struct{} -// Days generates a sequence of timestamps by day, from -days to today. +// Days generates a seq of timestamps by day, from -days to today. func (ts timeSequence) Days(days int) []time.Time { var values []time.Time for day := days; day >= 0; day-- { diff --git a/sequence/time_test.go b/seq/time_test.go similarity index 99% rename from sequence/time_test.go rename to seq/time_test.go index a26be04..31da051 100644 --- a/sequence/time_test.go +++ b/seq/time_test.go @@ -1,4 +1,4 @@ -package sequence +package seq import ( "testing" diff --git a/sequence/util.go b/seq/util.go similarity index 96% rename from sequence/util.go rename to seq/util.go index 7d9e57e..685a408 100644 --- a/sequence/util.go +++ b/seq/util.go @@ -1,4 +1,4 @@ -package sequence +package seq import "math" diff --git a/sequence/linear_test.go b/sequence/linear_test.go deleted file mode 100644 index 979b799..0000000 --- a/sequence/linear_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package sequence - -import ( - "testing" - - assert "github.com/blendlabs/go-assert" -) - -func TestValues(t *testing.T) { - assert := assert.New(t) - - values := Values(1, 100) - assert.Len(values, 100) - assert.Equal(1, values[0]) - assert.Equal(100, values[99]) -} - -func TestValuesWithStep(t *testing.T) { - assert := assert.New(t) - - values := ValuesWithStep(0, 100, 5) - assert.Equal(100, values[20]) - assert.Len(values, 21) -} - -func TestValuesReversed(t *testing.T) { - assert := assert.New(t) - - values := Values(10.0, 1.0) - assert.Equal(10, len(values)) - assert.Equal(10.0, values[0]) - assert.Equal(1.0, values[9]) -} diff --git a/sma_series_test.go b/sma_series_test.go index 6c110f4..fabb06a 100644 --- a/sma_series_test.go +++ b/sma_series_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/blendlabs/go-assert" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" "github.com/wcharczuk/go-chart/util" ) @@ -33,8 +33,8 @@ func TestSMASeriesGetValue(t *testing.T) { assert := assert.New(t) mockSeries := mockValuesProvider{ - sequence.Values(1.0, 10.0), - sequence.Values(10, 1.0), + seq.Range(1.0, 10.0), + seq.Range(10, 1.0), } assert.Equal(10, mockSeries.Len()) @@ -64,8 +64,8 @@ func TestSMASeriesGetLastValueWindowOverlap(t *testing.T) { assert := assert.New(t) mockSeries := mockValuesProvider{ - sequence.Values(1.0, 10.0), - sequence.Values(10, 1.0), + seq.Range(1.0, 10.0), + seq.Range(10, 1.0), } assert.Equal(10, mockSeries.Len()) @@ -90,8 +90,8 @@ func TestSMASeriesGetLastValue(t *testing.T) { assert := assert.New(t) mockSeries := mockValuesProvider{ - sequence.Values(1.0, 100.0), - sequence.Values(100, 1.0), + seq.Range(1.0, 100.0), + seq.Range(100, 1.0), } assert.Equal(100, mockSeries.Len()) diff --git a/stacked_bar_chart.go b/stacked_bar_chart.go index 5bd5959..49e4739 100644 --- a/stacked_bar_chart.go +++ b/stacked_bar_chart.go @@ -7,7 +7,7 @@ import ( "math" "github.com/golang/freetype/truetype" - "github.com/wcharczuk/go-chart/sequence" + "github.com/wcharczuk/go-chart/seq" util "github.com/wcharczuk/go-chart/util" ) @@ -202,7 +202,7 @@ func (sbc StackedBarChart) drawYAxis(r Renderer, canvasBox Box) { r.LineTo(canvasBox.Right+DefaultHorizontalTickWidth, canvasBox.Bottom) r.Stroke() - ticks := sequence.ValuesWithStep(0.0, 1.0, 0.2) + ticks := seq.RangeWithStep(0.0, 1.0, 0.2) for _, t := range ticks { axisStyle.GetStrokeOptions().WriteToRenderer(r) ty := canvasBox.Bottom - int(t*float64(canvasBox.Height()))