govuk_publishing_components 44.3.0 → 44.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/components/chart.js +1 -0
  3. data/app/assets/stylesheets/govuk_publishing_components/components/_chart.scss +44 -0
  4. data/app/assets/stylesheets/govuk_publishing_components/components/_contents-list.scss +28 -5
  5. data/app/assets/stylesheets/govuk_publishing_components/components/_organisation-logo.scss +15 -0
  6. data/app/views/govuk_publishing_components/components/_chart.html.erb +151 -0
  7. data/app/views/govuk_publishing_components/components/_contents_list.html.erb +7 -3
  8. data/app/views/govuk_publishing_components/components/_organisation_logo.html.erb +2 -0
  9. data/app/views/govuk_publishing_components/components/docs/chart.yml +238 -0
  10. data/app/views/govuk_publishing_components/components/docs/contents_list.yml +32 -0
  11. data/app/views/govuk_publishing_components/components/docs/organisation_logo.yml +11 -1
  12. data/config/locales/ar.yml +3 -0
  13. data/config/locales/az.yml +3 -0
  14. data/config/locales/be.yml +3 -0
  15. data/config/locales/bg.yml +3 -0
  16. data/config/locales/bn.yml +3 -0
  17. data/config/locales/cs.yml +3 -0
  18. data/config/locales/cy.yml +3 -0
  19. data/config/locales/da.yml +3 -0
  20. data/config/locales/de.yml +3 -0
  21. data/config/locales/dr.yml +3 -0
  22. data/config/locales/el.yml +3 -0
  23. data/config/locales/en.yml +3 -0
  24. data/config/locales/es-419.yml +3 -0
  25. data/config/locales/es.yml +3 -0
  26. data/config/locales/et.yml +3 -0
  27. data/config/locales/fa.yml +3 -0
  28. data/config/locales/fi.yml +3 -0
  29. data/config/locales/fr.yml +3 -0
  30. data/config/locales/gd.yml +3 -0
  31. data/config/locales/gu.yml +3 -0
  32. data/config/locales/he.yml +3 -0
  33. data/config/locales/hi.yml +3 -0
  34. data/config/locales/hr.yml +3 -0
  35. data/config/locales/hu.yml +3 -0
  36. data/config/locales/hy.yml +3 -0
  37. data/config/locales/id.yml +3 -0
  38. data/config/locales/is.yml +3 -0
  39. data/config/locales/it.yml +3 -0
  40. data/config/locales/ja.yml +3 -0
  41. data/config/locales/ka.yml +3 -0
  42. data/config/locales/kk.yml +3 -0
  43. data/config/locales/ko.yml +3 -0
  44. data/config/locales/lt.yml +3 -0
  45. data/config/locales/lv.yml +3 -0
  46. data/config/locales/ms.yml +3 -0
  47. data/config/locales/mt.yml +3 -0
  48. data/config/locales/nl.yml +3 -0
  49. data/config/locales/no.yml +3 -0
  50. data/config/locales/pa-pk.yml +3 -0
  51. data/config/locales/pa.yml +3 -0
  52. data/config/locales/pl.yml +3 -0
  53. data/config/locales/ps.yml +3 -0
  54. data/config/locales/pt.yml +3 -0
  55. data/config/locales/ro.yml +3 -0
  56. data/config/locales/ru.yml +3 -0
  57. data/config/locales/si.yml +3 -0
  58. data/config/locales/sk.yml +3 -0
  59. data/config/locales/sl.yml +3 -0
  60. data/config/locales/so.yml +3 -0
  61. data/config/locales/sq.yml +3 -0
  62. data/config/locales/sr.yml +3 -0
  63. data/config/locales/sv.yml +3 -0
  64. data/config/locales/sw.yml +3 -0
  65. data/config/locales/ta.yml +3 -0
  66. data/config/locales/th.yml +3 -0
  67. data/config/locales/tk.yml +3 -0
  68. data/config/locales/tr.yml +3 -0
  69. data/config/locales/uk.yml +3 -0
  70. data/config/locales/ur.yml +3 -0
  71. data/config/locales/uz.yml +3 -0
  72. data/config/locales/vi.yml +3 -0
  73. data/config/locales/zh-hk.yml +3 -0
  74. data/config/locales/zh-tw.yml +3 -0
  75. data/config/locales/zh.yml +3 -0
  76. data/lib/govuk_publishing_components/version.rb +1 -1
  77. data/node_modules/chartkick/LICENSE.txt +22 -0
  78. data/node_modules/chartkick/README.md +593 -0
  79. data/node_modules/chartkick/chart.js/chart.esm.js +5 -0
  80. data/node_modules/chartkick/chart.js/package.json +6 -0
  81. data/node_modules/chartkick/dist/chartkick.esm.js +2562 -0
  82. data/node_modules/chartkick/dist/chartkick.js +2570 -0
  83. data/node_modules/chartkick/dist/chartkick.min.js +2 -0
  84. data/node_modules/chartkick/highcharts/highcharts.esm.js +4 -0
  85. data/node_modules/chartkick/highcharts/package.json +6 -0
  86. data/node_modules/chartkick/package.json +50 -0
  87. metadata +31 -3
@@ -0,0 +1,2562 @@
1
+ /*!
2
+ * Chartkick.js v5.0.1
3
+ * Create beautiful charts with one line of JavaScript
4
+ * https://github.com/ankane/chartkick.js
5
+ * MIT License
6
+ */
7
+
8
+ function isArray(variable) {
9
+ return Object.prototype.toString.call(variable) === "[object Array]";
10
+ }
11
+
12
+ function isFunction(variable) {
13
+ return variable instanceof Function;
14
+ }
15
+
16
+ function isPlainObject(variable) {
17
+ // protect against prototype pollution, defense 2
18
+ return Object.prototype.toString.call(variable) === "[object Object]" && !isFunction(variable) && variable instanceof Object;
19
+ }
20
+
21
+ // https://github.com/madrobby/zepto/blob/master/src/zepto.js
22
+ function extend(target, source) {
23
+ for (var key in source) {
24
+ // protect against prototype pollution, defense 1
25
+ if (key === "__proto__") { continue; }
26
+
27
+ if (isPlainObject(source[key]) || isArray(source[key])) {
28
+ if (isPlainObject(source[key]) && !isPlainObject(target[key])) {
29
+ target[key] = {};
30
+ }
31
+ if (isArray(source[key]) && !isArray(target[key])) {
32
+ target[key] = [];
33
+ }
34
+ extend(target[key], source[key]);
35
+ } else if (source[key] !== undefined) {
36
+ target[key] = source[key];
37
+ }
38
+ }
39
+ }
40
+
41
+ function merge(obj1, obj2) {
42
+ var target = {};
43
+ extend(target, obj1);
44
+ extend(target, obj2);
45
+ return target;
46
+ }
47
+
48
+ var DATE_PATTERN = /^(\d\d\d\d)(?:-)?(\d\d)(?:-)?(\d\d)$/i;
49
+
50
+ function negativeValues(series) {
51
+ for (var i = 0; i < series.length; i++) {
52
+ var data = series[i].data;
53
+ for (var j = 0; j < data.length; j++) {
54
+ if (data[j][1] < 0) {
55
+ return true;
56
+ }
57
+ }
58
+ }
59
+ return false;
60
+ }
61
+
62
+ function toStr(obj) {
63
+ return "" + obj;
64
+ }
65
+
66
+ function toFloat(obj) {
67
+ return parseFloat(obj);
68
+ }
69
+
70
+ function toDate(obj) {
71
+ if (obj instanceof Date) {
72
+ return obj;
73
+ } else if (typeof obj === "number") {
74
+ return new Date(obj * 1000); // ms
75
+ } else {
76
+ var s = toStr(obj);
77
+ var matches = s.match(DATE_PATTERN);
78
+ if (matches) {
79
+ var year = parseInt(matches[1], 10);
80
+ var month = parseInt(matches[2], 10) - 1;
81
+ var day = parseInt(matches[3], 10);
82
+ return new Date(year, month, day);
83
+ } else {
84
+ // try our best to get the str into iso8601
85
+ // TODO be smarter about this
86
+ var str = s.replace(/ /, "T").replace(" ", "").replace("UTC", "Z");
87
+ // Date.parse returns milliseconds if valid and NaN if invalid
88
+ return new Date(Date.parse(str) || s);
89
+ }
90
+ }
91
+ }
92
+
93
+ function toArr(obj) {
94
+ if (isArray(obj)) {
95
+ return obj;
96
+ } else {
97
+ var arr = [];
98
+ for (var i in obj) {
99
+ if (Object.prototype.hasOwnProperty.call(obj, i)) {
100
+ arr.push([i, obj[i]]);
101
+ }
102
+ }
103
+ return arr;
104
+ }
105
+ }
106
+
107
+ function jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle) {
108
+ return function (chart, opts, chartOptions) {
109
+ var series = chart.data;
110
+ var options = merge({}, defaultOptions);
111
+ options = merge(options, chartOptions || {});
112
+
113
+ if (chart.singleSeriesFormat || "legend" in opts) {
114
+ hideLegend(options, opts.legend, chart.singleSeriesFormat);
115
+ }
116
+
117
+ if (opts.title) {
118
+ setTitle(options, opts.title);
119
+ }
120
+
121
+ // min
122
+ if ("min" in opts) {
123
+ setMin(options, opts.min);
124
+ } else if (!negativeValues(series)) {
125
+ setMin(options, 0);
126
+ }
127
+
128
+ // max
129
+ if (opts.max) {
130
+ setMax(options, opts.max);
131
+ }
132
+
133
+ if ("stacked" in opts) {
134
+ setStacked(options, opts.stacked);
135
+ }
136
+
137
+ if (opts.colors) {
138
+ options.colors = opts.colors;
139
+ }
140
+
141
+ if (opts.xtitle) {
142
+ setXtitle(options, opts.xtitle);
143
+ }
144
+
145
+ if (opts.ytitle) {
146
+ setYtitle(options, opts.ytitle);
147
+ }
148
+
149
+ // merge library last
150
+ options = merge(options, opts.library || {});
151
+
152
+ return options;
153
+ };
154
+ }
155
+
156
+ function sortByTime(a, b) {
157
+ return a[0].getTime() - b[0].getTime();
158
+ }
159
+
160
+ function sortByNumberSeries(a, b) {
161
+ return a[0] - b[0];
162
+ }
163
+
164
+ // needed since sort() without arguments does string comparison
165
+ function sortByNumber(a, b) {
166
+ return a - b;
167
+ }
168
+
169
+ function every(values, fn) {
170
+ for (var i = 0; i < values.length; i++) {
171
+ if (!fn(values[i])) {
172
+ return false;
173
+ }
174
+ }
175
+ return true;
176
+ }
177
+
178
+ function isDay(timeUnit) {
179
+ return timeUnit === "day" || timeUnit === "week" || timeUnit === "month" || timeUnit === "year";
180
+ }
181
+
182
+ function calculateTimeUnit(values, maxDay) {
183
+ if ( maxDay === void 0 ) maxDay = false;
184
+
185
+ if (values.length === 0) {
186
+ return null;
187
+ }
188
+
189
+ var minute = every(values, function (d) { return d.getMilliseconds() === 0 && d.getSeconds() === 0; });
190
+ if (!minute) {
191
+ return null;
192
+ }
193
+
194
+ var hour = every(values, function (d) { return d.getMinutes() === 0; });
195
+ if (!hour) {
196
+ return "minute";
197
+ }
198
+
199
+ var day = every(values, function (d) { return d.getHours() === 0; });
200
+ if (!day) {
201
+ return "hour";
202
+ }
203
+
204
+ if (maxDay) {
205
+ return "day";
206
+ }
207
+
208
+ var month = every(values, function (d) { return d.getDate() === 1; });
209
+ if (!month) {
210
+ var dayOfWeek = values[0].getDay();
211
+ var week = every(values, function (d) { return d.getDay() === dayOfWeek; });
212
+ return (week ? "week" : "day");
213
+ }
214
+
215
+ var year = every(values, function (d) { return d.getMonth() === 0; });
216
+ if (!year) {
217
+ return "month";
218
+ }
219
+
220
+ return "year";
221
+ }
222
+
223
+ function isDate(obj) {
224
+ return !isNaN(toDate(obj)) && toStr(obj).length >= 6;
225
+ }
226
+
227
+ function isNumber(obj) {
228
+ return typeof obj === "number";
229
+ }
230
+
231
+ var byteSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB"];
232
+
233
+ function formatValue(pre, value, options, axis) {
234
+ pre = pre || "";
235
+ if (options.prefix) {
236
+ if (value < 0) {
237
+ value = value * -1;
238
+ pre += "-";
239
+ }
240
+ pre += options.prefix;
241
+ }
242
+
243
+ var suffix = options.suffix || "";
244
+ var precision = options.precision;
245
+ var round = options.round;
246
+
247
+ if (options.byteScale) {
248
+ var positive = value >= 0;
249
+ if (!positive) {
250
+ value *= -1;
251
+ }
252
+
253
+ var baseValue = axis ? options.byteScale : value;
254
+
255
+ var suffixIdx;
256
+ if (baseValue >= 1152921504606846976) {
257
+ value /= 1152921504606846976;
258
+ suffixIdx = 6;
259
+ } else if (baseValue >= 1125899906842624) {
260
+ value /= 1125899906842624;
261
+ suffixIdx = 5;
262
+ } else if (baseValue >= 1099511627776) {
263
+ value /= 1099511627776;
264
+ suffixIdx = 4;
265
+ } else if (baseValue >= 1073741824) {
266
+ value /= 1073741824;
267
+ suffixIdx = 3;
268
+ } else if (baseValue >= 1048576) {
269
+ value /= 1048576;
270
+ suffixIdx = 2;
271
+ } else if (baseValue >= 1024) {
272
+ value /= 1024;
273
+ suffixIdx = 1;
274
+ } else {
275
+ suffixIdx = 0;
276
+ }
277
+
278
+ // TODO handle manual precision case
279
+ if (precision === undefined && round === undefined) {
280
+ if (value >= 1023.5) {
281
+ if (suffixIdx < byteSuffixes.length - 1) {
282
+ value = 1.0;
283
+ suffixIdx += 1;
284
+ }
285
+ }
286
+ precision = value >= 1000 ? 4 : 3;
287
+ }
288
+ suffix = " " + byteSuffixes[suffixIdx];
289
+
290
+ // flip value back
291
+ if (!positive) {
292
+ value *= -1;
293
+ }
294
+ }
295
+
296
+ if (precision !== undefined && round !== undefined) {
297
+ throw Error("Use either round or precision, not both");
298
+ }
299
+
300
+ if (!axis) {
301
+ if (precision !== undefined) {
302
+ value = value.toPrecision(precision);
303
+ if (!options.zeros) {
304
+ value = parseFloat(value);
305
+ }
306
+ }
307
+
308
+ if (round !== undefined) {
309
+ if (round < 0) {
310
+ var num = Math.pow(10, -1 * round);
311
+ value = parseInt((1.0 * value / num).toFixed(0)) * num;
312
+ } else {
313
+ value = value.toFixed(round);
314
+ if (!options.zeros) {
315
+ value = parseFloat(value);
316
+ }
317
+ }
318
+ }
319
+ }
320
+
321
+ if (options.thousands || options.decimal) {
322
+ value = toStr(value);
323
+ var parts = value.split(".");
324
+ value = parts[0];
325
+ if (options.thousands) {
326
+ value = value.replace(/\B(?=(\d{3})+(?!\d))/g, options.thousands);
327
+ }
328
+ if (parts.length > 1) {
329
+ value += (options.decimal || ".") + parts[1];
330
+ }
331
+ }
332
+
333
+ return pre + value + suffix;
334
+ }
335
+
336
+ function seriesOption(chart, series, option) {
337
+ if (option in series) {
338
+ return series[option];
339
+ } else if (option in chart.options) {
340
+ return chart.options[option];
341
+ }
342
+ return null;
343
+ }
344
+
345
+ var baseOptions = {
346
+ maintainAspectRatio: false,
347
+ animation: false,
348
+ plugins: {
349
+ legend: {},
350
+ tooltip: {
351
+ displayColors: false,
352
+ callbacks: {}
353
+ },
354
+ title: {
355
+ font: {
356
+ size: 20
357
+ },
358
+ color: "#333"
359
+ }
360
+ },
361
+ interaction: {}
362
+ };
363
+
364
+ var defaultOptions$2 = {
365
+ scales: {
366
+ y: {
367
+ ticks: {
368
+ maxTicksLimit: 4
369
+ },
370
+ title: {
371
+ font: {
372
+ size: 16
373
+ },
374
+ color: "#333"
375
+ },
376
+ grid: {}
377
+ },
378
+ x: {
379
+ grid: {
380
+ drawOnChartArea: false
381
+ },
382
+ title: {
383
+ font: {
384
+ size: 16
385
+ },
386
+ color: "#333"
387
+ },
388
+ time: {},
389
+ ticks: {}
390
+ }
391
+ }
392
+ };
393
+
394
+ // http://there4.io/2012/05/02/google-chart-color-list/
395
+ var defaultColors = [
396
+ "#3366CC", "#DC3912", "#FF9900", "#109618", "#990099", "#3B3EAC", "#0099C6",
397
+ "#DD4477", "#66AA00", "#B82E2E", "#316395", "#994499", "#22AA99", "#AAAA11",
398
+ "#6633CC", "#E67300", "#8B0707", "#329262", "#5574A6", "#651067"
399
+ ];
400
+
401
+ function hideLegend$2(options, legend, hideLegend) {
402
+ if (legend !== undefined) {
403
+ options.plugins.legend.display = !!legend;
404
+ if (legend && legend !== true) {
405
+ options.plugins.legend.position = legend;
406
+ }
407
+ } else if (hideLegend) {
408
+ options.plugins.legend.display = false;
409
+ }
410
+ }
411
+
412
+ function setTitle$2(options, title) {
413
+ options.plugins.title.display = true;
414
+ options.plugins.title.text = title;
415
+ }
416
+
417
+ function setMin$2(options, min) {
418
+ if (min !== null) {
419
+ options.scales.y.min = toFloat(min);
420
+ }
421
+ }
422
+
423
+ function setMax$2(options, max) {
424
+ options.scales.y.max = toFloat(max);
425
+ }
426
+
427
+ function setBarMin$1(options, min) {
428
+ if (min !== null) {
429
+ options.scales.x.min = toFloat(min);
430
+ }
431
+ }
432
+
433
+ function setBarMax$1(options, max) {
434
+ options.scales.x.max = toFloat(max);
435
+ }
436
+
437
+ function setStacked$2(options, stacked) {
438
+ options.scales.x.stacked = !!stacked;
439
+ options.scales.y.stacked = !!stacked;
440
+ }
441
+
442
+ function setXtitle$2(options, title) {
443
+ options.scales.x.title.display = true;
444
+ options.scales.x.title.text = title;
445
+ }
446
+
447
+ function setYtitle$2(options, title) {
448
+ options.scales.y.title.display = true;
449
+ options.scales.y.title.text = title;
450
+ }
451
+
452
+ // https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
453
+ function addOpacity(hex, opacity) {
454
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
455
+ return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
456
+ }
457
+
458
+ function notnull(x) {
459
+ return x !== null && x !== undefined;
460
+ }
461
+
462
+ function setLabelSize(chart, data, options) {
463
+ var maxLabelSize = Math.ceil(chart.element.offsetWidth / 4.0 / data.labels.length);
464
+ if (maxLabelSize > 25) {
465
+ maxLabelSize = 25;
466
+ } else if (maxLabelSize < 10) {
467
+ maxLabelSize = 10;
468
+ }
469
+ if (!options.scales.x.ticks.callback) {
470
+ options.scales.x.ticks.callback = function (value) {
471
+ value = toStr(this.getLabelForValue(value));
472
+ if (value.length > maxLabelSize) {
473
+ return value.substring(0, maxLabelSize - 2) + "...";
474
+ } else {
475
+ return value;
476
+ }
477
+ };
478
+ }
479
+ }
480
+
481
+ function calculateScale(series) {
482
+ var scale = 1;
483
+ var max = maxAbsY(series);
484
+ while (max >= 1024) {
485
+ scale *= 1024;
486
+ max /= 1024;
487
+ }
488
+ return scale;
489
+ }
490
+
491
+ function setFormatOptions$1(chart, options, chartType) {
492
+ // options to apply to x and r values for scatter and bubble
493
+ var numericOptions = {
494
+ thousands: chart.options.thousands,
495
+ decimal: chart.options.decimal
496
+ };
497
+
498
+ // options to apply to y value
499
+ var formatOptions = merge({
500
+ prefix: chart.options.prefix,
501
+ suffix: chart.options.suffix,
502
+ precision: chart.options.precision,
503
+ round: chart.options.round,
504
+ zeros: chart.options.zeros
505
+ }, numericOptions);
506
+
507
+ if (chart.options.bytes) {
508
+ var series = chart.data;
509
+ if (chartType === "pie") {
510
+ series = [{data: series}];
511
+ }
512
+
513
+ // set step size
514
+ formatOptions.byteScale = calculateScale(series);
515
+ }
516
+
517
+ if (chartType !== "pie") {
518
+ var axis = options.scales.y;
519
+ if (chartType === "bar") {
520
+ axis = options.scales.x;
521
+ }
522
+
523
+ if (formatOptions.byteScale) {
524
+ if (!axis.ticks.stepSize) {
525
+ axis.ticks.stepSize = formatOptions.byteScale / 2;
526
+ }
527
+ if (!axis.ticks.maxTicksLimit) {
528
+ axis.ticks.maxTicksLimit = 4;
529
+ }
530
+ }
531
+
532
+ if (!axis.ticks.callback) {
533
+ axis.ticks.callback = function (value) {
534
+ return formatValue("", value, formatOptions, true);
535
+ };
536
+ }
537
+
538
+ if ((chartType === "scatter" || chartType === "bubble") && !options.scales.x.ticks.callback) {
539
+ options.scales.x.ticks.callback = function (value) {
540
+ return formatValue("", value, numericOptions, true);
541
+ };
542
+ }
543
+ }
544
+
545
+ if (!options.plugins.tooltip.callbacks.label) {
546
+ if (chartType === "scatter") {
547
+ options.plugins.tooltip.callbacks.label = function (context) {
548
+ var label = context.dataset.label || '';
549
+ if (label) {
550
+ label += ': ';
551
+ }
552
+
553
+ var dataPoint = context.parsed;
554
+ return label + '(' + formatValue('', dataPoint.x, numericOptions) + ', ' + formatValue('', dataPoint.y, formatOptions) + ')';
555
+ };
556
+ } else if (chartType === "bubble") {
557
+ options.plugins.tooltip.callbacks.label = function (context) {
558
+ var label = context.dataset.label || '';
559
+ if (label) {
560
+ label += ': ';
561
+ }
562
+ var dataPoint = context.raw;
563
+ return label + '(' + formatValue('', dataPoint.x, numericOptions) + ', ' + formatValue('', dataPoint.y, formatOptions) + ', ' + formatValue('', dataPoint.v, numericOptions) + ')';
564
+ };
565
+ } else if (chartType === "pie") {
566
+ // need to use separate label for pie charts
567
+ options.plugins.tooltip.callbacks.label = function (context) {
568
+ return formatValue('', context.parsed, formatOptions);
569
+ };
570
+ } else {
571
+ var valueLabel = chartType === "bar" ? "x" : "y";
572
+ options.plugins.tooltip.callbacks.label = function (context) {
573
+ // don't show null values for stacked charts
574
+ if (context.parsed[valueLabel] === null) {
575
+ return;
576
+ }
577
+
578
+ var label = context.dataset.label || '';
579
+ if (label) {
580
+ label += ': ';
581
+ }
582
+ return formatValue(label, context.parsed[valueLabel], formatOptions);
583
+ };
584
+ }
585
+ }
586
+
587
+ // avoid formatting x-axis labels
588
+ // by default, Chart.js applies locale
589
+ if ((chartType === "line" || chartType === "area") && chart.xtype === "number") {
590
+ if (!options.scales.x.ticks.callback) {
591
+ options.scales.x.ticks.callback = function (value) {
592
+ return toStr(value);
593
+ };
594
+ }
595
+
596
+ if (!options.plugins.tooltip.callbacks.title) {
597
+ options.plugins.tooltip.callbacks.title = function (context) {
598
+ return toStr(context[0].parsed.x);
599
+ };
600
+ }
601
+ }
602
+ }
603
+
604
+ function maxAbsY(series) {
605
+ var max = 0;
606
+ for (var i = 0; i < series.length; i++) {
607
+ var data = series[i].data;
608
+ for (var j = 0; j < data.length; j++) {
609
+ var v = Math.abs(data[j][1]);
610
+ if (v > max) {
611
+ max = v;
612
+ }
613
+ }
614
+ }
615
+ return max;
616
+ }
617
+
618
+ function maxR(series) {
619
+ // start at zero since radius must be positive
620
+ var max = 0;
621
+ for (var i = 0; i < series.length; i++) {
622
+ var data = series[i].data;
623
+ for (var j = 0; j < data.length; j++) {
624
+ var v = data[j][2];
625
+ if (v > max) {
626
+ max = v;
627
+ }
628
+ }
629
+ }
630
+ return max;
631
+ }
632
+
633
+ var jsOptions$2 = jsOptionsFunc(merge(baseOptions, defaultOptions$2), hideLegend$2, setTitle$2, setMin$2, setMax$2, setStacked$2, setXtitle$2, setYtitle$2);
634
+
635
+ function prepareDefaultData(chart) {
636
+ var series = chart.data;
637
+ var rows = {};
638
+ var keys = [];
639
+ var labels = [];
640
+ var values = [];
641
+
642
+ for (var i = 0; i < series.length; i++) {
643
+ var data = series[i].data;
644
+
645
+ for (var j = 0; j < data.length; j++) {
646
+ var d = data[j];
647
+ var key = chart.xtype === "datetime" ? d[0].getTime() : d[0];
648
+ if (!rows[key]) {
649
+ rows[key] = new Array(series.length);
650
+ keys.push(key);
651
+ }
652
+ rows[key][i] = d[1];
653
+ }
654
+ }
655
+
656
+ if (chart.xtype === "datetime" || chart.xtype === "number") {
657
+ keys.sort(sortByNumber);
658
+ }
659
+
660
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
661
+ values.push([]);
662
+ }
663
+
664
+ for (var i$2 = 0; i$2 < keys.length; i$2++) {
665
+ var key$1 = keys[i$2];
666
+
667
+ var label = chart.xtype === "datetime" ? new Date(key$1) : key$1;
668
+ labels.push(label);
669
+
670
+ var row = rows[key$1];
671
+ for (var j$1 = 0; j$1 < series.length; j$1++) {
672
+ var v = row[j$1];
673
+ // Chart.js doesn't like undefined
674
+ values[j$1].push(v === undefined ? null : v);
675
+ }
676
+ }
677
+
678
+ return {
679
+ labels: labels,
680
+ values: values
681
+ };
682
+ }
683
+
684
+ function prepareBubbleData(chart) {
685
+ var series = chart.data;
686
+ var values = [];
687
+ var max = maxR(series);
688
+
689
+ for (var i = 0; i < series.length; i++) {
690
+ var data = series[i].data;
691
+ var points = [];
692
+ for (var j = 0; j < data.length; j++) {
693
+ var v = data[j];
694
+ points.push({
695
+ x: v[0],
696
+ y: v[1],
697
+ r: v[2] * 20 / max,
698
+ // custom attribute, for tooltip
699
+ v: v[2]
700
+ });
701
+ }
702
+ values.push(points);
703
+ }
704
+
705
+ return {
706
+ labels: [],
707
+ values: values
708
+ };
709
+ }
710
+
711
+ // scatter or numeric line/area
712
+ function prepareNumberData(chart) {
713
+ var series = chart.data;
714
+ var values = [];
715
+
716
+ for (var i = 0; i < series.length; i++) {
717
+ var data = series[i].data;
718
+
719
+ data.sort(sortByNumberSeries);
720
+
721
+ var points = [];
722
+ for (var j = 0; j < data.length; j++) {
723
+ var v = data[j];
724
+ points.push({
725
+ x: v[0],
726
+ y: v[1]
727
+ });
728
+ }
729
+ values.push(points);
730
+ }
731
+
732
+ return {
733
+ labels: [],
734
+ values: values
735
+ };
736
+ }
737
+
738
+ function prepareData(chart, chartType) {
739
+ if (chartType === "bubble") {
740
+ return prepareBubbleData(chart);
741
+ } else if (chart.xtype === "number" && chartType !== "bar" && chartType !== "column") {
742
+ return prepareNumberData(chart);
743
+ } else {
744
+ return prepareDefaultData(chart);
745
+ }
746
+ }
747
+
748
+ function createDataTable(chart, options, chartType) {
749
+ var ref = prepareData(chart, chartType);
750
+ var labels = ref.labels;
751
+ var values = ref.values;
752
+
753
+ var series = chart.data;
754
+ var datasets = [];
755
+ var colors = chart.options.colors || defaultColors;
756
+ for (var i = 0; i < series.length; i++) {
757
+ var s = series[i];
758
+
759
+ // use colors for each bar for single series format
760
+ var color = (void 0);
761
+ var backgroundColor = (void 0);
762
+ if (chart.options.colors && chart.singleSeriesFormat && (chartType === "bar" || chartType === "column") && !s.color && isArray(chart.options.colors) && !isArray(chart.options.colors[0])) {
763
+ color = colors;
764
+ backgroundColor = [];
765
+ for (var j = 0; j < colors.length; j++) {
766
+ backgroundColor[j] = addOpacity(color[j], 0.5);
767
+ }
768
+ } else {
769
+ color = s.color || colors[i];
770
+ backgroundColor = chartType !== "line" ? addOpacity(color, 0.5) : color;
771
+ }
772
+
773
+ var dataset = {
774
+ label: s.name || "",
775
+ data: values[i],
776
+ fill: chartType === "area",
777
+ borderColor: color,
778
+ backgroundColor: backgroundColor,
779
+ borderWidth: 2
780
+ };
781
+
782
+ var pointChart = chartType === "line" || chartType === "area" || chartType === "scatter" || chartType === "bubble";
783
+ if (pointChart) {
784
+ dataset.pointBackgroundColor = color;
785
+ dataset.pointHoverBackgroundColor = color;
786
+ dataset.pointHitRadius = 50;
787
+ }
788
+
789
+ if (chartType === "bubble") {
790
+ dataset.pointBackgroundColor = backgroundColor;
791
+ dataset.pointHoverBackgroundColor = backgroundColor;
792
+ dataset.pointHoverBorderWidth = 2;
793
+ }
794
+
795
+ if (s.stack) {
796
+ dataset.stack = s.stack;
797
+ }
798
+
799
+ var curve = seriesOption(chart, s, "curve");
800
+ if (curve === false) {
801
+ dataset.tension = 0;
802
+ } else if (pointChart) {
803
+ dataset.tension = 0.4;
804
+ }
805
+
806
+ var points = seriesOption(chart, s, "points");
807
+ if (points === false) {
808
+ dataset.pointRadius = 0;
809
+ dataset.pointHoverRadius = 0;
810
+ }
811
+
812
+ dataset = merge(dataset, chart.options.dataset || {});
813
+ dataset = merge(dataset, s.library || {});
814
+ dataset = merge(dataset, s.dataset || {});
815
+
816
+ datasets.push(dataset);
817
+ }
818
+
819
+ var xmin = chart.options.xmin;
820
+ var xmax = chart.options.xmax;
821
+
822
+ if (chart.xtype === "datetime") {
823
+ if (notnull(xmin)) {
824
+ options.scales.x.min = toDate(xmin).getTime();
825
+ }
826
+ if (notnull(xmax)) {
827
+ options.scales.x.max = toDate(xmax).getTime();
828
+ }
829
+ } else if (chart.xtype === "number") {
830
+ if (notnull(xmin)) {
831
+ options.scales.x.min = xmin;
832
+ }
833
+ if (notnull(xmax)) {
834
+ options.scales.x.max = xmax;
835
+ }
836
+ }
837
+
838
+ if (chart.xtype === "datetime") {
839
+ var timeUnit = calculateTimeUnit(labels);
840
+
841
+ // for empty datetime chart
842
+ if (labels.length === 0) {
843
+ if (notnull(xmin)) {
844
+ labels.push(toDate(xmin));
845
+ }
846
+ if (notnull(xmax)) {
847
+ labels.push(toDate(xmax));
848
+ }
849
+ }
850
+
851
+ if (labels.length > 0) {
852
+ var minTime = (notnull(xmin) ? toDate(xmin) : labels[0]).getTime();
853
+ var maxTime = (notnull(xmax) ? toDate(xmax) : labels[0]).getTime();
854
+
855
+ for (var i$1 = 1; i$1 < labels.length; i$1++) {
856
+ var value = labels[i$1].getTime();
857
+ if (value < minTime) {
858
+ minTime = value;
859
+ }
860
+ if (value > maxTime) {
861
+ maxTime = value;
862
+ }
863
+ }
864
+
865
+ var timeDiff = (maxTime - minTime) / (86400 * 1000.0);
866
+
867
+ if (!options.scales.x.time.unit) {
868
+ var step;
869
+ if (timeUnit === "year" || timeDiff > 365 * 10) {
870
+ options.scales.x.time.unit = "year";
871
+ step = 365;
872
+ } else if (timeUnit === "month" || timeDiff > 30 * 10) {
873
+ options.scales.x.time.unit = "month";
874
+ step = 30;
875
+ } else if (timeUnit === "week" || timeUnit === "day" || timeDiff > 10) {
876
+ options.scales.x.time.unit = "day";
877
+ step = 1;
878
+ } else if (timeUnit === "hour" || timeDiff > 0.5) {
879
+ options.scales.x.time.displayFormats = {hour: "MMM d, h a"};
880
+ options.scales.x.time.unit = "hour";
881
+ step = 1 / 24.0;
882
+ } else if (timeUnit === "minute") {
883
+ options.scales.x.time.displayFormats = {minute: "h:mm a"};
884
+ options.scales.x.time.unit = "minute";
885
+ step = 1 / 24.0 / 60.0;
886
+ }
887
+
888
+ if (step && timeDiff > 0) {
889
+ // width not available for hidden elements
890
+ var width = chart.element.offsetWidth;
891
+ if (width > 0) {
892
+ var unitStepSize = Math.ceil(timeDiff / step / (width / 100.0));
893
+ if (timeUnit === "week" && step === 1) {
894
+ unitStepSize = Math.ceil(unitStepSize / 7.0) * 7;
895
+ }
896
+ options.scales.x.ticks.stepSize = unitStepSize;
897
+ }
898
+ }
899
+ }
900
+
901
+ if (!options.scales.x.time.tooltipFormat) {
902
+ if (timeUnit === "year") {
903
+ options.scales.x.time.tooltipFormat = "yyyy";
904
+ } else if (timeUnit === "month") {
905
+ options.scales.x.time.tooltipFormat = "MMM yyyy";
906
+ } else if (timeUnit === "week" || timeUnit === "day") {
907
+ options.scales.x.time.tooltipFormat = "PP";
908
+ } else if (timeUnit === "hour") {
909
+ options.scales.x.time.tooltipFormat = "MMM d, h a";
910
+ } else if (timeUnit === "minute") {
911
+ options.scales.x.time.tooltipFormat = "h:mm a";
912
+ }
913
+ }
914
+ }
915
+ }
916
+
917
+ return {
918
+ labels: labels,
919
+ datasets: datasets
920
+ };
921
+ }
922
+
923
+ var defaultExport$2 = function defaultExport(library) {
924
+ this.name = "chartjs";
925
+ this.library = library;
926
+ };
927
+
928
+ defaultExport$2.prototype.renderLineChart = function renderLineChart (chart, chartType) {
929
+ if (!chartType) {
930
+ chartType = "line";
931
+ }
932
+
933
+ var chartOptions = {};
934
+
935
+ var options = jsOptions$2(chart, merge(chartOptions, chart.options));
936
+ setFormatOptions$1(chart, options, chartType);
937
+
938
+ var data = createDataTable(chart, options, chartType);
939
+
940
+ if (chart.xtype === "number") {
941
+ options.scales.x.type = options.scales.x.type || "linear";
942
+ options.scales.x.position = options.scales.x.position || "bottom";
943
+ } else {
944
+ options.scales.x.type = chart.xtype === "string" ? "category" : "time";
945
+ }
946
+
947
+ this.drawChart(chart, "line", data, options);
948
+ };
949
+
950
+ defaultExport$2.prototype.renderPieChart = function renderPieChart (chart) {
951
+ var options = merge({}, baseOptions);
952
+ if (chart.options.donut) {
953
+ options.cutout = "50%";
954
+ }
955
+
956
+ if ("legend" in chart.options) {
957
+ hideLegend$2(options, chart.options.legend);
958
+ }
959
+
960
+ if (chart.options.title) {
961
+ setTitle$2(options, chart.options.title);
962
+ }
963
+
964
+ options = merge(options, chart.options.library || {});
965
+ setFormatOptions$1(chart, options, "pie");
966
+
967
+ var labels = [];
968
+ var values = [];
969
+ for (var i = 0; i < chart.data.length; i++) {
970
+ var point = chart.data[i];
971
+ labels.push(point[0]);
972
+ values.push(point[1]);
973
+ }
974
+
975
+ var dataset = {
976
+ data: values,
977
+ backgroundColor: chart.options.colors || defaultColors
978
+ };
979
+ dataset = merge(dataset, chart.options.dataset || {});
980
+
981
+ var data = {
982
+ labels: labels,
983
+ datasets: [dataset]
984
+ };
985
+
986
+ this.drawChart(chart, "pie", data, options);
987
+ };
988
+
989
+ defaultExport$2.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
990
+ var options;
991
+ if (chartType === "bar") {
992
+ var barOptions = merge(baseOptions, defaultOptions$2);
993
+ barOptions.indexAxis = "y";
994
+
995
+ // ensure gridlines have proper orientation
996
+ barOptions.scales.x.grid.drawOnChartArea = true;
997
+ barOptions.scales.y.grid.drawOnChartArea = false;
998
+ delete barOptions.scales.y.ticks.maxTicksLimit;
999
+
1000
+ options = jsOptionsFunc(barOptions, hideLegend$2, setTitle$2, setBarMin$1, setBarMax$1, setStacked$2, setXtitle$2, setYtitle$2)(chart, chart.options);
1001
+ } else {
1002
+ options = jsOptions$2(chart, chart.options);
1003
+ }
1004
+ setFormatOptions$1(chart, options, chartType);
1005
+ var data = createDataTable(chart, options, "column");
1006
+ if (chartType !== "bar") {
1007
+ setLabelSize(chart, data, options);
1008
+ }
1009
+ if (!("mode" in options.interaction)) {
1010
+ options.interaction.mode = "index";
1011
+ }
1012
+ this.drawChart(chart, "bar", data, options);
1013
+ };
1014
+
1015
+ defaultExport$2.prototype.renderAreaChart = function renderAreaChart (chart) {
1016
+ this.renderLineChart(chart, "area");
1017
+ };
1018
+
1019
+ defaultExport$2.prototype.renderBarChart = function renderBarChart (chart) {
1020
+ this.renderColumnChart(chart, "bar");
1021
+ };
1022
+
1023
+ defaultExport$2.prototype.renderScatterChart = function renderScatterChart (chart, chartType) {
1024
+ chartType = chartType || "scatter";
1025
+
1026
+ var options = jsOptions$2(chart, chart.options);
1027
+ setFormatOptions$1(chart, options, chartType);
1028
+
1029
+ if (!("showLine" in options)) {
1030
+ options.showLine = false;
1031
+ }
1032
+
1033
+ var data = createDataTable(chart, options, chartType);
1034
+
1035
+ options.scales.x.type = options.scales.x.type || "linear";
1036
+ options.scales.x.position = options.scales.x.position || "bottom";
1037
+
1038
+ // prevent grouping hover and tooltips
1039
+ if (!("mode" in options.interaction)) {
1040
+ options.interaction.mode = "nearest";
1041
+ }
1042
+
1043
+ this.drawChart(chart, chartType, data, options);
1044
+ };
1045
+
1046
+ defaultExport$2.prototype.renderBubbleChart = function renderBubbleChart (chart) {
1047
+ this.renderScatterChart(chart, "bubble");
1048
+ };
1049
+
1050
+ defaultExport$2.prototype.destroy = function destroy (chart) {
1051
+ if (chart.chart) {
1052
+ chart.chart.destroy();
1053
+ }
1054
+ };
1055
+
1056
+ defaultExport$2.prototype.drawChart = function drawChart (chart, type, data, options) {
1057
+ this.destroy(chart);
1058
+ if (chart.destroyed) { return; }
1059
+
1060
+ var chartOptions = {
1061
+ type: type,
1062
+ data: data,
1063
+ options: options
1064
+ };
1065
+
1066
+ if (chart.options.code) {
1067
+ window.console.log("new Chart(ctx, " + JSON.stringify(chartOptions) + ");");
1068
+ }
1069
+
1070
+ chart.element.innerHTML = "<canvas></canvas>";
1071
+ var ctx = chart.element.getElementsByTagName("CANVAS")[0];
1072
+ chart.chart = new this.library(ctx, chartOptions);
1073
+ };
1074
+
1075
+ var defaultOptions$1 = {
1076
+ chart: {},
1077
+ xAxis: {
1078
+ title: {
1079
+ text: null
1080
+ },
1081
+ labels: {
1082
+ style: {
1083
+ fontSize: "12px"
1084
+ }
1085
+ }
1086
+ },
1087
+ yAxis: {
1088
+ title: {
1089
+ text: null
1090
+ },
1091
+ labels: {
1092
+ style: {
1093
+ fontSize: "12px"
1094
+ }
1095
+ }
1096
+ },
1097
+ title: {
1098
+ text: null
1099
+ },
1100
+ credits: {
1101
+ enabled: false
1102
+ },
1103
+ legend: {
1104
+ borderWidth: 0
1105
+ },
1106
+ tooltip: {
1107
+ style: {
1108
+ fontSize: "12px"
1109
+ }
1110
+ },
1111
+ plotOptions: {
1112
+ areaspline: {},
1113
+ area: {},
1114
+ series: {
1115
+ marker: {}
1116
+ }
1117
+ },
1118
+ time: {
1119
+ useUTC: false
1120
+ }
1121
+ };
1122
+
1123
+ function hideLegend$1(options, legend, hideLegend) {
1124
+ if (legend !== undefined) {
1125
+ options.legend.enabled = !!legend;
1126
+ if (legend && legend !== true) {
1127
+ if (legend === "top" || legend === "bottom") {
1128
+ options.legend.verticalAlign = legend;
1129
+ } else {
1130
+ options.legend.layout = "vertical";
1131
+ options.legend.verticalAlign = "middle";
1132
+ options.legend.align = legend;
1133
+ }
1134
+ }
1135
+ } else if (hideLegend) {
1136
+ options.legend.enabled = false;
1137
+ }
1138
+ }
1139
+
1140
+ function setTitle$1(options, title) {
1141
+ options.title.text = title;
1142
+ }
1143
+
1144
+ function setMin$1(options, min) {
1145
+ options.yAxis.min = min;
1146
+ }
1147
+
1148
+ function setMax$1(options, max) {
1149
+ options.yAxis.max = max;
1150
+ }
1151
+
1152
+ function setStacked$1(options, stacked) {
1153
+ var stackedValue = stacked ? (stacked === true ? "normal" : stacked) : null;
1154
+ options.plotOptions.series.stacking = stackedValue;
1155
+ options.plotOptions.area.stacking = stackedValue;
1156
+ options.plotOptions.areaspline.stacking = stackedValue;
1157
+ }
1158
+
1159
+ function setXtitle$1(options, title) {
1160
+ options.xAxis.title.text = title;
1161
+ }
1162
+
1163
+ function setYtitle$1(options, title) {
1164
+ options.yAxis.title.text = title;
1165
+ }
1166
+
1167
+ var jsOptions$1 = jsOptionsFunc(defaultOptions$1, hideLegend$1, setTitle$1, setMin$1, setMax$1, setStacked$1, setXtitle$1, setYtitle$1);
1168
+
1169
+ function setFormatOptions(chart, options, chartType) {
1170
+ var formatOptions = {
1171
+ prefix: chart.options.prefix,
1172
+ suffix: chart.options.suffix,
1173
+ thousands: chart.options.thousands,
1174
+ decimal: chart.options.decimal,
1175
+ precision: chart.options.precision,
1176
+ round: chart.options.round,
1177
+ zeros: chart.options.zeros
1178
+ };
1179
+
1180
+ // skip when axis is an array (like with min/max)
1181
+ if (chartType !== "pie" && !isArray(options.yAxis) && !options.yAxis.labels.formatter) {
1182
+ options.yAxis.labels.formatter = function () {
1183
+ return formatValue("", this.value, formatOptions);
1184
+ };
1185
+ }
1186
+
1187
+ if (!options.tooltip.pointFormatter && !options.tooltip.pointFormat) {
1188
+ options.tooltip.pointFormatter = function () {
1189
+ return '<span style="color:' + this.color + '">\u25CF</span> ' + formatValue(this.series.name + ': <b>', this.y, formatOptions) + '</b><br/>';
1190
+ };
1191
+ }
1192
+ }
1193
+
1194
+ var defaultExport$1 = function defaultExport(library) {
1195
+ this.name = "highcharts";
1196
+ this.library = library;
1197
+ };
1198
+
1199
+ defaultExport$1.prototype.renderLineChart = function renderLineChart (chart, chartType) {
1200
+ chartType = chartType || "spline";
1201
+ var chartOptions = {};
1202
+ if (chartType === "areaspline") {
1203
+ chartOptions = {
1204
+ plotOptions: {
1205
+ areaspline: {
1206
+ stacking: "normal"
1207
+ },
1208
+ area: {
1209
+ stacking: "normal"
1210
+ },
1211
+ series: {
1212
+ marker: {
1213
+ enabled: false
1214
+ }
1215
+ }
1216
+ }
1217
+ };
1218
+ }
1219
+
1220
+ if (chart.options.curve === false) {
1221
+ if (chartType === "areaspline") {
1222
+ chartType = "area";
1223
+ } else if (chartType === "spline") {
1224
+ chartType = "line";
1225
+ }
1226
+ }
1227
+
1228
+ var options = jsOptions$1(chart, chart.options, chartOptions);
1229
+ if (chart.xtype === "number") {
1230
+ options.xAxis.type = options.xAxis.type || "linear";
1231
+ } else {
1232
+ options.xAxis.type = chart.xtype === "string" ? "category" : "datetime";
1233
+ }
1234
+ if (!options.chart.type) {
1235
+ options.chart.type = chartType;
1236
+ }
1237
+ setFormatOptions(chart, options, chartType);
1238
+
1239
+ var series = chart.data;
1240
+ for (var i = 0; i < series.length; i++) {
1241
+ series[i].name = series[i].name || "Value";
1242
+ var data = series[i].data;
1243
+ if (chart.xtype === "datetime") {
1244
+ for (var j = 0; j < data.length; j++) {
1245
+ data[j][0] = data[j][0].getTime();
1246
+ }
1247
+ } else if (chart.xtype === "number") {
1248
+ data.sort(sortByNumberSeries);
1249
+ }
1250
+ series[i].marker = {symbol: "circle"};
1251
+ if (chart.options.points === false) {
1252
+ series[i].marker.enabled = false;
1253
+ }
1254
+ }
1255
+
1256
+ this.drawChart(chart, series, options);
1257
+ };
1258
+
1259
+ defaultExport$1.prototype.renderScatterChart = function renderScatterChart (chart) {
1260
+ var options = jsOptions$1(chart, chart.options, {});
1261
+ options.chart.type = "scatter";
1262
+ this.drawChart(chart, chart.data, options);
1263
+ };
1264
+
1265
+ defaultExport$1.prototype.renderPieChart = function renderPieChart (chart) {
1266
+ var chartOptions = merge(defaultOptions$1, {});
1267
+
1268
+ if (chart.options.colors) {
1269
+ chartOptions.colors = chart.options.colors;
1270
+ }
1271
+ if (chart.options.donut) {
1272
+ chartOptions.plotOptions = {pie: {innerSize: "50%"}};
1273
+ }
1274
+
1275
+ if ("legend" in chart.options) {
1276
+ hideLegend$1(chartOptions, chart.options.legend);
1277
+ }
1278
+
1279
+ if (chart.options.title) {
1280
+ setTitle$1(chartOptions, chart.options.title);
1281
+ }
1282
+
1283
+ var options = merge(chartOptions, chart.options.library || {});
1284
+ setFormatOptions(chart, options, "pie");
1285
+ var series = [{
1286
+ type: "pie",
1287
+ name: chart.options.label || "Value",
1288
+ data: chart.data
1289
+ }];
1290
+
1291
+ this.drawChart(chart, series, options);
1292
+ };
1293
+
1294
+ defaultExport$1.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
1295
+ chartType = chartType || "column";
1296
+ var series = chart.data;
1297
+ var options = jsOptions$1(chart, chart.options);
1298
+ var rows = [];
1299
+ var categories = [];
1300
+ options.chart.type = chartType;
1301
+ setFormatOptions(chart, options, chartType);
1302
+
1303
+ for (var i = 0; i < series.length; i++) {
1304
+ var s = series[i];
1305
+
1306
+ for (var j = 0; j < s.data.length; j++) {
1307
+ var d = s.data[j];
1308
+ if (!rows[d[0]]) {
1309
+ rows[d[0]] = new Array(series.length);
1310
+ categories.push(d[0]);
1311
+ }
1312
+ rows[d[0]][i] = d[1];
1313
+ }
1314
+ }
1315
+
1316
+ if (chart.xtype === "number") {
1317
+ categories.sort(sortByNumber);
1318
+ }
1319
+
1320
+ options.xAxis.categories = categories;
1321
+
1322
+ var newSeries = [];
1323
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
1324
+ var d$1 = [];
1325
+ for (var j$1 = 0; j$1 < categories.length; j$1++) {
1326
+ d$1.push(rows[categories[j$1]][i$1] || 0);
1327
+ }
1328
+
1329
+ var d2 = {
1330
+ name: series[i$1].name || "Value",
1331
+ data: d$1
1332
+ };
1333
+ if (series[i$1].stack) {
1334
+ d2.stack = series[i$1].stack;
1335
+ }
1336
+
1337
+ newSeries.push(d2);
1338
+ }
1339
+
1340
+ this.drawChart(chart, newSeries, options);
1341
+ };
1342
+
1343
+ defaultExport$1.prototype.renderBarChart = function renderBarChart (chart) {
1344
+ this.renderColumnChart(chart, "bar");
1345
+ };
1346
+
1347
+ defaultExport$1.prototype.renderAreaChart = function renderAreaChart (chart) {
1348
+ this.renderLineChart(chart, "areaspline");
1349
+ };
1350
+
1351
+ defaultExport$1.prototype.destroy = function destroy (chart) {
1352
+ if (chart.chart) {
1353
+ chart.chart.destroy();
1354
+ }
1355
+ };
1356
+
1357
+ defaultExport$1.prototype.drawChart = function drawChart (chart, data, options) {
1358
+ this.destroy(chart);
1359
+ if (chart.destroyed) { return; }
1360
+
1361
+ options.chart.renderTo = chart.element.id;
1362
+ options.series = data;
1363
+
1364
+ if (chart.options.code) {
1365
+ window.console.log("new Highcharts.Chart(" + JSON.stringify(options) + ");");
1366
+ }
1367
+
1368
+ chart.chart = new this.library.Chart(options);
1369
+ };
1370
+
1371
+ var loaded = {};
1372
+ var callbacks = [];
1373
+
1374
+ // Set chart options
1375
+ var defaultOptions = {
1376
+ chartArea: {},
1377
+ fontName: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",
1378
+ pointSize: 6,
1379
+ legend: {
1380
+ textStyle: {
1381
+ fontSize: 12,
1382
+ color: "#444"
1383
+ },
1384
+ alignment: "center",
1385
+ position: "right"
1386
+ },
1387
+ curveType: "function",
1388
+ hAxis: {
1389
+ textStyle: {
1390
+ color: "#666",
1391
+ fontSize: 12
1392
+ },
1393
+ titleTextStyle: {},
1394
+ gridlines: {
1395
+ color: "transparent"
1396
+ },
1397
+ baselineColor: "#ccc",
1398
+ viewWindow: {}
1399
+ },
1400
+ vAxis: {
1401
+ textStyle: {
1402
+ color: "#666",
1403
+ fontSize: 12
1404
+ },
1405
+ titleTextStyle: {},
1406
+ baselineColor: "#ccc",
1407
+ viewWindow: {}
1408
+ },
1409
+ tooltip: {
1410
+ textStyle: {
1411
+ color: "#666",
1412
+ fontSize: 12
1413
+ }
1414
+ }
1415
+ };
1416
+
1417
+ function hideLegend(options, legend, hideLegend) {
1418
+ if (legend !== undefined) {
1419
+ var position;
1420
+ if (!legend) {
1421
+ position = "none";
1422
+ } else if (legend === true) {
1423
+ position = "right";
1424
+ } else {
1425
+ position = legend;
1426
+ }
1427
+ options.legend.position = position;
1428
+ } else if (hideLegend) {
1429
+ options.legend.position = "none";
1430
+ }
1431
+ }
1432
+
1433
+ function setTitle(options, title) {
1434
+ options.title = title;
1435
+ options.titleTextStyle = {color: "#333", fontSize: "20px"};
1436
+ }
1437
+
1438
+ function setMin(options, min) {
1439
+ options.vAxis.viewWindow.min = min;
1440
+ }
1441
+
1442
+ function setMax(options, max) {
1443
+ options.vAxis.viewWindow.max = max;
1444
+ }
1445
+
1446
+ function setBarMin(options, min) {
1447
+ options.hAxis.viewWindow.min = min;
1448
+ }
1449
+
1450
+ function setBarMax(options, max) {
1451
+ options.hAxis.viewWindow.max = max;
1452
+ }
1453
+
1454
+ function setStacked(options, stacked) {
1455
+ options.isStacked = stacked || false;
1456
+ }
1457
+
1458
+ function setXtitle(options, title) {
1459
+ options.hAxis.title = title;
1460
+ options.hAxis.titleTextStyle.italic = false;
1461
+ }
1462
+
1463
+ function setYtitle(options, title) {
1464
+ options.vAxis.title = title;
1465
+ options.vAxis.titleTextStyle.italic = false;
1466
+ }
1467
+
1468
+ var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
1469
+
1470
+ function resize(callback) {
1471
+ if (window.attachEvent) {
1472
+ window.attachEvent("onresize", callback);
1473
+ } else if (window.addEventListener) {
1474
+ window.addEventListener("resize", callback, true);
1475
+ }
1476
+ callback();
1477
+ }
1478
+
1479
+ var defaultExport = function defaultExport(library) {
1480
+ this.name = "google";
1481
+ this.library = library;
1482
+ };
1483
+
1484
+ defaultExport.prototype.renderLineChart = function renderLineChart (chart) {
1485
+ var this$1$1 = this;
1486
+
1487
+ this.waitForLoaded(chart, function () {
1488
+ var chartOptions = {};
1489
+
1490
+ if (chart.options.curve === false) {
1491
+ chartOptions.curveType = "none";
1492
+ }
1493
+
1494
+ if (chart.options.points === false) {
1495
+ chartOptions.pointSize = 0;
1496
+ }
1497
+
1498
+ var options = jsOptions(chart, chart.options, chartOptions);
1499
+ var data = this$1$1.createDataTable(chart.data, chart.xtype);
1500
+
1501
+ this$1$1.drawChart(chart, "LineChart", data, options);
1502
+ });
1503
+ };
1504
+
1505
+ defaultExport.prototype.renderPieChart = function renderPieChart (chart) {
1506
+ var this$1$1 = this;
1507
+
1508
+ this.waitForLoaded(chart, function () {
1509
+ var chartOptions = {
1510
+ chartArea: {
1511
+ top: "10%",
1512
+ height: "80%"
1513
+ },
1514
+ legend: {}
1515
+ };
1516
+ if (chart.options.colors) {
1517
+ chartOptions.colors = chart.options.colors;
1518
+ }
1519
+ if (chart.options.donut) {
1520
+ chartOptions.pieHole = 0.5;
1521
+ }
1522
+ if ("legend" in chart.options) {
1523
+ hideLegend(chartOptions, chart.options.legend);
1524
+ }
1525
+ if (chart.options.title) {
1526
+ setTitle(chartOptions, chart.options.title);
1527
+ }
1528
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
1529
+
1530
+ var data = new this$1$1.library.visualization.DataTable();
1531
+ data.addColumn("string", "");
1532
+ data.addColumn("number", "Value");
1533
+ data.addRows(chart.data);
1534
+
1535
+ this$1$1.drawChart(chart, "PieChart", data, options);
1536
+ });
1537
+ };
1538
+
1539
+ defaultExport.prototype.renderColumnChart = function renderColumnChart (chart) {
1540
+ var this$1$1 = this;
1541
+
1542
+ this.waitForLoaded(chart, function () {
1543
+ var options = jsOptions(chart, chart.options);
1544
+ var data = this$1$1.createDataTable(chart.data, chart.xtype);
1545
+
1546
+ this$1$1.drawChart(chart, "ColumnChart", data, options);
1547
+ });
1548
+ };
1549
+
1550
+ defaultExport.prototype.renderBarChart = function renderBarChart (chart) {
1551
+ var this$1$1 = this;
1552
+
1553
+ this.waitForLoaded(chart, function () {
1554
+ var chartOptions = {
1555
+ hAxis: {
1556
+ gridlines: {
1557
+ color: "#ccc"
1558
+ }
1559
+ }
1560
+ };
1561
+ var options = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options, chartOptions);
1562
+ var data = this$1$1.createDataTable(chart.data, chart.xtype);
1563
+
1564
+ this$1$1.drawChart(chart, "BarChart", data, options);
1565
+ });
1566
+ };
1567
+
1568
+ defaultExport.prototype.renderAreaChart = function renderAreaChart (chart) {
1569
+ var this$1$1 = this;
1570
+
1571
+ this.waitForLoaded(chart, function () {
1572
+ var chartOptions = {
1573
+ isStacked: true,
1574
+ pointSize: 0,
1575
+ areaOpacity: 0.5
1576
+ };
1577
+
1578
+ var options = jsOptions(chart, chart.options, chartOptions);
1579
+ var data = this$1$1.createDataTable(chart.data, chart.xtype);
1580
+
1581
+ this$1$1.drawChart(chart, "AreaChart", data, options);
1582
+ });
1583
+ };
1584
+
1585
+ defaultExport.prototype.renderGeoChart = function renderGeoChart (chart) {
1586
+ var this$1$1 = this;
1587
+
1588
+ this.waitForLoaded(chart, "geochart", function () {
1589
+ var chartOptions = {
1590
+ legend: "none",
1591
+ colorAxis: {
1592
+ colors: chart.options.colors || ["#f6c7b6", "#ce502d"]
1593
+ }
1594
+ };
1595
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
1596
+
1597
+ var data = new this$1$1.library.visualization.DataTable();
1598
+ data.addColumn("string", "");
1599
+ data.addColumn("number", chart.options.label || "Value");
1600
+ data.addRows(chart.data);
1601
+
1602
+ this$1$1.drawChart(chart, "GeoChart", data, options);
1603
+ });
1604
+ };
1605
+
1606
+ defaultExport.prototype.renderScatterChart = function renderScatterChart (chart) {
1607
+ var this$1$1 = this;
1608
+
1609
+ this.waitForLoaded(chart, function () {
1610
+ var chartOptions = {};
1611
+ var options = jsOptions(chart, chart.options, chartOptions);
1612
+
1613
+ var series = chart.data;
1614
+ var rows2 = [];
1615
+ for (var i = 0; i < series.length; i++) {
1616
+ series[i].name = series[i].name || "Value";
1617
+ var d = series[i].data;
1618
+ for (var j = 0; j < d.length; j++) {
1619
+ var row = new Array(series.length + 1);
1620
+ row[0] = d[j][0];
1621
+ row[i + 1] = d[j][1];
1622
+ rows2.push(row);
1623
+ }
1624
+ }
1625
+
1626
+ var data = new this$1$1.library.visualization.DataTable();
1627
+ data.addColumn("number", "");
1628
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
1629
+ data.addColumn("number", series[i$1].name);
1630
+ }
1631
+ data.addRows(rows2);
1632
+
1633
+ this$1$1.drawChart(chart, "ScatterChart", data, options);
1634
+ });
1635
+ };
1636
+
1637
+ defaultExport.prototype.renderTimeline = function renderTimeline (chart) {
1638
+ var this$1$1 = this;
1639
+
1640
+ this.waitForLoaded(chart, "timeline", function () {
1641
+ var chartOptions = {
1642
+ legend: "none"
1643
+ };
1644
+
1645
+ if (chart.options.colors) {
1646
+ chartOptions.colors = chart.options.colors;
1647
+ }
1648
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
1649
+
1650
+ var data = new this$1$1.library.visualization.DataTable();
1651
+ data.addColumn({type: "string", id: "Name"});
1652
+ data.addColumn({type: "date", id: "Start"});
1653
+ data.addColumn({type: "date", id: "End"});
1654
+ data.addRows(chart.data);
1655
+
1656
+ chart.element.style.lineHeight = "normal";
1657
+
1658
+ this$1$1.drawChart(chart, "Timeline", data, options);
1659
+ });
1660
+ };
1661
+
1662
+ // TODO remove resize events
1663
+ defaultExport.prototype.destroy = function destroy (chart) {
1664
+ if (chart.chart) {
1665
+ chart.chart.clearChart();
1666
+ }
1667
+ };
1668
+
1669
+ defaultExport.prototype.drawChart = function drawChart (chart, type, data, options) {
1670
+ this.destroy(chart);
1671
+ if (chart.destroyed) { return; }
1672
+
1673
+ if (chart.options.code) {
1674
+ window.console.log("var data = new google.visualization.DataTable(" + data.toJSON() + ");\nvar chart = new google.visualization." + type + "(element);\nchart.draw(data, " + JSON.stringify(options) + ");");
1675
+ }
1676
+
1677
+ chart.chart = new this.library.visualization[type](chart.element);
1678
+ resize(function () {
1679
+ chart.chart.draw(data, options);
1680
+ });
1681
+ };
1682
+
1683
+ defaultExport.prototype.waitForLoaded = function waitForLoaded (chart, pack, callback) {
1684
+ var this$1$1 = this;
1685
+
1686
+ if (!callback) {
1687
+ callback = pack;
1688
+ pack = "corechart";
1689
+ }
1690
+
1691
+ callbacks.push({pack: pack, callback: callback});
1692
+
1693
+ if (loaded[pack]) {
1694
+ this.runCallbacks();
1695
+ } else {
1696
+ loaded[pack] = true;
1697
+
1698
+ // https://groups.google.com/forum/#!topic/google-visualization-api/fMKJcyA2yyI
1699
+ var loadOptions = {
1700
+ packages: [pack],
1701
+ callback: function () { this$1$1.runCallbacks(); }
1702
+ };
1703
+ var config = chart.__config();
1704
+ if (config.language) {
1705
+ loadOptions.language = config.language;
1706
+ }
1707
+ if (pack === "geochart" && config.mapsApiKey) {
1708
+ loadOptions.mapsApiKey = config.mapsApiKey;
1709
+ }
1710
+
1711
+ this.library.charts.load("current", loadOptions);
1712
+ }
1713
+ };
1714
+
1715
+ defaultExport.prototype.runCallbacks = function runCallbacks () {
1716
+ for (var i = 0; i < callbacks.length; i++) {
1717
+ var cb = callbacks[i];
1718
+ var call = this.library.visualization && ((cb.pack === "corechart" && this.library.visualization.LineChart) || (cb.pack === "timeline" && this.library.visualization.Timeline) || (cb.pack === "geochart" && this.library.visualization.GeoChart));
1719
+ if (call) {
1720
+ cb.callback();
1721
+ callbacks.splice(i, 1);
1722
+ i--;
1723
+ }
1724
+ }
1725
+ };
1726
+
1727
+ // cant use object as key
1728
+ defaultExport.prototype.createDataTable = function createDataTable (series, columnType) {
1729
+ var rows = [];
1730
+ var sortedLabels = [];
1731
+ for (var i = 0; i < series.length; i++) {
1732
+ var s = series[i];
1733
+ series[i].name = series[i].name || "Value";
1734
+
1735
+ for (var j = 0; j < s.data.length; j++) {
1736
+ var d = s.data[j];
1737
+ var key = columnType === "datetime" ? d[0].getTime() : d[0];
1738
+ if (!rows[key]) {
1739
+ rows[key] = new Array(series.length);
1740
+ sortedLabels.push(key);
1741
+ }
1742
+ rows[key][i] = d[1];
1743
+ }
1744
+ }
1745
+
1746
+ var rows2 = [];
1747
+ var values = [];
1748
+ for (var j$1 = 0; j$1 < sortedLabels.length; j$1++) {
1749
+ var i$1 = sortedLabels[j$1];
1750
+ var value = (void 0);
1751
+ if (columnType === "datetime") {
1752
+ value = new Date(i$1);
1753
+ values.push(value);
1754
+ } else {
1755
+ value = i$1;
1756
+ }
1757
+ rows2.push([value].concat(rows[i$1]));
1758
+ }
1759
+
1760
+ var day = true;
1761
+ if (columnType === "datetime") {
1762
+ rows2.sort(sortByTime);
1763
+
1764
+ var timeUnit = calculateTimeUnit(values, true);
1765
+ day = isDay(timeUnit);
1766
+ } else if (columnType === "number") {
1767
+ rows2.sort(sortByNumberSeries);
1768
+
1769
+ for (var i$2 = 0; i$2 < rows2.length; i$2++) {
1770
+ rows2[i$2][0] = toStr(rows2[i$2][0]);
1771
+ }
1772
+
1773
+ columnType = "string";
1774
+ }
1775
+
1776
+ // create datatable
1777
+ var data = new this.library.visualization.DataTable();
1778
+ columnType = columnType === "datetime" && day ? "date" : columnType;
1779
+ data.addColumn(columnType, "");
1780
+ for (var i$3 = 0; i$3 < series.length; i$3++) {
1781
+ data.addColumn("number", series[i$3].name);
1782
+ }
1783
+ data.addRows(rows2);
1784
+
1785
+ return data;
1786
+ };
1787
+
1788
+ var adapters = [];
1789
+
1790
+ function getAdapterType(library) {
1791
+ if (library) {
1792
+ if (library.product === "Highcharts") {
1793
+ return defaultExport$1;
1794
+ } else if (library.charts) {
1795
+ return defaultExport;
1796
+ } else if (isFunction(library)) {
1797
+ return defaultExport$2;
1798
+ }
1799
+ }
1800
+ throw new Error("Unknown adapter");
1801
+ }
1802
+
1803
+ function addAdapter(library) {
1804
+ var adapterType = getAdapterType(library);
1805
+
1806
+ for (var i = 0; i < adapters.length; i++) {
1807
+ if (adapters[i].library === library) {
1808
+ return;
1809
+ }
1810
+ }
1811
+
1812
+ adapters.push(new adapterType(library));
1813
+ }
1814
+
1815
+ function loadAdapters() {
1816
+ if ("Chart" in window) {
1817
+ addAdapter(window.Chart);
1818
+ }
1819
+
1820
+ if ("Highcharts" in window) {
1821
+ addAdapter(window.Highcharts);
1822
+ }
1823
+
1824
+ if (window.google && window.google.charts) {
1825
+ addAdapter(window.google);
1826
+ }
1827
+ }
1828
+
1829
+ // TODO remove chartType if cross-browser way
1830
+ // to get the name of the chart class
1831
+ function callAdapter(chartType, chart) {
1832
+ var fnName = "render" + chartType;
1833
+ var adapterName = chart.options.adapter;
1834
+
1835
+ loadAdapters();
1836
+
1837
+ for (var i = 0; i < adapters.length; i++) {
1838
+ var adapter = adapters[i];
1839
+ if ((!adapterName || adapterName === adapter.name) && isFunction(adapter[fnName])) {
1840
+ chart.adapter = adapter.name;
1841
+ chart.__adapterObject = adapter;
1842
+ return adapter[fnName](chart);
1843
+ }
1844
+ }
1845
+
1846
+ if (adapters.length > 0) {
1847
+ throw new Error("No charting library found for " + chartType);
1848
+ } else {
1849
+ throw new Error("No charting libraries found - be sure to include one before your charts");
1850
+ }
1851
+ }
1852
+
1853
+ var Chartkick = {
1854
+ charts: {},
1855
+ configure: function (options) {
1856
+ for (var key in options) {
1857
+ if (Object.prototype.hasOwnProperty.call(options, key)) {
1858
+ Chartkick.config[key] = options[key];
1859
+ }
1860
+ }
1861
+ },
1862
+ setDefaultOptions: function (opts) {
1863
+ Chartkick.options = opts;
1864
+ },
1865
+ eachChart: function (callback) {
1866
+ for (var chartId in Chartkick.charts) {
1867
+ if (Object.prototype.hasOwnProperty.call(Chartkick.charts, chartId)) {
1868
+ callback(Chartkick.charts[chartId]);
1869
+ }
1870
+ }
1871
+ },
1872
+ destroyAll: function () {
1873
+ for (var chartId in Chartkick.charts) {
1874
+ if (Object.prototype.hasOwnProperty.call(Chartkick.charts, chartId)) {
1875
+ Chartkick.charts[chartId].destroy();
1876
+ delete Chartkick.charts[chartId];
1877
+ }
1878
+ }
1879
+ },
1880
+ config: {},
1881
+ options: {},
1882
+ adapters: adapters,
1883
+ addAdapter: addAdapter,
1884
+ use: function (adapter) {
1885
+ addAdapter(adapter);
1886
+ return Chartkick;
1887
+ }
1888
+ };
1889
+
1890
+ function formatSeriesBubble(data) {
1891
+ var r = [];
1892
+ for (var i = 0; i < data.length; i++) {
1893
+ r.push([toFloat(data[i][0]), toFloat(data[i][1]), toFloat(data[i][2])]);
1894
+ }
1895
+ return r;
1896
+ }
1897
+
1898
+ // casts data to proper type
1899
+ // sorting is left to adapters
1900
+ function formatSeriesData(data, keyType) {
1901
+ if (keyType === "bubble") {
1902
+ return formatSeriesBubble(data);
1903
+ }
1904
+
1905
+ var keyFunc;
1906
+ if (keyType === "number") {
1907
+ keyFunc = toFloat;
1908
+ } else if (keyType === "datetime") {
1909
+ keyFunc = toDate;
1910
+ } else {
1911
+ keyFunc = toStr;
1912
+ }
1913
+
1914
+ var r = [];
1915
+ for (var i = 0; i < data.length; i++) {
1916
+ r.push([keyFunc(data[i][0]), toFloat(data[i][1])]);
1917
+ }
1918
+ return r;
1919
+ }
1920
+
1921
+ function detectXType(series, noDatetime, options) {
1922
+ if (dataEmpty(series)) {
1923
+ if ((options.xmin || options.xmax) && (!options.xmin || isDate(options.xmin)) && (!options.xmax || isDate(options.xmax))) {
1924
+ return "datetime";
1925
+ } else {
1926
+ return "number";
1927
+ }
1928
+ } else if (detectXTypeWithFunction(series, isNumber)) {
1929
+ return "number";
1930
+ } else if (!noDatetime && detectXTypeWithFunction(series, isDate)) {
1931
+ return "datetime";
1932
+ } else {
1933
+ return "string";
1934
+ }
1935
+ }
1936
+
1937
+ function detectXTypeWithFunction(series, func) {
1938
+ for (var i = 0; i < series.length; i++) {
1939
+ var data = toArr(series[i].data);
1940
+ for (var j = 0; j < data.length; j++) {
1941
+ if (!func(data[j][0])) {
1942
+ return false;
1943
+ }
1944
+ }
1945
+ }
1946
+ return true;
1947
+ }
1948
+
1949
+ // creates a shallow copy of each element of the array
1950
+ // elements are expected to be objects
1951
+ function copySeries(series) {
1952
+ var newSeries = [];
1953
+ for (var i = 0; i < series.length; i++) {
1954
+ var copy = {};
1955
+ for (var j in series[i]) {
1956
+ if (Object.prototype.hasOwnProperty.call(series[i], j)) {
1957
+ copy[j] = series[i][j];
1958
+ }
1959
+ }
1960
+ newSeries.push(copy);
1961
+ }
1962
+ return newSeries;
1963
+ }
1964
+
1965
+ function processSeries(chart, keyType, noDatetime) {
1966
+ var opts = chart.options;
1967
+ var series = chart.rawData;
1968
+
1969
+ // see if one series or multiple
1970
+ chart.singleSeriesFormat = !isArray(series) || !isPlainObject(series[0]);
1971
+ if (chart.singleSeriesFormat) {
1972
+ series = [{name: opts.label, data: series}];
1973
+ }
1974
+
1975
+ // convert to array
1976
+ // must come before dataEmpty check
1977
+ series = copySeries(series);
1978
+ for (var i = 0; i < series.length; i++) {
1979
+ series[i].data = toArr(series[i].data);
1980
+ }
1981
+
1982
+ chart.xtype = keyType || (opts.discrete ? "string" : detectXType(series, noDatetime, opts));
1983
+
1984
+ // right format
1985
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
1986
+ series[i$1].data = formatSeriesData(series[i$1].data, chart.xtype);
1987
+ }
1988
+
1989
+ return series;
1990
+ }
1991
+
1992
+ function processSimple(chart) {
1993
+ var perfectData = toArr(chart.rawData);
1994
+ for (var i = 0; i < perfectData.length; i++) {
1995
+ perfectData[i] = [toStr(perfectData[i][0]), toFloat(perfectData[i][1])];
1996
+ }
1997
+ return perfectData;
1998
+ }
1999
+
2000
+ function dataEmpty(data, chartType) {
2001
+ if (chartType === "PieChart" || chartType === "GeoChart" || chartType === "Timeline") {
2002
+ return data.length === 0;
2003
+ } else {
2004
+ for (var i = 0; i < data.length; i++) {
2005
+ if (data[i].data.length > 0) {
2006
+ return false;
2007
+ }
2008
+ }
2009
+ return true;
2010
+ }
2011
+ }
2012
+
2013
+ function addDownloadButton(chart) {
2014
+ var download = chart.options.download;
2015
+ if (download === true) {
2016
+ download = {};
2017
+ } else if (typeof download === "string") {
2018
+ download = {filename: download};
2019
+ }
2020
+
2021
+ var link = document.createElement("a");
2022
+ link.download = download.filename || "chart.png";
2023
+ link.style.position = "absolute";
2024
+ link.style.top = "20px";
2025
+ link.style.right = "20px";
2026
+ link.style.zIndex = 1000;
2027
+ link.style.lineHeight = "20px";
2028
+ link.target = "_blank"; // for safari
2029
+
2030
+ var image = document.createElement("img");
2031
+ // icon from Font Awesome, modified to set fill color
2032
+ var svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path fill=\"#CCCCCC\" d=\"M344 240h-56L287.1 152c0-13.25-10.75-24-24-24h-16C234.7 128 223.1 138.8 223.1 152L224 240h-56c-9.531 0-18.16 5.656-22 14.38C142.2 263.1 143.9 273.3 150.4 280.3l88.75 96C243.7 381.2 250.1 384 256.8 384c7.781-.3125 13.25-2.875 17.75-7.844l87.25-96c6.406-7.031 8.031-17.19 4.188-25.88S353.5 240 344 240zM256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 464c-114.7 0-208-93.31-208-208S141.3 48 256 48s208 93.31 208 208S370.7 464 256 464z\"/></svg>";
2033
+ image.src = "data:image/svg+xml;utf8," + (encodeURIComponent(svg));
2034
+ image.alt = "Download";
2035
+ image.style.width = "20px";
2036
+ image.style.height = "20px";
2037
+ image.style.border = "none";
2038
+ link.appendChild(image);
2039
+
2040
+ var element = chart.element;
2041
+ element.style.position = "relative";
2042
+
2043
+ chart.__downloadAttached = true;
2044
+
2045
+ // mouseenter
2046
+ chart.__enterEvent = element.addEventListener("mouseover", function (e) {
2047
+ var related = e.relatedTarget;
2048
+ // check download option again to ensure it wasn't changed
2049
+ if ((!related || (related !== this && !this.contains(related))) && chart.options.download) {
2050
+ link.href = chart.toImage(download);
2051
+ element.appendChild(link);
2052
+ }
2053
+ });
2054
+
2055
+ // mouseleave
2056
+ chart.__leaveEvent = element.addEventListener("mouseout", function (e) {
2057
+ var related = e.relatedTarget;
2058
+ if (!related || (related !== this && !this.contains(related))) {
2059
+ if (link.parentNode) {
2060
+ link.parentNode.removeChild(link);
2061
+ }
2062
+ }
2063
+ });
2064
+ }
2065
+
2066
+ var pendingRequests = [];
2067
+ var runningRequests = 0;
2068
+ var maxRequests = 4;
2069
+
2070
+ function pushRequest(url, success, error) {
2071
+ pendingRequests.push([url, success, error]);
2072
+ runNext();
2073
+ }
2074
+
2075
+ function runNext() {
2076
+ if (runningRequests < maxRequests) {
2077
+ var request = pendingRequests.shift();
2078
+ if (request) {
2079
+ runningRequests++;
2080
+ getJSON(request[0], request[1], request[2]);
2081
+ runNext();
2082
+ }
2083
+ }
2084
+ }
2085
+
2086
+ function requestComplete() {
2087
+ runningRequests--;
2088
+ runNext();
2089
+ }
2090
+
2091
+ function getJSON(url, success, error) {
2092
+ var xhr = new XMLHttpRequest();
2093
+ xhr.open("GET", url, true);
2094
+ xhr.setRequestHeader("Content-Type", "application/json");
2095
+ xhr.onload = function () {
2096
+ requestComplete();
2097
+ if (xhr.status === 200) {
2098
+ success(JSON.parse(xhr.responseText));
2099
+ } else {
2100
+ error(xhr.statusText);
2101
+ }
2102
+ };
2103
+ xhr.send();
2104
+ }
2105
+
2106
+ // helpers
2107
+
2108
+ function setText(element, text) {
2109
+ element.textContent = text;
2110
+ }
2111
+
2112
+ // TODO remove prefix for all messages
2113
+ function chartError(element, message, noPrefix) {
2114
+ if (!noPrefix) {
2115
+ message = "Error Loading Chart: " + message;
2116
+ }
2117
+ setText(element, message);
2118
+ element.style.color = "#ff0000";
2119
+ }
2120
+
2121
+ function errorCatcher(chart) {
2122
+ try {
2123
+ chart.__render();
2124
+ } catch (err) {
2125
+ chartError(chart.element, err.message);
2126
+ throw err;
2127
+ }
2128
+ }
2129
+
2130
+ function fetchDataSource(chart, dataSource, showLoading) {
2131
+ // only show loading message for urls and callbacks
2132
+ if (showLoading && chart.options.loading && (typeof dataSource === "string" || typeof dataSource === "function")) {
2133
+ setText(chart.element, chart.options.loading);
2134
+ }
2135
+
2136
+ if (typeof dataSource === "string") {
2137
+ pushRequest(dataSource, function (data) {
2138
+ chart.rawData = data;
2139
+ errorCatcher(chart);
2140
+ }, function (message) {
2141
+ chartError(chart.element, message);
2142
+ });
2143
+ } else if (typeof dataSource === "function") {
2144
+ try {
2145
+ dataSource(function (data) {
2146
+ chart.rawData = data;
2147
+ errorCatcher(chart);
2148
+ }, function (message) {
2149
+ chartError(chart.element, message, true);
2150
+ });
2151
+ } catch (err) {
2152
+ chartError(chart.element, err, true);
2153
+ }
2154
+ } else {
2155
+ chart.rawData = dataSource;
2156
+ errorCatcher(chart);
2157
+ }
2158
+ }
2159
+
2160
+ function renderChart(chartType, chart) {
2161
+ if (dataEmpty(chart.data, chartType)) {
2162
+ var message = chart.options.empty || (chart.options.messages && chart.options.messages.empty) || "No data";
2163
+ setText(chart.element, message);
2164
+ } else {
2165
+ callAdapter(chartType, chart);
2166
+ // TODO add downloadSupported method to adapter
2167
+ if (chart.options.download && !chart.__downloadAttached && chart.adapter === "chartjs") {
2168
+ addDownloadButton(chart);
2169
+ }
2170
+ }
2171
+ }
2172
+
2173
+ function getElement(element) {
2174
+ if (typeof element === "string") {
2175
+ var elementId = element;
2176
+ element = document.getElementById(element);
2177
+ if (!element) {
2178
+ throw new Error("No element with id " + elementId);
2179
+ }
2180
+ }
2181
+ return element;
2182
+ }
2183
+
2184
+ // define classes
2185
+
2186
+ var Chart = function Chart(element, dataSource, options) {
2187
+ this.element = getElement(element);
2188
+ this.options = merge(Chartkick.options, options || {});
2189
+ this.dataSource = dataSource;
2190
+
2191
+ // TODO handle charts without an id for eachChart and destroyAll
2192
+ if (this.element.id) {
2193
+ Chartkick.charts[this.element.id] = this;
2194
+ }
2195
+
2196
+ fetchDataSource(this, dataSource, true);
2197
+
2198
+ if (this.options.refresh) {
2199
+ this.startRefresh();
2200
+ }
2201
+ };
2202
+
2203
+ Chart.prototype.getElement = function getElement () {
2204
+ return this.element;
2205
+ };
2206
+
2207
+ Chart.prototype.getDataSource = function getDataSource () {
2208
+ return this.dataSource;
2209
+ };
2210
+
2211
+ Chart.prototype.getData = function getData () {
2212
+ return this.data;
2213
+ };
2214
+
2215
+ Chart.prototype.getOptions = function getOptions () {
2216
+ return this.options;
2217
+ };
2218
+
2219
+ Chart.prototype.getChartObject = function getChartObject () {
2220
+ return this.chart;
2221
+ };
2222
+
2223
+ Chart.prototype.getAdapter = function getAdapter () {
2224
+ return this.adapter;
2225
+ };
2226
+
2227
+ Chart.prototype.updateData = function updateData (dataSource, options) {
2228
+ this.dataSource = dataSource;
2229
+ if (options) {
2230
+ this.__updateOptions(options);
2231
+ }
2232
+ fetchDataSource(this, dataSource, true);
2233
+ };
2234
+
2235
+ Chart.prototype.setOptions = function setOptions (options) {
2236
+ this.__updateOptions(options);
2237
+ this.redraw();
2238
+ };
2239
+
2240
+ Chart.prototype.redraw = function redraw () {
2241
+ fetchDataSource(this, this.rawData);
2242
+ };
2243
+
2244
+ Chart.prototype.refreshData = function refreshData () {
2245
+ if (typeof this.dataSource === "string") {
2246
+ // prevent browser from caching
2247
+ var sep = this.dataSource.indexOf("?") === -1 ? "?" : "&";
2248
+ var url = this.dataSource + sep + "_=" + (new Date()).getTime();
2249
+ fetchDataSource(this, url);
2250
+ } else if (typeof this.dataSource === "function") {
2251
+ fetchDataSource(this, this.dataSource);
2252
+ }
2253
+ };
2254
+
2255
+ Chart.prototype.startRefresh = function startRefresh () {
2256
+ var this$1$1 = this;
2257
+
2258
+ var refresh = this.options.refresh;
2259
+
2260
+ if (refresh && typeof this.dataSource !== "string" && typeof this.dataSource !== "function") {
2261
+ throw new Error("Data source must be a URL or callback for refresh");
2262
+ }
2263
+
2264
+ if (!this.intervalId) {
2265
+ if (refresh) {
2266
+ this.intervalId = setInterval(function () {
2267
+ this$1$1.refreshData();
2268
+ }, refresh * 1000);
2269
+ } else {
2270
+ throw new Error("No refresh interval");
2271
+ }
2272
+ }
2273
+ };
2274
+
2275
+ Chart.prototype.stopRefresh = function stopRefresh () {
2276
+ if (this.intervalId) {
2277
+ clearInterval(this.intervalId);
2278
+ this.intervalId = null;
2279
+ }
2280
+ };
2281
+
2282
+ Chart.prototype.toImage = function toImage (download) {
2283
+ // TODO move logic to adapter
2284
+ if (this.adapter === "chartjs") {
2285
+ if (download && download.background && download.background !== "transparent") {
2286
+ // https://stackoverflow.com/questions/30464750/chartjs-line-chart-set-background-color
2287
+ var canvas = this.chart.canvas;
2288
+ var ctx = this.chart.ctx;
2289
+ var tmpCanvas = document.createElement("canvas");
2290
+ var tmpCtx = tmpCanvas.getContext("2d");
2291
+ tmpCanvas.width = ctx.canvas.width;
2292
+ tmpCanvas.height = ctx.canvas.height;
2293
+ tmpCtx.fillStyle = download.background;
2294
+ tmpCtx.fillRect(0, 0, tmpCanvas.width, tmpCanvas.height);
2295
+ tmpCtx.drawImage(canvas, 0, 0);
2296
+ return tmpCanvas.toDataURL("image/png");
2297
+ } else {
2298
+ return this.chart.toBase64Image();
2299
+ }
2300
+ } else {
2301
+ throw new Error("Feature only available for Chart.js");
2302
+ }
2303
+ };
2304
+
2305
+ Chart.prototype.destroy = function destroy () {
2306
+ this.destroyed = true;
2307
+ this.stopRefresh();
2308
+
2309
+ if (this.__adapterObject) {
2310
+ this.__adapterObject.destroy(this);
2311
+ }
2312
+
2313
+ if (this.__enterEvent) {
2314
+ this.element.removeEventListener("mouseover", this.__enterEvent);
2315
+ }
2316
+
2317
+ if (this.__leaveEvent) {
2318
+ this.element.removeEventListener("mouseout", this.__leaveEvent);
2319
+ }
2320
+ };
2321
+
2322
+ Chart.prototype.__updateOptions = function __updateOptions (options) {
2323
+ var updateRefresh = options.refresh && options.refresh !== this.options.refresh;
2324
+ this.options = merge(Chartkick.options, options);
2325
+ if (updateRefresh) {
2326
+ this.stopRefresh();
2327
+ this.startRefresh();
2328
+ }
2329
+ };
2330
+
2331
+ Chart.prototype.__render = function __render () {
2332
+ this.data = this.__processData();
2333
+ renderChart(this.__chartName(), this);
2334
+ };
2335
+
2336
+ Chart.prototype.__config = function __config () {
2337
+ return Chartkick.config;
2338
+ };
2339
+
2340
+ var LineChart = /*@__PURE__*/(function (Chart) {
2341
+ function LineChart () {
2342
+ Chart.apply(this, arguments);
2343
+ }
2344
+
2345
+ if ( Chart ) LineChart.__proto__ = Chart;
2346
+ LineChart.prototype = Object.create( Chart && Chart.prototype );
2347
+ LineChart.prototype.constructor = LineChart;
2348
+
2349
+ LineChart.prototype.__processData = function __processData () {
2350
+ return processSeries(this);
2351
+ };
2352
+
2353
+ LineChart.prototype.__chartName = function __chartName () {
2354
+ return "LineChart";
2355
+ };
2356
+
2357
+ return LineChart;
2358
+ }(Chart));
2359
+
2360
+ var PieChart = /*@__PURE__*/(function (Chart) {
2361
+ function PieChart () {
2362
+ Chart.apply(this, arguments);
2363
+ }
2364
+
2365
+ if ( Chart ) PieChart.__proto__ = Chart;
2366
+ PieChart.prototype = Object.create( Chart && Chart.prototype );
2367
+ PieChart.prototype.constructor = PieChart;
2368
+
2369
+ PieChart.prototype.__processData = function __processData () {
2370
+ return processSimple(this);
2371
+ };
2372
+
2373
+ PieChart.prototype.__chartName = function __chartName () {
2374
+ return "PieChart";
2375
+ };
2376
+
2377
+ return PieChart;
2378
+ }(Chart));
2379
+
2380
+ var ColumnChart = /*@__PURE__*/(function (Chart) {
2381
+ function ColumnChart () {
2382
+ Chart.apply(this, arguments);
2383
+ }
2384
+
2385
+ if ( Chart ) ColumnChart.__proto__ = Chart;
2386
+ ColumnChart.prototype = Object.create( Chart && Chart.prototype );
2387
+ ColumnChart.prototype.constructor = ColumnChart;
2388
+
2389
+ ColumnChart.prototype.__processData = function __processData () {
2390
+ return processSeries(this, null, true);
2391
+ };
2392
+
2393
+ ColumnChart.prototype.__chartName = function __chartName () {
2394
+ return "ColumnChart";
2395
+ };
2396
+
2397
+ return ColumnChart;
2398
+ }(Chart));
2399
+
2400
+ var BarChart = /*@__PURE__*/(function (Chart) {
2401
+ function BarChart () {
2402
+ Chart.apply(this, arguments);
2403
+ }
2404
+
2405
+ if ( Chart ) BarChart.__proto__ = Chart;
2406
+ BarChart.prototype = Object.create( Chart && Chart.prototype );
2407
+ BarChart.prototype.constructor = BarChart;
2408
+
2409
+ BarChart.prototype.__processData = function __processData () {
2410
+ return processSeries(this, null, true);
2411
+ };
2412
+
2413
+ BarChart.prototype.__chartName = function __chartName () {
2414
+ return "BarChart";
2415
+ };
2416
+
2417
+ return BarChart;
2418
+ }(Chart));
2419
+
2420
+ var AreaChart = /*@__PURE__*/(function (Chart) {
2421
+ function AreaChart () {
2422
+ Chart.apply(this, arguments);
2423
+ }
2424
+
2425
+ if ( Chart ) AreaChart.__proto__ = Chart;
2426
+ AreaChart.prototype = Object.create( Chart && Chart.prototype );
2427
+ AreaChart.prototype.constructor = AreaChart;
2428
+
2429
+ AreaChart.prototype.__processData = function __processData () {
2430
+ return processSeries(this);
2431
+ };
2432
+
2433
+ AreaChart.prototype.__chartName = function __chartName () {
2434
+ return "AreaChart";
2435
+ };
2436
+
2437
+ return AreaChart;
2438
+ }(Chart));
2439
+
2440
+ var GeoChart = /*@__PURE__*/(function (Chart) {
2441
+ function GeoChart () {
2442
+ Chart.apply(this, arguments);
2443
+ }
2444
+
2445
+ if ( Chart ) GeoChart.__proto__ = Chart;
2446
+ GeoChart.prototype = Object.create( Chart && Chart.prototype );
2447
+ GeoChart.prototype.constructor = GeoChart;
2448
+
2449
+ GeoChart.prototype.__processData = function __processData () {
2450
+ return processSimple(this);
2451
+ };
2452
+
2453
+ GeoChart.prototype.__chartName = function __chartName () {
2454
+ return "GeoChart";
2455
+ };
2456
+
2457
+ return GeoChart;
2458
+ }(Chart));
2459
+
2460
+ var ScatterChart = /*@__PURE__*/(function (Chart) {
2461
+ function ScatterChart () {
2462
+ Chart.apply(this, arguments);
2463
+ }
2464
+
2465
+ if ( Chart ) ScatterChart.__proto__ = Chart;
2466
+ ScatterChart.prototype = Object.create( Chart && Chart.prototype );
2467
+ ScatterChart.prototype.constructor = ScatterChart;
2468
+
2469
+ ScatterChart.prototype.__processData = function __processData () {
2470
+ return processSeries(this, "number");
2471
+ };
2472
+
2473
+ ScatterChart.prototype.__chartName = function __chartName () {
2474
+ return "ScatterChart";
2475
+ };
2476
+
2477
+ return ScatterChart;
2478
+ }(Chart));
2479
+
2480
+ var BubbleChart = /*@__PURE__*/(function (Chart) {
2481
+ function BubbleChart () {
2482
+ Chart.apply(this, arguments);
2483
+ }
2484
+
2485
+ if ( Chart ) BubbleChart.__proto__ = Chart;
2486
+ BubbleChart.prototype = Object.create( Chart && Chart.prototype );
2487
+ BubbleChart.prototype.constructor = BubbleChart;
2488
+
2489
+ BubbleChart.prototype.__processData = function __processData () {
2490
+ return processSeries(this, "bubble");
2491
+ };
2492
+
2493
+ BubbleChart.prototype.__chartName = function __chartName () {
2494
+ return "BubbleChart";
2495
+ };
2496
+
2497
+ return BubbleChart;
2498
+ }(Chart));
2499
+
2500
+ var Timeline = /*@__PURE__*/(function (Chart) {
2501
+ function Timeline () {
2502
+ Chart.apply(this, arguments);
2503
+ }
2504
+
2505
+ if ( Chart ) Timeline.__proto__ = Chart;
2506
+ Timeline.prototype = Object.create( Chart && Chart.prototype );
2507
+ Timeline.prototype.constructor = Timeline;
2508
+
2509
+ Timeline.prototype.__processData = function __processData () {
2510
+ var data = this.rawData;
2511
+ for (var i = 0; i < data.length; i++) {
2512
+ data[i][1] = toDate(data[i][1]);
2513
+ data[i][2] = toDate(data[i][2]);
2514
+ }
2515
+ return data;
2516
+ };
2517
+
2518
+ Timeline.prototype.__chartName = function __chartName () {
2519
+ return "Timeline";
2520
+ };
2521
+
2522
+ return Timeline;
2523
+ }(Chart));
2524
+
2525
+ Chartkick.LineChart = LineChart;
2526
+ Chartkick.PieChart = PieChart;
2527
+ Chartkick.ColumnChart = ColumnChart;
2528
+ Chartkick.BarChart = BarChart;
2529
+ Chartkick.AreaChart = AreaChart;
2530
+ Chartkick.GeoChart = GeoChart;
2531
+ Chartkick.ScatterChart = ScatterChart;
2532
+ Chartkick.BubbleChart = BubbleChart;
2533
+ Chartkick.Timeline = Timeline;
2534
+
2535
+ // not ideal, but allows for simpler integration
2536
+ if (typeof window !== "undefined" && !window.Chartkick) {
2537
+ window.Chartkick = Chartkick;
2538
+
2539
+ // clean up previous charts before Turbolinks loads new page
2540
+ document.addEventListener("turbolinks:before-render", function () {
2541
+ if (Chartkick.config.autoDestroy !== false) {
2542
+ Chartkick.destroyAll();
2543
+ }
2544
+ });
2545
+
2546
+ // clean up previous charts before Turbo loads new page
2547
+ document.addEventListener("turbo:before-render", function () {
2548
+ if (Chartkick.config.autoDestroy !== false) {
2549
+ Chartkick.destroyAll();
2550
+ }
2551
+ });
2552
+
2553
+ // use setTimeout so charting library can come later in same JS file
2554
+ setTimeout(function () {
2555
+ window.dispatchEvent(new Event("chartkick:load"));
2556
+ }, 0);
2557
+ }
2558
+
2559
+ // backwards compatibility for esm require
2560
+ Chartkick.default = Chartkick;
2561
+
2562
+ export { Chartkick as default };