sequence => seq

This commit is contained in:
Will Charczuk 2017-05-12 14:17:43 -07:00
parent 182c4eeed2
commit 9ca1b0466a
28 changed files with 205 additions and 141 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -5,6 +5,7 @@ import (
"github.com/wcharczuk/go-chart" "github.com/wcharczuk/go-chart"
"github.com/wcharczuk/go-chart/drawing" "github.com/wcharczuk/go-chart/drawing"
"github.com/wcharczuk/go-chart/seq"
) )
func drawChart(res http.ResponseWriter, req *http.Request) { func drawChart(res http.ResponseWriter, req *http.Request) {
@ -30,8 +31,8 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
}, },
Series: []chart.Series{ Series: []chart.Series{
chart.ContinuousSeries{ chart.ContinuousSeries{
XValues: chart.Sequence.Float64(1.0, 100.0), XValues: seq.Wrap(seq.NewLinear().WithStart(1.0).WithEnd(100.0)).Array(),
YValues: chart.Sequence.Random(100.0, 256.0), 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{ Series: []chart.Series{
chart.ContinuousSeries{ chart.ContinuousSeries{
XValues: chart.Sequence.Float64(1.0, 100.0), XValues: seq.Wrap(seq.NewLinear().WithStart(1.0).WithEnd(100.0)).Array(),
YValues: chart.Sequence.Random(100.0, 256.0), YValues: seq.Wrap(seq.NewRandom().WithLen(100).WithAverage(256)).Array(),
}, },
}, },
} }

View file

@ -3,7 +3,7 @@ package chart
import ( import (
"fmt" "fmt"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
) )
// BollingerBandsSeries draws bollinger bands for an inner series. // BollingerBandsSeries draws bollinger bands for an inner series.
@ -17,7 +17,7 @@ type BollingerBandsSeries struct {
K float64 K float64
InnerSeries ValuesProvider InnerSeries ValuesProvider
valueBuffer *sequence.Buffer valueBuffer *seq.Buffer
} }
// GetName returns the name of the time series. // GetName returns the name of the time series.
@ -67,7 +67,7 @@ func (bbs *BollingerBandsSeries) GetBoundedValues(index int) (x, y1, y2 float64)
return return
} }
if bbs.valueBuffer == nil || index == 0 { if bbs.valueBuffer == nil || index == 0 {
bbs.valueBuffer = sequence.NewBufferWithCapacity(bbs.GetPeriod()) bbs.valueBuffer = seq.NewBufferWithCapacity(bbs.GetPeriod())
} }
if bbs.valueBuffer.Len() >= bbs.GetPeriod() { if bbs.valueBuffer.Len() >= bbs.GetPeriod() {
bbs.valueBuffer.Dequeue() bbs.valueBuffer.Dequeue()
@ -76,8 +76,8 @@ func (bbs *BollingerBandsSeries) GetBoundedValues(index int) (x, y1, y2 float64)
bbs.valueBuffer.Enqueue(py) bbs.valueBuffer.Enqueue(py)
x = px x = px
ay := sequence.Seq{Provider: bbs.valueBuffer}.Average() ay := seq.New(bbs.valueBuffer).Average()
std := sequence.Seq{Provider: bbs.valueBuffer}.StdDev() std := seq.New(bbs.valueBuffer).StdDev()
y1 = ay + (bbs.GetK() * std) y1 = ay + (bbs.GetK() * std)
y2 = ay - (bbs.GetK() * std) y2 = ay - (bbs.GetK() * std)
@ -96,15 +96,15 @@ func (bbs *BollingerBandsSeries) GetBoundedLastValues() (x, y1, y2 float64) {
startAt = 0 startAt = 0
} }
vb := sequence.NewBufferWithCapacity(period) vb := seq.NewBufferWithCapacity(period)
for index := startAt; index < seriesLength; index++ { for index := startAt; index < seriesLength; index++ {
xn, yn := bbs.InnerSeries.GetValues(index) xn, yn := bbs.InnerSeries.GetValues(index)
vb.Enqueue(yn) vb.Enqueue(yn)
x = xn x = xn
} }
ay := sequence.Seq{Provider: vb}.Average() ay := seq.Seq{Provider: vb}.Average()
std := sequence.Seq{Provider: vb}.StdDev() std := seq.Seq{Provider: vb}.StdDev()
y1 = ay + (bbs.GetK() * std) y1 = ay + (bbs.GetK() * std)
y2 = ay - (bbs.GetK() * std) y2 = ay - (bbs.GetK() * std)

View file

@ -6,15 +6,15 @@ import (
"testing" "testing"
"github.com/blendlabs/go-assert" "github.com/blendlabs/go-assert"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
) )
func TestBollingerBandSeries(t *testing.T) { func TestBollingerBandSeries(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
s1 := mockValuesProvider{ s1 := mockValuesProvider{
X: sequence.Values(1.0, 100.0), X: seq.Range(1.0, 100.0),
Y: sequence.RandomValuesWithAverage(1024, 100), Y: seq.RandomValuesWithAverage(1024, 100),
} }
bbs := &BollingerBandsSeries{ bbs := &BollingerBandsSeries{
@ -38,8 +38,8 @@ func TestBollingerBandLastValue(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
s1 := mockValuesProvider{ s1 := mockValuesProvider{
X: sequence.Values(1.0, 100.0), X: seq.Range(1.0, 100.0),
Y: sequence.Values(1.0, 100.0), Y: seq.Range(1.0, 100.0),
} }
bbs := &BollingerBandsSeries{ bbs := &BollingerBandsSeries{

View file

@ -10,7 +10,7 @@ import (
"github.com/blendlabs/go-assert" "github.com/blendlabs/go-assert"
"github.com/wcharczuk/go-chart/drawing" "github.com/wcharczuk/go-chart/drawing"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
) )
func TestChartGetDPI(t *testing.T) { func TestChartGetDPI(t *testing.T) {
@ -392,8 +392,8 @@ func TestChartRegressionBadRangesByUser(t *testing.T) {
}, },
Series: []Series{ Series: []Series{
ContinuousSeries{ ContinuousSeries{
XValues: sequence.Values(1.0, 10.0), XValues: seq.Range(1.0, 10.0),
YValues: sequence.Values(1.0, 10.0), YValues: seq.Range(1.0, 10.0),
}, },
}, },
} }
@ -408,8 +408,8 @@ func TestChartValidatesSeries(t *testing.T) {
c := Chart{ c := Chart{
Series: []Series{ Series: []Series{
ContinuousSeries{ ContinuousSeries{
XValues: sequence.Values(1.0, 10.0), XValues: seq.Range(1.0, 10.0),
YValues: sequence.Values(1.0, 10.0), YValues: seq.Range(1.0, 10.0),
}, },
}, },
} }
@ -419,7 +419,7 @@ func TestChartValidatesSeries(t *testing.T) {
c = Chart{ c = Chart{
Series: []Series{ Series: []Series{
ContinuousSeries{ 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{ Series: []Series{
ContinuousSeries{ ContinuousSeries{
XValues: sequence.ValuesWithStep(0, 4, 1), XValues: seq.RangeWithStep(0, 4, 1),
YValues: sequence.ValuesWithStep(0, 4, 1), YValues: seq.RangeWithStep(0, 4, 1),
}, },
}, },
} }
@ -550,8 +550,8 @@ func TestChartE2ELineWithFill(t *testing.T) {
StrokeColor: drawing.ColorBlue, StrokeColor: drawing.ColorBlue,
FillColor: drawing.ColorRed, FillColor: drawing.ColorRed,
}, },
XValues: sequence.ValuesWithStep(0, 4, 1), XValues: seq.RangeWithStep(0, 4, 1),
YValues: sequence.ValuesWithStep(0, 4, 1), YValues: seq.RangeWithStep(0, 4, 1),
}, },
}, },
} }

View file

@ -4,25 +4,25 @@ import (
"testing" "testing"
assert "github.com/blendlabs/go-assert" assert "github.com/blendlabs/go-assert"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
) )
func TestConcatSeries(t *testing.T) { func TestConcatSeries(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
s1 := ContinuousSeries{ s1 := ContinuousSeries{
XValues: sequence.Values(1.0, 10.0), XValues: seq.Range(1.0, 10.0),
YValues: sequence.Values(1.0, 10.0), YValues: seq.Range(1.0, 10.0),
} }
s2 := ContinuousSeries{ s2 := ContinuousSeries{
XValues: sequence.Values(11, 20.0), XValues: seq.Range(11, 20.0),
YValues: sequence.Values(10.0, 1.0), YValues: seq.Range(10.0, 1.0),
} }
s3 := ContinuousSeries{ s3 := ContinuousSeries{
XValues: sequence.Values(21, 30.0), XValues: seq.Range(21, 30.0),
YValues: sequence.Values(1.0, 10.0), YValues: seq.Range(1.0, 10.0),
} }
cs := ConcatSeries([]Series{s1, s2, s3}) cs := ConcatSeries([]Series{s1, s2, s3})

View file

@ -5,7 +5,7 @@ import (
"testing" "testing"
assert "github.com/blendlabs/go-assert" assert "github.com/blendlabs/go-assert"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
) )
func TestContinuousSeries(t *testing.T) { func TestContinuousSeries(t *testing.T) {
@ -13,8 +13,8 @@ func TestContinuousSeries(t *testing.T) {
cs := ContinuousSeries{ cs := ContinuousSeries{
Name: "Test Series", Name: "Test Series",
XValues: sequence.Values(1.0, 10.0), XValues: seq.Range(1.0, 10.0),
YValues: sequence.Values(1.0, 10.0), YValues: seq.Range(1.0, 10.0),
} }
assert.Equal("Test Series", cs.GetName()) assert.Equal("Test Series", cs.GetName())
@ -54,20 +54,20 @@ func TestContinuousSeriesValidate(t *testing.T) {
cs := ContinuousSeries{ cs := ContinuousSeries{
Name: "Test Series", Name: "Test Series",
XValues: sequence.Values(1.0, 10.0), XValues: seq.Range(1.0, 10.0),
YValues: sequence.Values(1.0, 10.0), YValues: seq.Range(1.0, 10.0),
} }
assert.Nil(cs.Validate()) assert.Nil(cs.Validate())
cs = ContinuousSeries{ cs = ContinuousSeries{
Name: "Test Series", Name: "Test Series",
XValues: sequence.Values(1.0, 10.0), XValues: seq.Range(1.0, 10.0),
} }
assert.NotNil(cs.Validate()) assert.NotNil(cs.Validate())
cs = ContinuousSeries{ cs = ContinuousSeries{
Name: "Test Series", Name: "Test Series",
YValues: sequence.Values(1.0, 10.0), YValues: seq.Range(1.0, 10.0),
} }
assert.NotNil(cs.Validate()) assert.NotNil(cs.Validate())
} }

View file

@ -4,11 +4,11 @@ import (
"testing" "testing"
"github.com/blendlabs/go-assert" "github.com/blendlabs/go-assert"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
) )
var ( var (
emaXValues = sequence.Values(1.0, 50.0) emaXValues = seq.Range(1.0, 50.0)
emaYValues = []float64{ emaYValues = []float64{
1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3, 2,
1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3, 2,

View file

@ -4,7 +4,7 @@ import (
"testing" "testing"
assert "github.com/blendlabs/go-assert" assert "github.com/blendlabs/go-assert"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
) )
func TestHistogramSeries(t *testing.T) { func TestHistogramSeries(t *testing.T) {
@ -12,8 +12,8 @@ func TestHistogramSeries(t *testing.T) {
cs := ContinuousSeries{ cs := ContinuousSeries{
Name: "Test Series", Name: "Test Series",
XValues: sequence.Values(1.0, 20.0), XValues: seq.Range(1.0, 20.0),
YValues: sequence.Values(10.0, -10.0), YValues: seq.Range(10.0, -10.0),
} }
hs := HistogramSeries{ hs := HistogramSeries{

View file

@ -3,7 +3,7 @@ package chart
import ( import (
"fmt" "fmt"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
util "github.com/wcharczuk/go-chart/util" util "github.com/wcharczuk/go-chart/util"
) )
@ -107,14 +107,14 @@ func (lrs *LinearRegressionSeries) computeCoefficients() {
p := float64(endIndex - startIndex) p := float64(endIndex - startIndex)
xvalues := sequence.NewBufferWithCapacity(lrs.Len()) xvalues := seq.NewBufferWithCapacity(lrs.Len())
for index := startIndex; index < endIndex; index++ { for index := startIndex; index < endIndex; index++ {
x, _ := lrs.InnerSeries.GetValues(index) x, _ := lrs.InnerSeries.GetValues(index)
xvalues.Enqueue(x) xvalues.Enqueue(x)
} }
lrs.avgx = sequence.Seq{Provider: xvalues}.Average() lrs.avgx = seq.Seq{Provider: xvalues}.Average()
lrs.stddevx = sequence.Seq{Provider: xvalues}.StdDev() lrs.stddevx = seq.Seq{Provider: xvalues}.StdDev()
var sumx, sumy, sumxx, sumxy float64 var sumx, sumy, sumxx, sumxy float64
for index := startIndex; index < endIndex; index++ { for index := startIndex; index < endIndex; index++ {

View file

@ -4,7 +4,7 @@ import (
"testing" "testing"
assert "github.com/blendlabs/go-assert" assert "github.com/blendlabs/go-assert"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
) )
func TestLinearRegressionSeries(t *testing.T) { func TestLinearRegressionSeries(t *testing.T) {
@ -12,8 +12,8 @@ func TestLinearRegressionSeries(t *testing.T) {
mainSeries := ContinuousSeries{ mainSeries := ContinuousSeries{
Name: "A test series", Name: "A test series",
XValues: sequence.Values(1.0, 100.0), XValues: seq.Range(1.0, 100.0),
YValues: sequence.Values(1.0, 100.0), YValues: seq.Range(1.0, 100.0),
} }
linRegSeries := &LinearRegressionSeries{ linRegSeries := &LinearRegressionSeries{
@ -34,8 +34,8 @@ func TestLinearRegressionSeriesDesc(t *testing.T) {
mainSeries := ContinuousSeries{ mainSeries := ContinuousSeries{
Name: "A test series", Name: "A test series",
XValues: sequence.Values(100.0, 1.0), XValues: seq.Range(100.0, 1.0),
YValues: sequence.Values(100.0, 1.0), YValues: seq.Range(100.0, 1.0),
} }
linRegSeries := &LinearRegressionSeries{ linRegSeries := &LinearRegressionSeries{
@ -56,8 +56,8 @@ func TestLinearRegressionSeriesWindowAndOffset(t *testing.T) {
mainSeries := ContinuousSeries{ mainSeries := ContinuousSeries{
Name: "A test series", Name: "A test series",
XValues: sequence.Values(100.0, 1.0), XValues: seq.Range(100.0, 1.0),
YValues: sequence.Values(100.0, 1.0), YValues: seq.Range(100.0, 1.0),
} }
linRegSeries := &LinearRegressionSeries{ linRegSeries := &LinearRegressionSeries{

View file

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
"github.com/wcharczuk/go-chart/util" "github.com/wcharczuk/go-chart/util"
) )
@ -115,31 +115,31 @@ func (mhr MarketHoursRange) GetMarketClose() time.Time {
// GetTicks returns the ticks for the range. // GetTicks returns the ticks for the range.
// This is to override the default continous ticks that would be generated 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 { 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) timesWidth := mhr.measureTimes(r, defaults, vf, times)
if timesWidth <= mhr.Domain { if timesWidth <= mhr.Domain {
return mhr.makeTicks(vf, times) 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) timesWidth = mhr.measureTimes(r, defaults, vf, times)
if timesWidth <= mhr.Domain { if timesWidth <= mhr.Domain {
return mhr.makeTicks(vf, times) 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) timesWidth = mhr.measureTimes(r, defaults, vf, times)
if timesWidth <= mhr.Domain { if timesWidth <= mhr.Domain {
return mhr.makeTicks(vf, times) 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) timesWidth = mhr.measureTimes(r, defaults, vf, times)
if timesWidth <= mhr.Domain { if timesWidth <= mhr.Domain {
return mhr.makeTicks(vf, times) 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) timesWidth = mhr.measureTimes(r, defaults, vf, times)
if timesWidth <= mhr.Domain { if timesWidth <= mhr.Domain {
return mhr.makeTicks(vf, times) return mhr.makeTicks(vf, times)

View file

@ -1,4 +1,4 @@
package sequence package seq
// NewArray creates a new array. // NewArray creates a new array.
func NewArray(values ...float64) Array { func NewArray(values ...float64) Array {

View file

@ -1,4 +1,4 @@
package sequence package seq
import ( import (
"fmt" "fmt"
@ -47,7 +47,7 @@ func NewBufferWithCapacity(capacity int) *Buffer {
// Buffer is a fifo datastructure that is backed by a pre-allocated array. // 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). // 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). // Enqueue can be O(n), Dequeue is generally O(1).
// Buffer implements `sequence.Provider` // Buffer implements `seq.Provider`
type Buffer struct { type Buffer struct {
array []float64 array []float64
head int head int
@ -61,7 +61,7 @@ func (b *Buffer) Len() int {
return b.size return b.size
} }
// GetValue implements sequence provider. // GetValue implements seq provider.
func (b *Buffer) GetValue(index int) float64 { func (b *Buffer) GetValue(index int) float64 {
effectiveIndex := (b.head + index) % len(b.array) effectiveIndex := (b.head + index) % len(b.array)
return b.array[effectiveIndex] return b.array[effectiveIndex]

View file

@ -1,4 +1,4 @@
package sequence package seq
import ( import (
"testing" "testing"

View file

@ -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. // Range returns the array values of a linear seq with a given start, end and optional step.
func Values(start, end float64) []float64 { func Range(start, end float64) []float64 {
return Seq{NewLinear().WithStart(start).WithEnd(end).WithStep(1.0)}.Array() 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. // RangeWithStep returns the array values of a linear seq with a given start, end and optional step.
func ValuesWithStep(start, end, step float64) []float64 { func RangeWithStep(start, end, step float64) []float64 {
return Seq{NewLinear().WithStart(start).WithEnd(end).WithStep(step)}.Array() return Seq{NewLinear().WithStart(start).WithEnd(end).WithStep(step)}.Array()
} }
// NewLinear returns a new linear generator. // NewLinear returns a new linear generator.
func NewLinear() *Linear { func NewLinear() *Linear {
return &Linear{} return &Linear{step: 1.0}
} }
// Linear is a stepwise generator. // Linear is a stepwise generator.
@ -22,7 +22,22 @@ type Linear struct {
step float64 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 { func (lg Linear) Len() int {
if lg.start < lg.end { if lg.start < lg.end {
return int((lg.end-lg.start)/lg.step) + 1 return int((lg.end-lg.start)/lg.step) + 1

48
seq/linear_test.go Normal file
View file

@ -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])
}

View file

@ -1,4 +1,4 @@
package sequence package seq
import ( import (
"math" "math"
@ -16,14 +16,14 @@ func RandomValuesWithAverage(average float64, count int) []float64 {
return Seq{NewRandom().WithAverage(average).WithLen(count)}.Array() return Seq{NewRandom().WithAverage(average).WithLen(count)}.Array()
} }
// NewRandom creates a new random sequence. // NewRandom creates a new random seq.
func NewRandom() *Random { func NewRandom() *Random {
return &Random{ return &Random{
rnd: rand.New(rand.NewSource(time.Now().Unix())), 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 { type Random struct {
rnd *rand.Rand rnd *rand.Rand
scale *float64 scale *float64
@ -55,12 +55,22 @@ func (r *Random) WithLen(length int) *Random {
return r return r
} }
// Scale returns the scale.
func (r Random) Scale() *float64 {
return r.scale
}
// WithScale sets the scale and returns the Random. // WithScale sets the scale and returns the Random.
func (r *Random) WithScale(scale float64) *Random { func (r *Random) WithScale(scale float64) *Random {
r.scale = &scale r.scale = &scale
return r return r
} }
// Average returns the average.
func (r Random) Average() *float64 {
return r.average
}
// WithAverage sets the average and returns the Random. // WithAverage sets the average and returns the Random.
func (r *Random) WithAverage(average float64) *Random { func (r *Random) WithAverage(average float64) *Random {
r.average = &average r.average = &average

18
seq/random_test.go Normal file
View file

@ -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)
}

View file

@ -1,27 +1,32 @@
package sequence package seq
import ( import (
"math" "math"
"sort" "sort"
) )
// New returns a new sequence. // New wraps a provider with a seq.
func New(values ...float64) 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)} 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 { type Provider interface {
Len() int Len() int
GetValue(int) float64 GetValue(int) float64
} }
// Seq is a utility wrapper for sequence providers. // Seq is a utility wrapper for seq providers.
type Seq struct { type Seq struct {
Provider Provider
} }
// Array enumerates the sequence into a slice. // Array enumerates the seq into a slice.
func (s Seq) Array() (output []float64) { func (s Seq) Array() (output []float64) {
if s.Len() == 0 { if s.Len() == 0 {
return return
@ -42,7 +47,7 @@ func (s Seq) Each(mapfn func(int, float64)) {
} }
// Map applies the `mapfn` to all values in the value provider, // 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 { func (s Seq) Map(mapfn func(i int, v float64) float64) Seq {
output := make([]float64, s.Len()) output := make([]float64, s.Len())
for i := 0; i < s.Len(); i++ { 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)} 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) { func (s Seq) FoldLeft(mapfn func(i int, v0, v float64) float64) (v0 float64) {
if s.Len() == 0 { if s.Len() == 0 {
return 0 return 0
@ -68,7 +73,7 @@ func (s Seq) FoldLeft(mapfn func(i int, v0, v float64) float64) (v0 float64) {
return 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) { func (s Seq) FoldRight(mapfn func(i int, v0, v float64) float64) (v0 float64) {
if s.Len() == 0 { if s.Len() == 0 {
return 0 return 0
@ -85,7 +90,7 @@ func (s Seq) FoldRight(mapfn func(i int, v0, v float64) float64) (v0 float64) {
return return
} }
// Min returns the minimum value in the sequence. // Min returns the minimum value in the seq.
func (s Seq) Min() float64 { func (s Seq) Min() float64 {
if s.Len() == 0 { if s.Len() == 0 {
return 0 return 0
@ -101,7 +106,7 @@ func (s Seq) Min() float64 {
return min return min
} }
// Max returns the maximum value in the sequence. // Max returns the maximum value in the seq.
func (s Seq) Max() float64 { func (s Seq) Max() float64 {
if s.Len() == 0 { if s.Len() == 0 {
return 0 return 0
@ -137,8 +142,8 @@ func (s Seq) MinMax() (min, max float64) {
return return
} }
// Sort returns the sequence sorted in ascending order. // Sort returns the seq sorted in ascending order.
// This fully enumerates the sequence. // This fully enumerates the seq.
func (s Seq) Sort() Seq { func (s Seq) Sort() Seq {
if s.Len() == 0 { if s.Len() == 0 {
return s return s
@ -148,7 +153,7 @@ func (s Seq) Sort() Seq {
return Seq{Provider: Array(values)} 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) { func (s Seq) Median() (median float64) {
l := s.Len() l := s.Len()
if l == 0 { if l == 0 {

View file

@ -1,4 +1,4 @@
package sequence package seq
import ( import (
"testing" "testing"
@ -85,7 +85,7 @@ func TestSequenceVariance(t *testing.T) {
func TestSequenceNormalize(t *testing.T) { func TestSequenceNormalize(t *testing.T) {
assert := assert.New(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.NotEmpty(normalized)
assert.Len(normalized, 5) assert.Len(normalized, 5)

View file

@ -1,4 +1,4 @@
package sequence package seq
import ( import (
"time" "time"
@ -6,12 +6,12 @@ import (
"github.com/wcharczuk/go-chart/util" "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 var Time timeSequence
type timeSequence struct{} 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 { func (ts timeSequence) Days(days int) []time.Time {
var values []time.Time var values []time.Time
for day := days; day >= 0; day-- { for day := days; day >= 0; day-- {

View file

@ -1,4 +1,4 @@
package sequence package seq
import ( import (
"testing" "testing"

View file

@ -1,4 +1,4 @@
package sequence package seq
import "math" import "math"

View file

@ -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])
}

View file

@ -4,7 +4,7 @@ import (
"testing" "testing"
"github.com/blendlabs/go-assert" "github.com/blendlabs/go-assert"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
"github.com/wcharczuk/go-chart/util" "github.com/wcharczuk/go-chart/util"
) )
@ -33,8 +33,8 @@ func TestSMASeriesGetValue(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
mockSeries := mockValuesProvider{ mockSeries := mockValuesProvider{
sequence.Values(1.0, 10.0), seq.Range(1.0, 10.0),
sequence.Values(10, 1.0), seq.Range(10, 1.0),
} }
assert.Equal(10, mockSeries.Len()) assert.Equal(10, mockSeries.Len())
@ -64,8 +64,8 @@ func TestSMASeriesGetLastValueWindowOverlap(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
mockSeries := mockValuesProvider{ mockSeries := mockValuesProvider{
sequence.Values(1.0, 10.0), seq.Range(1.0, 10.0),
sequence.Values(10, 1.0), seq.Range(10, 1.0),
} }
assert.Equal(10, mockSeries.Len()) assert.Equal(10, mockSeries.Len())
@ -90,8 +90,8 @@ func TestSMASeriesGetLastValue(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
mockSeries := mockValuesProvider{ mockSeries := mockValuesProvider{
sequence.Values(1.0, 100.0), seq.Range(1.0, 100.0),
sequence.Values(100, 1.0), seq.Range(100, 1.0),
} }
assert.Equal(100, mockSeries.Len()) assert.Equal(100, mockSeries.Len())

View file

@ -7,7 +7,7 @@ import (
"math" "math"
"github.com/golang/freetype/truetype" "github.com/golang/freetype/truetype"
"github.com/wcharczuk/go-chart/sequence" "github.com/wcharczuk/go-chart/seq"
util "github.com/wcharczuk/go-chart/util" 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.LineTo(canvasBox.Right+DefaultHorizontalTickWidth, canvasBox.Bottom)
r.Stroke() r.Stroke()
ticks := sequence.ValuesWithStep(0.0, 1.0, 0.2) ticks := seq.RangeWithStep(0.0, 1.0, 0.2)
for _, t := range ticks { for _, t := range ticks {
axisStyle.GetStrokeOptions().WriteToRenderer(r) axisStyle.GetStrokeOptions().WriteToRenderer(r)
ty := canvasBox.Bottom - int(t*float64(canvasBox.Height())) ty := canvasBox.Bottom - int(t*float64(canvasBox.Height()))