diff --git a/chart_option.go b/chart_option.go
index 643c4e7..db2f57b 100644
--- a/chart_option.go
+++ b/chart_option.go
@@ -201,17 +201,7 @@ func ChildOptionFunc(child ...ChartOption) OptionFunc {
// RadarIndicatorOptionFunc set radar indicator of chart
func RadarIndicatorOptionFunc(names []string, values []float64) OptionFunc {
return func(opt *ChartOption) {
- if len(names) != len(values) {
- return
- }
- indicators := make([]RadarIndicator, len(names))
- for index, name := range names {
- indicators[index] = RadarIndicator{
- Name: name,
- Max: values[index],
- }
- }
- opt.RadarIndicators = indicators
+ opt.RadarIndicators = NewRadarIndicators(names, values)
}
}
diff --git a/echarts_test.go b/echarts_test.go
new file mode 100644
index 0000000..1ed14d3
--- /dev/null
+++ b/echarts_test.go
@@ -0,0 +1,263 @@
+// 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 (
+ "encoding/json"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestConvertToArray(t *testing.T) {
+ assert := assert.New(t)
+
+ assert.Equal([]byte(`[1]`), convertToArray([]byte("1")))
+ assert.Equal([]byte(`[1]`), convertToArray([]byte("[1]")))
+}
+
+func TestEChartsPosition(t *testing.T) {
+ assert := assert.New(t)
+ var p EChartsPosition
+ err := p.UnmarshalJSON([]byte("1"))
+ assert.Nil(err)
+ assert.Equal(EChartsPosition("1"), p)
+ err = p.UnmarshalJSON([]byte(`"left"`))
+ assert.Nil(err)
+ assert.Equal(EChartsPosition("left"), p)
+}
+
+func TestEChartsSeriesDataValue(t *testing.T) {
+ assert := assert.New(t)
+
+ es := EChartsSeriesDataValue{}
+ err := es.UnmarshalJSON([]byte(`[1, 2]`))
+ assert.Nil(err)
+ assert.Equal(EChartsSeriesDataValue{
+ values: []float64{
+ 1,
+ 2,
+ },
+ }, es)
+ assert.Equal(1.0, es.First())
+}
+
+func TestEChartsSeriesData(t *testing.T) {
+ assert := assert.New(t)
+ es := EChartsSeriesData{}
+ err := es.UnmarshalJSON([]byte("1.1"))
+ assert.Nil(err)
+ assert.Equal(EChartsSeriesDataValue{
+ values: []float64{
+ 1.1,
+ },
+ }, es.Value)
+
+ err = es.UnmarshalJSON([]byte(`{"value":200,"itemStyle":{"color":"#a90000"}}`))
+ assert.Nil(err)
+ assert.Nil(err)
+ assert.Equal(EChartsSeriesData{
+ Value: EChartsSeriesDataValue{
+ values: []float64{
+ 200.0,
+ },
+ },
+ ItemStyle: EChartStyle{
+ Color: "#a90000",
+ },
+ }, es)
+}
+
+func TestEChartsXAxis(t *testing.T) {
+ assert := assert.New(t)
+ ex := EChartsXAxis{}
+ err := ex.UnmarshalJSON([]byte(`{"boundaryGap": true, "splitNumber": 5, "data": ["a", "b"], "type": "value"}`))
+ assert.Nil(err)
+
+ assert.Equal(EChartsXAxis{
+ Data: []EChartsXAxisData{
+ {
+ BoundaryGap: TrueFlag(),
+ SplitNumber: 5,
+ Data: []string{
+ "a",
+ "b",
+ },
+ Type: "value",
+ },
+ },
+ }, ex)
+}
+
+func TestEChartsOption(t *testing.T) {
+ assert := assert.New(t)
+
+ opt := EChartsOption{}
+ err := json.Unmarshal([]byte(`{
+ "title": {
+ "text": "Rainfall vs Evaporation",
+ "subtext": "Fake Data"
+ },
+ "tooltip": {
+ "trigger": "axis"
+ },
+ "legend": {
+ "data": [
+ "Rainfall",
+ "Evaporation"
+ ]
+ },
+ "toolbox": {
+ "show": true,
+ "feature": {
+ "dataView": {
+ "show": true,
+ "readOnly": false
+ },
+ "magicType": {
+ "show": true,
+ "type": [
+ "line",
+ "bar"
+ ]
+ },
+ "restore": {
+ "show": true
+ },
+ "saveAsImage": {
+ "show": true
+ }
+ }
+ },
+ "calculable": true,
+ "xAxis": [
+ {
+ "type": "category",
+ "data": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ]
+ }
+ ],
+ "yAxis": [
+ {
+ "type": "value"
+ }
+ ],
+ "series": [
+ {
+ "name": "Rainfall",
+ "type": "bar",
+ "data": [
+ 2,
+ 4.9,
+ 7,
+ 23.2,
+ 25.6,
+ 76.7,
+ 135.6,
+ 162.2,
+ 32.6,
+ 20,
+ 6.4,
+ 3.3
+ ],
+ "markPoint": {
+ "data": [
+ {
+ "type": "max",
+ "name": "Max"
+ },
+ {
+ "type": "min",
+ "name": "Min"
+ }
+ ]
+ },
+ "markLine": {
+ "data": [
+ {
+ "type": "average",
+ "name": "Avg"
+ }
+ ]
+ }
+ },
+ {
+ "name": "Evaporation",
+ "type": "bar",
+ "data": [
+ 2.6,
+ 5.9,
+ 9,
+ 26.4,
+ 28.7,
+ 70.7,
+ 175.6,
+ 182.2,
+ 48.7,
+ 18.8,
+ 6,
+ 2.3
+ ],
+ "markPoint": {
+ "data": [
+ {
+ "name": "Max",
+ "value": 182.2,
+ "xAxis": 7,
+ "yAxis": 183
+ },
+ {
+ "name": "Min",
+ "value": 2.3,
+ "xAxis": 11,
+ "yAxis": 3
+ }
+ ]
+ },
+ "markLine": {
+ "data": [
+ {
+ "type": "average",
+ "name": "Avg"
+ }
+ ]
+ }
+ }
+ ]
+ }`), &opt)
+
+ assert.Nil(err)
+ assert.NotEmpty(opt.Series)
+}
diff --git a/grid_test.go b/grid_test.go
new file mode 100644
index 0000000..f6880dc
--- /dev/null
+++ b/grid_test.go
@@ -0,0 +1,69 @@
+// 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 (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/wcharczuk/go-chart/v2/drawing"
+)
+
+func TestGrid(t *testing.T) {
+ assert := assert.New(t)
+
+ tests := []struct {
+ render func(*Painter) ([]byte, error)
+ result string
+ }{
+ {
+ render: func(p *Painter) ([]byte, error) {
+ _, err := NewGridPainter(p, GridPainterOption{
+ StrokeColor: drawing.ColorBlack,
+ Column: 6,
+ Row: 6,
+ IgnoreFirstRow: true,
+ IgnoreLastRow: true,
+ IgnoreFirstColumn: true,
+ IgnoreLastColumn: true,
+ }).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)
+ assert.Nil(err)
+ assert.Equal(tt.result, string(data))
+ }
+}
diff --git a/legend_test.go b/legend_test.go
index e10b538..9078006 100644
--- a/legend_test.go
+++ b/legend_test.go
@@ -89,10 +89,7 @@ func TestNewLegend(t *testing.T) {
result: "",
},
}
- for index, tt := range tests {
- if index != 0 {
- continue
- }
+ for _, tt := range tests {
p, err := NewPainter(PainterOptions{
Type: ChartOutputSVG,
Width: 600,
diff --git a/line_chart_test.go b/line_chart_test.go
new file mode 100644
index 0000000..856cdf3
--- /dev/null
+++ b/line_chart_test.go
@@ -0,0 +1,219 @@
+// 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 (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestLineChart(t *testing.T) {
+ assert := assert.New(t)
+
+ tests := []struct {
+ render func(*Painter) ([]byte, error)
+ result string
+ }{
+ {
+ render: func(p *Painter) ([]byte, error) {
+ values := [][]float64{
+ {
+ 120,
+ 132,
+ 101,
+ 134,
+ 90,
+ 230,
+ 210,
+ },
+ {
+ 220,
+ 182,
+ 191,
+ 234,
+ 290,
+ 330,
+ 310,
+ },
+ {
+ 150,
+ 232,
+ 201,
+ 154,
+ 190,
+ 330,
+ 410,
+ },
+ {
+ 320,
+ 332,
+ 301,
+ 334,
+ 390,
+ 330,
+ 320,
+ },
+ {
+ 820,
+ 932,
+ 901,
+ 934,
+ 1290,
+ 1330,
+ 1320,
+ },
+ }
+ _, err := NewLineChart(p, LineChartOption{
+ Title: TitleOption{
+ Text: "Line",
+ },
+ Padding: Box{
+ Top: 10,
+ Right: 10,
+ Bottom: 10,
+ Left: 10,
+ },
+ XAxis: NewXAxisOption([]string{
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+ "Sun",
+ }),
+ Legend: NewLegendOption([]string{
+ "Email",
+ "Union Ads",
+ "Video Ads",
+ "Direct",
+ "Search Engine",
+ }, PositionCenter),
+ SeriesList: NewSeriesListDataFromValues(values),
+ }).Render()
+ if err != nil {
+ return nil, err
+ }
+ return p.Bytes()
+ },
+ result: "",
+ },
+ {
+ render: func(p *Painter) ([]byte, error) {
+ values := [][]float64{
+ {
+ 120,
+ 132,
+ 101,
+ 134,
+ 90,
+ 230,
+ 210,
+ },
+ {
+ 220,
+ 182,
+ 191,
+ 234,
+ 290,
+ 330,
+ 310,
+ },
+ {
+ 150,
+ 232,
+ 201,
+ 154,
+ 190,
+ 330,
+ 410,
+ },
+ {
+ 320,
+ 332,
+ 301,
+ 334,
+ 390,
+ 330,
+ 320,
+ },
+ {
+ 820,
+ 932,
+ 901,
+ 934,
+ 1290,
+ 1330,
+ 1320,
+ },
+ }
+ _, err := NewLineChart(p, LineChartOption{
+ Title: TitleOption{
+ Text: "Line",
+ },
+ Padding: Box{
+ Top: 10,
+ Right: 10,
+ Bottom: 10,
+ Left: 10,
+ },
+ XAxis: NewXAxisOption([]string{
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+ "Sun",
+ }, FalseFlag()),
+ Legend: NewLegendOption([]string{
+ "Email",
+ "Union Ads",
+ "Video Ads",
+ "Direct",
+ "Search Engine",
+ }, PositionCenter),
+ SeriesList: NewSeriesListDataFromValues(values),
+ }).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)
+ assert.Nil(err)
+ assert.Equal(tt.result, string(data))
+ }
+}
diff --git a/mark_line.go b/mark_line.go
index 00a37f2..a0efcfb 100644
--- a/mark_line.go
+++ b/mark_line.go
@@ -24,6 +24,7 @@ package charts
import (
"github.com/golang/freetype/truetype"
+ "github.com/wcharczuk/go-chart/v2"
)
func NewMarkLine(markLineTypes ...string) SeriesMarkLine {
@@ -70,6 +71,10 @@ func (m *markLinePainter) Render() (Box, error) {
if len(s.MarkLine.Data) == 0 {
continue
}
+ font := opt.Font
+ if font == nil {
+ font, _ = chart.GetDefaultFont()
+ }
summary := s.Summary()
for _, markLine := range s.MarkLine.Data {
// 由于mark line会修改style,因此每次重新设置
@@ -82,7 +87,7 @@ func (m *markLinePainter) Render() (Box, error) {
2,
},
}).OverrideTextStyle(Style{
- Font: opt.Font,
+ Font: font,
FontColor: opt.FontColor,
FontSize: labelFontSize,
})
diff --git a/mark_line_test.go b/mark_line_test.go
new file mode 100644
index 0000000..84152ce
--- /dev/null
+++ b/mark_line_test.go
@@ -0,0 +1,89 @@
+// 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 (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/wcharczuk/go-chart/v2/drawing"
+)
+
+func TestMarkLine(t *testing.T) {
+ assert := assert.New(t)
+
+ tests := []struct {
+ render func(*Painter) ([]byte, error)
+ result string
+ }{
+ {
+ render: func(p *Painter) ([]byte, error) {
+ markLine := NewMarkLinePainter(p)
+ series := NewSeriesFromValues([]float64{
+ 1,
+ 2,
+ 3,
+ })
+ series.MarkLine = NewMarkLine(
+ SeriesMarkDataTypeMax,
+ SeriesMarkDataTypeAverage,
+ SeriesMarkDataTypeMin,
+ )
+ markLine.Add(markLineRenderOption{
+ FillColor: drawing.ColorBlack,
+ FontColor: drawing.ColorBlack,
+ StrokeColor: drawing.ColorBlack,
+ Series: series,
+ Range: NewRange(AxisRangeOption{
+ Min: 0,
+ Max: 5,
+ Size: p.Height(),
+ DivideCount: 6,
+ }),
+ })
+ _, err := markLine.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))
+ }
+}
diff --git a/mark_point_test.go b/mark_point_test.go
new file mode 100644
index 0000000..1a810cf
--- /dev/null
+++ b/mark_point_test.go
@@ -0,0 +1,92 @@
+// 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 (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/wcharczuk/go-chart/v2/drawing"
+)
+
+func TestMarkPoint(t *testing.T) {
+ assert := assert.New(t)
+
+ tests := []struct {
+ render func(*Painter) ([]byte, error)
+ result string
+ }{
+ {
+ render: func(p *Painter) ([]byte, error) {
+ series := NewSeriesFromValues([]float64{
+ 1,
+ 2,
+ 3,
+ })
+ series.MarkPoint = NewMarkPoint(SeriesMarkDataTypeMax)
+ markPoint := NewMarkPointPainter(p)
+ markPoint.Add(markPointRenderOption{
+ FillColor: drawing.ColorBlack,
+ Series: series,
+ Points: []Point{
+ {
+ X: 10,
+ Y: 10,
+ },
+ {
+ X: 30,
+ Y: 30,
+ },
+ {
+ X: 50,
+ Y: 50,
+ },
+ },
+ })
+ _, err := markPoint.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))
+ }
+}
diff --git a/pie_chart_test.go b/pie_chart_test.go
new file mode 100644
index 0000000..c373a7e
--- /dev/null
+++ b/pie_chart_test.go
@@ -0,0 +1,100 @@
+// 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 (
+ "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))
+ }
+}
diff --git a/radar_chart.go b/radar_chart.go
index 610d5f7..5b8aa85 100644
--- a/radar_chart.go
+++ b/radar_chart.go
@@ -62,6 +62,20 @@ type RadarChartOption struct {
backgroundIsFilled bool
}
+func NewRadarIndicators(names []string, values []float64) []RadarIndicator {
+ if len(names) != len(values) {
+ return nil
+ }
+ indicators := make([]RadarIndicator, len(names))
+ for index, name := range names {
+ indicators[index] = RadarIndicator{
+ Name: name,
+ Max: values[index],
+ }
+ }
+ return indicators
+}
+
func NewRadarChart(p *Painter, opt RadarChartOption) *radarChart {
if opt.Theme == nil {
opt.Theme = defaultTheme
diff --git a/radar_chart_test.go b/radar_chart_test.go
new file mode 100644
index 0000000..baf616d
--- /dev/null
+++ b/radar_chart_test.go
@@ -0,0 +1,109 @@
+// 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 (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestRadarChart(t *testing.T) {
+ assert := assert.New(t)
+
+ tests := []struct {
+ render func(*Painter) ([]byte, error)
+ result string
+ }{
+ {
+ render: func(p *Painter) ([]byte, error) {
+ values := [][]float64{
+ {
+ 4200,
+ 3000,
+ 20000,
+ 35000,
+ 50000,
+ 18000,
+ },
+ {
+ 5000,
+ 14000,
+ 28000,
+ 26000,
+ 42000,
+ 21000,
+ },
+ }
+ _, err := NewRadarChart(p, RadarChartOption{
+ SeriesList: NewSeriesListDataFromValues(values, ChartTypeRadar),
+ Title: TitleOption{
+ Text: "Basic Radar Chart",
+ },
+ Legend: NewLegendOption([]string{
+ "Allocated Budget",
+ "Actual Spending",
+ }),
+ RadarIndicators: NewRadarIndicators([]string{
+ "Sales",
+ "Administration",
+ "Information Technology",
+ "Customer Support",
+ "Development",
+ "Marketing",
+ }, []float64{
+ 6500,
+ 16000,
+ 30000,
+ 38000,
+ 52000,
+ 25000,
+ }),
+ }).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)
+ fmt.Println(string(data))
+ assert.Equal(tt.result, string(data))
+ }
+}