test: add test for axis
This commit is contained in:
parent
9db6bcab1b
commit
bf25dad141
7 changed files with 226 additions and 13 deletions
20
Makefile
Normal file
20
Makefile
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
export GO111MODULE = on
|
||||||
|
|
||||||
|
.PHONY: default test test-cover dev hooks
|
||||||
|
|
||||||
|
|
||||||
|
# for test
|
||||||
|
test:
|
||||||
|
go test -race -cover ./...
|
||||||
|
|
||||||
|
test-cover:
|
||||||
|
go test -race -coverprofile=test.out ./... && go tool cover --html=test.out
|
||||||
|
|
||||||
|
bench:
|
||||||
|
go test --benchmem -bench=. ./...
|
||||||
|
|
||||||
|
lint:
|
||||||
|
golangci-lint run
|
||||||
|
|
||||||
|
hooks:
|
||||||
|
cp hooks/* .git/hooks/
|
||||||
29
axis.go
29
axis.go
|
|
@ -30,25 +30,27 @@ import (
|
||||||
type (
|
type (
|
||||||
// AxisData string
|
// AxisData string
|
||||||
XAxis struct {
|
XAxis struct {
|
||||||
// 'value' 数值轴,适用于连续数据。
|
// data value of axis
|
||||||
// 'category' 类目轴,适用于离散的类目数据。为该类型时类目数据可自动从 series.data 或 dataset.source 中取,或者可通过 xAxis.data 设置类目数据。
|
Data []string
|
||||||
// 'time' 时间轴,适用于连续的时序数据,与数值轴相比时间轴带有时间的格式化,在刻度计算上也有所不同,例如会根据跨度的范围来决定使用月,星期,日还是小时范围的刻度。
|
// number of segments
|
||||||
// 'log' 对数轴。适用于对数数据。
|
|
||||||
Type string
|
|
||||||
Data []string
|
|
||||||
SplitNumber int
|
SplitNumber int
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type YAxisOption struct {
|
type YAxisOption struct {
|
||||||
|
// formater of axis
|
||||||
Formater chart.ValueFormatter
|
Formater chart.ValueFormatter
|
||||||
|
// disabled axis
|
||||||
Disabled bool
|
Disabled bool
|
||||||
Min *float64
|
// min value of axis
|
||||||
Max *float64
|
Min *float64
|
||||||
|
// max value of axis
|
||||||
|
Max *float64
|
||||||
}
|
}
|
||||||
|
|
||||||
const axisStrokeWidth = 1
|
const axisStrokeWidth = 1
|
||||||
|
|
||||||
|
// GetXAxisAndValues returns x axis by theme, and the values of axis.
|
||||||
func GetXAxisAndValues(xAxis XAxis, tickPosition chart.TickPosition, theme string) (chart.XAxis, []float64) {
|
func GetXAxisAndValues(xAxis XAxis, tickPosition chart.TickPosition, theme string) (chart.XAxis, []float64) {
|
||||||
data := xAxis.Data
|
data := xAxis.Data
|
||||||
originalSize := len(data)
|
originalSize := len(data)
|
||||||
|
|
@ -75,6 +77,7 @@ func GetXAxisAndValues(xAxis XAxis, tickPosition chart.TickPosition, theme strin
|
||||||
minUnitSize++
|
minUnitSize++
|
||||||
}
|
}
|
||||||
unitSize := minUnitSize
|
unitSize := minUnitSize
|
||||||
|
// 尽可能选择一格展示更多的块
|
||||||
for i := minUnitSize; i < 2*minUnitSize; i++ {
|
for i := minUnitSize; i < 2*minUnitSize; i++ {
|
||||||
if originalSize%i == 0 {
|
if originalSize%i == 0 {
|
||||||
unitSize = i
|
unitSize = i
|
||||||
|
|
@ -107,12 +110,14 @@ func defaultFloatFormater(v interface{}) string {
|
||||||
if !ok {
|
if !ok {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
// 大于10的则直接取整展示
|
||||||
if value >= 10 {
|
if value >= 10 {
|
||||||
return humanize.CommafWithDigits(value, 0)
|
return humanize.CommafWithDigits(value, 0)
|
||||||
}
|
}
|
||||||
return humanize.CommafWithDigits(value, 2)
|
return humanize.CommafWithDigits(value, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSecondaryYAxis returns the secondary y axis by theme
|
||||||
func GetSecondaryYAxis(theme string, option *YAxisOption) chart.YAxis {
|
func GetSecondaryYAxis(theme string, option *YAxisOption) chart.YAxis {
|
||||||
strokeColor := getGridColor(theme)
|
strokeColor := getGridColor(theme)
|
||||||
yAxis := chart.YAxis{
|
yAxis := chart.YAxis{
|
||||||
|
|
@ -134,11 +139,11 @@ func GetSecondaryYAxis(theme string, option *YAxisOption) chart.YAxis {
|
||||||
StrokeWidth: axisStrokeWidth,
|
StrokeWidth: axisStrokeWidth,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
setYAxis(&yAxis, option)
|
setYAxisOption(&yAxis, option)
|
||||||
return yAxis
|
return yAxis
|
||||||
}
|
}
|
||||||
|
|
||||||
func setYAxis(yAxis *chart.YAxis, option *YAxisOption) {
|
func setYAxisOption(yAxis *chart.YAxis, option *YAxisOption) {
|
||||||
if option == nil {
|
if option == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -153,6 +158,7 @@ func setYAxis(yAxis *chart.YAxis, option *YAxisOption) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetYAxis returns the primary y axis by theme
|
||||||
func GetYAxis(theme string, option *YAxisOption) chart.YAxis {
|
func GetYAxis(theme string, option *YAxisOption) chart.YAxis {
|
||||||
disabled := false
|
disabled := false
|
||||||
if option != nil {
|
if option != nil {
|
||||||
|
|
@ -173,10 +179,11 @@ func GetYAxis(theme string, option *YAxisOption) chart.YAxis {
|
||||||
StrokeWidth: axisStrokeWidth,
|
StrokeWidth: axisStrokeWidth,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
// 如果禁用,则默认为隐藏,并设置range
|
||||||
if disabled {
|
if disabled {
|
||||||
yAxis.Range = &HiddenRange{}
|
yAxis.Range = &HiddenRange{}
|
||||||
yAxis.Style.Hidden = true
|
yAxis.Style.Hidden = true
|
||||||
}
|
}
|
||||||
setYAxis(&yAxis, option)
|
setYAxisOption(&yAxis, option)
|
||||||
return yAxis
|
return yAxis
|
||||||
}
|
}
|
||||||
|
|
|
||||||
172
axis_test.go
Normal file
172
axis_test.go
Normal file
|
|
@ -0,0 +1,172 @@
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
// Copyright (c) 2021 Tree Xie
|
||||||
|
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package charts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/wcharczuk/go-chart/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetXAxisAndValues(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
genLabels := func(count int) []string {
|
||||||
|
arr := make([]string, count)
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
arr[i] = strconv.Itoa(i)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
genValues := func(count int, betweenTicks bool) []float64 {
|
||||||
|
if betweenTicks {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
arr := make([]float64, count)
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
arr[i] = float64(i)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
genTicks := func(count int, betweenTicks bool) []chart.Tick {
|
||||||
|
arr := make([]chart.Tick, 0)
|
||||||
|
offset := 0
|
||||||
|
if betweenTicks {
|
||||||
|
offset = 1
|
||||||
|
arr = append(arr, chart.Tick{})
|
||||||
|
}
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
arr = append(arr, chart.Tick{
|
||||||
|
Value: float64(i + offset),
|
||||||
|
Label: strconv.Itoa(i),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
xAxis XAxis
|
||||||
|
tickPosition chart.TickPosition
|
||||||
|
theme string
|
||||||
|
result chart.XAxis
|
||||||
|
values []float64
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
xAxis: XAxis{
|
||||||
|
Data: genLabels(5),
|
||||||
|
},
|
||||||
|
values: genValues(5, false),
|
||||||
|
result: chart.XAxis{
|
||||||
|
Ticks: genTicks(5, false),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 居中
|
||||||
|
{
|
||||||
|
xAxis: XAxis{
|
||||||
|
Data: genLabels(5),
|
||||||
|
},
|
||||||
|
tickPosition: chart.TickPositionBetweenTicks,
|
||||||
|
// 居中因此value多一个
|
||||||
|
values: genValues(5, true),
|
||||||
|
result: chart.XAxis{
|
||||||
|
Ticks: genTicks(5, true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xAxis: XAxis{
|
||||||
|
Data: genLabels(20),
|
||||||
|
},
|
||||||
|
// 居中因此value多一个
|
||||||
|
values: genValues(20, false),
|
||||||
|
result: chart.XAxis{
|
||||||
|
Ticks: []chart.Tick{
|
||||||
|
{Value: 0, Label: "0"}, {Value: 2, Label: "2"}, {Value: 4, Label: "4"}, {Value: 6, Label: "6"}, {Value: 8, Label: "8"}, {Value: 10, Label: "10"}, {Value: 12, Label: "12"}, {Value: 14, Label: "14"}, {Value: 16, Label: "16"}, {Value: 18, Label: "18"}, {Value: 19, Label: "19"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
xAxis, values := GetXAxisAndValues(tt.xAxis, tt.tickPosition, tt.theme)
|
||||||
|
|
||||||
|
assert.Equal(tt.result.Ticks, xAxis.Ticks)
|
||||||
|
assert.Equal(tt.tickPosition, xAxis.TickPosition)
|
||||||
|
assert.Equal(tt.values, values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDefaultFloatFormater(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
assert.Equal("", defaultFloatFormater(1))
|
||||||
|
|
||||||
|
assert.Equal("0.1", defaultFloatFormater(0.1))
|
||||||
|
assert.Equal("0.12", defaultFloatFormater(0.123))
|
||||||
|
assert.Equal("10", defaultFloatFormater(10.1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetYAxisOption(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
min := 10.0
|
||||||
|
max := 20.0
|
||||||
|
opt := &YAxisOption{
|
||||||
|
Formater: func(v interface{}) string {
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
Min: &min,
|
||||||
|
Max: &max,
|
||||||
|
}
|
||||||
|
yAxis := &chart.YAxis{
|
||||||
|
Range: &chart.ContinuousRange{},
|
||||||
|
}
|
||||||
|
setYAxisOption(yAxis, opt)
|
||||||
|
|
||||||
|
assert.NotEmpty(yAxis.ValueFormatter)
|
||||||
|
assert.Equal(max, yAxis.Range.GetMax())
|
||||||
|
assert.Equal(min, yAxis.Range.GetMin())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetYAxis(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
yAxis := GetYAxis(ThemeDark, nil)
|
||||||
|
|
||||||
|
assert.True(yAxis.GridMajorStyle.Hidden)
|
||||||
|
assert.True(yAxis.GridMajorStyle.Hidden)
|
||||||
|
assert.False(yAxis.Style.Hidden)
|
||||||
|
|
||||||
|
yAxis = GetYAxis(ThemeDark, &YAxisOption{
|
||||||
|
Disabled: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.True(yAxis.GridMajorStyle.Hidden)
|
||||||
|
assert.True(yAxis.GridMajorStyle.Hidden)
|
||||||
|
assert.True(yAxis.Style.Hidden)
|
||||||
|
|
||||||
|
// secondary yAxis
|
||||||
|
yAxis = GetSecondaryYAxis(ThemeDark, nil)
|
||||||
|
assert.False(yAxis.GridMajorStyle.Hidden)
|
||||||
|
assert.False(yAxis.GridMajorStyle.Hidden)
|
||||||
|
assert.True(yAxis.Style.StrokeColor.IsZero())
|
||||||
|
}
|
||||||
|
|
@ -262,7 +262,6 @@ func (e *ECharsOptions) ToOptions() Options {
|
||||||
if len(e.XAxis.Data) != 0 {
|
if len(e.XAxis.Data) != 0 {
|
||||||
xAxis := e.XAxis.Data[0]
|
xAxis := e.XAxis.Data[0]
|
||||||
o.XAxis = XAxis{
|
o.XAxis = XAxis{
|
||||||
Type: xAxis.Type,
|
|
||||||
Data: xAxis.Data,
|
Data: xAxis.Data,
|
||||||
SplitNumber: xAxis.SplitNumber,
|
SplitNumber: xAxis.SplitNumber,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
go.mod
4
go.mod
|
|
@ -4,10 +4,14 @@ go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/dustin/go-humanize v1.0.0
|
github.com/dustin/go-humanize v1.0.0
|
||||||
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/wcharczuk/go-chart/v2 v2.1.0
|
github.com/wcharczuk/go-chart/v2 v2.1.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect
|
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
11
go.sum
11
go.sum
|
|
@ -1,9 +1,20 @@
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
|
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
|
||||||
github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA=
|
github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA=
|
||||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
|
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
|
||||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
|
||||||
2
theme.go
2
theme.go
|
|
@ -29,7 +29,7 @@ import (
|
||||||
"github.com/wcharczuk/go-chart/v2/drawing"
|
"github.com/wcharczuk/go-chart/v2/drawing"
|
||||||
)
|
)
|
||||||
|
|
||||||
var hiddenColor = drawing.Color{R: 110, G: 112, B: 121, A: 0}
|
var hiddenColor = drawing.Color{R: 0, G: 0, B: 0, A: 0}
|
||||||
|
|
||||||
var AxisColorLight = drawing.Color{
|
var AxisColorLight = drawing.Color{
|
||||||
R: 110,
|
R: 110,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue