test: add test for legend, series and theme
This commit is contained in:
parent
a128a2513c
commit
c289ba7cde
11 changed files with 828 additions and 43 deletions
11
echarts.go
11
echarts.go
|
|
@ -112,12 +112,15 @@ func (ep *EChartsPadding) UnmarshalJSON(data []byte) error {
|
|||
default:
|
||||
result := make([]int, 4)
|
||||
copy(result, arr)
|
||||
if len(arr) == 3 {
|
||||
result[3] = result[1]
|
||||
}
|
||||
// 上右下左
|
||||
ep.box = chart.Box{
|
||||
Top: arr[0],
|
||||
Right: arr[1],
|
||||
Bottom: arr[2],
|
||||
Left: arr[3],
|
||||
Top: result[0],
|
||||
Right: result[1],
|
||||
Bottom: result[2],
|
||||
Left: result[3],
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
381
echarts_test.go
Normal file
381
echarts_test.go
Normal file
|
|
@ -0,0 +1,381 @@
|
|||
// 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 (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/wcharczuk/go-chart/v2"
|
||||
)
|
||||
|
||||
func TestConvertToArray(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
assert.Nil(convertToArray([]byte(" ")))
|
||||
|
||||
assert.Equal([]byte("[{}]"), convertToArray([]byte("{}")))
|
||||
assert.Equal([]byte("[{}]"), convertToArray([]byte("[{}]")))
|
||||
}
|
||||
|
||||
func TestECharsSeriesData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
es := ECharsSeriesData{}
|
||||
err := es.UnmarshalJSON([]byte(" "))
|
||||
assert.Nil(err)
|
||||
assert.Equal(ECharsSeriesData{}, es)
|
||||
|
||||
es = ECharsSeriesData{}
|
||||
err = es.UnmarshalJSON([]byte("12.1"))
|
||||
assert.Nil(err)
|
||||
assert.Equal(ECharsSeriesData{
|
||||
Value: 12.1,
|
||||
}, es)
|
||||
|
||||
es = ECharsSeriesData{}
|
||||
err = es.UnmarshalJSON([]byte(`{
|
||||
"value": 12.1,
|
||||
"name": "test",
|
||||
"itemStyle": {
|
||||
"color": "#333"
|
||||
}
|
||||
}`))
|
||||
assert.Nil(err)
|
||||
assert.Equal(ECharsSeriesData{
|
||||
Value: 12.1,
|
||||
Name: "test",
|
||||
ItemStyle: EChartStyle{
|
||||
Color: "#333",
|
||||
},
|
||||
}, es)
|
||||
}
|
||||
|
||||
func TestEChartsPadding(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
ep := EChartsPadding{}
|
||||
err := ep.UnmarshalJSON([]byte(" "))
|
||||
assert.Nil(err)
|
||||
assert.Equal(EChartsPadding{}, ep)
|
||||
|
||||
ep = EChartsPadding{}
|
||||
err = ep.UnmarshalJSON([]byte("1"))
|
||||
assert.Nil(err)
|
||||
assert.Equal(EChartsPadding{
|
||||
box: chart.Box{
|
||||
Top: 1,
|
||||
Left: 1,
|
||||
Right: 1,
|
||||
Bottom: 1,
|
||||
},
|
||||
}, ep)
|
||||
|
||||
ep = EChartsPadding{}
|
||||
err = ep.UnmarshalJSON([]byte("[1, 2]"))
|
||||
assert.Nil(err)
|
||||
assert.Equal(EChartsPadding{
|
||||
box: chart.Box{
|
||||
Top: 1,
|
||||
Left: 2,
|
||||
Right: 2,
|
||||
Bottom: 1,
|
||||
},
|
||||
}, ep)
|
||||
|
||||
ep = EChartsPadding{}
|
||||
err = ep.UnmarshalJSON([]byte("[1, 2, 3]"))
|
||||
assert.Nil(err)
|
||||
assert.Equal(EChartsPadding{
|
||||
box: chart.Box{
|
||||
Top: 1,
|
||||
Right: 2,
|
||||
Bottom: 3,
|
||||
Left: 2,
|
||||
},
|
||||
}, ep)
|
||||
|
||||
ep = EChartsPadding{}
|
||||
err = ep.UnmarshalJSON([]byte("[1, 2, 3, 4]"))
|
||||
assert.Nil(err)
|
||||
assert.Equal(EChartsPadding{
|
||||
box: chart.Box{
|
||||
Top: 1,
|
||||
Right: 2,
|
||||
Bottom: 3,
|
||||
Left: 4,
|
||||
},
|
||||
}, ep)
|
||||
}
|
||||
|
||||
func TestConvertEChartsSeries(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
seriesList, tickPosition := convertEChartsSeries(&ECharsOptions{})
|
||||
assert.Empty(seriesList)
|
||||
assert.Equal(chart.TickPositionUnset, tickPosition)
|
||||
|
||||
e := ECharsOptions{}
|
||||
err := json.Unmarshal([]byte(`{
|
||||
"title": {
|
||||
"text": "Referer of a Website"
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"name": "Access From",
|
||||
"type": "pie",
|
||||
"radius": "50%",
|
||||
"data": [
|
||||
{
|
||||
"value": 1048,
|
||||
"name": "Search Engine"
|
||||
},
|
||||
{
|
||||
"value": 735,
|
||||
"name": "Direct"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}`), &e)
|
||||
assert.Nil(err)
|
||||
seriesList, tickPosition = convertEChartsSeries(&e)
|
||||
assert.Equal(chart.TickPositionUnset, tickPosition)
|
||||
assert.Equal([]Series{
|
||||
{
|
||||
Data: []SeriesData{
|
||||
{
|
||||
Value: 1048,
|
||||
},
|
||||
},
|
||||
Type: SeriesPie,
|
||||
Name: "Search Engine",
|
||||
},
|
||||
{
|
||||
Data: []SeriesData{
|
||||
{
|
||||
Value: 735,
|
||||
},
|
||||
},
|
||||
Type: SeriesPie,
|
||||
Name: "Direct",
|
||||
},
|
||||
}, seriesList)
|
||||
|
||||
err = json.Unmarshal([]byte(`{
|
||||
"series": [
|
||||
{
|
||||
"name": "Evaporation",
|
||||
"type": "bar",
|
||||
"data": [2, {
|
||||
"value": 4.9,
|
||||
"itemStyle": {
|
||||
"color": "#a90000"
|
||||
}
|
||||
}, 7, 23.2, 25.6, 76.7, 135.6]
|
||||
},
|
||||
{
|
||||
"name": "Precipitation",
|
||||
"type": "bar",
|
||||
"data": [2.6, 5.9, 9, 26.4, 28.7, 70.7, 175.6]
|
||||
},
|
||||
{
|
||||
"name": "Temperature",
|
||||
"type": "line",
|
||||
"yAxisIndex": 1,
|
||||
"data": [2, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3]
|
||||
}
|
||||
]
|
||||
}`), &e)
|
||||
assert.Nil(err)
|
||||
bar1Data := NewSeriesDataListFromFloat([]float64{
|
||||
2, 4.9, 7, 23.2, 25.6, 76.7, 135.6,
|
||||
})
|
||||
bar1Data[1].Style.FillColor = parseColor("#a90000")
|
||||
bar1Data[1].Style.StrokeColor = bar1Data[1].Style.FillColor
|
||||
|
||||
seriesList, tickPosition = convertEChartsSeries(&e)
|
||||
assert.Equal(chart.TickPositionBetweenTicks, tickPosition)
|
||||
assert.Equal([]Series{
|
||||
{
|
||||
Data: bar1Data,
|
||||
Type: SeriesBar,
|
||||
},
|
||||
{
|
||||
Data: NewSeriesDataListFromFloat([]float64{
|
||||
2.6, 5.9, 9, 26.4, 28.7, 70.7, 175.6,
|
||||
}),
|
||||
Type: SeriesBar,
|
||||
},
|
||||
{
|
||||
Data: NewSeriesDataListFromFloat([]float64{
|
||||
2, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3,
|
||||
}),
|
||||
Type: SeriesLine,
|
||||
YAxisIndex: 1,
|
||||
},
|
||||
}, seriesList)
|
||||
|
||||
}
|
||||
|
||||
func TestParseECharsOptions(t *testing.T) {
|
||||
|
||||
assert := assert.New(t)
|
||||
options, err := ParseECharsOptions(`{
|
||||
"theme": "dark",
|
||||
"padding": [5, 10],
|
||||
"title": {
|
||||
"text": "Multi Line",
|
||||
"textAlign": "left",
|
||||
"textStyle": {
|
||||
"color": "#333",
|
||||
"fontSize": 24,
|
||||
"height": 40
|
||||
}
|
||||
},
|
||||
"legend": {
|
||||
"align": "left",
|
||||
"padding": [5, 0, 0, 50],
|
||||
"data": ["Email", "Union Ads", "Video Ads", "Direct", "Search Engine"]
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "category",
|
||||
"data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||||
"splitNumber": 10
|
||||
},
|
||||
"yAxis": [
|
||||
{
|
||||
"min": 0,
|
||||
"max": 250
|
||||
},
|
||||
{
|
||||
"min": 0,
|
||||
"max": 25
|
||||
}
|
||||
],
|
||||
"series": [
|
||||
{
|
||||
"name": "Evaporation",
|
||||
"type": "bar",
|
||||
"data": [2, {
|
||||
"value": 4.9,
|
||||
"itemStyle": {
|
||||
"color": "#a90000"
|
||||
}
|
||||
}, 7, 23.2, 25.6, 76.7, 135.6]
|
||||
},
|
||||
{
|
||||
"name": "Precipitation",
|
||||
"type": "bar",
|
||||
"data": [2.6, 5.9, 9, 26.4, 28.7, 70.7, 175.6]
|
||||
},
|
||||
{
|
||||
"name": "Temperature",
|
||||
"type": "line",
|
||||
"yAxisIndex": 1,
|
||||
"data": [2, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3]
|
||||
}
|
||||
]
|
||||
}`)
|
||||
|
||||
assert.Nil(err)
|
||||
|
||||
min1 := float64(0)
|
||||
max1 := float64(250)
|
||||
min2 := float64(0)
|
||||
max2 := float64(25)
|
||||
|
||||
bar1Data := NewSeriesDataListFromFloat([]float64{
|
||||
2, 4.9, 7, 23.2, 25.6, 76.7, 135.6,
|
||||
})
|
||||
bar1Data[1].Style.FillColor = parseColor("#a90000")
|
||||
bar1Data[1].Style.StrokeColor = bar1Data[1].Style.FillColor
|
||||
|
||||
assert.Equal(Options{
|
||||
Theme: ThemeDark,
|
||||
Padding: chart.Box{
|
||||
Top: 5,
|
||||
Bottom: 5,
|
||||
Left: 10,
|
||||
Right: 10,
|
||||
},
|
||||
Title: Title{
|
||||
Text: "Multi Line",
|
||||
Style: chart.Style{
|
||||
FontColor: parseColor("#333"),
|
||||
FontSize: 24,
|
||||
Padding: chart.Box{
|
||||
Top: 8,
|
||||
Bottom: 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
Legend: Legend{
|
||||
Data: []string{
|
||||
"Email", "Union Ads", "Video Ads", "Direct", "Search Engine",
|
||||
},
|
||||
Align: "left",
|
||||
Padding: chart.Box{
|
||||
Top: 5,
|
||||
Right: 0,
|
||||
Bottom: 0,
|
||||
Left: 50,
|
||||
},
|
||||
},
|
||||
XAxis: XAxis{
|
||||
Data: []string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"},
|
||||
SplitNumber: 10,
|
||||
},
|
||||
TickPosition: chart.TickPositionBetweenTicks,
|
||||
YAxisOptions: []*YAxisOption{
|
||||
{
|
||||
Min: &min1,
|
||||
Max: &max1,
|
||||
},
|
||||
{
|
||||
Min: &min2,
|
||||
Max: &max2,
|
||||
},
|
||||
},
|
||||
Series: []Series{
|
||||
{
|
||||
Data: bar1Data,
|
||||
Type: SeriesBar,
|
||||
},
|
||||
{
|
||||
Data: NewSeriesDataListFromFloat([]float64{
|
||||
2.6, 5.9, 9, 26.4, 28.7, 70.7, 175.6,
|
||||
}),
|
||||
Type: SeriesBar,
|
||||
},
|
||||
{
|
||||
Data: NewSeriesDataListFromFloat([]float64{
|
||||
2, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3,
|
||||
}),
|
||||
Type: SeriesLine,
|
||||
YAxisIndex: 1,
|
||||
},
|
||||
},
|
||||
}, options)
|
||||
}
|
||||
|
|
@ -87,6 +87,7 @@ func LegendCustomize(series []chart.Series, opt LegendOption) chart.Renderable {
|
|||
|
||||
var labels []string
|
||||
var lines []chart.Style
|
||||
// 计算label和lines
|
||||
for _, s := range series {
|
||||
if !s.GetStyle().Hidden {
|
||||
if _, isAnnotationSeries := s.(chart.AnnotationSeries); !isAnnotationSeries {
|
||||
|
|
@ -100,6 +101,7 @@ func LegendCustomize(series []chart.Series, opt LegendOption) chart.Renderable {
|
|||
var textWidth int
|
||||
var textBox chart.Box
|
||||
labelWidth := 0
|
||||
// 计算文本宽度与高度(取最大值)
|
||||
for x := 0; x < len(labels); x++ {
|
||||
if len(labels[x]) > 0 {
|
||||
textBox = r.MeasureText(labels[x])
|
||||
|
|
|
|||
|
|
@ -41,10 +41,26 @@ func TestLegendCustomize(t *testing.T) {
|
|||
Name: "edge",
|
||||
},
|
||||
}, chart.TickPositionBetweenTicks, "")
|
||||
|
||||
tests := []struct {
|
||||
textPosition string
|
||||
svg string
|
||||
}{
|
||||
{
|
||||
textPosition: LegendTextPositionRight,
|
||||
svg: "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"800\" height=\"600\">\\n<path d=\"M 100 100\nL 208 100\nL 208 110\nL 100 110\nL 100 100\" style=\"stroke-width:0;stroke:rgba(51,51,51,1.0);fill:none\"/><path d=\"M 100 107\nL 125 107\" style=\"stroke-width:2;stroke:rgba(84,112,198,1.0);fill:none\"/><circle cx=\"112\" cy=\"107\" r=\"5\" style=\"stroke-width:2;stroke:rgba(84,112,198,1.0);fill:rgba(255,255,255,1.0)\"/><path d=\"\" style=\"stroke-width:2;stroke:rgba(84,112,198,1.0);fill:rgba(255,255,255,1.0)\"/><text x=\"130\" y=\"110\" style=\"stroke-width:0;stroke:none;fill:rgba(51,51,51,1.0);font-size:10.2px;font-family:'Roboto Medium',sans-serif\">chrome</text><path d=\"M 185 107\nL 210 107\" style=\"stroke-width:2;stroke:rgba(145,204,117,1.0);fill:rgba(255,255,255,1.0)\"/><circle cx=\"197\" cy=\"107\" r=\"5\" style=\"stroke-width:2;stroke:rgba(145,204,117,1.0);fill:rgba(255,255,255,1.0)\"/><path d=\"\" style=\"stroke-width:2;stroke:rgba(145,204,117,1.0);fill:rgba(255,255,255,1.0)\"/><text x=\"215\" y=\"110\" style=\"stroke-width:0;stroke:none;fill:rgba(51,51,51,1.0);font-size:10.2px;font-family:'Roboto Medium',sans-serif\">edge</text></svg>",
|
||||
},
|
||||
{
|
||||
textPosition: LegendAlignLeft,
|
||||
svg: "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"800\" height=\"600\">\\n<path d=\"M 100 100\nL 208 100\nL 208 110\nL 100 110\nL 100 100\" style=\"stroke-width:0;stroke:rgba(51,51,51,1.0);fill:none\"/><text x=\"100\" y=\"110\" style=\"stroke-width:0;stroke:none;fill:rgba(51,51,51,1.0);font-size:10.2px;font-family:'Roboto Medium',sans-serif\">chrome</text><path d=\"M 140 107\nL 165 107\" style=\"stroke-width:2;stroke:rgba(84,112,198,1.0);fill:none\"/><circle cx=\"152\" cy=\"107\" r=\"5\" style=\"stroke-width:2;stroke:rgba(84,112,198,1.0);fill:rgba(255,255,255,1.0)\"/><path d=\"\" style=\"stroke-width:2;stroke:rgba(84,112,198,1.0);fill:rgba(255,255,255,1.0)\"/><text x=\"185\" y=\"110\" style=\"stroke-width:0;stroke:none;fill:rgba(51,51,51,1.0);font-size:10.2px;font-family:'Roboto Medium',sans-serif\">edge</text><path d=\"M 213 107\nL 238 107\" style=\"stroke-width:2;stroke:rgba(145,204,117,1.0);fill:rgba(255,255,255,1.0)\"/><circle cx=\"225\" cy=\"107\" r=\"5\" style=\"stroke-width:2;stroke:rgba(145,204,117,1.0);fill:rgba(255,255,255,1.0)\"/><path d=\"\" style=\"stroke-width:2;stroke:rgba(145,204,117,1.0);fill:rgba(255,255,255,1.0)\"/></svg>",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
r, err := chart.SVG(800, 600)
|
||||
assert.Nil(err)
|
||||
fn := LegendCustomize(series, LegendOption{
|
||||
TextPosition: LegendTextPositionRight,
|
||||
TextPosition: tt.textPosition,
|
||||
IconDraw: DefaultLegendIconDraw,
|
||||
Align: LegendAlignLeft,
|
||||
Padding: chart.Box{
|
||||
|
|
@ -58,5 +74,6 @@ func TestLegendCustomize(t *testing.T) {
|
|||
buf := bytes.Buffer{}
|
||||
err = r.Save(&buf)
|
||||
assert.Nil(err)
|
||||
assert.Equal("<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"800\" height=\"600\">\\n<path d=\"M 100 100\nL 208 100\nL 208 110\nL 100 110\nL 100 100\" style=\"stroke-width:0;stroke:rgba(51,51,51,1.0);fill:none\"/><path d=\"M 100 107\nL 125 107\" style=\"stroke-width:2;stroke:rgba(84,112,198,1.0);fill:none\"/><circle cx=\"112\" cy=\"107\" r=\"5\" style=\"stroke-width:2;stroke:rgba(84,112,198,1.0);fill:rgba(255,255,255,1.0)\"/><path d=\"\" style=\"stroke-width:2;stroke:rgba(84,112,198,1.0);fill:rgba(255,255,255,1.0)\"/><text x=\"130\" y=\"110\" style=\"stroke-width:0;stroke:none;fill:rgba(51,51,51,1.0);font-size:10.2px;font-family:'Roboto Medium',sans-serif\">chrome</text><path d=\"M 185 107\nL 210 107\" style=\"stroke-width:2;stroke:rgba(145,204,117,1.0);fill:rgba(255,255,255,1.0)\"/><circle cx=\"197\" cy=\"107\" r=\"5\" style=\"stroke-width:2;stroke:rgba(145,204,117,1.0);fill:rgba(255,255,255,1.0)\"/><path d=\"\" style=\"stroke-width:2;stroke:rgba(145,204,117,1.0);fill:rgba(255,255,255,1.0)\"/><text x=\"215\" y=\"110\" style=\"stroke-width:0;stroke:none;fill:rgba(51,51,51,1.0);font-size:10.2px;font-family:'Roboto Medium',sans-serif\">edge</text></svg>", buf.String())
|
||||
assert.Equal(tt.svg, buf.String())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,11 +30,16 @@ type LineSeries struct {
|
|||
BaseSeries
|
||||
}
|
||||
|
||||
func (bs LineSeries) Render(r chart.Renderer, canvasBox chart.Box, xrange, yrange chart.Range, defaults chart.Style) {
|
||||
style := bs.Style.InheritFrom(defaults)
|
||||
func (ls LineSeries) getXRange(xrange chart.Range) chart.Range {
|
||||
if ls.TickPosition != chart.TickPositionBetweenTicks {
|
||||
return xrange
|
||||
}
|
||||
// 如果是居中,画线时重新调整
|
||||
if bs.TickPosition == chart.TickPositionBetweenTicks {
|
||||
xrange = wrapRange(xrange, bs.TickPosition)
|
||||
return wrapRange(xrange, ls.TickPosition)
|
||||
}
|
||||
chart.Draw.LineSeries(r, canvasBox, xrange, yrange, style, bs)
|
||||
|
||||
func (ls LineSeries) Render(r chart.Renderer, canvasBox chart.Box, xrange, yrange chart.Range, defaults chart.Style) {
|
||||
style := ls.Style.InheritFrom(defaults)
|
||||
xrange = ls.getXRange(xrange)
|
||||
chart.Draw.LineSeries(r, canvasBox, xrange, yrange, style, ls)
|
||||
}
|
||||
|
|
|
|||
46
line_series_test.go
Normal file
46
line_series_test.go
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// 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 (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/wcharczuk/go-chart/v2"
|
||||
)
|
||||
|
||||
func TestLineSeries(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
ls := LineSeries{}
|
||||
|
||||
originalRange := &chart.ContinuousRange{}
|
||||
xrange := ls.getXRange(originalRange)
|
||||
assert.Equal(originalRange, xrange)
|
||||
|
||||
ls.TickPosition = chart.TickPositionBetweenTicks
|
||||
xrange = ls.getXRange(originalRange)
|
||||
value, ok := xrange.(*Range)
|
||||
assert.True(ok)
|
||||
assert.Equal(originalRange, &value.ContinuousRange)
|
||||
}
|
||||
54
range_test.go
Normal file
54
range_test.go
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// 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 (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/wcharczuk/go-chart/v2"
|
||||
)
|
||||
|
||||
func TestRange(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
r := Range{
|
||||
ContinuousRange: chart.ContinuousRange{
|
||||
Min: 0,
|
||||
Max: 5,
|
||||
Domain: 500,
|
||||
},
|
||||
}
|
||||
|
||||
assert.Equal(100, r.Translate(1))
|
||||
|
||||
r.TickPosition = chart.TickPositionBetweenTicks
|
||||
assert.Equal(50, r.Translate(1))
|
||||
}
|
||||
|
||||
func TestHiddenRange(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
r := HiddenRange{}
|
||||
|
||||
assert.Equal(float64(0), r.GetDelta())
|
||||
}
|
||||
|
|
@ -108,7 +108,6 @@ func GetSeries(series []Series, tickPosition chart.TickPosition, theme string) [
|
|||
if item.YAxisIndex != 0 {
|
||||
baseSeries.YAxis = chart.YAxisPrimary
|
||||
}
|
||||
// TODO 判断类型
|
||||
switch item.Type {
|
||||
case SeriesBar:
|
||||
arr[index] = BarSeries{
|
||||
|
|
|
|||
125
series_test.go
Normal file
125
series_test.go
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
// 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 (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/wcharczuk/go-chart/v2"
|
||||
)
|
||||
|
||||
func TestNewSeriesDataListFromFloat(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
assert.Equal([]SeriesData{
|
||||
{
|
||||
Value: 1,
|
||||
},
|
||||
{
|
||||
Value: 2,
|
||||
},
|
||||
}, NewSeriesDataListFromFloat([]float64{
|
||||
1,
|
||||
2,
|
||||
}))
|
||||
}
|
||||
|
||||
func TestGetSeries(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
xValues := []float64{
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
}
|
||||
|
||||
barData := NewSeriesDataListFromFloat([]float64{
|
||||
10,
|
||||
20,
|
||||
30,
|
||||
40,
|
||||
50,
|
||||
})
|
||||
barData[1].Style = chart.Style{
|
||||
FillColor: AxisColorDark,
|
||||
}
|
||||
seriesList := GetSeries([]Series{
|
||||
{
|
||||
Type: SeriesBar,
|
||||
Data: barData,
|
||||
XValues: xValues,
|
||||
YAxisIndex: 1,
|
||||
},
|
||||
{
|
||||
Data: NewSeriesDataListFromFloat([]float64{
|
||||
11,
|
||||
21,
|
||||
31,
|
||||
41,
|
||||
51,
|
||||
}),
|
||||
XValues: xValues,
|
||||
},
|
||||
}, chart.TickPositionBetweenTicks, "")
|
||||
|
||||
assert.Equal(seriesList[0].GetYAxis(), chart.YAxisPrimary)
|
||||
assert.Equal(seriesList[1].GetYAxis(), chart.YAxisSecondary)
|
||||
|
||||
barSeries, ok := seriesList[0].(BarSeries)
|
||||
assert.True(ok)
|
||||
// 居中前置多插入一个点
|
||||
assert.Equal([]float64{
|
||||
0,
|
||||
10,
|
||||
20,
|
||||
30,
|
||||
40,
|
||||
50,
|
||||
}, barSeries.YValues)
|
||||
assert.Equal(xValues, barSeries.XValues)
|
||||
assert.Equal(1, barSeries.Count)
|
||||
assert.Equal(0, barSeries.Index)
|
||||
assert.Equal([]BarSeriesCustomStyle{
|
||||
{
|
||||
PointIndex: 1,
|
||||
Index: 0,
|
||||
Style: barData[1].Style,
|
||||
},
|
||||
}, barSeries.CustomStyles)
|
||||
|
||||
lineSeries, ok := seriesList[1].(LineSeries)
|
||||
assert.True(ok)
|
||||
// 居中前置多插入一个点
|
||||
assert.Equal([]float64{
|
||||
0,
|
||||
11,
|
||||
21,
|
||||
31,
|
||||
41,
|
||||
51,
|
||||
}, lineSeries.YValues)
|
||||
assert.Equal(xValues, lineSeries.XValues)
|
||||
}
|
||||
61
theme.go
61
theme.go
|
|
@ -23,6 +23,8 @@
|
|||
package charts
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/wcharczuk/go-chart/v2"
|
||||
|
|
@ -44,6 +46,20 @@ var AxisColorDark = drawing.Color{
|
|||
A: 255,
|
||||
}
|
||||
|
||||
var GridColorDark = drawing.Color{
|
||||
R: 72,
|
||||
G: 71,
|
||||
B: 83,
|
||||
A: 255,
|
||||
}
|
||||
|
||||
var GridColorLight = drawing.Color{
|
||||
R: 224,
|
||||
G: 230,
|
||||
B: 241,
|
||||
A: 255,
|
||||
}
|
||||
|
||||
var BackgroundColorDark = drawing.Color{
|
||||
R: 16,
|
||||
G: 12,
|
||||
|
|
@ -67,19 +83,9 @@ func getAxisColor(theme string) drawing.Color {
|
|||
|
||||
func getGridColor(theme string) drawing.Color {
|
||||
if theme == ThemeDark {
|
||||
return drawing.Color{
|
||||
R: 72,
|
||||
G: 71,
|
||||
B: 83,
|
||||
A: 255,
|
||||
}
|
||||
}
|
||||
return drawing.Color{
|
||||
R: 224,
|
||||
G: 230,
|
||||
B: 241,
|
||||
A: 255,
|
||||
return GridColorDark
|
||||
}
|
||||
return GridColorLight
|
||||
}
|
||||
|
||||
var SeriesColorsLight = []drawing.Color{
|
||||
|
|
@ -180,12 +186,37 @@ func getSeriesColor(theme string, index int) drawing.Color {
|
|||
}
|
||||
|
||||
func parseColor(color string) drawing.Color {
|
||||
c := drawing.Color{}
|
||||
if color == "" {
|
||||
return drawing.Color{}
|
||||
return c
|
||||
}
|
||||
if strings.HasPrefix(color, "#") {
|
||||
return drawing.ColorFromHex(color[1:])
|
||||
}
|
||||
// TODO rgba
|
||||
return drawing.Color{}
|
||||
reg := regexp.MustCompile(`\((\S+)\)`)
|
||||
result := reg.FindAllStringSubmatch(color, 1)
|
||||
if len(result) == 0 || len(result[0]) != 2 {
|
||||
return c
|
||||
}
|
||||
arr := strings.Split(result[0][1], ",")
|
||||
if len(arr) < 3 {
|
||||
return c
|
||||
}
|
||||
// 设置默认为255
|
||||
c.A = 255
|
||||
for index, v := range arr {
|
||||
value, _ := strconv.Atoi(strings.TrimSpace(v))
|
||||
ui8 := uint8(value)
|
||||
switch index {
|
||||
case 0:
|
||||
c.R = ui8
|
||||
case 1:
|
||||
c.G = ui8
|
||||
case 2:
|
||||
c.B = ui8
|
||||
default:
|
||||
c.A = ui8
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
|
|
|||
122
theme_test.go
Normal file
122
theme_test.go
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
// 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 (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/wcharczuk/go-chart/v2"
|
||||
"github.com/wcharczuk/go-chart/v2/drawing"
|
||||
)
|
||||
|
||||
func TestThemeColors(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
assert.Equal(AxisColorDark, getAxisColor(ThemeDark))
|
||||
assert.Equal(AxisColorLight, getAxisColor(""))
|
||||
|
||||
assert.Equal(GridColorDark, getGridColor(ThemeDark))
|
||||
assert.Equal(GridColorLight, getGridColor(""))
|
||||
|
||||
assert.Equal(BackgroundColorDark, getBackgroundColor(ThemeDark))
|
||||
assert.Equal(chart.DefaultBackgroundColor, getBackgroundColor(""))
|
||||
|
||||
assert.Equal(TextColorDark, getTextColor(ThemeDark))
|
||||
assert.Equal(chart.DefaultTextColor, getTextColor(""))
|
||||
}
|
||||
|
||||
func TestThemeColorPalette(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
dark := ThemeColorPalette{
|
||||
Theme: ThemeDark,
|
||||
}
|
||||
assert.Equal(BackgroundColorDark, dark.BackgroundColor())
|
||||
assert.Equal(chart.DefaultBackgroundStrokeColor, dark.BackgroundStrokeColor())
|
||||
assert.Equal(BackgroundColorDark, dark.CanvasColor())
|
||||
assert.Equal(chart.DefaultCanvasStrokeColor, dark.CanvasStrokeColor())
|
||||
assert.Equal(BackgroundColorDark, dark.AxisStrokeColor())
|
||||
assert.Equal(TextColorDark, dark.TextColor())
|
||||
// series 使用统一的color
|
||||
assert.Equal(SeriesColorsLight[0], dark.GetSeriesColor(0))
|
||||
|
||||
light := ThemeColorPalette{}
|
||||
assert.Equal(chart.DefaultBackgroundColor, light.BackgroundColor())
|
||||
assert.Equal(chart.DefaultBackgroundStrokeColor, light.BackgroundStrokeColor())
|
||||
assert.Equal(chart.DefaultCanvasColor, light.CanvasColor())
|
||||
assert.Equal(chart.DefaultCanvasStrokeColor, light.CanvasStrokeColor())
|
||||
assert.Equal(chart.DefaultAxisColor, light.AxisStrokeColor())
|
||||
assert.Equal(chart.DefaultTextColor, light.TextColor())
|
||||
// series 使用统一的color
|
||||
assert.Equal(SeriesColorsLight[0], light.GetSeriesColor(0))
|
||||
}
|
||||
|
||||
func TestPieThemeColorPalette(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
p := PieThemeColorPalette{}
|
||||
|
||||
// pie无认哪种theme,文本的颜色都一样
|
||||
assert.Equal(chart.DefaultTextColor, p.TextColor())
|
||||
p.Theme = ThemeDark
|
||||
assert.Equal(chart.DefaultTextColor, p.TextColor())
|
||||
}
|
||||
|
||||
func TestParseColor(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
c := parseColor("")
|
||||
assert.True(c.IsZero())
|
||||
|
||||
c = parseColor("#333")
|
||||
assert.Equal(drawing.Color{
|
||||
R: 51,
|
||||
G: 51,
|
||||
B: 51,
|
||||
A: 255,
|
||||
}, c)
|
||||
|
||||
c = parseColor("#313233")
|
||||
assert.Equal(drawing.Color{
|
||||
R: 49,
|
||||
G: 50,
|
||||
B: 51,
|
||||
A: 255,
|
||||
}, c)
|
||||
|
||||
c = parseColor("rgb(31,32,33)")
|
||||
assert.Equal(drawing.Color{
|
||||
R: 31,
|
||||
G: 32,
|
||||
B: 33,
|
||||
A: 255,
|
||||
}, c)
|
||||
|
||||
c = parseColor("rgba(50,51,52,250)")
|
||||
assert.Equal(drawing.Color{
|
||||
R: 50,
|
||||
G: 51,
|
||||
B: 52,
|
||||
A: 250,
|
||||
}, c)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue