govuk_publishing_components 44.4.0 → 44.4.2

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