diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..4680624 Binary files /dev/null and b/.DS_Store differ diff --git a/_examples/annotations/output.png b/_examples/annotations/output.png index 0643df1..a2e80fa 100644 Binary files a/_examples/annotations/output.png and b/_examples/annotations/output.png differ diff --git a/_examples/axes/output.png b/_examples/axes/output.png index 61c376c..cacd47d 100644 Binary files a/_examples/axes/output.png and b/_examples/axes/output.png differ diff --git a/_examples/axes_labels/output.png b/_examples/axes_labels/output.png index 5f93731..61c376c 100644 Binary files a/_examples/axes_labels/output.png and b/_examples/axes_labels/output.png differ diff --git a/_examples/bar_chart/output.png b/_examples/bar_chart/output.png index ced62f1..59c6c89 100644 Binary files a/_examples/bar_chart/output.png and b/_examples/bar_chart/output.png differ diff --git a/_examples/basic/output.png b/_examples/basic/output.png index fd33373..2c781a7 100644 Binary files a/_examples/basic/output.png and b/_examples/basic/output.png differ diff --git a/_examples/benchmark_line_charts/main.go b/_examples/benchmark_line_charts/main.go index db5c952..09b1b89 100644 --- a/_examples/benchmark_line_charts/main.go +++ b/_examples/benchmark_line_charts/main.go @@ -20,12 +20,18 @@ func drawLargeChart(res http.ResponseWriter, r *http.Request) { if err != nil { numSeriesInt64 = int64(1) } + if numSeriesInt64 == 0 { + numSeriesInt64 = 1 + } numSeries := int(numSeriesInt64) numValuesInt64, err := strconv.ParseInt(r.FormValue("values"), 10, 64) if err != nil { numValuesInt64 = int64(100) } + if numValuesInt64 == 0 { + numValuesInt64 = int64(100) + } numValues := int(numValuesInt64) series := make([]chart.Series, numSeries) diff --git a/_examples/benchmark_line_charts/output.png b/_examples/benchmark_line_charts/output.png new file mode 100644 index 0000000..444c790 Binary files /dev/null and b/_examples/benchmark_line_charts/output.png differ diff --git a/_examples/custom_formatters/output.png b/_examples/custom_formatters/output.png index 65cf531..ced62f1 100644 Binary files a/_examples/custom_formatters/output.png and b/_examples/custom_formatters/output.png differ diff --git a/_examples/custom_padding/main.go b/_examples/custom_padding/main.go index 30194b4..f1a5db5 100644 --- a/_examples/custom_padding/main.go +++ b/_examples/custom_padding/main.go @@ -32,7 +32,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) { Series: []chart.Series{ chart.ContinuousSeries{ XValues: seq.Range(1.0, 100.0), - YValues: seq.New(seq.NewRandom().WithLen(100).WithAverage(256)).Array(), + YValues: seq.RandomValuesWithMax(100, 512), }, }, } @@ -59,7 +59,7 @@ func drawChartDefault(res http.ResponseWriter, req *http.Request) { Series: []chart.Series{ chart.ContinuousSeries{ XValues: seq.Range(1.0, 100.0), - YValues: seq.New(seq.NewRandom().WithLen(100).WithAverage(256)).Array(), + YValues: seq.RandomValuesWithMax(100, 512), }, }, } diff --git a/_examples/custom_padding/output.png b/_examples/custom_padding/output.png index 1e965a0..368e539 100644 Binary files a/_examples/custom_padding/output.png and b/_examples/custom_padding/output.png differ diff --git a/_examples/custom_ticks/output.png b/_examples/custom_ticks/output.png index b8bf634..aefa3c3 100644 Binary files a/_examples/custom_ticks/output.png and b/_examples/custom_ticks/output.png differ diff --git a/_examples/descending/output.png b/_examples/descending/output.png new file mode 100644 index 0000000..a9a00a9 Binary files /dev/null and b/_examples/descending/output.png differ diff --git a/_examples/legend/output.png b/_examples/legend/output.png index 5a18ba7..d5fd6d8 100644 Binary files a/_examples/legend/output.png and b/_examples/legend/output.png differ diff --git a/_examples/linear_regression/main.go b/_examples/linear_regression/main.go index 966b04a..8209f9f 100644 --- a/_examples/linear_regression/main.go +++ b/_examples/linear_regression/main.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/wcharczuk/go-chart" + "github.com/wcharczuk/go-chart/seq" ) func drawChart(res http.ResponseWriter, req *http.Request) { @@ -15,8 +16,8 @@ func drawChart(res http.ResponseWriter, req *http.Request) { mainSeries := chart.ContinuousSeries{ Name: "A test series", - XValues: chart.Sequence.Float64(1.0, 100.0), //generates a []float64 from 1.0 to 100.0 in 1.0 step increments, or 100 elements. - YValues: chart.Sequence.Random(100, 100), //generates a []float64 randomly from 0 to 100 with 100 elements. + XValues: seq.Range(1.0, 100.0), //generates a []float64 from 1.0 to 100.0 in 1.0 step increments, or 100 elements. + YValues: seq.RandomValuesWithAverage(100, 100), //generates a []float64 randomly from 0 to 100 with 100 elements. } // note we create a LinearRegressionSeries series by assignin the inner series. diff --git a/_examples/market_hours/main.go b/_examples/market_hours/main.go index 2dd1b37..d0be1d3 100644 --- a/_examples/market_hours/main.go +++ b/_examples/market_hours/main.go @@ -4,13 +4,15 @@ import ( "net/http" "github.com/wcharczuk/go-chart" + "github.com/wcharczuk/go-chart/seq" + "github.com/wcharczuk/go-chart/util" ) func drawChart(res http.ResponseWriter, req *http.Request) { - start := chart.Date.Date(2016, 7, 01, chart.Date.Eastern()) - end := chart.Date.Date(2016, 07, 21, chart.Date.Eastern()) - xv := chart.Sequence.MarketHours(start, end, chart.NYSEOpen, chart.NYSEClose, chart.Date.IsNYSEHoliday) - yv := chart.Sequence.RandomWithAverage(len(xv), 200, 10) + start := util.Date.Date(2016, 7, 01, util.Date.Eastern()) + end := util.Date.Date(2016, 07, 21, util.Date.Eastern()) + xv := seq.Time.MarketHours(start, end, util.NYSEOpen(), util.NYSEClose(), util.Date.IsNYSEHoliday) + yv := seq.New(seq.NewRandom().WithLen(len(xv)).WithAverage(200).WithScale(10)).Array() graph := chart.Chart{ XAxis: chart.XAxis{ @@ -18,9 +20,9 @@ func drawChart(res http.ResponseWriter, req *http.Request) { TickPosition: chart.TickPositionBetweenTicks, ValueFormatter: chart.TimeHourValueFormatter, Range: &chart.MarketHoursRange{ - MarketOpen: chart.NYSEOpen, - MarketClose: chart.NYSEClose, - HolidayProvider: chart.Date.IsNYSEHoliday, + MarketOpen: util.NYSEOpen(), + MarketClose: util.NYSEClose(), + HolidayProvider: util.Date.IsNYSEHoliday, }, }, YAxis: chart.YAxis{ diff --git a/_examples/min_max/main.go b/_examples/min_max/main.go index 05c1413..d8cc3a0 100644 --- a/_examples/min_max/main.go +++ b/_examples/min_max/main.go @@ -4,13 +4,14 @@ import ( "net/http" "github.com/wcharczuk/go-chart" + "github.com/wcharczuk/go-chart/seq" ) func drawChart(res http.ResponseWriter, req *http.Request) { mainSeries := chart.ContinuousSeries{ Name: "A test series", - XValues: chart.Sequence.Float64(1.0, 100.0), - YValues: chart.Sequence.RandomWithAverage(100, 100, 50), + XValues: seq.Range(1.0, 100.0), + YValues: seq.New(seq.NewRandom().WithLen(100).WithAverage(100).WithScale(50)).Array(), } minSeries := &chart.MinSeries{ diff --git a/_examples/pie_chart/output.png b/_examples/pie_chart/output.png index 1828cbf..c24fc67 100644 Binary files a/_examples/pie_chart/output.png and b/_examples/pie_chart/output.png differ diff --git a/_examples/poly_regression/main.go b/_examples/poly_regression/main.go index e6250ac..9ca6b2b 100644 --- a/_examples/poly_regression/main.go +++ b/_examples/poly_regression/main.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/wcharczuk/go-chart" + "github.com/wcharczuk/go-chart/seq" ) func drawChart(res http.ResponseWriter, req *http.Request) { @@ -15,8 +16,8 @@ func drawChart(res http.ResponseWriter, req *http.Request) { mainSeries := chart.ContinuousSeries{ Name: "A test series", - XValues: chart.Sequence.Float64(1.0, 100.0), //generates a []float64 from 1.0 to 100.0 in 1.0 step increments, or 100 elements. - YValues: chart.Sequence.Random(100, 100), //generates a []float64 randomly from 0 to 100 with 100 elements. + XValues: seq.Range(1.0, 100.0), //generates a []float64 from 1.0 to 100.0 in 1.0 step increments, or 100 elements. + YValues: seq.RandomValuesWithAverage(100, 100), //generates a []float64 randomly from 0 to 100 with 100 elements. } polyRegSeries := &chart.PolynomialRegressionSeries{ diff --git a/_examples/poly_regression/output.png b/_examples/poly_regression/output.png new file mode 100644 index 0000000..ae9b8f6 Binary files /dev/null and b/_examples/poly_regression/output.png differ diff --git a/_examples/request_timings/main.go b/_examples/request_timings/main.go index a521b1c..d5867af 100644 --- a/_examples/request_timings/main.go +++ b/_examples/request_timings/main.go @@ -8,6 +8,7 @@ import ( "time" "github.com/wcharczuk/go-chart" + util "github.com/wcharczuk/go-chart/util" ) func parseInt(str string) int { @@ -23,7 +24,7 @@ func parseFloat64(str string) float64 { func readData() ([]time.Time, []float64) { var xvalues []time.Time var yvalues []float64 - err := chart.File.ReadByLines("requests.csv", func(line string) { + err := util.File.ReadByLines("requests.csv", func(line string) error { parts := strings.Split(line, ",") year := parseInt(parts[0]) month := parseInt(parts[1]) @@ -32,6 +33,7 @@ func readData() ([]time.Time, []float64) { elapsedMillis := parseFloat64(parts[4]) xvalues = append(xvalues, time.Date(year, time.Month(month), day, hour, 0, 0, 0, time.UTC)) yvalues = append(yvalues, elapsedMillis) + return nil }) if err != nil { fmt.Println(err.Error()) @@ -41,12 +43,12 @@ func readData() ([]time.Time, []float64) { func releases() []chart.GridLine { return []chart.GridLine{ - {Value: chart.Time.ToFloat64(time.Date(2016, 8, 1, 9, 30, 0, 0, time.UTC))}, - {Value: chart.Time.ToFloat64(time.Date(2016, 8, 2, 9, 30, 0, 0, time.UTC))}, - {Value: chart.Time.ToFloat64(time.Date(2016, 8, 2, 15, 30, 0, 0, time.UTC))}, - {Value: chart.Time.ToFloat64(time.Date(2016, 8, 4, 9, 30, 0, 0, time.UTC))}, - {Value: chart.Time.ToFloat64(time.Date(2016, 8, 5, 9, 30, 0, 0, time.UTC))}, - {Value: chart.Time.ToFloat64(time.Date(2016, 8, 6, 9, 30, 0, 0, time.UTC))}, + {Value: util.Time.ToFloat64(time.Date(2016, 8, 1, 9, 30, 0, 0, time.UTC))}, + {Value: util.Time.ToFloat64(time.Date(2016, 8, 2, 9, 30, 0, 0, time.UTC))}, + {Value: util.Time.ToFloat64(time.Date(2016, 8, 2, 15, 30, 0, 0, time.UTC))}, + {Value: util.Time.ToFloat64(time.Date(2016, 8, 4, 9, 30, 0, 0, time.UTC))}, + {Value: util.Time.ToFloat64(time.Date(2016, 8, 5, 9, 30, 0, 0, time.UTC))}, + {Value: util.Time.ToFloat64(time.Date(2016, 8, 6, 9, 30, 0, 0, time.UTC))}, } } @@ -125,8 +127,8 @@ func drawChart(res http.ResponseWriter, req *http.Request) { graph.Elements = []chart.Renderable{chart.LegendThin(&graph)} - res.Header().Set("Content-Type", chart.ContentTypeSVG) - graph.Render(chart.SVG, res) + res.Header().Set("Content-Type", chart.ContentTypePNG) + graph.Render(chart.PNG, res) } func main() { diff --git a/_examples/scatter/main.go b/_examples/scatter/main.go index 4347868..6d0560c 100644 --- a/_examples/scatter/main.go +++ b/_examples/scatter/main.go @@ -8,6 +8,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) { @@ -25,8 +26,8 @@ func drawChart(res http.ResponseWriter, req *http.Request) { DotWidth: 5, DotColorProvider: viridisByY, }, - XValues: chart.Sequence.Random(128, 1024), - YValues: chart.Sequence.Random(128, 1024), + XValues: seq.Range(0, 127), + YValues: seq.New(seq.NewRandom().WithLen(128).WithMax(1024)).Array(), }, }, } @@ -50,8 +51,8 @@ func unit(res http.ResponseWriter, req *http.Request) { }, Series: []chart.Series{ chart.ContinuousSeries{ - XValues: chart.Sequence.Float64(0, 4, 1), - YValues: chart.Sequence.Float64(0, 4, 1), + XValues: seq.RangeWithStep(0, 4, 1), + YValues: seq.RangeWithStep(0, 4, 1), }, }, } diff --git a/_examples/scatter/output.png b/_examples/scatter/output.png index 1f16d44..eb920e2 100644 Binary files a/_examples/scatter/output.png and b/_examples/scatter/output.png differ diff --git a/_examples/simple_moving_average/main.go b/_examples/simple_moving_average/main.go index 0334b46..3020b0a 100644 --- a/_examples/simple_moving_average/main.go +++ b/_examples/simple_moving_average/main.go @@ -4,19 +4,15 @@ import ( "net/http" "github.com/wcharczuk/go-chart" + "github.com/wcharczuk/go-chart/seq" ) func drawChart(res http.ResponseWriter, req *http.Request) { - /* - In this example we add a new type of series, a `SimpleMovingAverageSeries` that takes another series as a required argument. - InnerSeries only needs to implement `ValuesProvider`, so really you could chain `SimpleMovingAverageSeries` together if you wanted. - */ - mainSeries := chart.ContinuousSeries{ Name: "A test series", - XValues: chart.Sequence.Float64(1.0, 100.0), //generates a []float64 from 1.0 to 100.0 in 1.0 step increments, or 100 elements. - YValues: chart.Sequence.Random(100, 100), //generates a []float64 randomly from 0 to 100 with 100 elements. + XValues: seq.Range(1.0, 100.0), //generates a []float64 from 1.0 to 100.0 in 1.0 step increments, or 100 elements. + YValues: seq.RandomValuesWithMax(100, 100), //generates a []float64 randomly from 0 to 100 with 100 elements. } // note we create a SimpleMovingAverage series by assignin the inner series. diff --git a/_examples/stacked_bar/output.png b/_examples/stacked_bar/output.png index 4b0e9ae..c503c7b 100644 Binary files a/_examples/stacked_bar/output.png and b/_examples/stacked_bar/output.png differ diff --git a/_examples/text_rotation/output.png b/_examples/text_rotation/output.png new file mode 100644 index 0000000..aac3a1d Binary files /dev/null and b/_examples/text_rotation/output.png differ diff --git a/_examples/timeseries/output.png b/_examples/timeseries/output.png index 3063111..ede73e0 100644 Binary files a/_examples/timeseries/output.png and b/_examples/timeseries/output.png differ diff --git a/_examples/twoaxis/output.png b/_examples/twoaxis/output.png index c86bfb8..8b6b029 100644 Binary files a/_examples/twoaxis/output.png and b/_examples/twoaxis/output.png differ diff --git a/_examples/twopoint/main.go b/_examples/twopoint/main.go index d703431..d51d37e 100644 --- a/_examples/twopoint/main.go +++ b/_examples/twopoint/main.go @@ -4,8 +4,8 @@ import ( "bytes" "log" "os" - //"time" - "github.com/wcharczuk/go-chart" //exposes "chart" + + "github.com/wcharczuk/go-chart" ) func main() { @@ -18,8 +18,6 @@ func main() { Style: chart.Style{ Show: true, }, - - //XValues: []time.Time{time.Unix(3*b,0),time.Unix(4*b,0),time.Unix(5*b,0),time.Unix(6*b,0),time.Unix(7*b,0),time.Unix(8*b,0),time.Unix(9*b,0),time.Unix(10*b,0)}, XValues: []float64{10 * b, 20 * b, 30 * b, 40 * b, 50 * b, 60 * b, 70 * b, 80 * b}, YValues: []float64{1.0, 2.0, 30.0, 4.0, 50.0, 6.0, 7.0, 88.0}, } diff --git a/bollinger_band_series_test.go b/bollinger_band_series_test.go index 8801220..9ef75fe 100644 --- a/bollinger_band_series_test.go +++ b/bollinger_band_series_test.go @@ -14,7 +14,7 @@ func TestBollingerBandSeries(t *testing.T) { s1 := mockValuesProvider{ X: seq.Range(1.0, 100.0), - Y: seq.RandomValuesWithAverage(1024, 100), + Y: seq.RandomValuesWithMax(100, 1024), } bbs := &BollingerBandsSeries{ diff --git a/seq/random.go b/seq/random.go index 72fc8ef..3d0768f 100644 --- a/seq/random.go +++ b/seq/random.go @@ -12,8 +12,8 @@ func RandomValues(count int) []float64 { } // RandomValuesWithAverage returns an array of random values with a given average. -func RandomValuesWithAverage(average float64, count int) []float64 { - return Seq{NewRandom().WithAverage(average).WithLen(count)}.Array() +func RandomValuesWithMax(count int, max float64) []float64 { + return Seq{NewRandom().WithMax(max).WithLen(count)}.Array() } // NewRandom creates a new random seq. @@ -25,10 +25,10 @@ func NewRandom() *Random { // Random is a random number seq generator. type Random struct { - rnd *rand.Rand - scale *float64 - average *float64 - len *int + rnd *rand.Rand + max *float64 + min *float64 + len *int } // Len returns the number of elements that will be generated. @@ -41,10 +41,20 @@ func (r *Random) Len() int { // GetValue returns the value. func (r *Random) GetValue(_ int) float64 { - if r.average != nil && r.scale != nil { - return *r.average + *r.scale - (r.rnd.Float64() * (2 * *r.scale)) - } else if r.scale != nil { - return r.rnd.Float64() * *r.scale + if r.min != nil && r.max != nil { + var delta float64 + + if *r.max > *r.min { + delta = *r.max - *r.min + } else { + delta = *r.min - *r.max + } + + return *r.min + (r.rnd.Float64() * delta) + } else if r.max != nil { + return r.rnd.Float64() * *r.max + } else if r.min != nil { + return *r.min + (r.rnd.Float64()) } return r.rnd.Float64() } @@ -55,24 +65,24 @@ func (r *Random) WithLen(length int) *Random { return r } -// Scale returns the scale. -func (r Random) Scale() *float64 { - return r.scale +// Min returns the minimum value. +func (r Random) Min() *float64 { + return r.min } -// WithScale sets the scale and returns the Random. -func (r *Random) WithScale(scale float64) *Random { - r.scale = &scale +// WithMin sets the scale and returns the Random. +func (r *Random) WithMin(min float64) *Random { + r.min = &min return r } -// Average returns the average. -func (r Random) Average() *float64 { - return r.average +// Max returns the maximum value. +func (r Random) Max() *float64 { + return r.max } -// WithAverage sets the average and returns the Random. -func (r *Random) WithAverage(average float64) *Random { - r.average = &average +// WithMax sets the average and returns the Random. +func (r *Random) WithMax(max float64) *Random { + r.max = &max return r } diff --git a/seq/random_test.go b/seq/random_test.go index 30261c0..2176909 100644 --- a/seq/random_test.go +++ b/seq/random_test.go @@ -9,10 +9,12 @@ import ( 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()) + randomProvider := NewRandom().WithLen(4096).WithMax(256) + assert.Equal(4096, randomProvider.Len()) + assert.Equal(256, *randomProvider.Max()) - randomValues := New(randomProvider).Array() - assert.Len(randomValues, 100) + randomSequence := New(randomProvider) + randomValues := randomSequence.Array() + assert.Len(randomValues, 4096) + assert.InDelta(128, randomSequence.Average(), 10.0) }