├── .eslintrc.json
├── .gitignore
├── LICENSE
├── README.md
├── demo
├── amcharts.html
├── amcharts.js
├── echarts.html
├── echarts.js
├── g2.html
├── g2.js
├── highcharts.html
├── highcharts.js
├── xcharts.html
└── xcharts.js
├── dist
├── sketchify.js
└── sketchify.min.js
├── docs
└── highcharts_demo.png
├── package-lock.json
├── package.json
├── src
├── highcharts.js
├── index.js
├── style.css
└── xcharts.js
└── webpack.config.js
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true
5 | },
6 | "extends": [
7 | "airbnb-base"
8 | ],
9 | "globals": {
10 | "Atomics": "readonly",
11 | "SharedArrayBuffer": "readonly"
12 | },
13 | "parserOptions": {
14 | "ecmaVersion": 2018,
15 | "sourceType": "module"
16 | },
17 | "rules": {
18 | "no-undef": "off",
19 | "import/extensions": "off"
20 | }
21 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | yarn.lock
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Gang Tao
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | turns svg graph into sketchy
9 |
10 |
11 | # Sketchify
12 | Sketchify is a js tool that turns svg graph into sketchy visualization. It is based on [Rough.js](https://github.com/pshihn/rough)
13 |
14 | ### Build
15 | ```sh
16 | npm install
17 | npm run build
18 | ```
19 |
20 | ### Usage
21 | To turn an existing graph that composed by svg into sketch mode.
22 |
23 | Add dependencies to your html:
24 | ```html
25 |
26 |
27 |
28 | ```
29 | Run following js code:
30 | ```javascript
31 | const option = {
32 | fillStyle: 'hachure',
33 | roughness: 1,
34 | bowing: 1,
35 | chartType: 'highcharts',
36 | };
37 | // container is the root dom element that contains related graph svg
38 | const handler = Sketchifier(container, option);
39 | handler.handify();
40 |
41 | // call restore will turn the graph back to original one
42 | handler.restore();
43 | ```
44 | Refer to [roughjs api document](https://github.com/pshihn/rough/wiki) for options of `fillStyle`, `roughness` and `bowing`.
45 |
46 | ### demo
47 |
48 | 
49 |
50 | There are 5 demo charts types:
51 | - [ECharts](https://echarts.apache.org/zh/index.html)
52 | - [AntV G2](https://antv.alipay.com/zh-cn/g2/3.x/index.html)
53 | - [highcharts](https://www.highcharts.com/)
54 | - [amcharts](https://www.amcharts.com/)
55 | - [xCharts](http://xgfe.github.io/xCharts/)
56 |
57 | After `npm run build-dev`, open related html file in `demo` folder will show you the demo.
58 |
59 | Or you can refer to following codepen pages:
60 | - [ECharts](https://codepen.io/gangtao/full/ZEEVzpw)
61 | - [AntV G2](https://codepen.io/gangtao/full/wvvRwzp)
62 | - [highcharts](https://codepen.io/gangtao/full/eYYrpBX)
63 | - [amcharts](https://codepen.io/gangtao/full/PooxBpV)
64 | - [xCharts](https://codepen.io/gangtao/full/PooxBWV)
65 |
66 |
67 | ### new chart type support
68 | Sketchify is high generalized, now I have tried to support most chart types in highcharts and xCharts, the customization is to filter some svg element that does not need to sketchify. Adding a blacklist of related element class. In case you want to do something similar, refer to [highcharts.js](./src/highcharts.js)
69 |
--------------------------------------------------------------------------------
/demo/amcharts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | sketchify
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/demo/amcharts.js:
--------------------------------------------------------------------------------
1 | function drawBarChart() {
2 | // Create chart instance
3 | var chart = am4core.create("container_bar", am4charts.XYChart);
4 | // Add data
5 | chart.data = [{
6 | "country": "USA",
7 | "visits": 2025
8 | }, {
9 | "country": "China",
10 | "visits": 1882
11 | }, {
12 | "country": "Japan",
13 | "visits": 1809
14 | }, {
15 | "country": "Germany",
16 | "visits": 1322
17 | }, {
18 | "country": "UK",
19 | "visits": 1122
20 | }, {
21 | "country": "France",
22 | "visits": 1114
23 | }, {
24 | "country": "India",
25 | "visits": 984
26 | }, {
27 | "country": "Spain",
28 | "visits": 711
29 | }, {
30 | "country": "Netherlands",
31 | "visits": 665
32 | }, {
33 | "country": "Russia",
34 | "visits": 580
35 | }, {
36 | "country": "South Korea",
37 | "visits": 443
38 | }, {
39 | "country": "Canada",
40 | "visits": 441
41 | }, {
42 | "country": "Brazil",
43 | "visits": 395
44 | }];
45 |
46 | // Create axes
47 | var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
48 | categoryAxis.dataFields.category = "country";
49 | categoryAxis.renderer.grid.template.location = 0;
50 | categoryAxis.renderer.minGridDistance = 30;
51 |
52 | categoryAxis.renderer.labels.template.adapter.add("dy", function(dy, target) {
53 | if (target.dataItem && target.dataItem.index & 2 == 2) {
54 | return dy + 25;
55 | }
56 | return dy;
57 | });
58 |
59 | var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
60 |
61 | // Create series
62 | var series = chart.series.push(new am4charts.ColumnSeries());
63 | series.dataFields.valueY = "visits";
64 | series.dataFields.categoryX = "country";
65 | series.name = "Visits";
66 | series.columns.template.tooltipText = "{categoryX}: [bold]{valueY}[/]";
67 | series.columns.template.fillOpacity = .8;
68 |
69 | var columnTemplate = series.columns.template;
70 | columnTemplate.strokeWidth = 2;
71 | columnTemplate.strokeOpacity = 1;
72 | }
73 |
74 | function drawScatterChart() {
75 | var chart = am4core.create("container_scatter", am4charts.XYChart);
76 |
77 | var valueAxisX = chart.xAxes.push(new am4charts.ValueAxis());
78 | valueAxisX.renderer.ticks.template.disabled = true;
79 | valueAxisX.renderer.axisFills.template.disabled = true;
80 |
81 | var valueAxisY = chart.yAxes.push(new am4charts.ValueAxis());
82 | valueAxisY.renderer.ticks.template.disabled = true;
83 | valueAxisY.renderer.axisFills.template.disabled = true;
84 |
85 | var series = chart.series.push(new am4charts.LineSeries());
86 | series.dataFields.valueX = "x";
87 | series.dataFields.valueY = "y";
88 | series.dataFields.value = "value";
89 | series.strokeOpacity = 0;
90 | series.sequencedInterpolation = true;
91 | series.tooltip.pointerOrientation = "vertical";
92 |
93 | var bullet = series.bullets.push(new am4core.Circle());
94 | bullet.fill = am4core.color("#ff0000");
95 | bullet.propertyFields.fill = "color";
96 | bullet.strokeOpacity = 0;
97 | bullet.strokeWidth = 2;
98 | bullet.fillOpacity = 0.5;
99 | bullet.stroke = am4core.color("#ffffff");
100 | bullet.hiddenState.properties.opacity = 0;
101 | bullet.tooltipText = "[bold]{title}:[/]\nPopulation: {value.value}\nIncome: {valueX.value}\nLife expectancy:{valueY.value}";
102 |
103 | var outline = chart.plotContainer.createChild(am4core.Circle);
104 | outline.fillOpacity = 0;
105 | outline.strokeOpacity = 0.8;
106 | outline.stroke = am4core.color("#ff0000");
107 | outline.strokeWidth = 2;
108 | outline.hide(0);
109 |
110 | var blurFilter = new am4core.BlurFilter();
111 | outline.filters.push(blurFilter);
112 |
113 | series.heatRules.push({
114 | target: bullet,
115 | min: 2,
116 | max: 60,
117 | property: "radius"
118 | });
119 |
120 |
121 | chart.cursor = new am4charts.XYCursor();
122 | chart.cursor.behavior = "zoomXY";
123 | chart.cursor.snapToSeries = series;
124 |
125 | chart.data = [{
126 | "title": "Afghanistan",
127 | "id": "AF",
128 | "color": "#eea638",
129 | "continent": "asia",
130 | "x": 1349.69694102398,
131 | "y": 60.524,
132 | "value": 33397058
133 | }, {
134 | "title": "Albania",
135 | "id": "AL",
136 | "color": "#d8854f",
137 | "continent": "europe",
138 | "x": 6969.30628256456,
139 | "y": 77.185,
140 | "value": 3227373
141 | }, {
142 | "title": "Algeria",
143 | "id": "DZ",
144 | "color": "#de4c4f",
145 | "continent": "africa",
146 | "x": 6419.12782939372,
147 | "y": 70.874,
148 | "value": 36485828
149 | }, {
150 | "title": "Angola",
151 | "id": "AO",
152 | "color": "#de4c4f",
153 | "continent": "africa",
154 | "x": 5838.15537582502,
155 | "y": 51.498,
156 | "value": 20162517
157 | }, {
158 | "title": "Argentina",
159 | "id": "AR",
160 | "color": "#86a965",
161 | "continent": "south_america",
162 | "x": 15714.1031814398,
163 | "y": 76.128,
164 | "value": 41118986
165 | }, {
166 | "title": "Armenia",
167 | "id": "AM",
168 | "color": "#d8854f",
169 | "continent": "europe",
170 | "x": 5059.0879636443,
171 | "y": 74.469,
172 | "value": 3108972
173 | }, {
174 | "title": "Australia",
175 | "id": "AU",
176 | "color": "#8aabb0",
177 | "continent": "australia",
178 | "x": 36064.7372768548,
179 | "y": 82.364,
180 | "value": 22918688
181 | }, {
182 | "title": "Austria",
183 | "id": "AT",
184 | "color": "#d8854f",
185 | "continent": "europe",
186 | "x": 36731.6287741081,
187 | "y": 80.965,
188 | "value": 8428915
189 | }, {
190 | "title": "Azerbaijan",
191 | "id": "AZ",
192 | "color": "#d8854f",
193 | "continent": "europe",
194 | "x": 9291.02626998762,
195 | "y": 70.686,
196 | "value": 9421233
197 | }, {
198 | "title": "Bahrain",
199 | "id": "BH",
200 | "color": "#eea638",
201 | "continent": "asia",
202 | "x": 24472.896235865,
203 | "y": 76.474,
204 | "value": 1359485
205 | }, {
206 | "title": "Bangladesh",
207 | "id": "BD",
208 | "color": "#eea638",
209 | "continent": "asia",
210 | "x": 1792.55023464123,
211 | "y": 70.258,
212 | "value": 152408774
213 | }, {
214 | "title": "Belarus",
215 | "id": "BY",
216 | "color": "#d8854f",
217 | "continent": "europe",
218 | "x": 13515.1610255056,
219 | "y": 69.829,
220 | "value": 9527498
221 | }, {
222 | "title": "Belgium",
223 | "id": "BE",
224 | "color": "#d8854f",
225 | "continent": "europe",
226 | "x": 32585.0119650436,
227 | "y": 80.373,
228 | "value": 10787788
229 | }, {
230 | "title": "Benin",
231 | "id": "BJ",
232 | "color": "#de4c4f",
233 | "continent": "africa",
234 | "x": 1464.13825459126,
235 | "y": 59.165,
236 | "value": 9351838
237 | }, {
238 | "title": "Bhutan",
239 | "id": "BT",
240 | "color": "#eea638",
241 | "continent": "asia",
242 | "x": 6130.86235464324,
243 | "y": 67.888,
244 | "value": 750443
245 | }, {
246 | "title": "Bolivia",
247 | "id": "BO",
248 | "color": "#86a965",
249 | "continent": "south_america",
250 | "x": 4363.43264453337,
251 | "y": 66.969,
252 | "value": 10248042
253 | }, {
254 | "title": "Bosnia and Herzegovina",
255 | "id": "BA",
256 | "color": "#d8854f",
257 | "continent": "europe",
258 | "x": 7664.15281166303,
259 | "y": 76.211,
260 | "value": 3744235
261 | }, {
262 | "title": "Botswana",
263 | "id": "BW",
264 | "color": "#de4c4f",
265 | "continent": "africa",
266 | "x": 14045.9403255843,
267 | "y": 47.152,
268 | "value": 2053237
269 | }, {
270 | "title": "Brazil",
271 | "id": "BR",
272 | "color": "#86a965",
273 | "continent": "south_america",
274 | "x": 10383.5405937283,
275 | "y": 73.667,
276 | "value": 198360943
277 | }, {
278 | "title": "Brunei",
279 | "id": "BN",
280 | "color": "#eea638",
281 | "continent": "asia",
282 | "x": 45658.2532642054,
283 | "y": 78.35,
284 | "value": 412892
285 | }, {
286 | "title": "Bulgaria",
287 | "id": "BG",
288 | "color": "#d8854f",
289 | "continent": "europe",
290 | "x": 11669.7223127119,
291 | "y": 73.448,
292 | "value": 7397873
293 | }, {
294 | "title": "Burkina Faso",
295 | "id": "BF",
296 | "color": "#de4c4f",
297 | "continent": "africa",
298 | "x": 1363.77981282077,
299 | "y": 55.932,
300 | "value": 17481984
301 | }, {
302 | "title": "Burundi",
303 | "id": "BI",
304 | "color": "#de4c4f",
305 | "continent": "africa",
306 | "x": 484.090924612833,
307 | "y": 53.637,
308 | "value": 8749387
309 | }, {
310 | "title": "Cambodia",
311 | "id": "KH",
312 | "color": "#eea638",
313 | "continent": "asia",
314 | "x": 2076.68958647462,
315 | "y": 71.577,
316 | "value": 14478320
317 | }, {
318 | "title": "Cameroon",
319 | "id": "CM",
320 | "color": "#de4c4f",
321 | "continent": "africa",
322 | "x": 2094.09541317011,
323 | "y": 54.61,
324 | "value": 20468943
325 | }, {
326 | "title": "Canada",
327 | "id": "CA",
328 | "color": "#a7a737",
329 | "continent": "north_america",
330 | "x": 35992.8327204722,
331 | "y": 81.323,
332 | "value": 34674708
333 | }, {
334 | "title": "Cape Verde",
335 | "id": "CV",
336 | "color": "#de4c4f",
337 | "continent": "africa",
338 | "x": 3896.04113919638,
339 | "y": 74.771,
340 | "value": 505335
341 | }, {
342 | "title": "Central African Rep.",
343 | "id": "CF",
344 | "color": "#de4c4f",
345 | "continent": "africa",
346 | "x": 718.264633200085,
347 | "y": 49.517,
348 | "value": 4575586
349 | }, {
350 | "title": "Chad",
351 | "id": "TD",
352 | "color": "#de4c4f",
353 | "continent": "africa",
354 | "x": 1768.88201756553,
355 | "y": 50.724,
356 | "value": 11830573
357 | }, {
358 | "title": "Chile",
359 | "id": "CL",
360 | "color": "#86a965",
361 | "continent": "south_america",
362 | "x": 15403.7608144625,
363 | "y": 79.691,
364 | "value": 17423214
365 | }, {
366 | "title": "China",
367 | "id": "CN",
368 | "color": "#eea638",
369 | "continent": "asia",
370 | "x": 9501.57424554247,
371 | "y": 75.178,
372 | "value": 1353600687
373 | }, {
374 | "title": "Colombia",
375 | "id": "CO",
376 | "color": "#86a965",
377 | "continent": "south_america",
378 | "x": 8035.65638212719,
379 | "y": 73.835,
380 | "value": 47550708
381 | }, {
382 | "title": "Comoros",
383 | "id": "KM",
384 | "color": "#de4c4f",
385 | "continent": "africa",
386 | "x": 1027.40854349726,
387 | "y": 60.661,
388 | "value": 773344
389 | }, {
390 | "title": "Congo, Dem. Rep.",
391 | "id": "CD",
392 | "color": "#de4c4f",
393 | "continent": "africa",
394 | "x": 403.164594003407,
395 | "y": 49.643,
396 | "value": 69575394
397 | }, {
398 | "title": "Congo, Rep.",
399 | "id": "CG",
400 | "color": "#de4c4f",
401 | "continent": "africa",
402 | "x": 4106.51173855966,
403 | "y": 58.32,
404 | "value": 4233063
405 | }, {
406 | "title": "Costa Rica",
407 | "id": "CR",
408 | "color": "#a7a737",
409 | "continent": "north_america",
410 | "x": 10827.6787293035,
411 | "y": 79.712,
412 | "value": 4793725
413 | }, {
414 | "title": "Cote d'Ivoire",
415 | "id": "CI",
416 | "color": "#de4c4f",
417 | "continent": "africa",
418 | "x": 1491.51631215108,
419 | "y": 50.367,
420 | "value": 20594615
421 | }, {
422 | "title": "Croatia",
423 | "id": "HR",
424 | "color": "#d8854f",
425 | "continent": "europe",
426 | "x": 13388.9902780816,
427 | "y": 76.881,
428 | "value": 4387376
429 | }, {
430 | "title": "Cuba",
431 | "id": "CU",
432 | "color": "#a7a737",
433 | "continent": "north_america",
434 | "x": 10197.4191892126,
435 | "y": 79.088,
436 | "value": 11249266
437 | }, {
438 | "title": "Cyprus",
439 | "id": "CY",
440 | "color": "#d8854f",
441 | "continent": "europe",
442 | "x": 23092.089792339,
443 | "y": 79.674,
444 | "value": 1129166
445 | }, {
446 | "title": "Czech Rep.",
447 | "id": "CZ",
448 | "color": "#d8854f",
449 | "continent": "europe",
450 | "x": 22565.2975367042,
451 | "y": 77.552,
452 | "value": 10565678
453 | }, {
454 | "title": "Denmark",
455 | "id": "DK",
456 | "color": "#d8854f",
457 | "continent": "europe",
458 | "x": 32731.2903910132,
459 | "y": 79.251,
460 | "value": 5592738
461 | }, {
462 | "title": "Djibouti",
463 | "id": "DJ",
464 | "color": "#de4c4f",
465 | "continent": "africa",
466 | "x": 2244.60241376688,
467 | "y": 61.319,
468 | "value": 922708
469 | }, {
470 | "title": "Dominican Rep.",
471 | "id": "DO",
472 | "color": "#a7a737",
473 | "continent": "north_america",
474 | "x": 6978.89657264408,
475 | "y": 73.181,
476 | "value": 10183339
477 | }, {
478 | "title": "Ecuador",
479 | "id": "EC",
480 | "color": "#86a965",
481 | "continent": "south_america",
482 | "x": 7903.09487034651,
483 | "y": 76.195,
484 | "value": 14864987
485 | }, {
486 | "title": "Egypt",
487 | "id": "EG",
488 | "color": "#de4c4f",
489 | "continent": "africa",
490 | "x": 6013.821462967,
491 | "y": 70.933,
492 | "value": 83958369
493 | }, {
494 | "title": "El Salvador",
495 | "id": "SV",
496 | "color": "#a7a737",
497 | "continent": "north_america",
498 | "x": 5833.63022804714,
499 | "y": 72.361,
500 | "value": 6264129
501 | }, {
502 | "title": "Equatorial Guinea",
503 | "id": "GQ",
504 | "color": "#de4c4f",
505 | "continent": "africa",
506 | "x": 13499.2115504397,
507 | "y": 52.562,
508 | "value": 740471
509 | }, {
510 | "title": "Eritrea",
511 | "id": "ER",
512 | "color": "#de4c4f",
513 | "continent": "africa",
514 | "x": 613.716963797415,
515 | "y": 62.329,
516 | "value": 5580862
517 | }, {
518 | "title": "Estonia",
519 | "id": "EE",
520 | "color": "#d8854f",
521 | "continent": "europe",
522 | "x": 18858.0538247661,
523 | "y": 74.335,
524 | "value": 1339762
525 | }, {
526 | "title": "Ethiopia",
527 | "id": "ET",
528 | "color": "#de4c4f",
529 | "continent": "africa",
530 | "x": 958.694705985043,
531 | "y": 62.983,
532 | "value": 86538534
533 | }, {
534 | "title": "Fiji",
535 | "id": "FJ",
536 | "color": "#8aabb0",
537 | "continent": "australia",
538 | "x": 4195.03497178682,
539 | "y": 69.626,
540 | "value": 875822
541 | }, {
542 | "title": "Finland",
543 | "id": "FI",
544 | "color": "#d8854f",
545 | "continent": "europe",
546 | "x": 31551.9534459533,
547 | "y": 80.362,
548 | "value": 5402627
549 | }, {
550 | "title": "France",
551 | "id": "FR",
552 | "color": "#d8854f",
553 | "continent": "europe",
554 | "x": 29896.4182238854,
555 | "y": 81.663,
556 | "value": 63457777
557 | }, {
558 | "title": "Gabon",
559 | "id": "GA",
560 | "color": "#de4c4f",
561 | "continent": "africa",
562 | "x": 13853.4616556007,
563 | "y": 63.115,
564 | "value": 1563873
565 | }, {
566 | "title": "Gambia",
567 | "id": "GM",
568 | "color": "#de4c4f",
569 | "continent": "africa",
570 | "x": 747.68096900917,
571 | "y": 58.59,
572 | "value": 1824777
573 | }, {
574 | "title": "Georgia",
575 | "id": "GE",
576 | "color": "#d8854f",
577 | "continent": "europe",
578 | "x": 4943.23814339098,
579 | "y": 74.162,
580 | "value": 4304363
581 | }, {
582 | "title": "Germany",
583 | "id": "DE",
584 | "color": "#d8854f",
585 | "continent": "europe",
586 | "x": 34131.8745974324,
587 | "y": 80.578,
588 | "value": 81990837
589 | }, {
590 | "title": "Ghana",
591 | "id": "GH",
592 | "color": "#de4c4f",
593 | "continent": "africa",
594 | "x": 1728.47847396661,
595 | "y": 60.979,
596 | "value": 25545939
597 | }, {
598 | "title": "Greece",
599 | "id": "GR",
600 | "color": "#d8854f",
601 | "continent": "europe",
602 | "x": 21811.3302462212,
603 | "y": 80.593,
604 | "value": 11418878
605 | }, {
606 | "title": "Guatemala",
607 | "id": "GT",
608 | "color": "#a7a737",
609 | "continent": "north_america",
610 | "x": 5290.75202738533,
611 | "y": 71.77,
612 | "value": 15137569
613 | }, {
614 | "title": "Guinea",
615 | "id": "GN",
616 | "color": "#de4c4f",
617 | "continent": "africa",
618 | "x": 965.699260160386,
619 | "y": 55.865,
620 | "value": 10480710
621 | }, {
622 | "title": "Guinea-Bissau",
623 | "id": "GW",
624 | "color": "#de4c4f",
625 | "continent": "africa",
626 | "x": 593.074251034428,
627 | "y": 54.054,
628 | "value": 1579632
629 | }, {
630 | "title": "Guyana",
631 | "id": "GY",
632 | "color": "#86a965",
633 | "continent": "south_america",
634 | "x": 4265.10644905906,
635 | "y": 66.134,
636 | "value": 757623
637 | }, {
638 | "title": "Haiti",
639 | "id": "HT",
640 | "color": "#a7a737",
641 | "continent": "north_america",
642 | "x": 1180.36719611488,
643 | "y": 62.746,
644 | "value": 10255644
645 | }, {
646 | "title": "Honduras",
647 | "id": "HN",
648 | "color": "#a7a737",
649 | "continent": "north_america",
650 | "x": 3615.1565803195,
651 | "y": 73.503,
652 | "value": 7912032
653 | }, {
654 | "title": "Hong Kong, China",
655 | "id": "HK",
656 | "color": "#eea638",
657 | "continent": "asia",
658 | "x": 43854.4129062733,
659 | "y": 83.199,
660 | "value": 7196450
661 | }, {
662 | "title": "Hungary",
663 | "id": "HU",
664 | "color": "#d8854f",
665 | "continent": "europe",
666 | "x": 17065.6047342876,
667 | "y": 74.491,
668 | "value": 9949589
669 | }, {
670 | "title": "Iceland",
671 | "id": "IS",
672 | "color": "#d8854f",
673 | "continent": "europe",
674 | "x": 34371.1793657215,
675 | "y": 81.96,
676 | "value": 328290
677 | }, {
678 | "title": "India",
679 | "id": "IN",
680 | "color": "#eea638",
681 | "continent": "asia",
682 | "x": 3229.14788745778,
683 | "y": 66.168,
684 | "value": 1258350971
685 | }, {
686 | "title": "Indonesia",
687 | "id": "ID",
688 | "color": "#eea638",
689 | "continent": "asia",
690 | "x": 4379.69981934714,
691 | "y": 70.624,
692 | "value": 244769110
693 | }, {
694 | "title": "Iran",
695 | "id": "IR",
696 | "color": "#eea638",
697 | "continent": "asia",
698 | "x": 12325.1280322371,
699 | "y": 73.736,
700 | "value": 75611798
701 | }, {
702 | "title": "Iraq",
703 | "id": "IQ",
704 | "color": "#eea638",
705 | "continent": "asia",
706 | "x": 4160.84708826172,
707 | "y": 69.181,
708 | "value": 33703068
709 | }, {
710 | "title": "Ireland",
711 | "id": "IE",
712 | "color": "#d8854f",
713 | "continent": "europe",
714 | "x": 35856.1099094562,
715 | "y": 80.531,
716 | "value": 4579498
717 | }, {
718 | "title": "Israel",
719 | "id": "IL",
720 | "color": "#eea638",
721 | "continent": "asia",
722 | "x": 27321.205182135,
723 | "y": 81.641,
724 | "value": 7694670
725 | }, {
726 | "title": "Italy",
727 | "id": "IT",
728 | "color": "#d8854f",
729 | "continent": "europe",
730 | "x": 25811.7393303661,
731 | "y": 82.235,
732 | "value": 60964145
733 | }, {
734 | "title": "Jamaica",
735 | "id": "JM",
736 | "color": "#a7a737",
737 | "continent": "north_america",
738 | "x": 6945.70274711582,
739 | "y": 73.338,
740 | "value": 2761331
741 | }, {
742 | "title": "Japan",
743 | "id": "JP",
744 | "color": "#eea638",
745 | "continent": "asia",
746 | "x": 31273.9932002261,
747 | "y": 83.418,
748 | "value": 126434653
749 | }, {
750 | "title": "Jordan",
751 | "id": "JO",
752 | "color": "#eea638",
753 | "continent": "asia",
754 | "x": 5242.51826246118,
755 | "y": 73.7,
756 | "value": 6457260
757 | }, {
758 | "title": "Kazakhstan",
759 | "id": "KZ",
760 | "color": "#eea638",
761 | "continent": "asia",
762 | "x": 11982.6526657273,
763 | "y": 66.394,
764 | "value": 16381297
765 | }, {
766 | "title": "Kenya",
767 | "id": "KE",
768 | "color": "#de4c4f",
769 | "continent": "africa",
770 | "x": 1517.69754383602,
771 | "y": 61.115,
772 | "value": 42749418
773 | }, {
774 | "title": "Korea, Dem. Rep.",
775 | "id": "KP",
776 | "color": "#eea638",
777 | "continent": "asia",
778 | "x": 1540.44018783769,
779 | "y": 69.701,
780 | "value": 24553672
781 | }, {
782 | "title": "Korea, Rep.",
783 | "id": "KR",
784 | "color": "#eea638",
785 | "continent": "asia",
786 | "x": 26199.4035642374,
787 | "y": 81.294,
788 | "value": 48588326
789 | }, {
790 | "title": "Kuwait",
791 | "id": "KW",
792 | "color": "#eea638",
793 | "continent": "asia",
794 | "x": 42045.05923634,
795 | "y": 74.186,
796 | "value": 2891553
797 | }, {
798 | "title": "Kyrgyzstan",
799 | "id": "KG",
800 | "color": "#eea638",
801 | "continent": "asia",
802 | "x": 2078.20824171434,
803 | "y": 67.37,
804 | "value": 5448085
805 | }, {
806 | "title": "Laos",
807 | "id": "LA",
808 | "color": "#eea638",
809 | "continent": "asia",
810 | "x": 2807.04752629832,
811 | "y": 67.865,
812 | "value": 6373934
813 | }, {
814 | "title": "Latvia",
815 | "id": "LV",
816 | "color": "#d8854f",
817 | "continent": "europe",
818 | "x": 15575.2762808015,
819 | "y": 72.045,
820 | "value": 2234572
821 | }, {
822 | "title": "Lebanon",
823 | "id": "LB",
824 | "color": "#eea638",
825 | "continent": "asia",
826 | "x": 13711.975683994,
827 | "y": 79.716,
828 | "value": 4291719
829 | }, {
830 | "title": "Lesotho",
831 | "id": "LS",
832 | "color": "#de4c4f",
833 | "continent": "africa",
834 | "x": 1970.47114938861,
835 | "y": 48.947,
836 | "value": 2216850
837 | }, {
838 | "title": "Liberia",
839 | "id": "LR",
840 | "color": "#de4c4f",
841 | "continent": "africa",
842 | "x": 499.809082037359,
843 | "y": 60.23,
844 | "value": 4244684
845 | }, {
846 | "title": "Libya",
847 | "id": "LY",
848 | "color": "#de4c4f",
849 | "continent": "africa",
850 | "x": 9136.34462458268,
851 | "y": 75.13,
852 | "value": 6469497
853 | }, {
854 | "title": "Lithuania",
855 | "id": "LT",
856 | "color": "#d8854f",
857 | "continent": "europe",
858 | "x": 18469.9748244583,
859 | "y": 71.942,
860 | "value": 3292454
861 | }, {
862 | "title": "Macedonia, FYR",
863 | "id": "MK",
864 | "color": "#d8854f",
865 | "continent": "europe",
866 | "x": 8918.81131421927,
867 | "y": 75.041,
868 | "value": 2066785
869 | }, {
870 | "title": "Madagascar",
871 | "id": "MG",
872 | "color": "#de4c4f",
873 | "continent": "africa",
874 | "x": 981.478674981018,
875 | "y": 64.28,
876 | "value": 21928518
877 | }, {
878 | "title": "Malawi",
879 | "id": "MW",
880 | "color": "#de4c4f",
881 | "continent": "africa",
882 | "x": 848.191013907702,
883 | "y": 54.798,
884 | "value": 15882815
885 | }, {
886 | "title": "Malaysia",
887 | "id": "MY",
888 | "color": "#eea638",
889 | "continent": "asia",
890 | "x": 14202.2119391177,
891 | "y": 74.836,
892 | "value": 29321798
893 | }, {
894 | "title": "Mali",
895 | "id": "ML",
896 | "color": "#de4c4f",
897 | "continent": "africa",
898 | "x": 1070.55152828447,
899 | "y": 54.622,
900 | "value": 16318897
901 | }, {
902 | "title": "Mauritania",
903 | "id": "MR",
904 | "color": "#de4c4f",
905 | "continent": "africa",
906 | "x": 1898.35192059663,
907 | "y": 61.39,
908 | "value": 3622961
909 | }, {
910 | "title": "Mauritius",
911 | "id": "MU",
912 | "color": "#de4c4f",
913 | "continent": "africa",
914 | "x": 13082.7750766535,
915 | "y": 73.453,
916 | "value": 1313803
917 | }, {
918 | "title": "Mexico",
919 | "id": "MX",
920 | "color": "#a7a737",
921 | "continent": "north_america",
922 | "x": 12030.3862129571,
923 | "y": 77.281,
924 | "value": 116146768
925 | }, {
926 | "title": "Moldova",
927 | "id": "MD",
928 | "color": "#d8854f",
929 | "continent": "europe",
930 | "x": 2963.99305976246,
931 | "y": 68.779,
932 | "value": 3519266
933 | }, {
934 | "title": "Mongolia",
935 | "id": "MN",
936 | "color": "#eea638",
937 | "continent": "asia",
938 | "x": 4300.13326887206,
939 | "y": 67.286,
940 | "value": 2844081
941 | }, {
942 | "title": "Montenegro",
943 | "id": "ME",
944 | "color": "#d8854f",
945 | "continent": "europe",
946 | "x": 10064.1609429569,
947 | "y": 74.715,
948 | "value": 632796
949 | }, {
950 | "title": "Morocco",
951 | "id": "MA",
952 | "color": "#de4c4f",
953 | "continent": "africa",
954 | "x": 4514.51993561297,
955 | "y": 70.714,
956 | "value": 32598536
957 | }, {
958 | "title": "Mozambique",
959 | "id": "MZ",
960 | "color": "#de4c4f",
961 | "continent": "africa",
962 | "x": 1058.44192915498,
963 | "y": 49.91,
964 | "value": 24475186
965 | }, {
966 | "title": "Myanmar",
967 | "id": "MM",
968 | "color": "#eea638",
969 | "continent": "asia",
970 | "x": 1657.04593430092,
971 | "y": 65.009,
972 | "value": 48724387
973 | }, {
974 | "title": "Namibia",
975 | "id": "NA",
976 | "color": "#de4c4f",
977 | "continent": "africa",
978 | "x": 5535.83674233219,
979 | "y": 64.014,
980 | "value": 2364433
981 | }, {
982 | "title": "Nepal",
983 | "id": "NP",
984 | "color": "#eea638",
985 | "continent": "asia",
986 | "x": 1264.49264527071,
987 | "y": 67.989,
988 | "value": 31011137
989 | }, {
990 | "title": "Netherlands",
991 | "id": "NL",
992 | "color": "#d8854f",
993 | "continent": "europe",
994 | "x": 36257.0874018501,
995 | "y": 80.906,
996 | "value": 16714228
997 | }, {
998 | "title": "New Zealand",
999 | "id": "NZ",
1000 | "color": "#8aabb0",
1001 | "continent": "australia",
1002 | "x": 25223.5351395532,
1003 | "y": 80.982,
1004 | "value": 4461257
1005 | }, {
1006 | "title": "Nicaragua",
1007 | "id": "NI",
1008 | "color": "#a7a737",
1009 | "continent": "north_america",
1010 | "x": 3098.48351674394,
1011 | "y": 74.515,
1012 | "value": 5954898
1013 | }, {
1014 | "title": "Niger",
1015 | "id": "NE",
1016 | "color": "#de4c4f",
1017 | "continent": "africa",
1018 | "x": 706.79424834157,
1019 | "y": 57.934,
1020 | "value": 16644339
1021 | }, {
1022 | "title": "Nigeria",
1023 | "id": "NG",
1024 | "color": "#de4c4f",
1025 | "continent": "africa",
1026 | "x": 2483.98940927953,
1027 | "y": 52.116,
1028 | "value": 166629383
1029 | }, {
1030 | "title": "Norway",
1031 | "id": "NO",
1032 | "color": "#d8854f",
1033 | "continent": "europe",
1034 | "x": 47383.6245293861,
1035 | "y": 81.367,
1036 | "value": 4960482
1037 | }, {
1038 | "title": "Oman",
1039 | "id": "OM",
1040 | "color": "#eea638",
1041 | "continent": "asia",
1042 | "x": 26292.8480723207,
1043 | "y": 76.287,
1044 | "value": 2904037
1045 | }, {
1046 | "title": "Pakistan",
1047 | "id": "PK",
1048 | "color": "#eea638",
1049 | "continent": "asia",
1050 | "x": 2681.12078190231,
1051 | "y": 66.42,
1052 | "value": 179951140
1053 | }, {
1054 | "title": "Panama",
1055 | "id": "PA",
1056 | "color": "#a7a737",
1057 | "continent": "north_america",
1058 | "x": 13607.1433621853,
1059 | "y": 77.342,
1060 | "value": 3624991
1061 | }, {
1062 | "title": "Papua New Guinea",
1063 | "id": "PG",
1064 | "color": "#8aabb0",
1065 | "continent": "australia",
1066 | "x": 2391.5795121997,
1067 | "y": 62.288,
1068 | "value": 7170112
1069 | }, {
1070 | "title": "Paraguay",
1071 | "id": "PY",
1072 | "color": "#86a965",
1073 | "continent": "south_america",
1074 | "x": 4467.15872465943,
1075 | "y": 72.181,
1076 | "value": 6682943
1077 | }, {
1078 | "title": "Peru",
1079 | "id": "PE",
1080 | "color": "#86a965",
1081 | "continent": "south_america",
1082 | "x": 9277.57076044381,
1083 | "y": 74.525,
1084 | "value": 29733829
1085 | }, {
1086 | "title": "Philippines",
1087 | "id": "PH",
1088 | "color": "#eea638",
1089 | "continent": "asia",
1090 | "x": 3677.10197520058,
1091 | "y": 68.538,
1092 | "value": 96471461
1093 | }, {
1094 | "title": "Poland",
1095 | "id": "PL",
1096 | "color": "#d8854f",
1097 | "continent": "europe",
1098 | "x": 17851.9477668397,
1099 | "y": 76.239,
1100 | "value": 38317090
1101 | }, {
1102 | "title": "Portugal",
1103 | "id": "PT",
1104 | "color": "#d8854f",
1105 | "continent": "europe",
1106 | "x": 19576.4108427574,
1107 | "y": 79.732,
1108 | "value": 10699333
1109 | }, {
1110 | "title": "Romania",
1111 | "id": "RO",
1112 | "color": "#d8854f",
1113 | "continent": "europe",
1114 | "x": 11058.1809744544,
1115 | "y": 73.718,
1116 | "value": 21387517
1117 | }, {
1118 | "title": "Russia",
1119 | "id": "RU",
1120 | "color": "#d8854f",
1121 | "continent": "europe",
1122 | "x": 15427.6167470064,
1123 | "y": 67.874,
1124 | "value": 142703181
1125 | }, {
1126 | "title": "Rwanda",
1127 | "id": "RW",
1128 | "color": "#de4c4f",
1129 | "continent": "africa",
1130 | "x": 1223.52570881561,
1131 | "y": 63.563,
1132 | "value": 11271786
1133 | }, {
1134 | "title": "Saudi Arabia",
1135 | "id": "SA",
1136 | "color": "#eea638",
1137 | "continent": "asia",
1138 | "x": 26259.6213479005,
1139 | "y": 75.264,
1140 | "value": 28705133
1141 | }, {
1142 | "title": "Senegal",
1143 | "id": "SN",
1144 | "color": "#de4c4f",
1145 | "continent": "africa",
1146 | "x": 1753.48800936096,
1147 | "y": 63.3,
1148 | "value": 13107945
1149 | }, {
1150 | "title": "Serbia",
1151 | "id": "RS",
1152 | "color": "#d8854f",
1153 | "continent": "europe",
1154 | "x": 9335.95911484282,
1155 | "y": 73.934,
1156 | "value": 9846582
1157 | }, {
1158 | "title": "Sierra Leone",
1159 | "id": "SL",
1160 | "color": "#de4c4f",
1161 | "continent": "africa",
1162 | "x": 1072.95787930719,
1163 | "y": 45.338,
1164 | "value": 6126450
1165 | }, {
1166 | "title": "Singapore",
1167 | "id": "SG",
1168 | "color": "#eea638",
1169 | "continent": "asia",
1170 | "x": 49381.9560054179,
1171 | "y": 82.155,
1172 | "value": 5256278
1173 | }, {
1174 | "title": "Slovak Republic",
1175 | "id": "SK",
1176 | "color": "#d8854f",
1177 | "continent": "europe",
1178 | "x": 20780.9857840812,
1179 | "y": 75.272,
1180 | "value": 5480332
1181 | }, {
1182 | "title": "Slovenia",
1183 | "id": "SI",
1184 | "color": "#d8854f",
1185 | "continent": "europe",
1186 | "x": 23986.8506836646,
1187 | "y": 79.444,
1188 | "value": 2040057
1189 | }, {
1190 | "title": "Solomon Islands",
1191 | "id": "SB",
1192 | "color": "#8aabb0",
1193 | "continent": "australia",
1194 | "x": 2024.23067334134,
1195 | "y": 67.465,
1196 | "value": 566481
1197 | }, {
1198 | "title": "Somalia",
1199 | "id": "SO",
1200 | "color": "#de4c4f",
1201 | "continent": "africa",
1202 | "x": 953.275713662563,
1203 | "y": 54,
1204 | "value": 9797445
1205 | }, {
1206 | "title": "South Africa",
1207 | "id": "ZA",
1208 | "color": "#de4c4f",
1209 | "continent": "africa",
1210 | "x": 9657.25275417241,
1211 | "y": 56.271,
1212 | "value": 50738255
1213 | }, {
1214 | "title": "South Sudan",
1215 | "id": "SS",
1216 | "color": "#de4c4f",
1217 | "continent": "africa",
1218 | "x": 1433.03720057714,
1219 | "y": 54.666,
1220 | "value": 10386101
1221 | }, {
1222 | "title": "Spain",
1223 | "id": "ES",
1224 | "color": "#d8854f",
1225 | "continent": "europe",
1226 | "x": 26457.7572559653,
1227 | "y": 81.958,
1228 | "value": 46771596
1229 | }, {
1230 | "title": "Sri Lanka",
1231 | "id": "LK",
1232 | "color": "#eea638",
1233 | "continent": "asia",
1234 | "x": 5182.66658831813,
1235 | "y": 74.116,
1236 | "value": 21223550
1237 | }, {
1238 | "title": "Sudan",
1239 | "id": "SD",
1240 | "color": "#de4c4f",
1241 | "continent": "africa",
1242 | "x": 2917.61641581811,
1243 | "y": 61.875,
1244 | "value": 35335982
1245 | }, {
1246 | "title": "Suriname",
1247 | "id": "SR",
1248 | "color": "#86a965",
1249 | "continent": "south_america",
1250 | "x": 8979.80549248675,
1251 | "y": 70.794,
1252 | "value": 534175
1253 | }, {
1254 | "title": "Swaziland",
1255 | "id": "SZ",
1256 | "color": "#de4c4f",
1257 | "continent": "africa",
1258 | "x": 4979.704126513,
1259 | "y": 48.91,
1260 | "value": 1220408
1261 | }, {
1262 | "title": "Sweden",
1263 | "id": "SE",
1264 | "color": "#d8854f",
1265 | "continent": "europe",
1266 | "x": 34530.2628238397,
1267 | "y": 81.69,
1268 | "value": 9495392
1269 | }, {
1270 | "title": "Switzerland",
1271 | "id": "CH",
1272 | "color": "#d8854f",
1273 | "continent": "europe",
1274 | "x": 37678.3928108684,
1275 | "y": 82.471,
1276 | "value": 7733709
1277 | }, {
1278 | "title": "Syria",
1279 | "id": "SY",
1280 | "color": "#eea638",
1281 | "continent": "asia",
1282 | "x": 4432.01553897559,
1283 | "y": 71,
1284 | "value": 21117690
1285 | }, {
1286 | "title": "Taiwan",
1287 | "id": "TW",
1288 | "color": "#eea638",
1289 | "continent": "asia",
1290 | "x": 32840.8623523232,
1291 | "y": 79.45,
1292 | "value": 23114000
1293 | }, {
1294 | "title": "Tajikistan",
1295 | "id": "TJ",
1296 | "color": "#eea638",
1297 | "continent": "asia",
1298 | "x": 1952.10042735043,
1299 | "y": 67.118,
1300 | "value": 7078755
1301 | }, {
1302 | "title": "Tanzania",
1303 | "id": "TZ",
1304 | "color": "#de4c4f",
1305 | "continent": "africa",
1306 | "x": 1330.05614548839,
1307 | "y": 60.885,
1308 | "value": 47656367
1309 | }, {
1310 | "title": "Thailand",
1311 | "id": "TH",
1312 | "color": "#eea638",
1313 | "continent": "asia",
1314 | "x": 8451.15964058768,
1315 | "y": 74.225,
1316 | "value": 69892142
1317 | }, {
1318 | "title": "Timor-Leste",
1319 | "id": "TL",
1320 | "color": "#eea638",
1321 | "continent": "asia",
1322 | "x": 3466.08281224683,
1323 | "y": 67.033,
1324 | "value": 1187194
1325 | }, {
1326 | "title": "Togo",
1327 | "id": "TG",
1328 | "color": "#de4c4f",
1329 | "continent": "africa",
1330 | "x": 975.396852535221,
1331 | "y": 56.198,
1332 | "value": 6283092
1333 | }, {
1334 | "title": "Trinidad and Tobago",
1335 | "id": "TT",
1336 | "color": "#a7a737",
1337 | "continent": "north_america",
1338 | "x": 17182.0954558471,
1339 | "y": 69.761,
1340 | "value": 1350999
1341 | }, {
1342 | "title": "Tunisia",
1343 | "id": "TN",
1344 | "color": "#de4c4f",
1345 | "continent": "africa",
1346 | "x": 7620.47056462131,
1347 | "y": 75.632,
1348 | "value": 10704948
1349 | }, {
1350 | "title": "Turkey",
1351 | "id": "TR",
1352 | "color": "#d8854f",
1353 | "continent": "europe",
1354 | "x": 9287.29312549815,
1355 | "y": 74.938,
1356 | "value": 74508771
1357 | }, {
1358 | "title": "Turkmenistan",
1359 | "id": "TM",
1360 | "color": "#eea638",
1361 | "continent": "asia",
1362 | "x": 7921.2740619558,
1363 | "y": 65.299,
1364 | "value": 5169660
1365 | }, {
1366 | "title": "Uganda",
1367 | "id": "UG",
1368 | "color": "#de4c4f",
1369 | "continent": "africa",
1370 | "x": 1251.09807015907,
1371 | "y": 58.668,
1372 | "value": 35620977
1373 | }, {
1374 | "title": "Ukraine",
1375 | "id": "UA",
1376 | "color": "#d8854f",
1377 | "continent": "europe",
1378 | "x": 6389.58597273257,
1379 | "y": 68.414,
1380 | "value": 44940268
1381 | }, {
1382 | "title": "United Arab Emirates",
1383 | "id": "AE",
1384 | "color": "#eea638",
1385 | "continent": "asia",
1386 | "x": 31980.24143802,
1387 | "y": 76.671,
1388 | "value": 8105873
1389 | }, {
1390 | "title": "United Kingdom",
1391 | "id": "GB",
1392 | "color": "#d8854f",
1393 | "continent": "europe",
1394 | "x": 31295.1431522074,
1395 | "y": 80.396,
1396 | "value": 62798099
1397 | }, {
1398 | "title": "United States",
1399 | "id": "US",
1400 | "color": "#a7a737",
1401 | "continent": "north_america",
1402 | "x": 42296.2316492477,
1403 | "y": 78.797,
1404 | "value": 315791284
1405 | }, {
1406 | "title": "Uruguay",
1407 | "id": "UY",
1408 | "color": "#86a965",
1409 | "continent": "south_america",
1410 | "x": 13179.2310803465,
1411 | "y": 77.084,
1412 | "value": 3391428
1413 | }, {
1414 | "title": "Uzbekistan",
1415 | "id": "UZ",
1416 | "color": "#eea638",
1417 | "continent": "asia",
1418 | "x": 3117.27386553102,
1419 | "y": 68.117,
1420 | "value": 28077486
1421 | }, {
1422 | "title": "Venezuela",
1423 | "id": "VE",
1424 | "color": "#86a965",
1425 | "continent": "south_america",
1426 | "x": 11685.1771941737,
1427 | "y": 74.477,
1428 | "value": 29890694
1429 | }, {
1430 | "title": "West Bank and Gaza",
1431 | "id": "PS",
1432 | "color": "#eea638",
1433 | "continent": "asia",
1434 | "x": 4328.39115760087,
1435 | "y": 73.018,
1436 | "value": 4270791
1437 | }, {
1438 | "title": "Vietnam",
1439 | "id": "VN",
1440 | "color": "#eea638",
1441 | "continent": "asia",
1442 | "x": 3073.64961158389,
1443 | "y": 75.793,
1444 | "value": 89730274
1445 | }, {
1446 | "title": "Yemen, Rep.",
1447 | "id": "YE",
1448 | "color": "#eea638",
1449 | "continent": "asia",
1450 | "x": 2043.7877761328,
1451 | "y": 62.923,
1452 | "value": 25569263
1453 | }, {
1454 | "title": "Zambia",
1455 | "id": "ZM",
1456 | "color": "#de4c4f",
1457 | "continent": "africa",
1458 | "x": 1550.92385858124,
1459 | "y": 57.037,
1460 | "value": 13883577
1461 | }, {
1462 | "title": "Zimbabwe",
1463 | "id": "ZW",
1464 | "color": "#de4c4f",
1465 | "continent": "africa",
1466 | "x": 545.344601005788,
1467 | "y": 58.142,
1468 | "value": 13013678
1469 | }];
1470 | }
1471 |
1472 | function drawPieChart() {
1473 | // Create chart instance
1474 | var chart = am4core.create("container_pie", am4charts.PieChart);
1475 |
1476 | // Add and configure Series
1477 | var pieSeries = chart.series.push(new am4charts.PieSeries());
1478 | pieSeries.dataFields.value = "litres";
1479 | pieSeries.dataFields.category = "country";
1480 |
1481 | // Let's cut a hole in our Pie chart the size of 30% the radius
1482 | chart.innerRadius = am4core.percent(30);
1483 |
1484 | // Put a thick white border around each Slice
1485 | pieSeries.slices.template.stroke = am4core.color("#fff");
1486 | pieSeries.slices.template.strokeWidth = 2;
1487 | pieSeries.slices.template.strokeOpacity = 1;
1488 | pieSeries.slices.template
1489 | // change the cursor on hover to make it apparent the object can be interacted with
1490 | .cursorOverStyle = [{
1491 | "property": "cursor",
1492 | "value": "pointer"
1493 | }];
1494 |
1495 | pieSeries.alignLabels = false;
1496 | pieSeries.labels.template.bent = true;
1497 | pieSeries.labels.template.radius = 3;
1498 | pieSeries.labels.template.padding(0, 0, 0, 0);
1499 |
1500 | pieSeries.ticks.template.disabled = true;
1501 |
1502 | // Create a base filter effect (as if it's not there) for the hover to return to
1503 | var shadow = pieSeries.slices.template.filters.push(new am4core.DropShadowFilter);
1504 | shadow.opacity = 0;
1505 |
1506 | // Create hover state
1507 | var hoverState = pieSeries.slices.template.states.getKey("hover"); // normally we have to create the hover state, in this case it already exists
1508 |
1509 | // Slightly shift the shadow and make it more prominent on hover
1510 | var hoverShadow = hoverState.filters.push(new am4core.DropShadowFilter);
1511 | hoverShadow.opacity = 0.7;
1512 | hoverShadow.blur = 5;
1513 |
1514 | // Add a legend
1515 | chart.legend = new am4charts.Legend();
1516 |
1517 | chart.data = [{
1518 | "country": "Lithuania",
1519 | "litres": 501.9
1520 | }, {
1521 | "country": "Germany",
1522 | "litres": 165.8
1523 | }, {
1524 | "country": "Australia",
1525 | "litres": 139.9
1526 | }, {
1527 | "country": "Austria",
1528 | "litres": 128.3
1529 | }, {
1530 | "country": "UK",
1531 | "litres": 99
1532 | }, {
1533 | "country": "Belgium",
1534 | "litres": 60
1535 | }];
1536 | }
1537 |
1538 | function drawLineChart() {
1539 | // Create chart instance
1540 | var chart = am4core.create("container_line", am4charts.XYChart);
1541 |
1542 | chart.colors.step = 2;
1543 | chart.maskBullets = false;
1544 |
1545 | // Add data
1546 | chart.data = [{
1547 | "date": "2012-01-01",
1548 | "distance": 227,
1549 | "townName": "New York",
1550 | "townName2": "New York",
1551 | "townSize": 12,
1552 | "latitude": 40.71,
1553 | "duration": 408
1554 | }, {
1555 | "date": "2012-01-02",
1556 | "distance": 371,
1557 | "townName": "Washington",
1558 | "townSize": 7,
1559 | "latitude": 38.89,
1560 | "duration": 482
1561 | }, {
1562 | "date": "2012-01-03",
1563 | "distance": 433,
1564 | "townName": "Wilmington",
1565 | "townSize": 3,
1566 | "latitude": 34.22,
1567 | "duration": 562
1568 | }, {
1569 | "date": "2012-01-04",
1570 | "distance": 345,
1571 | "townName": "Jacksonville",
1572 | "townSize": 3.5,
1573 | "latitude": 30.35,
1574 | "duration": 379
1575 | }, {
1576 | "date": "2012-01-05",
1577 | "distance": 480,
1578 | "townName": "Miami",
1579 | "townName2": "Miami",
1580 | "townSize": 5,
1581 | "latitude": 25.83,
1582 | "duration": 501
1583 | }, {
1584 | "date": "2012-01-06",
1585 | "distance": 386,
1586 | "townName": "Tallahassee",
1587 | "townSize": 3.5,
1588 | "latitude": 30.46,
1589 | "duration": 443
1590 | }, {
1591 | "date": "2012-01-07",
1592 | "distance": 348,
1593 | "townName": "New Orleans",
1594 | "townSize": 5,
1595 | "latitude": 29.94,
1596 | "duration": 405
1597 | }, {
1598 | "date": "2012-01-08",
1599 | "distance": 238,
1600 | "townName": "Houston",
1601 | "townName2": "Houston",
1602 | "townSize": 8,
1603 | "latitude": 29.76,
1604 | "duration": 309
1605 | }, {
1606 | "date": "2012-01-09",
1607 | "distance": 218,
1608 | "townName": "Dalas",
1609 | "townSize": 8,
1610 | "latitude": 32.8,
1611 | "duration": 287
1612 | }, {
1613 | "date": "2012-01-10",
1614 | "distance": 349,
1615 | "townName": "Oklahoma City",
1616 | "townSize": 5,
1617 | "latitude": 35.49,
1618 | "duration": 485
1619 | }, {
1620 | "date": "2012-01-11",
1621 | "distance": 603,
1622 | "townName": "Kansas City",
1623 | "townSize": 5,
1624 | "latitude": 39.1,
1625 | "duration": 890
1626 | }, {
1627 | "date": "2012-01-12",
1628 | "distance": 534,
1629 | "townName": "Denver",
1630 | "townName2": "Denver",
1631 | "townSize": 9,
1632 | "latitude": 39.74,
1633 | "duration": 810
1634 | }, {
1635 | "date": "2012-01-13",
1636 | "townName": "Salt Lake City",
1637 | "townSize": 6,
1638 | "distance": 425,
1639 | "duration": 670,
1640 | "latitude": 40.75,
1641 | "dashLength": 8,
1642 | "alpha": 0.4
1643 | }, {
1644 | "date": "2012-01-14",
1645 | "latitude": 36.1,
1646 | "duration": 470,
1647 | "townName": "Las Vegas",
1648 | "townName2": "Las Vegas"
1649 | }, {
1650 | "date": "2012-01-15"
1651 | }, {
1652 | "date": "2012-01-16"
1653 | }, {
1654 | "date": "2012-01-17"
1655 | }];
1656 |
1657 | // Create axes
1658 | var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
1659 | dateAxis.renderer.grid.template.location = 0;
1660 | dateAxis.renderer.minGridDistance = 50;
1661 | dateAxis.renderer.grid.template.disabled = true;
1662 | dateAxis.renderer.fullWidthTooltip = true;
1663 |
1664 | var distanceAxis = chart.yAxes.push(new am4charts.ValueAxis());
1665 | distanceAxis.title.text = "Distance";
1666 | distanceAxis.renderer.grid.template.disabled = true;
1667 |
1668 | var durationAxis = chart.yAxes.push(new am4charts.DurationAxis());
1669 | durationAxis.title.text = "Duration";
1670 | durationAxis.baseUnit = "minute";
1671 | durationAxis.renderer.grid.template.disabled = true;
1672 | durationAxis.renderer.opposite = true;
1673 |
1674 | durationAxis.durationFormatter.durationFormat = "hh'h' mm'min'";
1675 |
1676 | var latitudeAxis = chart.yAxes.push(new am4charts.ValueAxis());
1677 | latitudeAxis.renderer.grid.template.disabled = true;
1678 | latitudeAxis.renderer.labels.template.disabled = true;
1679 |
1680 | // Create series
1681 | var distanceSeries = chart.series.push(new am4charts.ColumnSeries());
1682 | distanceSeries.dataFields.valueY = "distance";
1683 | distanceSeries.dataFields.dateX = "date";
1684 | distanceSeries.yAxis = distanceAxis;
1685 | distanceSeries.tooltipText = "{valueY} miles";
1686 | distanceSeries.name = "Distance";
1687 | distanceSeries.columns.template.fillOpacity = 0.7;
1688 | distanceSeries.columns.template.propertyFields.strokeDasharray = "dashLength";
1689 | distanceSeries.columns.template.propertyFields.fillOpacity = "alpha";
1690 |
1691 | var disatnceState = distanceSeries.columns.template.states.create("hover");
1692 | disatnceState.properties.fillOpacity = 0.9;
1693 |
1694 | var durationSeries = chart.series.push(new am4charts.LineSeries());
1695 | durationSeries.dataFields.valueY = "duration";
1696 | durationSeries.dataFields.dateX = "date";
1697 | durationSeries.yAxis = durationAxis;
1698 | durationSeries.name = "Duration";
1699 | durationSeries.strokeWidth = 2;
1700 | durationSeries.propertyFields.strokeDasharray = "dashLength";
1701 | durationSeries.tooltipText = "{valueY.formatDuration()}";
1702 |
1703 | var durationBullet = durationSeries.bullets.push(new am4charts.Bullet());
1704 | var durationRectangle = durationBullet.createChild(am4core.Rectangle);
1705 | durationBullet.horizontalCenter = "middle";
1706 | durationBullet.verticalCenter = "middle";
1707 | durationBullet.width = 7;
1708 | durationBullet.height = 7;
1709 | durationRectangle.width = 7;
1710 | durationRectangle.height = 7;
1711 |
1712 | var durationState = durationBullet.states.create("hover");
1713 | durationState.properties.scale = 1.2;
1714 |
1715 | var latitudeSeries = chart.series.push(new am4charts.LineSeries());
1716 | latitudeSeries.dataFields.valueY = "latitude";
1717 | latitudeSeries.dataFields.dateX = "date";
1718 | latitudeSeries.yAxis = latitudeAxis;
1719 | latitudeSeries.name = "Duration";
1720 | latitudeSeries.strokeWidth = 2;
1721 | latitudeSeries.propertyFields.strokeDasharray = "dashLength";
1722 | latitudeSeries.tooltipText = "Latitude: {valueY} ({townName})";
1723 |
1724 | var latitudeBullet = latitudeSeries.bullets.push(new am4charts.CircleBullet());
1725 | latitudeBullet.circle.fill = am4core.color("#fff");
1726 | latitudeBullet.circle.strokeWidth = 2;
1727 | latitudeBullet.circle.propertyFields.radius = "townSize";
1728 |
1729 | var latitudeState = latitudeBullet.states.create("hover");
1730 | latitudeState.properties.scale = 1.2;
1731 |
1732 | var latitudeLabel = latitudeSeries.bullets.push(new am4charts.LabelBullet());
1733 | latitudeLabel.label.text = "{townName2}";
1734 | latitudeLabel.label.horizontalCenter = "left";
1735 | latitudeLabel.label.dx = 14;
1736 |
1737 | // Add legend
1738 | chart.legend = new am4charts.Legend();
1739 |
1740 | // Add cursor
1741 | chart.cursor = new am4charts.XYCursor();
1742 | chart.cursor.fullWidthLineX = true;
1743 | chart.cursor.xAxis = dateAxis;
1744 | chart.cursor.lineX.strokeOpacity = 0;
1745 | chart.cursor.lineX.fill = am4core.color("#000");
1746 | chart.cursor.lineX.fillOpacity = 0.1;
1747 | }
1748 |
1749 | function drawRadarChart() {
1750 | /* Create chart instance */
1751 | var chart = am4core.create("container_radar", am4charts.RadarChart);
1752 |
1753 | /* Add data */
1754 | chart.data = [{
1755 | "country": "Lithuania",
1756 | "litres": 501
1757 | }, {
1758 | "country": "Czechia",
1759 | "litres": 301
1760 | }, {
1761 | "country": "Ireland",
1762 | "litres": 266
1763 | }, {
1764 | "country": "Germany",
1765 | "litres": 165
1766 | }, {
1767 | "country": "Australia",
1768 | "litres": 139
1769 | }, {
1770 | "country": "Austria",
1771 | "litres": 336
1772 | }, {
1773 | "country": "UK",
1774 | "litres": 290
1775 | }, {
1776 | "country": "Belgium",
1777 | "litres": 325
1778 | }, {
1779 | "country": "The Netherlands",
1780 | "litres": 40
1781 | }];
1782 |
1783 | /* Create axes */
1784 | var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
1785 | categoryAxis.dataFields.category = "country";
1786 |
1787 | var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
1788 | valueAxis.renderer.axisFills.template.fill = chart.colors.getIndex(2);
1789 | valueAxis.renderer.axisFills.template.fillOpacity = 0.05;
1790 |
1791 | /* Create and configure series */
1792 | var series = chart.series.push(new am4charts.RadarSeries());
1793 | series.dataFields.valueY = "litres";
1794 | series.dataFields.categoryX = "country";
1795 | series.name = "Sales";
1796 | series.strokeWidth = 3;
1797 | }
1798 |
1799 | function drawFunnelChart() {
1800 | var chart = am4core.create("container_funnel", am4charts.SlicedChart);
1801 | chart.hiddenState.properties.opacity = 0;
1802 | // this makes initial fade in effect
1803 |
1804 | chart.data = [{
1805 | "name": "The first",
1806 | "value": 600
1807 | }, {
1808 | "name": "The second",
1809 | "value": 300
1810 | }, {
1811 | "name": "The third",
1812 | "value": 200
1813 | }, {
1814 | "name": "The fourth",
1815 | "value": 180
1816 | }, {
1817 | "name": "The fifth",
1818 | "value": 50
1819 | }, {
1820 | "name": "The sixth",
1821 | "value": 20
1822 | }, {
1823 | "name": "The seventh",
1824 | "value": 10
1825 | }];
1826 |
1827 | var series = chart.series.push(new am4charts.FunnelSeries());
1828 | series.colors.step = 2;
1829 | series.dataFields.value = "value";
1830 | series.dataFields.category = "name";
1831 | series.alignLabels = true;
1832 | series.orientation = "horizontal";
1833 | series.bottomRatio = 1;
1834 | }
1835 |
1836 | function drawChart() {
1837 | am4core.ready(function() {
1838 | drawBarChart();
1839 | drawScatterChart();
1840 | drawPieChart();
1841 | drawLineChart();
1842 | drawRadarChart();
1843 | drawFunnelChart();
1844 | });
1845 | }
1846 |
1847 | function getHandler() {
1848 | const option = {
1849 | fillStyle: $('#fillStyleSelector').children('option:selected').val(),
1850 | bowing: $('#bowingRange').val(),
1851 | roughness: $('#roughnessRange').val()
1852 | };
1853 |
1854 | const container = $('#charts')[0];
1855 | return handler = Sketchifier(container, option);
1856 | }
1857 |
1858 | $(function() {
1859 | drawChart();
1860 | var handler = getHandler();
1861 |
1862 | function updateHandler() {
1863 | handler.restore();
1864 | handler = getHandler();
1865 | if ($('#handifyChecker').prop('checked')) {
1866 | handler.handify();
1867 | }
1868 | }
1869 |
1870 | $('#fillStyleSelector').change(function() {
1871 | updateHandler();
1872 | })
1873 |
1874 | $('#bowingRange').change(function() {
1875 | updateHandler();
1876 | })
1877 |
1878 | $('#roughnessRange').change(function() {
1879 | updateHandler();
1880 | })
1881 |
1882 | $('#handifyChecker').change(function() {
1883 | if (this.checked) {
1884 | handler.handify();
1885 | } else {
1886 | handler.restore();
1887 | }
1888 | });
1889 | });
--------------------------------------------------------------------------------
/demo/echarts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | sketchify
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/demo/echarts.js:
--------------------------------------------------------------------------------
1 | function drawBarChart() {
2 | const myChart = echarts.init(document.getElementById('container_bar'), null, {
3 | renderer: 'svg'
4 | });
5 | const option = {
6 | xAxis: {
7 | type: 'category',
8 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun中午']
9 | },
10 | yAxis: {
11 | type: 'value'
12 | },
13 | series: [{
14 | data: [120, 200, 150, 80, 70, 110, 130],
15 | type: 'bar'
16 | }]
17 | };
18 | myChart.setOption(option);
19 | }
20 |
21 | function drawScatterChart() {
22 | const myChart = echarts.init(document.getElementById('container_scatter'), null, {
23 | renderer: 'svg'
24 | });
25 |
26 | const option = {
27 | xAxis: {},
28 | yAxis: {},
29 | series: [{
30 | symbolSize: 50,
31 | data: [
32 | [10.0, 8.04],
33 | [8.0, 6.95],
34 | [13.0, 7.58],
35 | [9.0, 8.81],
36 | [11.0, 8.33],
37 | [14.0, 9.96],
38 | [6.0, 7.24],
39 | [4.0, 4.26],
40 | [12.0, 10.84],
41 | [7.0, 4.82],
42 | [5.0, 5.68]
43 | ],
44 | type: 'scatter'
45 | }]
46 | };
47 |
48 | myChart.setOption(option);
49 | }
50 |
51 | function drawPieChart() {
52 | const myChart = echarts.init(document.getElementById('container_pie'), null, {
53 | renderer: 'svg'
54 | });
55 | const option = {
56 | tooltip: {
57 | trigger: 'item',
58 | formatter: "{a} {b}: {c} ({d}%)"
59 | },
60 | legend: {
61 | orient: 'vertical',
62 | x: 'left',
63 | data: ['A', 'B', 'C', 'D', 'E']
64 | },
65 | series: [{
66 | name: 'F',
67 | type: 'pie',
68 | radius: ['50%', '70%'],
69 | avoidLabelOverlap: false,
70 | label: {
71 | normal: {
72 | show: false,
73 | position: 'center'
74 | },
75 | emphasis: {
76 | show: true,
77 | textStyle: {
78 | fontSize: '30',
79 | fontWeight: 'bold'
80 | }
81 | }
82 | },
83 | labelLine: {
84 | normal: {
85 | show: false
86 | }
87 | },
88 | data: [{
89 | value: 335,
90 | name: 'A'
91 | }, {
92 | value: 310,
93 | name: 'B'
94 | }, {
95 | value: 234,
96 | name: 'C'
97 | }, {
98 | value: 135,
99 | name: 'D'
100 | }, {
101 | value: 1548,
102 | name: 'E'
103 | }]
104 | }]
105 | };
106 |
107 | myChart.setOption(option);
108 | }
109 |
110 | function drawLineChart() {
111 | const myChart = echarts.init(document.getElementById('container_line'), null, {
112 | renderer: 'svg'
113 | });
114 | const option = {
115 | title: {
116 | text: 'Step Line'
117 | },
118 | tooltip: {
119 | trigger: 'axis'
120 | },
121 | legend: {
122 | data: ['Step Start', 'Step Middle', 'Step End']
123 | },
124 | grid: {
125 | left: '3%',
126 | right: '4%',
127 | bottom: '3%',
128 | containLabel: true
129 | },
130 | toolbox: {
131 | feature: {
132 | saveAsImage: {}
133 | }
134 | },
135 | xAxis: {
136 | type: 'category',
137 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
138 | },
139 | yAxis: {
140 | type: 'value'
141 | },
142 | series: [{
143 | name: 'Step Start',
144 | type: 'line',
145 | step: 'start',
146 | data: [120, 132, 101, 134, 90, 230, 210]
147 | }, {
148 | name: 'Step Middle',
149 | type: 'line',
150 | step: 'middle',
151 | data: [220, 282, 201, 234, 290, 430, 410]
152 | }, {
153 | name: 'Step End',
154 | type: 'line',
155 | step: 'end',
156 | data: [450, 432, 401, 454, 590, 530, 510]
157 | }]
158 | };
159 | myChart.setOption(option);
160 | }
161 |
162 | function drawRadarChart() {
163 | const myChart = echarts.init(document.getElementById('container_radar'), null, {
164 | renderer: 'svg'
165 | });
166 | const option = {
167 | title: {
168 | text: 'radar'
169 | },
170 | tooltip: {},
171 | legend: {
172 | data: ['Allocated Budget', 'Actual Spending']
173 | },
174 | radar: {
175 | // shape: 'circle',
176 | name: {
177 | textStyle: {
178 | color: '#fff',
179 | backgroundColor: '#999',
180 | borderRadius: 3,
181 | padding: [3, 5]
182 | }
183 | },
184 | indicator: [{
185 | name: 'sales',
186 | max: 6500
187 | }, {
188 | name: 'Administration',
189 | max: 16000
190 | }, {
191 | name: 'Information Techology',
192 | max: 30000
193 | }, {
194 | name: 'Customer Support',
195 | max: 38000
196 | }, {
197 | name: 'Development',
198 | max: 52000
199 | }, {
200 | name: 'Marketing',
201 | max: 25000
202 | }]
203 | },
204 | series: [{
205 | name: 'Budget vs spending',
206 | type: 'radar',
207 | // areaStyle: {normal: {}},
208 | data: [{
209 | value: [4300, 10000, 28000, 35000, 50000, 19000],
210 | name: '(Allocated Budget)'
211 | }, {
212 | value: [5000, 14000, 28000, 31000, 42000, 21000],
213 | name: '(Actual Spending)'
214 | }]
215 | }]
216 | };
217 | myChart.setOption(option);
218 | }
219 |
220 | function drawFunnelChart() {
221 | const myChart = echarts.init(document.getElementById('container_funnel'), null, {
222 | renderer: 'svg'
223 | });
224 | const option = {
225 | title: {
226 | text: '漏斗图',
227 | subtext: '纯属虚构',
228 | left: 'left',
229 | top: 'bottom'
230 | },
231 | tooltip: {
232 | trigger: 'item',
233 | formatter: "{a} {b} : {c}%"
234 | },
235 | toolbox: {
236 | orient: 'vertical',
237 | top: 'center',
238 | feature: {
239 | dataView: {
240 | readOnly: false
241 | },
242 | restore: {},
243 | saveAsImage: {}
244 | }
245 | },
246 | legend: {
247 | orient: 'vertical',
248 | left: 'left',
249 | data: ['A', 'B', 'C', 'D', 'E']
250 | },
251 | calculable: true,
252 | series: [{
253 | name: '漏斗图',
254 | type: 'funnel',
255 | width: '40%',
256 | height: '45%',
257 | left: '5%',
258 | top: '50%',
259 | data: [{
260 | value: 60,
261 | name: 'C'
262 | }, {
263 | value: 30,
264 | name: 'D'
265 | }, {
266 | value: 10,
267 | name: 'E'
268 | }, {
269 | value: 80,
270 | name: 'B'
271 | }, {
272 | value: 100,
273 | name: 'A'
274 | }]
275 | }, {
276 | name: '金字塔',
277 | type: 'funnel',
278 | width: '40%',
279 | height: '45%',
280 | left: '5%',
281 | top: '5%',
282 | sort: 'ascending',
283 | data: [{
284 | value: 60,
285 | name: 'C'
286 | }, {
287 | value: 30,
288 | name: 'D'
289 | }, {
290 | value: 10,
291 | name: 'E'
292 | }, {
293 | value: 80,
294 | name: 'B'
295 | }, {
296 | value: 100,
297 | name: 'A'
298 | }]
299 | }, {
300 | name: '漏斗图',
301 | type: 'funnel',
302 | width: '40%',
303 | height: '45%',
304 | left: '55%',
305 | top: '5%',
306 | label: {
307 | normal: {
308 | position: 'left'
309 | }
310 | },
311 | data: [{
312 | value: 60,
313 | name: 'C'
314 | }, {
315 | value: 30,
316 | name: 'D'
317 | }, {
318 | value: 10,
319 | name: 'E'
320 | }, {
321 | value: 80,
322 | name: 'B'
323 | }, {
324 | value: 100,
325 | name: 'A'
326 | }]
327 | }, {
328 | name: '金字塔',
329 | type: 'funnel',
330 | width: '40%',
331 | height: '45%',
332 | left: '55%',
333 | top: '50%',
334 | sort: 'ascending',
335 | label: {
336 | normal: {
337 | position: 'left'
338 | }
339 | },
340 | data: [{
341 | value: 60,
342 | name: 'C'
343 | }, {
344 | value: 30,
345 | name: 'D'
346 | }, {
347 | value: 10,
348 | name: 'E'
349 | }, {
350 | value: 80,
351 | name: 'B'
352 | }, {
353 | value: 100,
354 | name: 'A'
355 | }]
356 | }]
357 | };
358 | myChart.setOption(option);
359 | }
360 |
361 | function drawChart() {
362 | drawBarChart();
363 | drawScatterChart();
364 | drawPieChart();
365 | drawLineChart();
366 | drawRadarChart();
367 | drawFunnelChart();
368 | }
369 |
370 | function getHandler() {
371 | const option = {
372 | fillStyle: $('#fillStyleSelector').children('option:selected').val(),
373 | bowing: $('#bowingRange').val(),
374 | roughness: $('#roughnessRange').val()
375 | };
376 |
377 | const container = $('#charts')[0];
378 | return handler = Sketchifier(container, option);
379 | }
380 |
381 | $(function() {
382 | drawChart();
383 | var handler = getHandler();
384 |
385 | function updateHandler() {
386 | handler.restore();
387 | handler = getHandler();
388 | if ($('#handifyChecker').prop('checked')) {
389 | handler.handify();
390 | }
391 | }
392 |
393 | $('#fillStyleSelector').change(function() {
394 | updateHandler();
395 | })
396 |
397 | $('#bowingRange').change(function() {
398 | updateHandler();
399 | })
400 |
401 | $('#roughnessRange').change(function() {
402 | updateHandler();
403 | })
404 |
405 | $('#handifyChecker').change(function() {
406 | if (this.checked) {
407 | handler.handify();
408 | } else {
409 | handler.restore();
410 | }
411 | });
412 | });
--------------------------------------------------------------------------------
/demo/g2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | sketchify
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/demo/g2.js:
--------------------------------------------------------------------------------
1 | function drawBarChart() {
2 | var data = [{
3 | year: '1951 年',
4 | sales: 38
5 | }, {
6 | year: '1952 年',
7 | sales: 52
8 | }, {
9 | year: '1956 年',
10 | sales: 61
11 | }, {
12 | year: '1957 年',
13 | sales: 145
14 | }, {
15 | year: '1958 年',
16 | sales: 48
17 | }, {
18 | year: '1959 年',
19 | sales: 38
20 | }, {
21 | year: '1960 年',
22 | sales: 38
23 | }, {
24 | year: '1962 年',
25 | sales: 38
26 | }];
27 | var chart = new G2.Chart({
28 | container: 'container_bar',
29 | forceFit: true,
30 | height: 300,
31 | renderer: 'svg'
32 | });
33 | chart.source(data);
34 | chart.scale('sales', {
35 | tickInterval: 20
36 | });
37 | chart.interval().position('year*sales');
38 | chart.render();
39 | }
40 |
41 | function drawScatterChart() {
42 | var data = [{
43 | x: 95,
44 | y: 95,
45 | z: 13.8,
46 | name: 'BE',
47 | country: 'Belgium'
48 | }, {
49 | x: 86.5,
50 | y: 102.9,
51 | z: 14.7,
52 | name: 'DE',
53 | country: 'Germany'
54 | }, {
55 | x: 80.8,
56 | y: 91.5,
57 | z: 15.8,
58 | name: 'FI',
59 | country: 'Finland'
60 | }, {
61 | x: 80.4,
62 | y: 102.5,
63 | z: 12,
64 | name: 'NL',
65 | country: 'Netherlands'
66 | }, {
67 | x: 80.3,
68 | y: 86.1,
69 | z: 11.8,
70 | name: 'SE',
71 | country: 'Sweden'
72 | }, {
73 | x: 78.4,
74 | y: 70.1,
75 | z: 16.6,
76 | name: 'ES',
77 | country: 'Spain'
78 | }, {
79 | x: 74.2,
80 | y: 68.5,
81 | z: 14.5,
82 | name: 'FR',
83 | country: 'France'
84 | }, {
85 | x: 73.5,
86 | y: 83.1,
87 | z: 10,
88 | name: 'NO',
89 | country: 'Norway'
90 | }, {
91 | x: 71,
92 | y: 93.2,
93 | z: 24.7,
94 | name: 'UK',
95 | country: 'United Kingdom'
96 | }, {
97 | x: 69.2,
98 | y: 57.6,
99 | z: 10.4,
100 | name: 'IT',
101 | country: 'Italy'
102 | }, {
103 | x: 68.6,
104 | y: 20,
105 | z: 16,
106 | name: 'RU',
107 | country: 'Russia'
108 | }, {
109 | x: 65.5,
110 | y: 126.4,
111 | z: 35.3,
112 | name: 'US',
113 | country: 'United States'
114 | }, {
115 | x: 65.4,
116 | y: 50.8,
117 | z: 28.5,
118 | name: 'HU',
119 | country: 'Hungary'
120 | }, {
121 | x: 63.4,
122 | y: 51.8,
123 | z: 15.4,
124 | name: 'PT',
125 | country: 'Portugal'
126 | }, {
127 | x: 64,
128 | y: 82.9,
129 | z: 31.3,
130 | name: 'NZ',
131 | country: 'New Zealand'
132 | }];
133 | var chart = new G2.Chart({
134 | container: 'container_scatter',
135 | forceFit: true,
136 | padding: [20, 20, 50, 80],
137 | height: 300,
138 | renderer: 'svg',
139 | plotBackground: {
140 | stroke: '#ccc', // 边颜色
141 | lineWidth: 1 // 边框粗细
142 | } // 绘图区域背景设置
143 | });
144 | chart.source(data, {
145 | x: {
146 | alias: 'Daily fat intake', // 定义别名
147 | tickInterval: 5, // 自定义刻度间距
148 | nice: false, // 不对最大最小值优化
149 | max: 96, // 自定义最大值
150 | min: 62 // 自定义最小是
151 | },
152 | y: {
153 | alias: 'Daily sugar intake',
154 | tickInterval: 50,
155 | nice: false,
156 | max: 165,
157 | min: 0
158 | },
159 | z: {
160 | alias: 'Obesity(adults) %'
161 | }
162 | });
163 | // 开始配置坐标轴
164 | chart.axis('x', {
165 | label: {
166 | formatter: function formatter(val) {
167 | return val + ' gr'; // 格式化坐标轴显示文本
168 | }
169 | },
170 | grid: {
171 | lineStyle: {
172 | stroke: '#d9d9d9',
173 | lineWidth: 1,
174 | lineDash: [2, 2]
175 | }
176 | }
177 | });
178 | chart.axis('y', {
179 | title: {
180 | offset: 64
181 | },
182 | label: {
183 | formatter: function formatter(val) {
184 | if (val > 0) {
185 | return val + ' gr';
186 | }
187 | }
188 | }
189 | });
190 | chart.legend(false);
191 | chart.tooltip({
192 | title: 'country'
193 | });
194 | chart.point().position('x*y').color('#1890ff').size('z', [10, 40]).label('name*country', {
195 | offset: 0, // 文本距离图形的距离
196 | textStyle: {
197 | fill: '#1890FF'
198 | }
199 | }).opacity(0.3).shape('circle').tooltip('x*y*z').style({
200 | lineWidth: 1,
201 | stroke: '#1890ff'
202 | });
203 | chart.guide().line({
204 | top: true,
205 | start: [65, 'min'],
206 | end: [65, 'max'],
207 | text: {
208 | content: 'Safe fat intake 65g/day',
209 | position: 'end',
210 | autoRotate: false,
211 | style: {
212 | textAlign: 'start'
213 | }
214 | }
215 | });
216 | chart.guide().line({
217 | top: true,
218 | start: ['min', 50],
219 | end: ['max', 50],
220 | text: {
221 | content: 'Safe sugar intake 50g/day',
222 | position: 'end',
223 | style: {
224 | textAlign: 'end'
225 | }
226 | }
227 | });
228 | chart.render();
229 | }
230 |
231 | function drawPieChart() {
232 | var data = [{
233 | year: '2001',
234 | population: 41.8
235 | }, {
236 | year: '2002',
237 | population: 38
238 | }, {
239 | year: '2003',
240 | population: 33.7
241 | }, {
242 | year: '2004',
243 | population: 30.7
244 | }, {
245 | year: '2005',
246 | population: 25.8
247 | }, {
248 | year: '2006',
249 | population: 31.7
250 | }, {
251 | year: '2007',
252 | population: 33
253 | }, {
254 | year: '2008',
255 | population: 46
256 | }, {
257 | year: '2009',
258 | population: 38.3
259 | }, {
260 | year: '2010',
261 | population: 28
262 | }, {
263 | year: '2011',
264 | population: 42.5
265 | }, {
266 | year: '2012',
267 | population: 30.3
268 | }];
269 |
270 | var chart = new G2.Chart({
271 | container: 'container_pie',
272 | forceFit: true,
273 | height: 300,
274 | renderer: 'svg',
275 | });
276 | chart.source(data);
277 | chart.coord('polar');
278 | chart.legend({
279 | position: 'right',
280 | offsetY: -window.innerHeight / 2 + 280,
281 | offsetX: -140
282 | });
283 | chart.axis(false);
284 | chart.interval().position('year*population').color('year', G2.Global.colors_pie_16).style({
285 | lineWidth: 1,
286 | stroke: '#fff'
287 | });
288 | chart.render();
289 | }
290 |
291 | function drawLineChart() {
292 | var data = [{
293 | month: 'Jan',
294 | Tokyo: 7.0,
295 | London: 3.9
296 | }, {
297 | month: 'Feb',
298 | Tokyo: 6.9,
299 | London: 4.2
300 | }, {
301 | month: 'Mar',
302 | Tokyo: 9.5,
303 | London: 5.7
304 | }, {
305 | month: 'Apr',
306 | Tokyo: 14.5,
307 | London: 8.5
308 | }, {
309 | month: 'May',
310 | Tokyo: 18.4,
311 | London: 11.9
312 | }, {
313 | month: 'Jun',
314 | Tokyo: 21.5,
315 | London: 15.2
316 | }, {
317 | month: 'Jul',
318 | Tokyo: 25.2,
319 | London: 17.0
320 | }, {
321 | month: 'Aug',
322 | Tokyo: 26.5,
323 | London: 16.6
324 | }, {
325 | month: 'Sep',
326 | Tokyo: 23.3,
327 | London: 14.2
328 | }, {
329 | month: 'Oct',
330 | Tokyo: 18.3,
331 | London: 10.3
332 | }, {
333 | month: 'Nov',
334 | Tokyo: 13.9,
335 | London: 6.6
336 | }, {
337 | month: 'Dec',
338 | Tokyo: 9.6,
339 | London: 4.8
340 | }];
341 | var ds = new DataSet();
342 | var dv = ds.createView().source(data);
343 | // fold 方式完成了行列转换,如果不想使用 DataSet 直接手工转换数据即可
344 | dv.transform({
345 | type: 'fold',
346 | fields: ['Tokyo', 'London'], // 展开字段集
347 | key: 'city', // key字段
348 | value: 'temperature' // value字段
349 | });
350 | var chart = new G2.Chart({
351 | container: 'container_line',
352 | forceFit: true,
353 | height: 300,
354 | renderer: 'svg',
355 | });
356 | chart.source(dv, {
357 | month: {
358 | range: [0, 1]
359 | }
360 | });
361 | chart.tooltip({
362 | crosshairs: {
363 | type: 'line'
364 | }
365 | });
366 | chart.axis('temperature', {
367 | label: {
368 | formatter: function formatter(val) {
369 | return val + '°C';
370 | }
371 | }
372 | });
373 | chart.line().position('month*temperature').color('city').shape('smooth');
374 | chart.point().position('month*temperature').color('city').size(4).shape('circle').style({
375 | stroke: '#fff',
376 | lineWidth: 1
377 | });
378 | chart.render();
379 | }
380 |
381 | function drawRadarChart() {
382 | var _DataSet = DataSet,
383 | DataView = _DataSet.DataView;
384 |
385 | var data = [{
386 | item: 'Design',
387 | a: 70,
388 | b: 30
389 | }, {
390 | item: 'Development',
391 | a: 60,
392 | b: 70
393 | }, {
394 | item: 'Marketing',
395 | a: 50,
396 | b: 60
397 | }, {
398 | item: 'Users',
399 | a: 40,
400 | b: 50
401 | }, {
402 | item: 'Test',
403 | a: 60,
404 | b: 70
405 | }, {
406 | item: 'Language',
407 | a: 70,
408 | b: 50
409 | }, {
410 | item: 'Technology',
411 | a: 50,
412 | b: 40
413 | }, {
414 | item: 'Support',
415 | a: 30,
416 | b: 40
417 | }, {
418 | item: 'Sales',
419 | a: 60,
420 | b: 40
421 | }, {
422 | item: 'UX',
423 | a: 50,
424 | b: 60
425 | }];
426 | var dv = new DataView().source(data);
427 | dv.transform({
428 | type: 'fold',
429 | fields: ['a', 'b'], // 展开字段集
430 | key: 'user', // key字段
431 | value: 'score' // value字段
432 | });
433 | var chart = new G2.Chart({
434 | container: 'container_radar',
435 | forceFit: true,
436 | height: 300,
437 | renderer: 'svg',
438 | padding: [20, 20, 95, 20]
439 | });
440 | chart.source(dv, {
441 | score: {
442 | min: 0,
443 | max: 80
444 | }
445 | });
446 | chart.coord('polar', {
447 | radius: 0.8
448 | });
449 | chart.axis('item', {
450 | line: null,
451 | tickLine: null,
452 | grid: {
453 | lineStyle: {
454 | lineDash: null
455 | },
456 | hideFirstLine: false
457 | }
458 | });
459 | chart.axis('score', {
460 | line: null,
461 | tickLine: null,
462 | grid: {
463 | type: 'polygon',
464 | lineStyle: {
465 | lineDash: null
466 | }
467 | }
468 | });
469 | chart.legend('user', {
470 | marker: 'circle',
471 | offset: 30
472 | });
473 | chart.line().position('item*score').color('user').size(2);
474 | chart.point().position('item*score').color('user').shape('circle').size(4).style({
475 | stroke: '#fff',
476 | lineWidth: 1,
477 | fillOpacity: 1
478 | });
479 | chart.area().position('item*score').color('user');
480 | chart.render();
481 | }
482 |
483 | function drawFunnelChart() {
484 | var _DataSet = DataSet,
485 | DataView = _DataSet.DataView;
486 |
487 | var data = [{
488 | action: 'A',
489 | pv: 50000
490 | }, {
491 | action: 'B',
492 | pv: 35000
493 | }, {
494 | action: 'C',
495 | pv: 25000
496 | }, {
497 | action: 'D',
498 | pv: 15000
499 | }, {
500 | action: 'E',
501 | pv: 8000
502 | }];
503 | var dv = new DataView().source(data);
504 | dv.transform({
505 | type: 'map',
506 | callback: function callback(row) {
507 | row.percent = row.pv / 50000;
508 | return row;
509 | }
510 | });
511 | data = dv.rows;
512 | var chart = new G2.Chart({
513 | container: 'container_funnel',
514 | forceFit: true,
515 | height: 300,
516 | renderer: 'svg',
517 | padding: [20, 120, 95]
518 | });
519 | chart.source(data, {
520 | percent: {
521 | nice: false
522 | }
523 | });
524 | chart.axis(false);
525 | chart.tooltip({
526 | showTitle: false,
527 | itemTpl: '' + ' ' + '{name} ' + '浏览人数:{pv} ' + '占比:{percent} ' + ' '
528 | });
529 | chart.coord('rect').transpose().scale(1, -1);
530 | chart.intervalSymmetric().position('action*percent').shape('funnel').color('action', ['#0050B3', '#1890FF', '#40A9FF', '#69C0FF', '#BAE7FF']).label('action*pv', function(action, pv) {
531 | return action + ' ' + pv;
532 | }, {
533 | offset: 35,
534 | labelLine: {
535 | lineWidth: 1,
536 | stroke: 'rgba(0, 0, 0, 0.15)'
537 | }
538 | }).tooltip('action*pv*percent', function(action, pv, percent) {
539 | return {
540 | name: action,
541 | percent: parseInt(percent * 100) + '%',
542 | pv: pv
543 | };
544 | });
545 | data.forEach(function(obj) {
546 | // 中间标签文本
547 | chart.guide().text({
548 | top: true,
549 | position: {
550 | action: obj.action,
551 | percent: 'median'
552 | },
553 | content: parseInt(obj.percent * 100) + '%', // 显示的文本内容
554 | style: {
555 | fill: '#fff',
556 | fontSize: '12',
557 | textAlign: 'center',
558 | shadowBlur: 2,
559 | shadowColor: 'rgba(0, 0, 0, .45)'
560 | }
561 | });
562 | });
563 | chart.render();
564 | }
565 |
566 | function drawChart() {
567 | drawBarChart();
568 | drawScatterChart();
569 | drawPieChart();
570 | drawLineChart();
571 | drawRadarChart();
572 | drawFunnelChart();
573 | }
574 |
575 | function getHandler() {
576 | const option = {
577 | fillStyle: $('#fillStyleSelector').children('option:selected').val(),
578 | bowing: $('#bowingRange').val(),
579 | roughness: $('#roughnessRange').val()
580 | };
581 |
582 | const container = $('#charts')[0];
583 | return handler = Sketchifier(container, option);
584 | }
585 |
586 | $(function() {
587 | drawChart();
588 | var handler = getHandler();
589 |
590 | function updateHandler() {
591 | handler.restore();
592 | handler = getHandler();
593 | if ($('#handifyChecker').prop('checked')) {
594 | handler.handify();
595 | }
596 | }
597 |
598 | $('#fillStyleSelector').change(function() {
599 | updateHandler();
600 | })
601 |
602 | $('#bowingRange').change(function() {
603 | updateHandler();
604 | })
605 |
606 | $('#roughnessRange').change(function() {
607 | updateHandler();
608 | })
609 |
610 | $('#handifyChecker').change(function() {
611 | if (this.checked) {
612 | handler.handify();
613 | } else {
614 | handler.restore();
615 | }
616 | });
617 | });
--------------------------------------------------------------------------------
/demo/highcharts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | sketchify
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/demo/highcharts.js:
--------------------------------------------------------------------------------
1 | function drawBarChart() {
2 | Highcharts.chart('container_bar', {
3 |
4 | chart: {
5 | type: 'column'
6 | },
7 |
8 | title: {
9 | text: 'Total fruit consumtion, grouped by gender'
10 | },
11 |
12 | xAxis: {
13 | categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
14 | },
15 |
16 | yAxis: {
17 | allowDecimals: false,
18 | min: 0,
19 | title: {
20 | text: 'Number of fruits'
21 | }
22 | },
23 |
24 | tooltip: {
25 | formatter: function() {
26 | return '' + this.x + ' ' +
27 | this.series.name + ': ' + this.y + ' ' +
28 | 'Total: ' + this.point.stackTotal;
29 | }
30 | },
31 |
32 | plotOptions: {
33 | column: {
34 | stacking: 'normal'
35 | }
36 | },
37 |
38 | series: [{
39 | name: 'John',
40 | data: [5, 3, 4, 7, 2],
41 | stack: 'male'
42 | }, {
43 | name: 'Joe',
44 | data: [3, 4, 4, 2, 5],
45 | stack: 'male'
46 | }, {
47 | name: 'Jane',
48 | data: [2, 5, 6, 2, 1],
49 | stack: 'female'
50 | }, {
51 | name: 'Janet',
52 | data: [3, 0, 4, 4, 3],
53 | stack: 'female'
54 | }]
55 | });
56 | }
57 |
58 | function drawScatterChart() {
59 | Highcharts.chart('container_scatter', {
60 |
61 | chart: {
62 | type: 'bubble',
63 | plotBorderWidth: 1,
64 | zoomType: 'xy'
65 | },
66 |
67 | legend: {
68 | enabled: false
69 | },
70 |
71 | title: {
72 | text: 'Sugar and fat intake per country'
73 | },
74 |
75 | subtitle: {
76 | text: 'Source: Euromonitor and OECD '
77 | },
78 |
79 | xAxis: {
80 | gridLineWidth: 1,
81 | title: {
82 | text: 'Daily fat intake'
83 | },
84 | labels: {
85 | format: '{value} gr'
86 | },
87 | plotLines: [{
88 | color: 'black',
89 | dashStyle: 'dot',
90 | width: 2,
91 | value: 65,
92 | label: {
93 | rotation: 0,
94 | y: 15,
95 | style: {
96 | fontStyle: 'italic'
97 | },
98 | text: 'Safe fat intake 65g/day'
99 | },
100 | zIndex: 3
101 | }]
102 | },
103 |
104 | yAxis: {
105 | startOnTick: false,
106 | endOnTick: false,
107 | title: {
108 | text: 'Daily sugar intake'
109 | },
110 | labels: {
111 | format: '{value} gr'
112 | },
113 | maxPadding: 0.2,
114 | plotLines: [{
115 | color: 'black',
116 | dashStyle: 'dot',
117 | width: 2,
118 | value: 50,
119 | label: {
120 | align: 'right',
121 | style: {
122 | fontStyle: 'italic'
123 | },
124 | text: 'Safe sugar intake 50g/day',
125 | x: -10
126 | },
127 | zIndex: 3
128 | }]
129 | },
130 |
131 | tooltip: {
132 | useHTML: true,
133 | headerFormat: '',
134 | pointFormat: '{point.country} ' +
135 | 'Fat intake: {point.x}g ' +
136 | 'Sugar intake: {point.y}g ' +
137 | 'Obesity (adults): {point.z}% ',
138 | footerFormat: '
',
139 | followPointer: true
140 | },
141 |
142 | plotOptions: {
143 | series: {
144 | dataLabels: {
145 | enabled: true,
146 | format: '{point.name}'
147 | }
148 | }
149 | },
150 |
151 | series: [{
152 | data: [{
153 | x: 95,
154 | y: 95,
155 | z: 13.8,
156 | name: 'BE',
157 | country: 'Belgium'
158 | }, {
159 | x: 86.5,
160 | y: 102.9,
161 | z: 14.7,
162 | name: 'DE',
163 | country: 'Germany'
164 | }, {
165 | x: 80.8,
166 | y: 91.5,
167 | z: 15.8,
168 | name: 'FI',
169 | country: 'Finland'
170 | }, {
171 | x: 80.4,
172 | y: 102.5,
173 | z: 12,
174 | name: 'NL',
175 | country: 'Netherlands'
176 | }, {
177 | x: 80.3,
178 | y: 86.1,
179 | z: 11.8,
180 | name: 'SE',
181 | country: 'Sweden'
182 | }, {
183 | x: 78.4,
184 | y: 70.1,
185 | z: 16.6,
186 | name: 'ES',
187 | country: 'Spain'
188 | }, {
189 | x: 74.2,
190 | y: 68.5,
191 | z: 14.5,
192 | name: 'FR',
193 | country: 'France'
194 | }, {
195 | x: 73.5,
196 | y: 83.1,
197 | z: 10,
198 | name: 'NO',
199 | country: 'Norway'
200 | }, {
201 | x: 71,
202 | y: 93.2,
203 | z: 24.7,
204 | name: 'UK',
205 | country: 'United Kingdom'
206 | }, {
207 | x: 69.2,
208 | y: 57.6,
209 | z: 10.4,
210 | name: 'IT',
211 | country: 'Italy'
212 | }, {
213 | x: 68.6,
214 | y: 20,
215 | z: 16,
216 | name: 'RU',
217 | country: 'Russia'
218 | }, {
219 | x: 65.5,
220 | y: 126.4,
221 | z: 35.3,
222 | name: 'US',
223 | country: 'United States'
224 | }, {
225 | x: 65.4,
226 | y: 50.8,
227 | z: 28.5,
228 | name: 'HU',
229 | country: 'Hungary'
230 | }, {
231 | x: 63.4,
232 | y: 51.8,
233 | z: 15.4,
234 | name: 'PT',
235 | country: 'Portugal'
236 | }, {
237 | x: 64,
238 | y: 82.9,
239 | z: 31.3,
240 | name: 'NZ',
241 | country: 'New Zealand'
242 | }]
243 | }]
244 |
245 | });
246 | }
247 |
248 | function drawPieChart() {
249 | Highcharts.chart('container_pie', {
250 | chart: {
251 | plotBackgroundColor: null,
252 | plotBorderWidth: null,
253 | plotShadow: false,
254 | type: 'pie'
255 | },
256 | title: {
257 | text: 'Browser market shares in January, 2018'
258 | },
259 | tooltip: {
260 | pointFormat: '{series.name}: {point.percentage:.1f}% '
261 | },
262 | plotOptions: {
263 | pie: {
264 | allowPointSelect: true,
265 | cursor: 'pointer',
266 | dataLabels: {
267 | enabled: true,
268 | format: '{point.name} : {point.percentage:.1f} %'
269 | }
270 | }
271 | },
272 | series: [{
273 | name: 'Brands',
274 | colorByPoint: true,
275 | data: [{
276 | name: 'Chrome',
277 | y: 61.41,
278 | sliced: true,
279 | selected: true
280 | }, {
281 | name: 'Internet Explorer',
282 | y: 11.84
283 | }, {
284 | name: 'Firefox',
285 | y: 10.85
286 | }, {
287 | name: 'Edge',
288 | y: 4.67
289 | }, {
290 | name: 'Safari',
291 | y: 4.18
292 | }, {
293 | name: 'Sogou Explorer',
294 | y: 1.64
295 | }, {
296 | name: 'Opera',
297 | y: 1.6
298 | }, {
299 | name: 'QQ',
300 | y: 1.2
301 | }, {
302 | name: 'Other',
303 | y: 2.61
304 | }]
305 | }]
306 | });
307 | }
308 |
309 | function drawLineChart() {
310 | Highcharts.chart('container_line', {
311 |
312 | title: {
313 | text: 'Solar Employment Growth by Sector, 2010-2016'
314 | },
315 |
316 | subtitle: {
317 | text: 'Source: thesolarfoundation.com'
318 | },
319 |
320 | yAxis: {
321 | title: {
322 | text: 'Number of Employees'
323 | }
324 | },
325 | legend: {
326 | layout: 'vertical',
327 | align: 'right',
328 | verticalAlign: 'middle'
329 | },
330 |
331 | plotOptions: {
332 | series: {
333 | label: {
334 | connectorAllowed: false
335 | },
336 | pointStart: 2010
337 | }
338 | },
339 |
340 | series: [{
341 | name: 'Installation',
342 | data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
343 | }, {
344 | name: 'Manufacturing',
345 | data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]
346 | }, {
347 | name: 'Sales & Distribution',
348 | data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]
349 | }, {
350 | name: 'Project Development',
351 | data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227]
352 | }, {
353 | name: 'Other',
354 | data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]
355 | }],
356 |
357 | responsive: {
358 | rules: [{
359 | condition: {
360 | maxWidth: 500
361 | },
362 | chartOptions: {
363 | legend: {
364 | layout: 'horizontal',
365 | align: 'center',
366 | verticalAlign: 'bottom'
367 | }
368 | }
369 | }]
370 | }
371 |
372 | });
373 | }
374 |
375 | function drawRadarChart() {
376 | Highcharts.chart('container_radar', {
377 |
378 | chart: {
379 | polar: true,
380 | type: 'line'
381 | },
382 |
383 | accessibility: {
384 | description: 'A spiderweb chart compares the allocated budget against actual spending within an organization. The spider chart has six spokes. Each spoke represents one of the 6 departments within the organization: sales, marketing, development, customer support, information technology and administration. The chart is interactive, and each data point is displayed upon hovering. The chart clearly shows that 4 of the 6 departments have overspent their budget with Marketing responsible for the greatest overspend of $20,000. The allocated budget and actual spending data points for each department are as follows: Sales. Budget equals $43,000; spending equals $50,000. Marketing. Budget equals $19,000; spending equals $39,000. Development. Budget equals $60,000; spending equals $42,000. Customer support. Budget equals $35,000; spending equals $31,000. Information technology. Budget equals $17,000; spending equals $26,000. Administration. Budget equals $10,000; spending equals $14,000.'
385 | },
386 |
387 | title: {
388 | text: 'Budget vs spending',
389 | x: -80
390 | },
391 |
392 | pane: {
393 | size: '80%'
394 | },
395 |
396 | xAxis: {
397 | categories: ['Sales', 'Marketing', 'Development', 'Customer Support',
398 | 'Information Technology', 'Administration'
399 | ],
400 | tickmarkPlacement: 'on',
401 | lineWidth: 0
402 | },
403 |
404 | yAxis: {
405 | gridLineInterpolation: 'polygon',
406 | lineWidth: 0,
407 | min: 0
408 | },
409 |
410 | tooltip: {
411 | shared: true,
412 | pointFormat: '{series.name}: ${point.y:,.0f} '
413 | },
414 |
415 | legend: {
416 | align: 'right',
417 | verticalAlign: 'middle'
418 | },
419 |
420 | series: [{
421 | name: 'Allocated Budget',
422 | data: [43000, 19000, 60000, 35000, 17000, 10000],
423 | pointPlacement: 'on'
424 | }, {
425 | name: 'Actual Spending',
426 | data: [50000, 39000, 42000, 31000, 26000, 14000],
427 | pointPlacement: 'on'
428 | }],
429 |
430 | responsive: {
431 | rules: [{
432 | condition: {
433 | maxWidth: 500
434 | },
435 | chartOptions: {
436 | legend: {
437 | align: 'center',
438 | verticalAlign: 'bottom'
439 | },
440 | pane: {
441 | size: '70%'
442 | }
443 | }
444 | }]
445 | }
446 |
447 | });
448 | }
449 |
450 | function drawFunnelChart() {
451 | Highcharts.chart('container_funnel', {
452 | chart: {
453 | type: 'funnel'
454 | },
455 | title: {
456 | text: 'Sales funnel'
457 | },
458 | plotOptions: {
459 | series: {
460 | dataLabels: {
461 | enabled: true,
462 | format: '{point.name} ({point.y:,.0f})',
463 | softConnector: true
464 | },
465 | center: ['40%', '50%'],
466 | neckWidth: '30%',
467 | neckHeight: '25%',
468 | width: '80%'
469 | }
470 | },
471 | legend: {
472 | enabled: false
473 | },
474 | series: [{
475 | name: 'Unique users',
476 | data: [
477 | ['Website visits', 15654],
478 | ['Downloads', 4064],
479 | ['Requested price list', 1987],
480 | ['Invoice sent', 976],
481 | ['Finalized', 846]
482 | ]
483 | }],
484 |
485 | responsive: {
486 | rules: [{
487 | condition: {
488 | maxWidth: 500
489 | },
490 | chartOptions: {
491 | plotOptions: {
492 | series: {
493 | dataLabels: {
494 | inside: true
495 | },
496 | center: ['50%', '50%'],
497 | width: '100%'
498 | }
499 | }
500 | }
501 | }]
502 | }
503 | });
504 | }
505 |
506 | function drawChart() {
507 | drawBarChart();
508 | drawScatterChart();
509 | drawPieChart();
510 | drawLineChart();
511 | drawRadarChart();
512 | drawFunnelChart();
513 | }
514 |
515 | function getHandler() {
516 | const option = {
517 | chartType: 'highcharts',
518 | fillStyle: $('#fillStyleSelector').children('option:selected').val(),
519 | bowing: $('#bowingRange').val(),
520 | roughness: $('#roughnessRange').val()
521 | };
522 |
523 | const container = $('#charts')[0];
524 | return handler = Sketchifier(container, option);
525 | }
526 |
527 | $(function() {
528 | drawChart();
529 | var handler = getHandler();
530 |
531 | function updateHandler() {
532 | handler.restore();
533 | handler = getHandler();
534 | if ($('#handifyChecker').prop('checked')) {
535 | handler.handify();
536 | }
537 | }
538 |
539 | $('#fillStyleSelector').change(function() {
540 | updateHandler();
541 | })
542 |
543 | $('#bowingRange').change(function() {
544 | updateHandler();
545 | })
546 |
547 | $('#roughnessRange').change(function() {
548 | updateHandler();
549 | })
550 |
551 | $('#handifyChecker').change(function() {
552 | if (this.checked) {
553 | handler.handify();
554 | } else {
555 | handler.restore();
556 | }
557 | });
558 | });
--------------------------------------------------------------------------------
/demo/xcharts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | sketchify
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/demo/xcharts.js:
--------------------------------------------------------------------------------
1 | function drawBarChart() {
2 | const chart = xCharts(document.querySelector('#container_bar'));
3 | option = {
4 | title: {
5 | text: 'Barchart'
6 | },
7 | tooltip: {
8 | show: true,
9 | trigger: 'axis'
10 | },
11 | legend: {
12 | x: 'center',
13 | y: 'bottom',
14 | show: true,
15 | data: ['Li', 'Han']
16 | },
17 | xAxis: [{
18 | type: 'category',
19 | data: ['A', 'B', 'C', 'D', 'E', 'F']
20 | }],
21 | yAxis: [{
22 | type: 'value',
23 | maxValue: 100,
24 | minValue: 0
25 | }],
26 | resize: {
27 | enable: true
28 | },
29 | animation: {
30 | enable: true
31 | },
32 | series: [{
33 | name: 'Li',
34 | type: 'bar',
35 | data: [10, 20, 30, 40, 50, 60]
36 | }, {
37 | name: 'Han',
38 | type: 'bar',
39 | data: [60, 50, 40, 30, 20, 10],
40 | formatter: function(name, value) {
41 | var htmlStr = '';
42 | htmlStr += '' + name + ':' + value + 'Score
';
43 | return htmlStr;
44 | }
45 | }]
46 | };
47 | chart.loadConfig(option);
48 | }
49 |
50 | function drawScatterChart() {
51 | const chart = xCharts(document.querySelector('#container_scatter'));
52 | option = {
53 | title: {
54 | text: 'Scatter'
55 | },
56 | legend: {
57 | data: ['Female', 'Male'],
58 | x: 'center'
59 | },
60 | tooltip: {
61 | trigger: 'axis'
62 | },
63 | xAxis: [{
64 | type: 'value',
65 | tickFormat: function(data) {
66 | return data + ' cm';
67 | }
68 | }],
69 | yAxis: [{
70 | type: 'value',
71 | tickFormat: function(data) {
72 | return data + ' kg';
73 | }
74 | }],
75 | resize: {
76 | enable: true
77 | },
78 | animation: {
79 | enable: true
80 | },
81 | series: [{
82 | name: 'Female',
83 | type: 'scatter',
84 | size: 30,
85 | data: [
86 | [161.2, 51.6],
87 | [167.5, 59.0],
88 | [159.5, 49.2],
89 | [157.0, 63.0],
90 | [155.8, 53.6],
91 | [170.0, 59.0],
92 | [159.1, 47.6],
93 | [166.0, 69.8],
94 | [176.2, 66.8],
95 | [160.2, 75.2]
96 | ]
97 | }, {
98 | name: 'Male',
99 | type: 'scatter',
100 | size: 30,
101 | data: [
102 | [174.0, 65.6],
103 | [175.3, 71.8],
104 | [193.5, 80.7],
105 | [186.5, 72.6],
106 | [187.2, 78.8],
107 | [181.5, 74.8],
108 | [184.0, 86.4],
109 | [184.5, 78.4],
110 | [175.0, 62.0],
111 | [184.0, 81.6]
112 | ]
113 | }]
114 | };
115 | chart.loadConfig(option);
116 | }
117 |
118 | function drawPieChart() {
119 | const chart = xCharts(document.querySelector('#container_pie'));
120 | option = {
121 | title: {
122 | text: 'Pie'
123 | },
124 | tooltip: {
125 | show: true
126 | },
127 | legend: {
128 | orient: 'vertical',
129 | x: 'right',
130 | show: true,
131 | data: ['section1', 'section2', 'section3', 'section4', 'section5', 'section6']
132 | },
133 | resize: {
134 | enable: true
135 | },
136 | animation: {
137 | enable: true
138 | },
139 | series: [{
140 | type: 'pie',
141 | center: ['50%', '50%'],
142 | radius: {
143 | outerRadius: '30%',
144 | innerRadius: 0
145 | },
146 | data: [{
147 | name: 'section1',
148 | value: 10
149 | }, {
150 | name: 'section2',
151 | value: 20
152 | }, {
153 | name: 'section3',
154 | value: 30
155 | }, {
156 | name: 'section4',
157 | value: 40
158 | }, {
159 | name: 'section5',
160 | value: 50
161 | }, {
162 | name: 'section6',
163 | value: 60
164 | }]
165 | }]
166 | };
167 | chart.loadConfig(option);
168 | }
169 |
170 | function drawLineChart() {
171 | const chart = xCharts(document.querySelector('#container_line'));
172 | option = {
173 | title: {
174 | text: 'Area'
175 | },
176 | legend: {
177 | data: ['Apple', 'Orange'],
178 | x: 'center'
179 | },
180 | tooltip: {
181 | trigger: 'axis'
182 | },
183 | xAxis: [{
184 | type: 'category',
185 | data: ['1', '2', '3', '4', '5', '6', '7'],
186 | tickFormat: function(data) {
187 | return 'week' + data;
188 | }
189 | }],
190 | yAxis: [{
191 | type: 'value'
192 | }],
193 | resize: {
194 | enable: true
195 | },
196 | animation: {
197 | enable: true
198 | },
199 | series: [{
200 | type: 'line',
201 | name: 'Apple',
202 | data: [100, 200, 300, 300, 350, 400, 450],
203 | areaStyle: {
204 | show: true
205 | },
206 | stack: 'sales'
207 | }, {
208 | type: 'line',
209 | name: 'Orange',
210 | data: [500, 400, 200, 200, 150, 200, 250],
211 | areaStyle: {
212 | show: true
213 | },
214 | stack: 'sales'
215 | }]
216 | };
217 | chart.loadConfig(option);
218 | }
219 |
220 | function drawRadarChart() {
221 | const chart = xCharts(document.querySelector('#container_radar'));
222 | option = {
223 | title: {
224 | text: 'Radar'
225 | },
226 | tooltip: {
227 | show: true
228 | },
229 | legend: {
230 | orient: 'vertical',
231 | x: 'right',
232 | show: true,
233 | data: ['Li', 'Han']
234 | },
235 | resize: {
236 | enable: true
237 | },
238 | animation: {
239 | enable: true
240 | },
241 | series: [{
242 | type: 'radar',
243 | levels: 4,
244 | radius: '25%',
245 | fill: false,
246 | center: ['50%', '50%'],
247 | indicator: [{
248 | text: 'A',
249 | max: 100,
250 | min: 0
251 | }, {
252 | text: 'B',
253 | max: 100,
254 | min: 0
255 | }, {
256 | text: 'C',
257 | max: 100,
258 | min: 0
259 | }, {
260 | text: 'D',
261 | max: 100,
262 | min: 0
263 | }, {
264 | text: 'E',
265 | max: 100,
266 | min: 0
267 | }, {
268 | text: 'F',
269 | max: 100,
270 | min: 0
271 | }],
272 | data: [{
273 | name: 'Li',
274 | value: [10, 20, 30, 40, 50, 60]
275 | }, {
276 | name: 'Han',
277 | value: [80, 70, 60, 50, 40, 30]
278 | }]
279 | }]
280 | };
281 | chart.loadConfig(option);
282 | }
283 |
284 | function drawFunnelChart() {
285 | const chart = xCharts(document.querySelector('#container_funnel'));
286 | option = {
287 | tooltip: {
288 | trigger: 'item'
289 | },
290 | legend: {
291 | show: true,
292 | data: ['A', 'B', 'C', 'D', 'E'],
293 | x: 'center'
294 | },
295 | title: {
296 | text: 'Funnel'
297 | },
298 | resize: {
299 | enable: true
300 | },
301 | animation: {
302 | enable: true
303 | },
304 | series: [{
305 | name: 'sample',
306 | size: ['50%', '70%'],
307 | type: 'funnel',
308 | data: [{
309 | name: 'A',
310 | value: '80'
311 | }, {
312 | name: 'B',
313 | value: '100'
314 | }, {
315 | name: 'C',
316 | value: '60'
317 | }, {
318 | name: 'D',
319 | value: '40'
320 | }, {
321 | name: 'E',
322 | value: '20'
323 | }, ]
324 | }]
325 | };
326 | chart.loadConfig(option);
327 | }
328 |
329 | function drawChart() {
330 | drawBarChart();
331 | drawScatterChart();
332 | drawPieChart();
333 | drawLineChart();
334 | drawRadarChart();
335 | drawFunnelChart();
336 | }
337 |
338 | function getHandler() {
339 | const option = {
340 | chartType: 'xcharts',
341 | fillStyle: $('#fillStyleSelector').children('option:selected').val(),
342 | bowing: $('#bowingRange').val(),
343 | roughness: $('#roughnessRange').val()
344 | };
345 |
346 | const container = $('#charts')[0];
347 | return handler = Sketchifier(container, option);
348 | }
349 |
350 | $(function() {
351 | drawChart();
352 | var handler = getHandler();
353 |
354 | function updateHandler() {
355 | handler.restore();
356 | handler = getHandler();
357 | if ($('#handifyChecker').prop('checked')) {
358 | handler.handify();
359 | }
360 | }
361 |
362 | $('#fillStyleSelector').change(function() {
363 | updateHandler();
364 | })
365 |
366 | $('#bowingRange').change(function() {
367 | updateHandler();
368 | })
369 |
370 | $('#roughnessRange').change(function() {
371 | updateHandler();
372 | })
373 |
374 | $('#handifyChecker').change(function() {
375 | if (this.checked) {
376 | handler.handify();
377 | } else {
378 | handler.restore();
379 | }
380 | });
381 | });
--------------------------------------------------------------------------------
/dist/sketchify.js:
--------------------------------------------------------------------------------
1 | /******/ (function(modules) { // webpackBootstrap
2 | /******/ // The module cache
3 | /******/ var installedModules = {};
4 | /******/
5 | /******/ // The require function
6 | /******/ function __webpack_require__(moduleId) {
7 | /******/
8 | /******/ // Check if module is in cache
9 | /******/ if(installedModules[moduleId]) {
10 | /******/ return installedModules[moduleId].exports;
11 | /******/ }
12 | /******/ // Create a new module (and put it into the cache)
13 | /******/ var module = installedModules[moduleId] = {
14 | /******/ i: moduleId,
15 | /******/ l: false,
16 | /******/ exports: {}
17 | /******/ };
18 | /******/
19 | /******/ // Execute the module function
20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21 | /******/
22 | /******/ // Flag the module as loaded
23 | /******/ module.l = true;
24 | /******/
25 | /******/ // Return the exports of the module
26 | /******/ return module.exports;
27 | /******/ }
28 | /******/
29 | /******/
30 | /******/ // expose the modules object (__webpack_modules__)
31 | /******/ __webpack_require__.m = modules;
32 | /******/
33 | /******/ // expose the module cache
34 | /******/ __webpack_require__.c = installedModules;
35 | /******/
36 | /******/ // define getter function for harmony exports
37 | /******/ __webpack_require__.d = function(exports, name, getter) {
38 | /******/ if(!__webpack_require__.o(exports, name)) {
39 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
40 | /******/ }
41 | /******/ };
42 | /******/
43 | /******/ // define __esModule on exports
44 | /******/ __webpack_require__.r = function(exports) {
45 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
46 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
47 | /******/ }
48 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
49 | /******/ };
50 | /******/
51 | /******/ // create a fake namespace object
52 | /******/ // mode & 1: value is a module id, require it
53 | /******/ // mode & 2: merge all properties of value into the ns
54 | /******/ // mode & 4: return value when already ns object
55 | /******/ // mode & 8|1: behave like require
56 | /******/ __webpack_require__.t = function(value, mode) {
57 | /******/ if(mode & 1) value = __webpack_require__(value);
58 | /******/ if(mode & 8) return value;
59 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
60 | /******/ var ns = Object.create(null);
61 | /******/ __webpack_require__.r(ns);
62 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
63 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
64 | /******/ return ns;
65 | /******/ };
66 | /******/
67 | /******/ // getDefaultExport function for compatibility with non-harmony modules
68 | /******/ __webpack_require__.n = function(module) {
69 | /******/ var getter = module && module.__esModule ?
70 | /******/ function getDefault() { return module['default']; } :
71 | /******/ function getModuleExports() { return module; };
72 | /******/ __webpack_require__.d(getter, 'a', getter);
73 | /******/ return getter;
74 | /******/ };
75 | /******/
76 | /******/ // Object.prototype.hasOwnProperty.call
77 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
78 | /******/
79 | /******/ // __webpack_public_path__
80 | /******/ __webpack_require__.p = "";
81 | /******/
82 | /******/
83 | /******/ // Load entry module and return exports
84 | /******/ return __webpack_require__(__webpack_require__.s = "./src/index.js");
85 | /******/ })
86 | /************************************************************************/
87 | /******/ ({
88 |
89 | /***/ "./node_modules/css-loader/dist/cjs.js!./src/style.css":
90 | /*!*************************************************************!*\
91 | !*** ./node_modules/css-loader/dist/cjs.js!./src/style.css ***!
92 | \*************************************************************/
93 | /*! no static exports found */
94 | /***/ (function(module, exports, __webpack_require__) {
95 |
96 | eval("exports = module.exports = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.i, \".sk-text {\\n font-family: 'Indie Flower', Helvetica, sans-serif, SimSun;\\n}\\n\\n/* latin */\\n@font-face {\\n font-family: 'Shadows Into Light';\\n font-style: normal;\\n font-weight: 400;\\n font-display: swap;\\n src: local('Shadows Into Light'), local('ShadowsIntoLight'), url(https://fonts.gstatic.com/s/shadowsintolight/v9/UqyNK9UOIntux_czAvDQx_ZcHqZXBNQzdcD55TecYQ.woff2) format('woff2');\\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\\n}\\n\\n/* latin */\\n@font-face {\\n font-family: 'Indie Flower';\\n font-style: normal;\\n font-weight: 400;\\n font-display: swap;\\n src: local('Indie Flower'), local('IndieFlower'), url(https://fonts.gstatic.com/s/indieflower/v11/m8JVjfNVeKWVnh3QMuKkFcZVaUuH99GUDg.woff2) format('woff2');\\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\\n}\", \"\"]);\n\n\n//# sourceURL=webpack:///./src/style.css?./node_modules/css-loader/dist/cjs.js");
97 |
98 | /***/ }),
99 |
100 | /***/ "./node_modules/css-loader/dist/runtime/api.js":
101 | /*!*****************************************************!*\
102 | !*** ./node_modules/css-loader/dist/runtime/api.js ***!
103 | \*****************************************************/
104 | /*! no static exports found */
105 | /***/ (function(module, exports, __webpack_require__) {
106 |
107 | "use strict";
108 | eval("\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (useSourceMap) {\n var list = []; // return the list of modules as css string\n\n list.toString = function toString() {\n return this.map(function (item) {\n var content = cssWithMappingToString(item, useSourceMap);\n\n if (item[2]) {\n return \"@media \".concat(item[2], \"{\").concat(content, \"}\");\n }\n\n return content;\n }).join('');\n }; // import a list of modules into the list\n // eslint-disable-next-line func-names\n\n\n list.i = function (modules, mediaQuery) {\n if (typeof modules === 'string') {\n // eslint-disable-next-line no-param-reassign\n modules = [[null, modules, '']];\n }\n\n var alreadyImportedModules = {};\n\n for (var i = 0; i < this.length; i++) {\n // eslint-disable-next-line prefer-destructuring\n var id = this[i][0];\n\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n\n for (var _i = 0; _i < modules.length; _i++) {\n var item = modules[_i]; // skip already imported module\n // this implementation is not 100% perfect for weird media query combinations\n // when a module is imported multiple times with different media queries.\n // I hope this will never occur (Hey this way we have smaller bundles)\n\n if (item[0] == null || !alreadyImportedModules[item[0]]) {\n if (mediaQuery && !item[2]) {\n item[2] = mediaQuery;\n } else if (mediaQuery) {\n item[2] = \"(\".concat(item[2], \") and (\").concat(mediaQuery, \")\");\n }\n\n list.push(item);\n }\n }\n };\n\n return list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring\n\n var cssMapping = item[3];\n\n if (!cssMapping) {\n return content;\n }\n\n if (useSourceMap && typeof btoa === 'function') {\n var sourceMapping = toComment(cssMapping);\n var sourceURLs = cssMapping.sources.map(function (source) {\n return \"/*# sourceURL=\".concat(cssMapping.sourceRoot).concat(source, \" */\");\n });\n return [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n }\n\n return [content].join('\\n');\n} // Adapted from convert-source-map (MIT)\n\n\nfunction toComment(sourceMap) {\n // eslint-disable-next-line no-undef\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n return \"/*# \".concat(data, \" */\");\n}\n\n//# sourceURL=webpack:///./node_modules/css-loader/dist/runtime/api.js?");
109 |
110 | /***/ }),
111 |
112 | /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js":
113 | /*!****************************************************************************!*\
114 | !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
115 | \****************************************************************************/
116 | /*! no static exports found */
117 | /***/ (function(module, exports, __webpack_require__) {
118 |
119 | "use strict";
120 | eval("\n\nvar stylesInDom = {};\n\nvar isOldIE = function isOldIE() {\n var memo;\n return function memorize() {\n if (typeof memo === 'undefined') {\n // Test for IE <= 9 as proposed by Browserhacks\n // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n // Tests for existence of standard globals is to allow style-loader\n // to operate correctly into non-standard environments\n // @see https://github.com/webpack-contrib/style-loader/issues/177\n memo = Boolean(window && document && document.all && !window.atob);\n }\n\n return memo;\n };\n}();\n\nvar getTarget = function getTarget() {\n var memo = {};\n return function memorize(target) {\n if (typeof memo[target] === 'undefined') {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n };\n}();\n\nfunction listToStyles(list, options) {\n var styles = [];\n var newStyles = {};\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var css = item[1];\n var media = item[2];\n var sourceMap = item[3];\n var part = {\n css: css,\n media: media,\n sourceMap: sourceMap\n };\n\n if (!newStyles[id]) {\n styles.push(newStyles[id] = {\n id: id,\n parts: [part]\n });\n } else {\n newStyles[id].parts.push(part);\n }\n }\n\n return styles;\n}\n\nfunction addStylesToDom(styles, options) {\n for (var i = 0; i < styles.length; i++) {\n var item = styles[i];\n var domStyle = stylesInDom[item.id];\n var j = 0;\n\n if (domStyle) {\n domStyle.refs++;\n\n for (; j < domStyle.parts.length; j++) {\n domStyle.parts[j](item.parts[j]);\n }\n\n for (; j < item.parts.length; j++) {\n domStyle.parts.push(addStyle(item.parts[j], options));\n }\n } else {\n var parts = [];\n\n for (; j < item.parts.length; j++) {\n parts.push(addStyle(item.parts[j], options));\n }\n\n stylesInDom[item.id] = {\n id: item.id,\n refs: 1,\n parts: parts\n };\n }\n }\n}\n\nfunction insertStyleElement(options) {\n var style = document.createElement('style');\n\n if (typeof options.attributes.nonce === 'undefined') {\n var nonce = true ? __webpack_require__.nc : undefined;\n\n if (nonce) {\n options.attributes.nonce = nonce;\n }\n }\n\n Object.keys(options.attributes).forEach(function (key) {\n style.setAttribute(key, options.attributes[key]);\n });\n\n if (typeof options.insert === 'function') {\n options.insert(style);\n } else {\n var target = getTarget(options.insert || 'head');\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n }\n\n return style;\n}\n\nfunction removeStyleElement(style) {\n // istanbul ignore if\n if (style.parentNode === null) {\n return false;\n }\n\n style.parentNode.removeChild(style);\n}\n/* istanbul ignore next */\n\n\nvar replaceText = function replaceText() {\n var textStore = [];\n return function replace(index, replacement) {\n textStore[index] = replacement;\n return textStore.filter(Boolean).join('\\n');\n };\n}();\n\nfunction applyToSingletonTag(style, index, remove, obj) {\n var css = remove ? '' : obj.css; // For old IE\n\n /* istanbul ignore if */\n\n if (style.styleSheet) {\n style.styleSheet.cssText = replaceText(index, css);\n } else {\n var cssNode = document.createTextNode(css);\n var childNodes = style.childNodes;\n\n if (childNodes[index]) {\n style.removeChild(childNodes[index]);\n }\n\n if (childNodes.length) {\n style.insertBefore(cssNode, childNodes[index]);\n } else {\n style.appendChild(cssNode);\n }\n }\n}\n\nfunction applyToTag(style, options, obj) {\n var css = obj.css;\n var media = obj.media;\n var sourceMap = obj.sourceMap;\n\n if (media) {\n style.setAttribute('media', media);\n }\n\n if (sourceMap && btoa) {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n while (style.firstChild) {\n style.removeChild(style.firstChild);\n }\n\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar singleton = null;\nvar singletonCounter = 0;\n\nfunction addStyle(obj, options) {\n var style;\n var update;\n var remove;\n\n if (options.singleton) {\n var styleIndex = singletonCounter++;\n style = singleton || (singleton = insertStyleElement(options));\n update = applyToSingletonTag.bind(null, style, styleIndex, false);\n remove = applyToSingletonTag.bind(null, style, styleIndex, true);\n } else {\n style = insertStyleElement(options);\n update = applyToTag.bind(null, style, options);\n\n remove = function remove() {\n removeStyleElement(style);\n };\n }\n\n update(obj);\n return function updateStyle(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {\n return;\n }\n\n update(obj = newObj);\n } else {\n remove();\n }\n };\n}\n\nmodule.exports = function (list, options) {\n options = options || {};\n options.attributes = typeof options.attributes === 'object' ? options.attributes : {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of