// MIT License
// Copyright (c) 2022 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"
)
func TestPieChart(t *testing.T) {
assert := assert.New(t)
tests := []struct {
render func(*Painter) ([]byte, error)
result string
}{
{
render: func(p *Painter) ([]byte, error) {
values := []float64{
1048,
735,
580,
484,
300,
}
_, err := NewPieChart(p, PieChartOption{
SeriesList: NewPieSeriesList(values, PieSeriesOption{
Label: SeriesLabel{
Show: true,
},
}),
Title: TitleOption{
Text: "Rainfall vs Evaporation",
Subtext: "Fake Data",
Left: PositionCenter,
},
Padding: Box{
Top: 20,
Right: 20,
Bottom: 20,
Left: 20,
},
Legend: LegendOption{
Orient: OrientVertical,
Data: []string{
"Search Engine",
"Direct",
"Email",
"Union Ads",
"Video Ads",
},
Left: PositionLeft,
},
}).Render()
if err != nil {
return nil, err
}
return p.Bytes()
},
result: "",
},
}
for _, tt := range tests {
p, err := NewPainter(PainterOptions{
Type: ChartOutputSVG,
Width: 600,
Height: 400,
}, PainterThemeOption(defaultTheme))
assert.Nil(err)
data, err := tt.render(p.Child(PainterPaddingOption(Box{
Left: 20,
Top: 20,
Right: 20,
Bottom: 20,
})))
assert.Nil(err)
assert.Equal(tt.result, string(data))
}
}
func TestPieChartWithLabelsValuesSortedDescending(t *testing.T) {
assert := assert.New(t)
tests := []struct {
render func(*Painter) ([]byte, error)
result string
}{
{
render: func(p *Painter) ([]byte, error) {
values := []float64{
84358845,
68070697,
58850717,
48059777,
36753736,
19051562,
17947406,
11754004,
10827529,
10521556,
10467366,
10394055,
9597085,
9104772,
6447710,
5932654,
5563970,
5428792,
5194336,
3850894,
2857279,
2116792,
1883008,
1373101,
920701,
660809,
542051,
}
_, err := NewPieChart(p, PieChartOption{
SeriesList: NewPieSeriesList(values, PieSeriesOption{
Label: SeriesLabel{
Show: true,
Formatter: "{b} ({c} ≅ {d})",
},
Radius: "200",
}),
Title: TitleOption{
Text: "European Union member states by population",
Left: PositionRight,
},
Padding: Box{
Top: 20,
Right: 20,
Bottom: 20,
Left: 20,
},
Legend: LegendOption{
Data: []string{
"Germany",
"France",
"Italy",
"Spain",
"Poland",
"Romania",
"Netherlands",
"Belgium",
"Czech Republic",
"Sweden",
"Portugal",
"Greece",
"Hungary",
"Austria",
"Bulgaria",
"Denmark",
"Finland",
"Slovakia",
"Ireland",
"Croatia",
"Lithuania",
"Slovenia",
"Latvia",
"Estonia",
"Cyprus",
"Luxembourg",
"Malta",
},
Show: FalseFlag(),
},
}).Render()
if err != nil {
return nil, err
}
return p.Bytes()
},
result: "",
},
}
for _, tt := range tests {
p, err := NewPainter(PainterOptions{
Type: ChartOutputSVG,
Width: 1000,
Height: 800,
}, PainterThemeOption(defaultTheme))
assert.Nil(err)
data, err := tt.render(p.Child(PainterPaddingOption(Box{
Left: 20,
Top: 20,
Right: 20,
Bottom: 20,
})))
assert.Nil(err)
assert.Equal(tt.result, string(data))
}
}
func TestPieChartWithLabelsValuesUnsorted(t *testing.T) {
assert := assert.New(t)
tests := []struct {
render func(*Painter) ([]byte, error)
result string
}{
{
render: func(p *Painter) ([]byte, error) {
values := []float64{
9104772,
11754004,
6447710,
3850894,
920701,
10827529,
5932654,
1373101,
5563970,
68070697,
84358845,
10394055,
9597085,
5194336,
58850717,
1883008,
2857279,
660809,
542051,
17947406,
36753736,
10467366,
19051562,
5428792,
2116792,
48059777,
10521556,
}
_, err := NewPieChart(p, PieChartOption{
SeriesList: NewPieSeriesList(values, PieSeriesOption{
Label: SeriesLabel{
Show: true,
Formatter: "{b} ({c} ≅ {d})",
},
Radius: "200",
}),
Title: TitleOption{
Text: "European Union member states by population",
Left: PositionRight,
},
Padding: Box{
Top: 20,
Right: 20,
Bottom: 20,
Left: 20,
},
Legend: LegendOption{
Data: []string{
"Austria",
"Belgium",
"Bulgaria",
"Croatia",
"Cyprus",
"Czech Republic",
"Denmark",
"Estonia",
"Finland",
"France",
"Germany",
"Greece",
"Hungary",
"Ireland",
"Italy",
"Latvia",
"Lithuania",
"Luxembourg",
"Malta",
"Netherlands",
"Poland",
"Portugal",
"Romania",
"Slovakia",
"Slovenia",
"Spain",
"Sweden",
},
Show: FalseFlag(),
},
}).Render()
if err != nil {
return nil, err
}
return p.Bytes()
},
result: "",
},
}
for _, tt := range tests {
p, err := NewPainter(PainterOptions{
Type: ChartOutputSVG,
Width: 1000,
Height: 800,
}, PainterThemeOption(defaultTheme))
assert.Nil(err)
data, err := tt.render(p.Child(PainterPaddingOption(Box{
Left: 20,
Top: 20,
Right: 20,
Bottom: 20,
})))
assert.Nil(err)
assert.Equal(tt.result, string(data))
}
}
func TestPieChartWith100Labels(t *testing.T) {
assert := assert.New(t)
tests := []struct {
render func(*Painter) ([]byte, error)
result string
}{
{
render: func(p *Painter) ([]byte, error) {
var values []float64
var labels []string
for i := 1; i <= 100; i++ {
values = append(values, float64(1))
labels = append(labels, "Label "+strconv.Itoa(i))
}
_, err := NewPieChart(p, PieChartOption{
SeriesList: NewPieSeriesList(values, PieSeriesOption{
Label: SeriesLabel{
Show: true,
},
Radius: "200",
}),
Title: TitleOption{
Text: "Test with 100 labels",
Left: PositionRight,
},
Padding: Box{
Top: 20,
Right: 20,
Bottom: 20,
Left: 20,
},
Legend: LegendOption{
Data: labels,
Show: FalseFlag(),
},
}).Render()
if err != nil {
return nil, err
}
return p.Bytes()
},
result: "",
},
}
for _, tt := range tests {
p, err := NewPainter(PainterOptions{
Type: ChartOutputSVG,
Width: 1000,
Height: 900,
}, PainterThemeOption(defaultTheme))
assert.Nil(err)
data, err := tt.render(p.Child(PainterPaddingOption(Box{
Left: 20,
Top: 20,
Right: 20,
Bottom: 20,
})))
assert.Nil(err)
assert.Equal(tt.result, string(data))
}
}
func TestPieChartFixLabelPos72586(t *testing.T) {
assert := assert.New(t)
tests := []struct {
render func(*Painter) ([]byte, error)
result string
}{
{
render: func(p *Painter) ([]byte, error) {
values := []float64{
397594,
185596,
149086,
144258,
120194,
117514,
99412,
91135,
87282,
76790,
72586,
58818,
58270,
56306,
55486,
54792,
53746,
51460,
41242,
39476,
37414,
36644,
33784,
32788,
32566,
29608,
29558,
29384,
28166,
26998,
26948,
26054,
25804,
25730,
24438,
23782,
22896,
21404,
428978,
}
_, err := NewPieChart(p, PieChartOption{
SeriesList: NewPieSeriesList(values, PieSeriesOption{
Label: SeriesLabel{
Show: true,
Formatter: "{b} ({c} ≅ {d})",
},
Radius: "150",
}),
Title: TitleOption{
Text: "Fix label K (72586)",
Left: PositionRight,
},
Padding: Box{
Top: 20,
Right: 20,
Bottom: 20,
Left: 20,
},
Legend: LegendOption{
Data: []string{
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"AA",
"AB",
"AC",
"AD",
"AE",
"AF",
"AG",
"AH",
"AI",
"AJ",
"AK",
"AL",
"AM",
},
Show: FalseFlag(),
},
}).Render()
if err != nil {
return nil, err
}
return p.Bytes()
},
result: "",
},
}
for _, tt := range tests {
p, err := NewPainter(PainterOptions{
Type: ChartOutputSVG,
Width: 1150,
Height: 550,
}, PainterThemeOption(defaultTheme))
assert.Nil(err)
data, err := tt.render(p.Child(PainterPaddingOption(Box{
Left: 20,
Top: 20,
Right: 20,
Bottom: 20,
})))
assert.Nil(err)
assert.Equal(tt.result, string(data))
}
}