-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathchart_option_test.go
341 lines (312 loc) · 67.2 KB
/
chart_option_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
package charts
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestChartOption(t *testing.T) {
t.Parallel()
fns := []OptionFunc{
SVGOutputOptionFunc(),
FontOptionFunc(GetDefaultFont()),
ThemeNameOptionFunc(ThemeVividDark),
TitleTextOptionFunc("title"),
LegendLabelsOptionFunc([]string{"label"}),
XAxisLabelsOptionFunc([]string{"xaxis"}),
YAxisLabelsOptionFunc([]string{"yaxis"}),
DimensionsOptionFunc(800, 600),
PaddingOptionFunc(NewBoxEqual(10)),
}
opt := ChartOption{}
for _, fn := range fns {
fn(&opt)
}
require.Equal(t, ChartOption{
OutputFormat: ChartOutputSVG,
Font: GetDefaultFont(),
Theme: GetTheme(ThemeVividDark),
Title: TitleOption{
Text: "title",
},
Legend: LegendOption{
SeriesNames: []string{"label"},
},
XAxis: XAxisOption{
Labels: []string{"xaxis"},
},
YAxis: []YAxisOption{
{
Labels: []string{"yaxis"},
},
},
Width: 800,
Height: 600,
Padding: NewBoxEqual(10),
}, opt)
}
func TestChartOptionSeriesShowLabel(t *testing.T) {
t.Parallel()
opt := ChartOption{
SeriesList: NewSeriesListPie([]float64{1, 2}).ToGenericSeriesList(),
}
SeriesShowLabel(true)(&opt)
assert.True(t, flagIs(true, opt.SeriesList[0].Label.Show))
SeriesShowLabel(false)(&opt)
assert.True(t, flagIs(false, opt.SeriesList[0].Label.Show))
}
func newNoTypeSeriesListFromValues(values [][]float64) GenericSeriesList {
return NewSeriesListGeneric(values, "")
}
func TestChartOptionMarkLine(t *testing.T) {
t.Parallel()
opt := ChartOption{
SeriesList: newNoTypeSeriesListFromValues([][]float64{{1, 2}}),
}
MarkLineOptionFunc(0, "min", "max")(&opt)
assert.Equal(t, NewMarkLine("min", "max"), opt.SeriesList[0].MarkLine)
}
func TestChartOptionMarkPoint(t *testing.T) {
t.Parallel()
opt := ChartOption{
SeriesList: newNoTypeSeriesListFromValues([][]float64{{1, 2}}),
}
MarkPointOptionFunc(0, "min", "max")(&opt)
assert.Equal(t, NewMarkPoint("min", "max"), opt.SeriesList[0].MarkPoint)
}
func TestLineRender(t *testing.T) {
t.Parallel()
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},
}
p, err := LineRender(
values,
SVGOutputOptionFunc(),
TitleTextOptionFunc("Line"),
XAxisLabelsOptionFunc([]string{
"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
}),
LegendLabelsOptionFunc([]string{
"Email", "Union Ads", "Video Ads", "Direct", "Search Engine",
}),
func(opt *ChartOption) {
opt.ValueFormatter = func(f float64) string {
return fmt.Sprintf("%.0f", f)
}
},
)
require.NoError(t, err)
data, err := p.Bytes()
require.NoError(t, err)
assertEqualSVG(t, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 600 400\"><path d=\"M 0 0\nL 600 0\nL 600 400\nL 0 400\nL 0 0\" style=\"stroke:none;fill:white\"/><path d=\"M 20 29\nL 50 29\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:none\"/><circle cx=\"35\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><text x=\"52\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Email</text><path d=\"M 111 29\nL 141 29\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:none\"/><circle cx=\"126\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><text x=\"143\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Union Ads</text><path d=\"M 234 29\nL 264 29\" style=\"stroke-width:3;stroke:rgb(250,200,88);fill:none\"/><circle cx=\"249\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(250,200,88);fill:rgb(250,200,88)\"/><text x=\"266\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Video Ads</text><path d=\"M 357 29\nL 387 29\" style=\"stroke-width:3;stroke:rgb(238,102,102);fill:none\"/><circle cx=\"372\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(238,102,102);fill:rgb(238,102,102)\"/><text x=\"389\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Direct</text><path d=\"M 450 29\nL 480 29\" style=\"stroke-width:3;stroke:rgb(115,192,222);fill:none\"/><circle cx=\"465\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(115,192,222);fill:rgb(115,192,222)\"/><text x=\"482\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Search Engine</text><text x=\"20\" y=\"36\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Line</text><text x=\"19\" y=\"62\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">1440</text><text x=\"19\" y=\"94\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">1280</text><text x=\"19\" y=\"127\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">1120</text><text x=\"27\" y=\"160\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">960</text><text x=\"27\" y=\"193\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">800</text><text x=\"27\" y=\"226\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">640</text><text x=\"27\" y=\"259\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">480</text><text x=\"27\" y=\"292\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">320</text><text x=\"27\" y=\"325\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">160</text><text x=\"45\" y=\"358\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">0</text><path d=\"M 60 56\nL 580 56\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 60 89\nL 580 89\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 60 122\nL 580 122\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 60 155\nL 580 155\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 60 188\nL 580 188\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 60 221\nL 580 221\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 60 254\nL 580 254\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 60 287\nL 580 287\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 60 320\nL 580 320\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 64 354\nL 580 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 64 359\nL 64 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 137 359\nL 137 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 211 359\nL 211 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 285 359\nL 285 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 358 359\nL 358 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 432 359\nL 432 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 506 359\nL 506 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 580 359\nL 580 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><text x=\"85\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Mon</text><text x=\"161\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Tue</text><text x=\"233\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Wed</text><text x=\"308\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Thu</text><text x=\"386\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Fri</text><text x=\"458\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Sat</text><text x=\"530\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Sun</text><path d=\"M 100 330\nL 174 327\nL 248 334\nL 321 327\nL 395 336\nL 469 307\nL 543 311\" style=\"stroke-width:2;stroke:rgb(84,112,198);fill:none\"/><circle cx=\"100\" cy=\"330\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"174\" cy=\"327\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"248\" cy=\"334\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"321\" cy=\"327\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"395\" cy=\"336\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"469\" cy=\"307\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"543\" cy=\"311\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><path d=\"M 100 309\nL 174 317\nL 248 315\nL 321 306\nL 395 294\nL 469 286\nL 543 290\" style=\"stroke-width:2;stroke:rgb(145,204,117);fill:none\"/><circle cx=\"100\" cy=\"309\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"174\" cy=\"317\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"248\" cy=\"315\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"321\" cy=\"306\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"395\" cy=\"294\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"469\" cy=\"286\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"543\" cy=\"290\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><path d=\"M 100 323\nL 174 306\nL 248 313\nL 321 323\nL 395 315\nL 469 286\nL 543 270\" style=\"stroke-width:2;stroke:rgb(250,200,88);fill:none\"/><circle cx=\"100\" cy=\"323\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"174\" cy=\"306\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"248\" cy=\"313\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"321\" cy=\"323\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"395\" cy=\"315\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"469\" cy=\"286\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"543\" cy=\"270\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><path d=\"M 100 288\nL 174 286\nL 248 292\nL 321 285\nL 395 274\nL 469 286\nL 543 288\" style=\"stroke-width:2;stroke:rgb(238,102,102);fill:none\"/><circle cx=\"100\" cy=\"288\" r=\"2\" style=\"stroke-width:1;stroke:rgb(238,102,102);fill:white\"/><circle cx=\"174\" cy=\"286\" r=\"2\" style=\"stroke-width:1;stroke:rgb(238,102,102);fill:white\"/><circle cx=\"248\" cy=\"292\" r=\"2\" style=\"stroke-width:1;stroke:rgb(238,102,102);fill:white\"/><circle cx=\"321\" cy=\"285\" r=\"2\" style=\"stroke-width:1;stroke:rgb(238,102,102);fill:white\"/><circle cx=\"395\" cy=\"274\" r=\"2\" style=\"stroke-width:1;stroke:rgb(238,102,102);fill:white\"/><circle cx=\"469\" cy=\"286\" r=\"2\" style=\"stroke-width:1;stroke:rgb(238,102,102);fill:white\"/><circle cx=\"543\" cy=\"288\" r=\"2\" style=\"stroke-width:1;stroke:rgb(238,102,102);fill:white\"/><path d=\"M 100 185\nL 174 162\nL 248 168\nL 321 161\nL 395 88\nL 469 79\nL 543 81\" style=\"stroke-width:2;stroke:rgb(115,192,222);fill:none\"/><circle cx=\"100\" cy=\"185\" r=\"2\" style=\"stroke-width:1;stroke:rgb(115,192,222);fill:white\"/><circle cx=\"174\" cy=\"162\" r=\"2\" style=\"stroke-width:1;stroke:rgb(115,192,222);fill:white\"/><circle cx=\"248\" cy=\"168\" r=\"2\" style=\"stroke-width:1;stroke:rgb(115,192,222);fill:white\"/><circle cx=\"321\" cy=\"161\" r=\"2\" style=\"stroke-width:1;stroke:rgb(115,192,222);fill:white\"/><circle cx=\"395\" cy=\"88\" r=\"2\" style=\"stroke-width:1;stroke:rgb(115,192,222);fill:white\"/><circle cx=\"469\" cy=\"79\" r=\"2\" style=\"stroke-width:1;stroke:rgb(115,192,222);fill:white\"/><circle cx=\"543\" cy=\"81\" r=\"2\" style=\"stroke-width:1;stroke:rgb(115,192,222);fill:white\"/></svg>", data)
}
func TestScatterRender(t *testing.T) {
t.Parallel()
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},
}
p, err := ScatterRender(
values,
SVGOutputOptionFunc(),
TitleTextOptionFunc("Scatter"),
XAxisLabelsOptionFunc([]string{
"1", "2", "3", "4", "5", "6", "7",
}),
LegendLabelsOptionFunc([]string{
"A", "B", "C", "D", "E",
}),
func(opt *ChartOption) {
opt.Symbol = SymbolSquare
opt.Legend.Symbol = SymbolSquare
},
)
require.NoError(t, err)
data, err := p.Bytes()
require.NoError(t, err)
assertEqualSVG(t, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 600 400\"><path d=\"M 0 0\nL 600 0\nL 600 400\nL 0 400\nL 0 0\" style=\"stroke:none;fill:white\"/><path d=\"M 155 23\nL 185 23\nL 185 36\nL 155 36\nL 155 23\" style=\"stroke:none;fill:rgb(84,112,198)\"/><text x=\"187\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">A</text><path d=\"M 218 23\nL 248 23\nL 248 36\nL 218 36\nL 218 23\" style=\"stroke:none;fill:rgb(145,204,117)\"/><text x=\"250\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">B</text><path d=\"M 280 23\nL 310 23\nL 310 36\nL 280 36\nL 280 23\" style=\"stroke:none;fill:rgb(250,200,88)\"/><text x=\"312\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">C</text><path d=\"M 342 23\nL 372 23\nL 372 36\nL 342 36\nL 342 23\" style=\"stroke:none;fill:rgb(238,102,102)\"/><text x=\"374\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">D</text><path d=\"M 405 23\nL 435 23\nL 435 36\nL 405 36\nL 405 23\" style=\"stroke:none;fill:rgb(115,192,222)\"/><text x=\"437\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">E</text><text x=\"20\" y=\"36\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Scatter</text><text x=\"19\" y=\"62\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">1.44k</text><text x=\"19\" y=\"94\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">1.28k</text><text x=\"19\" y=\"127\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">1.12k</text><text x=\"31\" y=\"160\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">960</text><text x=\"31\" y=\"193\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">800</text><text x=\"31\" y=\"226\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">640</text><text x=\"31\" y=\"259\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">480</text><text x=\"31\" y=\"292\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">320</text><text x=\"31\" y=\"325\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">160</text><text x=\"49\" y=\"358\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">0</text><path d=\"M 64 56\nL 580 56\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 64 89\nL 580 89\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 64 122\nL 580 122\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 64 155\nL 580 155\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 64 188\nL 580 188\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 64 221\nL 580 221\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 64 254\nL 580 254\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 64 287\nL 580 287\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 64 320\nL 580 320\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 68 354\nL 580 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 68 359\nL 68 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 141 359\nL 141 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 214 359\nL 214 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 287 359\nL 287 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 360 359\nL 360 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 433 359\nL 433 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 506 359\nL 506 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 580 359\nL 580 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><text x=\"100\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">1</text><text x=\"173\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">2</text><text x=\"246\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">3</text><text x=\"319\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">4</text><text x=\"392\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">5</text><text x=\"465\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">6</text><text x=\"539\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">7</text><path d=\"M 66 328\nL 70 328\nL 70 332\nL 66 332\nL 66 328\nM 151 325\nL 155 325\nL 155 329\nL 151 329\nL 151 325\nM 236 332\nL 240 332\nL 240 336\nL 236 336\nL 236 332\nM 322 325\nL 326 325\nL 326 329\nL 322 329\nL 322 325\nM 407 334\nL 411 334\nL 411 338\nL 407 338\nL 407 334\nM 492 305\nL 496 305\nL 496 309\nL 492 309\nL 492 305\nM 578 309\nL 582 309\nL 582 313\nL 578 313\nL 578 309\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><path d=\"M 66 307\nL 70 307\nL 70 311\nL 66 311\nL 66 307\nM 151 315\nL 155 315\nL 155 319\nL 151 319\nL 151 315\nM 236 313\nL 240 313\nL 240 317\nL 236 317\nL 236 313\nM 322 304\nL 326 304\nL 326 308\nL 322 308\nL 322 304\nM 407 292\nL 411 292\nL 411 296\nL 407 296\nL 407 292\nM 492 284\nL 496 284\nL 496 288\nL 492 288\nL 492 284\nM 578 288\nL 582 288\nL 582 292\nL 578 292\nL 578 288\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><path d=\"M 66 321\nL 70 321\nL 70 325\nL 66 325\nL 66 321\nM 151 304\nL 155 304\nL 155 308\nL 151 308\nL 151 304\nM 236 311\nL 240 311\nL 240 315\nL 236 315\nL 236 311\nM 322 321\nL 326 321\nL 326 325\nL 322 325\nL 322 321\nM 407 313\nL 411 313\nL 411 317\nL 407 317\nL 407 313\nM 492 284\nL 496 284\nL 496 288\nL 492 288\nL 492 284\nM 578 268\nL 582 268\nL 582 272\nL 578 272\nL 578 268\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:rgb(250,200,88)\"/><path d=\"M 66 286\nL 70 286\nL 70 290\nL 66 290\nL 66 286\nM 151 284\nL 155 284\nL 155 288\nL 151 288\nL 151 284\nM 236 290\nL 240 290\nL 240 294\nL 236 294\nL 236 290\nM 322 283\nL 326 283\nL 326 287\nL 322 287\nL 322 283\nM 407 272\nL 411 272\nL 411 276\nL 407 276\nL 407 272\nM 492 284\nL 496 284\nL 496 288\nL 492 288\nL 492 284\nM 578 286\nL 582 286\nL 582 290\nL 578 290\nL 578 286\" style=\"stroke-width:1;stroke:rgb(238,102,102);fill:rgb(238,102,102)\"/><path d=\"M 66 183\nL 70 183\nL 70 187\nL 66 187\nL 66 183\nM 151 160\nL 155 160\nL 155 164\nL 151 164\nL 151 160\nM 236 166\nL 240 166\nL 240 170\nL 236 170\nL 236 166\nM 322 159\nL 326 159\nL 326 163\nL 322 163\nL 322 159\nM 407 86\nL 411 86\nL 411 90\nL 407 90\nL 407 86\nM 492 77\nL 496 77\nL 496 81\nL 492 81\nL 492 77\nM 578 79\nL 582 79\nL 582 83\nL 578 83\nL 578 79\" style=\"stroke-width:1;stroke:rgb(115,192,222);fill:rgb(115,192,222)\"/></svg>", data)
}
func TestBarRender(t *testing.T) {
t.Parallel()
values := [][]float64{
{2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3},
{2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3},
}
p, err := BarRender(
values,
SVGOutputOptionFunc(),
XAxisLabelsOptionFunc([]string{
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
}),
LegendLabelsOptionFunc([]string{
"Rainfall", "Evaporation",
}),
MarkLineOptionFunc(0, SeriesMarkTypeAverage),
MarkPointOptionFunc(0, SeriesMarkTypeMax, SeriesMarkTypeMin),
// custom option func
func(opt *ChartOption) {
opt.Legend.Offset = OffsetRight
opt.Legend.OverlayChart = Ptr(true)
opt.SeriesList[1].MarkPoint = NewMarkPoint(SeriesMarkTypeMax, SeriesMarkTypeMin)
opt.SeriesList[1].MarkLine = NewMarkLine(SeriesMarkTypeAverage)
},
)
require.NoError(t, err)
data, err := p.Bytes()
require.NoError(t, err)
assertEqualSVG(t, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 600 400\"><path d=\"M 0 0\nL 600 0\nL 600 400\nL 0 400\nL 0 0\" style=\"stroke:none;fill:white\"/><path d=\"M 364 29\nL 394 29\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:none\"/><circle cx=\"379\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><text x=\"396\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Rainfall</text><path d=\"M 468 29\nL 498 29\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:none\"/><circle cx=\"483\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><text x=\"500\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Evaporation</text><text x=\"19\" y=\"26\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">270</text><text x=\"19\" y=\"62\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">240</text><text x=\"19\" y=\"99\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">210</text><text x=\"19\" y=\"136\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">180</text><text x=\"19\" y=\"173\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">150</text><text x=\"19\" y=\"210\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">120</text><text x=\"28\" y=\"247\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">90</text><text x=\"28\" y=\"284\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">60</text><text x=\"28\" y=\"321\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">30</text><text x=\"37\" y=\"358\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">0</text><path d=\"M 52 20\nL 580 20\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 57\nL 580 57\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 94\nL 580 94\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 131\nL 580 131\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 168\nL 580 168\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 205\nL 580 205\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 242\nL 580 242\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 279\nL 580 279\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 316\nL 580 316\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 56 354\nL 580 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 56 359\nL 56 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 99 359\nL 99 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 143 359\nL 143 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 187 359\nL 187 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 230 359\nL 230 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 274 359\nL 274 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 318 359\nL 318 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 361 359\nL 361 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 405 359\nL 405 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 449 359\nL 449 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 492 359\nL 492 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 536 359\nL 536 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 580 359\nL 580 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><text x=\"64\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Jan</text><text x=\"108\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Feb</text><text x=\"151\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Mar</text><text x=\"196\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Apr</text><text x=\"237\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">May</text><text x=\"283\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Jun</text><text x=\"329\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Jul</text><text x=\"369\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Aug</text><text x=\"414\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Sep</text><text x=\"458\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Oct</text><text x=\"500\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Nov</text><text x=\"545\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Dec</text><path d=\"M 61 352\nL 76 352\nL 76 353\nL 61 353\nL 61 352\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 104 348\nL 119 348\nL 119 353\nL 104 353\nL 104 348\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 148 346\nL 163 346\nL 163 353\nL 148 353\nL 148 346\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 192 326\nL 207 326\nL 207 353\nL 192 353\nL 192 326\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 235 323\nL 250 323\nL 250 353\nL 235 353\nL 235 323\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 279 260\nL 294 260\nL 294 353\nL 279 353\nL 279 260\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 323 187\nL 338 187\nL 338 353\nL 323 353\nL 323 187\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 366 154\nL 381 154\nL 381 353\nL 366 353\nL 366 154\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 410 314\nL 425 314\nL 425 353\nL 410 353\nL 410 314\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 454 330\nL 469 330\nL 469 353\nL 454 353\nL 454 330\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 497 347\nL 512 347\nL 512 353\nL 497 353\nL 497 347\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 541 350\nL 556 350\nL 556 353\nL 541 353\nL 541 350\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 79 351\nL 94 351\nL 94 353\nL 79 353\nL 79 351\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 122 347\nL 137 347\nL 137 353\nL 122 353\nL 122 347\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 166 343\nL 181 343\nL 181 353\nL 166 353\nL 166 343\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 210 322\nL 225 322\nL 225 353\nL 210 353\nL 210 322\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 253 319\nL 268 319\nL 268 353\nL 253 353\nL 253 319\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 297 267\nL 312 267\nL 312 353\nL 297 353\nL 297 267\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 341 137\nL 356 137\nL 356 353\nL 341 353\nL 341 137\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 384 129\nL 399 129\nL 399 353\nL 384 353\nL 384 129\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 428 294\nL 443 294\nL 443 353\nL 428 353\nL 428 294\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 472 331\nL 487 331\nL 487 353\nL 472 353\nL 472 331\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 515 347\nL 530 347\nL 530 353\nL 515 353\nL 515 347\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 559 352\nL 574 352\nL 574 353\nL 559 353\nL 559 352\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 369 147\nA 14 14 330.00 1 1 377 147\nL 373 133\nZ\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 359 133\nQ373,168 387,133\nZ\" style=\"stroke:none;fill:rgb(84,112,198)\"/><text x=\"360\" y=\"138\" style=\"stroke:none;fill:rgb(238,238,238);font-size:10.2px;font-family:'Roboto Medium',sans-serif\">162.2</text><path d=\"M 64 345\nA 14 14 330.00 1 1 72 345\nL 68 331\nZ\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 54 331\nQ68,366 82,331\nZ\" style=\"stroke:none;fill:rgb(84,112,198)\"/><text x=\"64\" y=\"336\" style=\"stroke:none;fill:rgb(238,238,238);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">2</text><path d=\"M 387 122\nA 14 14 330.00 1 1 395 122\nL 391 108\nZ\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 377 108\nQ391,143 405,108\nZ\" style=\"stroke:none;fill:rgb(145,204,117)\"/><text x=\"378\" y=\"113\" style=\"stroke:none;fill:rgb(70,70,70);font-size:10.2px;font-family:'Roboto Medium',sans-serif\">182.2</text><path d=\"M 562 345\nA 14 14 330.00 1 1 570 345\nL 566 331\nZ\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 552 331\nQ566,366 580,331\nZ\" style=\"stroke:none;fill:rgb(145,204,117)\"/><text x=\"557\" y=\"336\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">2.3</text><circle cx=\"59\" cy=\"303\" r=\"3\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><path stroke-dasharray=\"4.0, 2.0\" d=\"M 65 303\nL 562 303\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><path stroke-dasharray=\"4.0, 2.0\" d=\"M 562 298\nL 578 303\nL 562 308\nL 567 303\nL 562 298\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><text x=\"580\" y=\"307\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">41.63</text><circle cx=\"59\" cy=\"295\" r=\"3\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><path stroke-dasharray=\"4.0, 2.0\" d=\"M 65 295\nL 562 295\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><path stroke-dasharray=\"4.0, 2.0\" d=\"M 562 290\nL 578 295\nL 562 300\nL 567 295\nL 562 290\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><text x=\"580\" y=\"299\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">48.07</text></svg>", data)
}
func TestHorizontalBarRender(t *testing.T) {
t.Parallel()
values := [][]float64{
{18203, 23489, 29034, 104970, 131744, 630230},
{19325, 23438, 31000, 121594, 134141, 681807},
}
p, err := HorizontalBarRender(
values,
SVGOutputOptionFunc(),
TitleTextOptionFunc("World Population"),
PaddingOptionFunc(Box{
Top: 20,
Right: 40,
Bottom: 20,
Left: 20,
}),
LegendLabelsOptionFunc([]string{"2011", "2012"}),
YAxisLabelsOptionFunc([]string{"Brazil", "Indonesia", "USA", "India", "China", "World"}),
)
require.NoError(t, err)
data, err := p.Bytes()
require.NoError(t, err)
assertEqualSVG(t, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 600 400\"><path d=\"M 0 0\nL 600 0\nL 600 400\nL 0 400\nL 0 0\" style=\"stroke:none;fill:white\"/><path d=\"M 214 29\nL 244 29\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:none\"/><circle cx=\"229\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><text x=\"246\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">2011</text><path d=\"M 301 29\nL 331 29\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:none\"/><circle cx=\"316\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><text x=\"333\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">2012</text><text x=\"20\" y=\"36\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">World Population</text><path d=\"M 97 56\nL 97 356\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 92 56\nL 97 56\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 92 106\nL 97 106\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 92 156\nL 97 156\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 92 206\nL 97 206\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 92 256\nL 97 256\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 92 306\nL 97 306\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 92 356\nL 97 356\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><text x=\"46\" y=\"86\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">World</text><text x=\"47\" y=\"136\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">China</text><text x=\"53\" y=\"186\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">India</text><text x=\"57\" y=\"235\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">USA</text><text x=\"19\" y=\"285\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Indonesia</text><text x=\"48\" y=\"335\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Brazil</text><text x=\"97\" y=\"375\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">0</text><text x=\"174\" y=\"375\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">120k</text><text x=\"251\" y=\"375\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">240k</text><text x=\"328\" y=\"375\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">360k</text><text x=\"405\" y=\"375\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">480k</text><text x=\"482\" y=\"375\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">600k</text><text x=\"525\" y=\"375\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">720k</text><path d=\"M 175 56\nL 175 352\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 252 56\nL 252 352\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 329 56\nL 329 352\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 406 56\nL 406 352\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 483 56\nL 483 352\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 560 56\nL 560 352\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 98 316\nL 109 316\nL 109 328\nL 98 328\nL 98 316\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 98 266\nL 113 266\nL 113 278\nL 98 278\nL 98 266\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 98 216\nL 116 216\nL 116 228\nL 98 228\nL 98 216\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 98 166\nL 165 166\nL 165 178\nL 98 178\nL 98 166\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 98 116\nL 182 116\nL 182 128\nL 98 128\nL 98 116\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 98 66\nL 502 66\nL 502 78\nL 98 78\nL 98 66\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 98 333\nL 110 333\nL 110 345\nL 98 345\nL 98 333\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 98 283\nL 113 283\nL 113 295\nL 98 295\nL 98 283\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 98 233\nL 117 233\nL 117 245\nL 98 245\nL 98 233\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 98 183\nL 176 183\nL 176 195\nL 98 195\nL 98 183\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 98 133\nL 184 133\nL 184 145\nL 98 145\nL 98 133\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 98 83\nL 535 83\nL 535 95\nL 98 95\nL 98 83\" style=\"stroke:none;fill:rgb(145,204,117)\"/></svg>", data)
}
func TestPieRender(t *testing.T) {
t.Parallel()
values := []float64{1048, 735, 580, 484, 300}
p, err := PieRender(
values,
SVGOutputOptionFunc(),
TitleOptionFunc(TitleOption{
Text: "Rainfall vs Evaporation",
Subtext: "Fake Data",
Offset: OffsetCenter,
}),
PaddingOptionFunc(NewBoxEqual(20)),
LegendOptionFunc(LegendOption{
Vertical: Ptr(true),
SeriesNames: []string{"Search Engine", "Direct", "Email", "Union Ads", "Video Ads"},
Offset: OffsetLeft,
}),
)
require.NoError(t, err)
data, err := p.Bytes()
require.NoError(t, err)
assertEqualSVG(t, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 600 400\"><path d=\"M 0 0\nL 600 0\nL 600 400\nL 0 400\nL 0 0\" style=\"stroke:none;fill:white\"/><path d=\"M 20 29\nL 50 29\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:none\"/><circle cx=\"35\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><text x=\"52\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Search Engine</text><path d=\"M 20 49\nL 50 49\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:none\"/><circle cx=\"35\" cy=\"49\" r=\"5\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><text x=\"52\" y=\"55\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Direct</text><path d=\"M 20 69\nL 50 69\" style=\"stroke-width:3;stroke:rgb(250,200,88);fill:none\"/><circle cx=\"35\" cy=\"69\" r=\"5\" style=\"stroke-width:3;stroke:rgb(250,200,88);fill:rgb(250,200,88)\"/><text x=\"52\" y=\"75\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Email</text><path d=\"M 20 89\nL 50 89\" style=\"stroke-width:3;stroke:rgb(238,102,102);fill:none\"/><circle cx=\"35\" cy=\"89\" r=\"5\" style=\"stroke-width:3;stroke:rgb(238,102,102);fill:rgb(238,102,102)\"/><text x=\"52\" y=\"95\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Union Ads</text><path d=\"M 20 109\nL 50 109\" style=\"stroke-width:3;stroke:rgb(115,192,222);fill:none\"/><circle cx=\"35\" cy=\"109\" r=\"5\" style=\"stroke-width:3;stroke:rgb(115,192,222);fill:rgb(115,192,222)\"/><text x=\"52\" y=\"115\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Video Ads</text><text x=\"222\" y=\"36\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Rainfall vs Evaporation</text><text x=\"266\" y=\"52\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Fake Data</text><path d=\"M 300 223\nL 300 98\nA 125 125 119.89 0 1 409 285\nL 300 223\nZ\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 408 161\nL 421 153\nM 421 153\nL 436 153\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:none\"/><text x=\"439\" y=\"158\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">: 33.3%</text><path d=\"M 300 223\nL 409 285\nA 125 125 84.08 0 1 249 337\nL 300 223\nZ\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 338 342\nL 343 356\nM 343 356\nL 358 356\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:none\"/><text x=\"361\" y=\"361\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">: 23.35%</text><path d=\"M 300 223\nL 249 337\nA 125 125 66.35 0 1 175 222\nL 300 223\nZ\" style=\"stroke:none;fill:rgb(250,200,88)\"/><path d=\"M 195 290\nL 183 299\nM 183 299\nL 168 299\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:none\"/><text x=\"116\" y=\"304\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">: 18.43%</text><path d=\"M 300 223\nL 175 222\nA 125 125 55.37 0 1 229 120\nL 300 223\nZ\" style=\"stroke:none;fill:rgb(238,102,102)\"/><path d=\"M 190 165\nL 177 158\nM 177 158\nL 162 158\" style=\"stroke-width:1;stroke:rgb(238,102,102);fill:none\"/><text x=\"110\" y=\"163\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">: 15.37%</text><path d=\"M 300 223\nL 229 120\nA 125 125 34.32 0 1 300 98\nL 300 223\nZ\" style=\"stroke:none;fill:rgb(115,192,222)\"/><path d=\"M 264 104\nL 259 90\nM 259 90\nL 244 90\" style=\"stroke-width:1;stroke:rgb(115,192,222);fill:none\"/><text x=\"199\" y=\"95\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">: 9.53%</text></svg>", data)
}
func TestDoughnutRender(t *testing.T) {
t.Parallel()
values := []float64{1048, 735, 580, 484, 300}
p, err := DoughnutRender(
values,
SVGOutputOptionFunc(),
TitleOptionFunc(TitleOption{
Text: "Title",
Subtext: "Fake Data",
Offset: OffsetCenter,
}),
PaddingOptionFunc(NewBoxEqual(20)),
LegendOptionFunc(LegendOption{
Vertical: Ptr(true),
SeriesNames: []string{"A", "B", "C", "D", "E"},
Offset: OffsetLeft,
}),
)
require.NoError(t, err)
data, err := p.Bytes()
require.NoError(t, err)
assertEqualSVG(t, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 600 400\"><path d=\"M 0 0\nL 600 0\nL 600 400\nL 0 400\nL 0 0\" style=\"stroke:none;fill:white\"/><path d=\"M 20 29\nL 50 29\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:none\"/><circle cx=\"35\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><text x=\"52\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">A</text><path d=\"M 20 49\nL 50 49\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:none\"/><circle cx=\"35\" cy=\"49\" r=\"5\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><text x=\"52\" y=\"55\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">B</text><path d=\"M 20 69\nL 50 69\" style=\"stroke-width:3;stroke:rgb(250,200,88);fill:none\"/><circle cx=\"35\" cy=\"69\" r=\"5\" style=\"stroke-width:3;stroke:rgb(250,200,88);fill:rgb(250,200,88)\"/><text x=\"52\" y=\"75\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">C</text><path d=\"M 20 89\nL 50 89\" style=\"stroke-width:3;stroke:rgb(238,102,102);fill:none\"/><circle cx=\"35\" cy=\"89\" r=\"5\" style=\"stroke-width:3;stroke:rgb(238,102,102);fill:rgb(238,102,102)\"/><text x=\"52\" y=\"95\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">D</text><path d=\"M 20 109\nL 50 109\" style=\"stroke-width:3;stroke:rgb(115,192,222);fill:none\"/><circle cx=\"35\" cy=\"109\" r=\"5\" style=\"stroke-width:3;stroke:rgb(115,192,222);fill:rgb(115,192,222)\"/><text x=\"52\" y=\"115\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">E</text><text x=\"285\" y=\"36\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Title</text><text x=\"266\" y=\"52\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Fake Data</text><path d=\"M 300 223\nL 300 98\nA 125 125 119.89 0 1 409 285\nL 300 223\nZ\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 408 161\nL 421 153\nM 421 153\nL 436 153\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:none\"/><text x=\"439\" y=\"158\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">: 33.3%</text><path d=\"M 300 223\nL 409 285\nA 125 125 84.08 0 1 249 337\nL 300 223\nZ\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 338 342\nL 343 356\nM 343 356\nL 358 356\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:none\"/><text x=\"361\" y=\"361\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">: 23.35%</text><path d=\"M 300 223\nL 249 337\nA 125 125 66.35 0 1 175 222\nL 300 223\nZ\" style=\"stroke:none;fill:rgb(250,200,88)\"/><path d=\"M 195 290\nL 183 299\nM 183 299\nL 168 299\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:none\"/><text x=\"116\" y=\"304\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">: 18.43%</text><path d=\"M 300 223\nL 175 222\nA 125 125 55.37 0 1 229 120\nL 300 223\nZ\" style=\"stroke:none;fill:rgb(238,102,102)\"/><path d=\"M 190 165\nL 177 158\nM 177 158\nL 162 158\" style=\"stroke-width:1;stroke:rgb(238,102,102);fill:none\"/><text x=\"110\" y=\"163\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">: 15.37%</text><path d=\"M 300 223\nL 229 120\nA 125 125 34.32 0 1 300 98\nL 300 223\nZ\" style=\"stroke:none;fill:rgb(115,192,222)\"/><path d=\"M 264 104\nL 259 90\nM 259 90\nL 244 90\" style=\"stroke-width:1;stroke:rgb(115,192,222);fill:none\"/><text x=\"199\" y=\"95\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">: 9.53%</text><circle cx=\"300\" cy=\"223\" r=\"75\" style=\"stroke:none;fill:white\"/></svg>", data)
}
func TestRadarRender(t *testing.T) {
t.Parallel()
values := [][]float64{
{4200, 3000, 20000, 35000, 50000, 18000},
{5000, 14000, 28000, 26000, 42000, 21000},
}
p, err := RadarRender(
values,
SVGOutputOptionFunc(),
TitleTextOptionFunc("Basic Radar Chart"),
LegendLabelsOptionFunc([]string{
"Allocated Budget", "Actual Spending",
}),
RadarIndicatorOptionFunc([]string{
"Sales",
"Administration",
"Information Technology",
"Customer Support",
"Development",
"Marketing",
}, []float64{
6500, 16000, 30000, 38000, 52000, 25000,
}),
)
require.NoError(t, err)
data, err := p.Bytes()
require.NoError(t, err)
assertEqualSVG(t, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 600 400\"><path d=\"M 0 0\nL 600 0\nL 600 400\nL 0 400\nL 0 0\" style=\"stroke:none;fill:white\"/><path d=\"M 143 29\nL 173 29\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:none\"/><circle cx=\"158\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><text x=\"175\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Allocated Budget</text><path d=\"M 313 29\nL 343 29\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:none\"/><circle cx=\"328\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><text x=\"345\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Actual Spending</text><text x=\"20\" y=\"36\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Basic Radar Chart</text><path d=\"M 300 193\nL 321 206\nL 321 230\nL 300 243\nL 279 230\nL 279 206\nL 300 193\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 300 168\nL 343 193\nL 343 242\nL 300 268\nL 257 243\nL 257 194\nL 300 168\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 300 143\nL 364 181\nL 364 255\nL 300 293\nL 236 255\nL 236 181\nL 300 143\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 300 118\nL 386 168\nL 386 267\nL 300 318\nL 214 268\nL 214 169\nL 300 118\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 300 93\nL 408 156\nL 408 280\nL 300 343\nL 192 280\nL 192 156\nL 300 93\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 300 218\nL 300 93\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 300 218\nL 408 156\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 300 218\nL 408 280\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 300 218\nL 300 343\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 300 218\nL 192 280\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 300 218\nL 192 156\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><text x=\"284\" y=\"85\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">Sales</text><text x=\"413\" y=\"161\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">Administration</text><text x=\"413\" y=\"285\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">Information Technology</text><text x=\"248\" y=\"361\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">Customer Support</text><text x=\"111\" y=\"285\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">Development</text><text x=\"128\" y=\"161\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">Marketing</text><path d=\"M 300 138\nL 320 207\nL 372 259\nL 300 333\nL 196 278\nL 223 174\nL 300 138\" style=\"stroke-width:2;stroke:rgb(84,112,198);fill:none\"/><path d=\"M 300 138\nL 320 207\nL 372 259\nL 300 333\nL 196 278\nL 223 174\nL 300 138\" style=\"stroke:none;fill:rgba(84,112,198,0.1)\"/><circle cx=\"300\" cy=\"138\" r=\"2\" style=\"stroke-width:2;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"320\" cy=\"207\" r=\"2\" style=\"stroke-width:2;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"372\" cy=\"259\" r=\"2\" style=\"stroke-width:2;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"300\" cy=\"333\" r=\"2\" style=\"stroke-width:2;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"196\" cy=\"278\" r=\"2\" style=\"stroke-width:2;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"223\" cy=\"174\" r=\"2\" style=\"stroke-width:2;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"300\" cy=\"138\" r=\"2\" style=\"stroke-width:2;stroke:rgb(84,112,198);fill:white\"/><path d=\"M 300 122\nL 394 164\nL 401 276\nL 300 303\nL 213 268\nL 210 166\nL 300 122\" style=\"stroke-width:2;stroke:rgb(145,204,117);fill:none\"/><path d=\"M 300 122\nL 394 164\nL 401 276\nL 300 303\nL 213 268\nL 210 166\nL 300 122\" style=\"stroke:none;fill:rgba(145,204,117,0.1)\"/><circle cx=\"300\" cy=\"122\" r=\"2\" style=\"stroke-width:2;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"394\" cy=\"164\" r=\"2\" style=\"stroke-width:2;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"401\" cy=\"276\" r=\"2\" style=\"stroke-width:2;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"300\" cy=\"303\" r=\"2\" style=\"stroke-width:2;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"213\" cy=\"268\" r=\"2\" style=\"stroke-width:2;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"210\" cy=\"166\" r=\"2\" style=\"stroke-width:2;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"300\" cy=\"122\" r=\"2\" style=\"stroke-width:2;stroke:rgb(145,204,117);fill:white\"/></svg>", data)
}
func TestFunnelRender(t *testing.T) {
t.Parallel()
values := []float64{
100, 80, 60, 40, 20,
}
p, err := FunnelRender(
values,
SVGOutputOptionFunc(),
TitleTextOptionFunc("Funnel"),
LegendLabelsOptionFunc([]string{
"Show", "Click", "Visit", "Inquiry", "Order",
}),
)
require.NoError(t, err)
data, err := p.Bytes()
require.NoError(t, err)
assertEqualSVG(t, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 600 400\"><path d=\"M 0 0\nL 600 0\nL 600 400\nL 0 400\nL 0 0\" style=\"stroke:none;fill:white\"/><path d=\"M 86 29\nL 116 29\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:none\"/><circle cx=\"101\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><text x=\"118\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Show</text><path d=\"M 176 29\nL 206 29\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:none\"/><circle cx=\"191\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><text x=\"208\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Click</text><path d=\"M 262 29\nL 292 29\" style=\"stroke-width:3;stroke:rgb(250,200,88);fill:none\"/><circle cx=\"277\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(250,200,88);fill:rgb(250,200,88)\"/><text x=\"294\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Visit</text><path d=\"M 345 29\nL 375 29\" style=\"stroke-width:3;stroke:rgb(238,102,102);fill:none\"/><circle cx=\"360\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(238,102,102);fill:rgb(238,102,102)\"/><text x=\"377\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Inquiry</text><path d=\"M 444 29\nL 474 29\" style=\"stroke-width:3;stroke:rgb(115,192,222);fill:none\"/><circle cx=\"459\" cy=\"29\" r=\"5\" style=\"stroke-width:3;stroke:rgb(115,192,222);fill:rgb(115,192,222)\"/><text x=\"476\" y=\"35\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Order</text><text x=\"20\" y=\"36\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Funnel</text><path d=\"M 20 56\nL 580 56\nL 524 119\nL 76 119\nL 20 56\" style=\"stroke:none;fill:rgb(84,112,198)\"/><text x=\"280\" y=\"87\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">(100%)</text><path d=\"M 76 121\nL 524 121\nL 468 184\nL 132 184\nL 76 121\" style=\"stroke:none;fill:rgb(145,204,117)\"/><text x=\"284\" y=\"152\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">(80%)</text><path d=\"M 132 186\nL 468 186\nL 412 249\nL 188 249\nL 132 186\" style=\"stroke:none;fill:rgb(250,200,88)\"/><text x=\"284\" y=\"217\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">(60%)</text><path d=\"M 188 251\nL 412 251\nL 356 314\nL 244 314\nL 188 251\" style=\"stroke:none;fill:rgb(238,102,102)\"/><text x=\"284\" y=\"282\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">(40%)</text><path d=\"M 244 316\nL 356 316\nL 300 379\nL 300 379\nL 244 316\" style=\"stroke:none;fill:rgb(115,192,222)\"/><text x=\"284\" y=\"347\" style=\"stroke:none;fill:rgb(70,70,70);font-size:12.8px;font-family:'Roboto Medium',sans-serif\">(20%)</text></svg>", data)
}
func TestChildRender(t *testing.T) {
p, err := LineRender(
[][]float64{
{120, 132, 101, 134, 90, 230, 210},
{150, 232, 201, 154, 190, 330, 410},
{320, 332, 301, 334, 390, 330, 320},
},
SVGOutputOptionFunc(),
XAxisLabelsOptionFunc([]string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}),
ChildOptionFunc(ChartOption{
Box: NewBox(200, 10, 500, 200),
SeriesList: NewSeriesListHorizontalBar([][]float64{
{70, 90, 110, 130},
{80, 100, 120, 140},
}).ToGenericSeriesList(),
Legend: LegendOption{
SeriesNames: []string{"2011", "2012"},
},
YAxis: []YAxisOption{
{
Labels: []string{"USA", "India", "China", "World"},
},
},
}),
)
require.NoError(t, err)
data, err := p.Bytes()
require.NoError(t, err)
assertEqualSVG(t, "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 600 400\"><path d=\"M 0 0\nL 600 0\nL 600 400\nL 0 400\nL 0 0\" style=\"stroke:none;fill:white\"/><text x=\"19\" y=\"26\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">450</text><text x=\"19\" y=\"62\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">410</text><text x=\"19\" y=\"99\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">370</text><text x=\"19\" y=\"136\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">330</text><text x=\"19\" y=\"173\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">290</text><text x=\"19\" y=\"210\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">250</text><text x=\"19\" y=\"247\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">210</text><text x=\"19\" y=\"284\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">170</text><text x=\"19\" y=\"321\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">130</text><text x=\"28\" y=\"358\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">90</text><path d=\"M 52 20\nL 580 20\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 57\nL 580 57\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 94\nL 580 94\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 131\nL 580 131\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 168\nL 580 168\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 205\nL 580 205\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 242\nL 580 242\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 279\nL 580 279\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 52 316\nL 580 316\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 56 354\nL 580 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 56 359\nL 56 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 130 359\nL 130 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 205 359\nL 205 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 280 359\nL 280 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 355 359\nL 355 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 430 359\nL 430 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 505 359\nL 505 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 580 359\nL 580 354\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><text x=\"78\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Mon</text><text x=\"154\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Tue</text><text x=\"227\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Wed</text><text x=\"304\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Thu</text><text x=\"383\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Fri</text><text x=\"456\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Sat</text><text x=\"529\" y=\"380\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">Sun</text><path d=\"M 93 327\nL 167 316\nL 242 344\nL 317 314\nL 392 354\nL 467 225\nL 542 243\" style=\"stroke-width:2;stroke:rgb(84,112,198);fill:none\"/><circle cx=\"93\" cy=\"327\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"167\" cy=\"316\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"242\" cy=\"344\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"317\" cy=\"314\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"392\" cy=\"354\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"467\" cy=\"225\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><circle cx=\"542\" cy=\"243\" r=\"2\" style=\"stroke-width:1;stroke:rgb(84,112,198);fill:white\"/><path d=\"M 93 299\nL 167 223\nL 242 252\nL 317 295\nL 392 262\nL 467 132\nL 542 58\" style=\"stroke-width:2;stroke:rgb(145,204,117);fill:none\"/><circle cx=\"93\" cy=\"299\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"167\" cy=\"223\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"242\" cy=\"252\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"317\" cy=\"295\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"392\" cy=\"262\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"467\" cy=\"132\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><circle cx=\"542\" cy=\"58\" r=\"2\" style=\"stroke-width:1;stroke:rgb(145,204,117);fill:white\"/><path d=\"M 93 141\nL 167 130\nL 242 159\nL 317 128\nL 392 76\nL 467 132\nL 542 141\" style=\"stroke-width:2;stroke:rgb(250,200,88);fill:none\"/><circle cx=\"93\" cy=\"141\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"167\" cy=\"130\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"242\" cy=\"159\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"317\" cy=\"128\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"392\" cy=\"76\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"467\" cy=\"132\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><circle cx=\"542\" cy=\"141\" r=\"2\" style=\"stroke-width:1;stroke:rgb(250,200,88);fill:white\"/><path d=\"M 274 39\nL 304 39\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:none\"/><circle cx=\"289\" cy=\"39\" r=\"5\" style=\"stroke-width:3;stroke:rgb(84,112,198);fill:rgb(84,112,198)\"/><text x=\"306\" y=\"45\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">2011</text><path d=\"M 361 39\nL 391 39\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:none\"/><circle cx=\"376\" cy=\"39\" r=\"5\" style=\"stroke-width:3;stroke:rgb(145,204,117);fill:rgb(145,204,117)\"/><text x=\"393\" y=\"45\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">2012</text><path d=\"M 270 66\nL 270 156\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 265 66\nL 270 66\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 265 88\nL 270 88\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 265 111\nL 270 111\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 265 133\nL 270 133\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><path d=\"M 265 156\nL 270 156\" style=\"stroke-width:1;stroke:rgb(110,112,121);fill:none\"/><text x=\"219\" y=\"83\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">World</text><text x=\"220\" y=\"105\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">China</text><text x=\"226\" y=\"127\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">India</text><text x=\"230\" y=\"149\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">USA</text><text x=\"270\" y=\"175\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">70</text><text x=\"374\" y=\"175\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">110</text><text x=\"453\" y=\"175\" style=\"stroke:none;fill:rgb(70,70,70);font-size:15.3px;font-family:'Roboto Medium',sans-serif\">150</text><path d=\"M 375 66\nL 375 152\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 480 66\nL 480 152\" style=\"stroke-width:1;stroke:rgb(224,230,242);fill:none\"/><path d=\"M 271 138\nL 271 138\nL 271 142\nL 271 142\nL 271 138\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 271 116\nL 323 116\nL 323 120\nL 271 120\nL 271 116\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 271 93\nL 375 93\nL 375 97\nL 271 97\nL 271 93\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 271 71\nL 427 71\nL 427 75\nL 271 75\nL 271 71\" style=\"stroke:none;fill:rgb(84,112,198)\"/><path d=\"M 271 145\nL 297 145\nL 297 149\nL 271 149\nL 271 145\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 271 123\nL 349 123\nL 349 127\nL 271 127\nL 271 123\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 271 100\nL 401 100\nL 401 104\nL 271 104\nL 271 100\" style=\"stroke:none;fill:rgb(145,204,117)\"/><path d=\"M 271 78\nL 453 78\nL 453 82\nL 271 82\nL 271 78\" style=\"stroke:none;fill:rgb(145,204,117)\"/></svg>", data)
}