chartkick 4.2.1 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,7 @@
1
1
  /*!
2
- * Chartkick.js
2
+ * Chartkick.js v5.0.1
3
3
  * Create beautiful charts with one line of JavaScript
4
4
  * https://github.com/ankane/chartkick.js
5
- * v4.2.0
6
5
  * MIT License
7
6
  */
8
7
 
@@ -27,8 +26,7 @@
27
26
 
28
27
  // https://github.com/madrobby/zepto/blob/master/src/zepto.js
29
28
  function extend(target, source) {
30
- var key;
31
- for (key in source) {
29
+ for (var key in source) {
32
30
  // protect against prototype pollution, defense 1
33
31
  if (key === "__proto__") { continue; }
34
32
 
@@ -53,13 +51,12 @@
53
51
  return target;
54
52
  }
55
53
 
56
- var DATE_PATTERN = /^(\d\d\d\d)(-)?(\d\d)(-)?(\d\d)$/i;
54
+ var DATE_PATTERN = /^(\d\d\d\d)(?:-)?(\d\d)(?:-)?(\d\d)$/i;
57
55
 
58
56
  function negativeValues(series) {
59
- var i, j, data;
60
- for (i = 0; i < series.length; i++) {
61
- data = series[i].data;
62
- for (j = 0; j < data.length; j++) {
57
+ for (var i = 0; i < series.length; i++) {
58
+ var data = series[i].data;
59
+ for (var j = 0; j < data.length; j++) {
63
60
  if (data[j][1] < 0) {
64
61
  return true;
65
62
  }
@@ -68,49 +65,49 @@
68
65
  return false;
69
66
  }
70
67
 
71
- function toStr(n) {
72
- return "" + n;
68
+ function toStr(obj) {
69
+ return "" + obj;
73
70
  }
74
71
 
75
- function toFloat(n) {
76
- return parseFloat(n);
72
+ function toFloat(obj) {
73
+ return parseFloat(obj);
77
74
  }
78
75
 
79
- function toDate(n) {
80
- var matches, year, month, day;
81
- if (typeof n !== "object") {
82
- if (typeof n === "number") {
83
- n = new Date(n * 1000); // ms
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);
84
89
  } else {
85
- n = toStr(n);
86
- if ((matches = n.match(DATE_PATTERN))) {
87
- year = parseInt(matches[1], 10);
88
- month = parseInt(matches[3], 10) - 1;
89
- day = parseInt(matches[5], 10);
90
- return new Date(year, month, day);
91
- } else {
92
- // try our best to get the str into iso8601
93
- // TODO be smarter about this
94
- var str = n.replace(/ /, "T").replace(" ", "").replace("UTC", "Z");
95
- // Date.parse returns milliseconds if valid and NaN if invalid
96
- n = new Date(Date.parse(str) || n);
97
- }
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);
98
95
  }
99
96
  }
100
- return n;
101
97
  }
102
98
 
103
- function toArr(n) {
104
- if (!isArray(n)) {
105
- var arr = [], i;
106
- for (i in n) {
107
- if (n.hasOwnProperty(i)) {
108
- arr.push([i, n[i]]);
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]]);
109
107
  }
110
108
  }
111
- n = arr;
109
+ return arr;
112
110
  }
113
- return n;
114
111
  }
115
112
 
116
113
  function jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle) {
@@ -170,32 +167,63 @@
170
167
  return a[0] - b[0];
171
168
  }
172
169
 
170
+ // needed since sort() without arguments does string comparison
173
171
  function sortByNumber(a, b) {
174
172
  return a - b;
175
173
  }
176
174
 
177
- function isMinute(d) {
178
- return d.getMilliseconds() === 0 && d.getSeconds() === 0;
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;
179
182
  }
180
183
 
181
- function isHour(d) {
182
- return isMinute(d) && d.getMinutes() === 0;
184
+ function isDay(timeUnit) {
185
+ return timeUnit === "day" || timeUnit === "week" || timeUnit === "month" || timeUnit === "year";
183
186
  }
184
187
 
185
- function isDay(d) {
186
- return isHour(d) && d.getHours() === 0;
187
- }
188
+ function calculateTimeUnit(values, maxDay) {
189
+ if ( maxDay === void 0 ) maxDay = false;
188
190
 
189
- function isWeek(d, dayOfWeek) {
190
- return isDay(d) && d.getDay() === dayOfWeek;
191
- }
191
+ if (values.length === 0) {
192
+ return null;
193
+ }
192
194
 
193
- function isMonth(d) {
194
- return isDay(d) && d.getDate() === 1;
195
- }
195
+ var minute = every(values, function (d) { return d.getMilliseconds() === 0 && d.getSeconds() === 0; });
196
+ if (!minute) {
197
+ return null;
198
+ }
196
199
 
197
- function isYear(d) {
198
- return isMonth(d) && d.getMonth() === 0;
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";
199
227
  }
200
228
 
201
229
  function isDate(obj) {
@@ -223,9 +251,14 @@
223
251
  var round = options.round;
224
252
 
225
253
  if (options.byteScale) {
226
- var suffixIdx;
254
+ var positive = value >= 0;
255
+ if (!positive) {
256
+ value *= -1;
257
+ }
258
+
227
259
  var baseValue = axis ? options.byteScale : value;
228
260
 
261
+ var suffixIdx;
229
262
  if (baseValue >= 1152921504606846976) {
230
263
  value /= 1152921504606846976;
231
264
  suffixIdx = 6;
@@ -259,6 +292,11 @@
259
292
  precision = value >= 1000 ? 4 : 3;
260
293
  }
261
294
  suffix = " " + byteSuffixes[suffixIdx];
295
+
296
+ // flip value back
297
+ if (!positive) {
298
+ value *= -1;
299
+ }
262
300
  }
263
301
 
264
302
  if (precision !== undefined && round !== undefined) {
@@ -310,19 +348,6 @@
310
348
  return null;
311
349
  }
312
350
 
313
- function allZeros(data) {
314
- var i, j, d;
315
- for (i = 0; i < data.length; i++) {
316
- d = data[i].data;
317
- for (j = 0; j < d.length; j++) {
318
- if (d[j][1] != 0) {
319
- return false;
320
- }
321
- }
322
- }
323
- return true;
324
- }
325
-
326
351
  var baseOptions = {
327
352
  maintainAspectRatio: false,
328
353
  animation: false,
@@ -379,7 +404,7 @@
379
404
  "#6633CC", "#E67300", "#8B0707", "#329262", "#5574A6", "#651067"
380
405
  ];
381
406
 
382
- var hideLegend$2 = function (options, legend, hideLegend) {
407
+ function hideLegend$2(options, legend, hideLegend) {
383
408
  if (legend !== undefined) {
384
409
  options.plugins.legend.display = !!legend;
385
410
  if (legend && legend !== true) {
@@ -388,61 +413,59 @@
388
413
  } else if (hideLegend) {
389
414
  options.plugins.legend.display = false;
390
415
  }
391
- };
416
+ }
392
417
 
393
- var setTitle$2 = function (options, title) {
418
+ function setTitle$2(options, title) {
394
419
  options.plugins.title.display = true;
395
420
  options.plugins.title.text = title;
396
- };
421
+ }
397
422
 
398
- var setMin$2 = function (options, min) {
423
+ function setMin$2(options, min) {
399
424
  if (min !== null) {
400
425
  options.scales.y.min = toFloat(min);
401
426
  }
402
- };
427
+ }
403
428
 
404
- var setMax$2 = function (options, max) {
429
+ function setMax$2(options, max) {
405
430
  options.scales.y.max = toFloat(max);
406
- };
431
+ }
407
432
 
408
- var setBarMin$1 = function (options, min) {
433
+ function setBarMin$1(options, min) {
409
434
  if (min !== null) {
410
435
  options.scales.x.min = toFloat(min);
411
436
  }
412
- };
437
+ }
413
438
 
414
- var setBarMax$1 = function (options, max) {
439
+ function setBarMax$1(options, max) {
415
440
  options.scales.x.max = toFloat(max);
416
- };
441
+ }
417
442
 
418
- var setStacked$2 = function (options, stacked) {
443
+ function setStacked$2(options, stacked) {
419
444
  options.scales.x.stacked = !!stacked;
420
445
  options.scales.y.stacked = !!stacked;
421
- };
446
+ }
422
447
 
423
- var setXtitle$2 = function (options, title) {
448
+ function setXtitle$2(options, title) {
424
449
  options.scales.x.title.display = true;
425
450
  options.scales.x.title.text = title;
426
- };
451
+ }
427
452
 
428
- var setYtitle$2 = function (options, title) {
453
+ function setYtitle$2(options, title) {
429
454
  options.scales.y.title.display = true;
430
455
  options.scales.y.title.text = title;
431
- };
456
+ }
432
457
 
433
458
  // https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
434
- var addOpacity = function (hex, opacity) {
459
+ function addOpacity(hex, opacity) {
435
460
  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
436
461
  return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
437
- };
462
+ }
438
463
 
439
- // check if not null or undefined
440
- // https://stackoverflow.com/a/27757708/1177228
441
- var notnull = function (x) {
442
- return x != null;
443
- };
464
+ function notnull(x) {
465
+ return x !== null && x !== undefined;
466
+ }
444
467
 
445
- var setLabelSize = function (chart, data, options) {
468
+ function setLabelSize(chart, data, options) {
446
469
  var maxLabelSize = Math.ceil(chart.element.offsetWidth / 4.0 / data.labels.length);
447
470
  if (maxLabelSize > 25) {
448
471
  maxLabelSize = 25;
@@ -459,18 +482,33 @@
459
482
  }
460
483
  };
461
484
  }
462
- };
485
+ }
463
486
 
464
- var setFormatOptions$1 = function (chart, options, chartType) {
465
- var formatOptions = {
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({
466
506
  prefix: chart.options.prefix,
467
507
  suffix: chart.options.suffix,
468
- thousands: chart.options.thousands,
469
- decimal: chart.options.decimal,
470
508
  precision: chart.options.precision,
471
509
  round: chart.options.round,
472
510
  zeros: chart.options.zeros
473
- };
511
+ }, numericOptions);
474
512
 
475
513
  if (chart.options.bytes) {
476
514
  var series = chart.data;
@@ -478,26 +516,8 @@
478
516
  series = [{data: series}];
479
517
  }
480
518
 
481
- // calculate max
482
- var max = 0;
483
- for (var i = 0; i < series.length; i++) {
484
- var s = series[i];
485
- for (var j = 0; j < s.data.length; j++) {
486
- if (s.data[j][1] > max) {
487
- max = s.data[j][1];
488
- }
489
- }
490
- }
491
-
492
- // calculate scale
493
- var scale = 1;
494
- while (max >= 1024) {
495
- scale *= 1024;
496
- max /= 1024;
497
- }
498
-
499
519
  // set step size
500
- formatOptions.byteScale = scale;
520
+ formatOptions.byteScale = calculateScale(series);
501
521
  }
502
522
 
503
523
  if (chartType !== "pie") {
@@ -520,6 +540,12 @@
520
540
  return formatValue("", value, formatOptions, true);
521
541
  };
522
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
+ }
523
549
  }
524
550
 
525
551
  if (!options.plugins.tooltip.callbacks.label) {
@@ -529,7 +555,9 @@
529
555
  if (label) {
530
556
  label += ': ';
531
557
  }
532
- return label + '(' + context.label + ', ' + context.formattedValue + ')';
558
+
559
+ var dataPoint = context.parsed;
560
+ return label + '(' + formatValue('', dataPoint.x, numericOptions) + ', ' + formatValue('', dataPoint.y, formatOptions) + ')';
533
561
  };
534
562
  } else if (chartType === "bubble") {
535
563
  options.plugins.tooltip.callbacks.label = function (context) {
@@ -538,24 +566,12 @@
538
566
  label += ': ';
539
567
  }
540
568
  var dataPoint = context.raw;
541
- return label + '(' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.v + ')';
569
+ return label + '(' + formatValue('', dataPoint.x, numericOptions) + ', ' + formatValue('', dataPoint.y, formatOptions) + ', ' + formatValue('', dataPoint.v, numericOptions) + ')';
542
570
  };
543
571
  } else if (chartType === "pie") {
544
572
  // need to use separate label for pie charts
545
573
  options.plugins.tooltip.callbacks.label = function (context) {
546
- var dataLabel = context.label;
547
- var value = ': ';
548
-
549
- if (isArray(dataLabel)) {
550
- // show value on first line of multiline label
551
- // need to clone because we are changing the value
552
- dataLabel = dataLabel.slice();
553
- dataLabel[0] += value;
554
- } else {
555
- dataLabel += value;
556
- }
557
-
558
- return formatValue(dataLabel, context.parsed, formatOptions);
574
+ return formatValue('', context.parsed, formatOptions);
559
575
  };
560
576
  } else {
561
577
  var valueLabel = chartType === "bar" ? "x" : "y";
@@ -573,124 +589,187 @@
573
589
  };
574
590
  }
575
591
  }
576
- };
577
592
 
578
- var jsOptions$2 = jsOptionsFunc(merge(baseOptions, defaultOptions$2), hideLegend$2, setTitle$2, setMin$2, setMax$2, setStacked$2, setXtitle$2, setYtitle$2);
579
-
580
- var createDataTable = function (chart, options, chartType) {
581
- var datasets = [];
582
- var labels = [];
583
-
584
- var colors = chart.options.colors || defaultColors;
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
+ }
585
601
 
586
- var day = true;
587
- var week = true;
588
- var dayOfWeek;
589
- var month = true;
590
- var year = true;
591
- var hour = true;
592
- var minute = true;
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
+ }
593
609
 
594
- var series = chart.data;
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
+ }
595
623
 
624
+ function maxR(series) {
625
+ // start at zero since radius must be positive
596
626
  var max = 0;
597
- if (chartType === "bubble") {
598
- for (var i$1 = 0; i$1 < series.length; i$1++) {
599
- var s$1 = series[i$1];
600
- for (var j$1 = 0; j$1 < s$1.data.length; j$1++) {
601
- if (s$1.data[j$1][2] > max) {
602
- max = s$1.data[j$1][2];
603
- }
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;
604
633
  }
605
634
  }
606
635
  }
636
+ return max;
637
+ }
607
638
 
608
- var i, j, s, d, key, rows = [], rows2 = [];
639
+ var jsOptions$2 = jsOptionsFunc(merge(baseOptions, defaultOptions$2), hideLegend$2, setTitle$2, setMin$2, setMax$2, setStacked$2, setXtitle$2, setYtitle$2);
609
640
 
610
- if (chartType === "bar" || chartType === "column" || (chart.xtype !== "number" && chart.xtype !== "bubble")) {
611
- var sortedLabels = [];
641
+ function prepareDefaultData(chart) {
642
+ var series = chart.data;
643
+ var rows = {};
644
+ var keys = [];
645
+ var labels = [];
646
+ var values = [];
612
647
 
613
- for (i = 0; i < series.length; i++) {
614
- s = series[i];
648
+ for (var i = 0; i < series.length; i++) {
649
+ var data = series[i].data;
615
650
 
616
- for (j = 0; j < s.data.length; j++) {
617
- d = s.data[j];
618
- key = chart.xtype == "datetime" ? d[0].getTime() : d[0];
619
- if (!rows[key]) {
620
- rows[key] = new Array(series.length);
621
- }
622
- rows[key][i] = toFloat(d[1]);
623
- if (sortedLabels.indexOf(key) === -1) {
624
- sortedLabels.push(key);
625
- }
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);
626
657
  }
658
+ rows[key][i] = d[1];
627
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];
628
672
 
629
- if (chart.xtype === "datetime" || chart.xtype === "number") {
630
- sortedLabels.sort(sortByNumber);
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);
631
681
  }
682
+ }
632
683
 
633
- for (j = 0; j < series.length; j++) {
634
- rows2.push([]);
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
+ });
635
707
  }
708
+ values.push(points);
709
+ }
636
710
 
637
- var value;
638
- var k;
639
- for (k = 0; k < sortedLabels.length; k++) {
640
- i = sortedLabels[k];
641
- if (chart.xtype === "datetime") {
642
- value = new Date(toFloat(i));
643
- // TODO make this efficient
644
- day = day && isDay(value);
645
- if (!dayOfWeek) {
646
- dayOfWeek = value.getDay();
647
- }
648
- week = week && isWeek(value, dayOfWeek);
649
- month = month && isMonth(value);
650
- year = year && isYear(value);
651
- hour = hour && isHour(value);
652
- minute = minute && isMinute(value);
653
- } else {
654
- value = i;
655
- }
656
- labels.push(value);
657
- for (j = 0; j < series.length; j++) {
658
- // Chart.js doesn't like undefined
659
- rows2[j].push(rows[i][j] === undefined ? null : rows[i][j]);
660
- }
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
+ });
661
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);
662
749
  } else {
663
- for (var i$2 = 0; i$2 < series.length; i$2++) {
664
- var s$2 = series[i$2];
665
- var d$1 = [];
666
- for (var j$2 = 0; j$2 < s$2.data.length; j$2++) {
667
- var point = {
668
- x: toFloat(s$2.data[j$2][0]),
669
- y: toFloat(s$2.data[j$2][1])
670
- };
671
- if (chartType === "bubble") {
672
- point.r = toFloat(s$2.data[j$2][2]) * 20 / max;
673
- // custom attribute, for tooltip
674
- point.v = s$2.data[j$2][2];
675
- }
676
- d$1.push(point);
677
- }
678
- rows2.push(d$1);
679
- }
750
+ return prepareDefaultData(chart);
680
751
  }
752
+ }
681
753
 
682
- var color;
683
- var backgroundColor;
754
+ function createDataTable(chart, options, chartType) {
755
+ var ref = prepareData(chart, chartType);
756
+ var labels = ref.labels;
757
+ var values = ref.values;
684
758
 
685
- for (i = 0; i < series.length; i++) {
686
- s = series[i];
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];
687
764
 
688
765
  // use colors for each bar for single series format
766
+ var color = (void 0);
767
+ var backgroundColor = (void 0);
689
768
  if (chart.options.colors && chart.singleSeriesFormat && (chartType === "bar" || chartType === "column") && !s.color && isArray(chart.options.colors) && !isArray(chart.options.colors[0])) {
690
769
  color = colors;
691
770
  backgroundColor = [];
692
- for (var j$3 = 0; j$3 < colors.length; j$3++) {
693
- backgroundColor[j$3] = addOpacity(color[j$3], 0.5);
771
+ for (var j = 0; j < colors.length; j++) {
772
+ backgroundColor[j] = addOpacity(color[j], 0.5);
694
773
  }
695
774
  } else {
696
775
  color = s.color || colors[i];
@@ -699,7 +778,7 @@
699
778
 
700
779
  var dataset = {
701
780
  label: s.name || "",
702
- data: rows2[i],
781
+ data: values[i],
703
782
  fill: chartType === "area",
704
783
  borderColor: color,
705
784
  backgroundColor: backgroundColor,
@@ -762,90 +841,90 @@
762
841
  }
763
842
  }
764
843
 
765
- // for empty datetime chart
766
- if (chart.xtype === "datetime" && labels.length === 0) {
767
- if (notnull(xmin)) {
768
- labels.push(toDate(xmin));
769
- }
770
- if (notnull(xmax)) {
771
- labels.push(toDate(xmax));
772
- }
773
- day = false;
774
- week = false;
775
- month = false;
776
- year = false;
777
- hour = false;
778
- minute = false;
779
- }
780
-
781
- if (chart.xtype === "datetime" && labels.length > 0) {
782
- var minTime = (notnull(xmin) ? toDate(xmin) : labels[0]).getTime();
783
- var maxTime = (notnull(xmax) ? toDate(xmax) : labels[0]).getTime();
844
+ if (chart.xtype === "datetime") {
845
+ var timeUnit = calculateTimeUnit(labels);
784
846
 
785
- for (i = 1; i < labels.length; i++) {
786
- var value$1 = labels[i].getTime();
787
- if (value$1 < minTime) {
788
- minTime = value$1;
847
+ // for empty datetime chart
848
+ if (labels.length === 0) {
849
+ if (notnull(xmin)) {
850
+ labels.push(toDate(xmin));
789
851
  }
790
- if (value$1 > maxTime) {
791
- maxTime = value$1;
852
+ if (notnull(xmax)) {
853
+ labels.push(toDate(xmax));
792
854
  }
793
855
  }
794
856
 
795
- var timeDiff = (maxTime - minTime) / (86400 * 1000.0);
796
-
797
- if (!options.scales.x.time.unit) {
798
- var step;
799
- if (year || timeDiff > 365 * 10) {
800
- options.scales.x.time.unit = "year";
801
- step = 365;
802
- } else if (month || timeDiff > 30 * 10) {
803
- options.scales.x.time.unit = "month";
804
- step = 30;
805
- } else if (day || timeDiff > 10) {
806
- options.scales.x.time.unit = "day";
807
- step = 1;
808
- } else if (hour || timeDiff > 0.5) {
809
- options.scales.x.time.displayFormats = {hour: "MMM d, h a"};
810
- options.scales.x.time.unit = "hour";
811
- step = 1 / 24.0;
812
- } else if (minute) {
813
- options.scales.x.time.displayFormats = {minute: "h:mm a"};
814
- options.scales.x.time.unit = "minute";
815
- step = 1 / 24.0 / 60.0;
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
+ }
816
869
  }
817
870
 
818
- if (step && timeDiff > 0) {
819
- // width not available for hidden elements
820
- var width = chart.element.offsetWidth;
821
- if (width > 0) {
822
- var unitStepSize = Math.ceil(timeDiff / step / (width / 100.0));
823
- if (week && step === 1) {
824
- unitStepSize = Math.ceil(unitStepSize / 7.0) * 7;
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;
825
903
  }
826
- options.scales.x.time.stepSize = unitStepSize;
827
904
  }
828
905
  }
829
- }
830
906
 
831
- if (!options.scales.x.time.tooltipFormat) {
832
- if (day) {
833
- options.scales.x.time.tooltipFormat = "PP";
834
- } else if (hour) {
835
- options.scales.x.time.tooltipFormat = "MMM d, h a";
836
- } else if (minute) {
837
- options.scales.x.time.tooltipFormat = "h:mm a";
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
+ }
838
919
  }
839
920
  }
840
921
  }
841
922
 
842
- var data = {
923
+ return {
843
924
  labels: labels,
844
925
  datasets: datasets
845
926
  };
846
-
847
- return data;
848
- };
927
+ }
849
928
 
850
929
  var defaultExport$2 = function defaultExport(library) {
851
930
  this.name = "chartjs";
@@ -853,20 +932,20 @@
853
932
  };
854
933
 
855
934
  defaultExport$2.prototype.renderLineChart = function renderLineChart (chart, chartType) {
856
- var chartOptions = {};
857
- // fix for https://github.com/chartjs/Chart.js/issues/2441
858
- if (!chart.options.max && allZeros(chart.data)) {
859
- chartOptions.max = 1;
935
+ if (!chartType) {
936
+ chartType = "line";
860
937
  }
861
938
 
939
+ var chartOptions = {};
940
+
862
941
  var options = jsOptions$2(chart, merge(chartOptions, chart.options));
863
942
  setFormatOptions$1(chart, options, chartType);
864
943
 
865
- var data = createDataTable(chart, options, chartType || "line");
944
+ var data = createDataTable(chart, options, chartType);
866
945
 
867
946
  if (chart.xtype === "number") {
868
947
  options.scales.x.type = options.scales.x.type || "linear";
869
- options.scales.x.position = options.scales.x.position ||"bottom";
948
+ options.scales.x.position = options.scales.x.position || "bottom";
870
949
  } else {
871
950
  options.scales.x.type = chart.xtype === "string" ? "category" : "time";
872
951
  }
@@ -933,6 +1012,9 @@
933
1012
  if (chartType !== "bar") {
934
1013
  setLabelSize(chart, data, options);
935
1014
  }
1015
+ if (!("mode" in options.interaction)) {
1016
+ options.interaction.mode = "index";
1017
+ }
936
1018
  this.drawChart(chart, "bar", data, options);
937
1019
  };
938
1020
 
@@ -1044,7 +1126,7 @@
1044
1126
  }
1045
1127
  };
1046
1128
 
1047
- var hideLegend$1 = function (options, legend, hideLegend) {
1129
+ function hideLegend$1(options, legend, hideLegend) {
1048
1130
  if (legend !== undefined) {
1049
1131
  options.legend.enabled = !!legend;
1050
1132
  if (legend && legend !== true) {
@@ -1059,38 +1141,38 @@
1059
1141
  } else if (hideLegend) {
1060
1142
  options.legend.enabled = false;
1061
1143
  }
1062
- };
1144
+ }
1063
1145
 
1064
- var setTitle$1 = function (options, title) {
1146
+ function setTitle$1(options, title) {
1065
1147
  options.title.text = title;
1066
- };
1148
+ }
1067
1149
 
1068
- var setMin$1 = function (options, min) {
1150
+ function setMin$1(options, min) {
1069
1151
  options.yAxis.min = min;
1070
- };
1152
+ }
1071
1153
 
1072
- var setMax$1 = function (options, max) {
1154
+ function setMax$1(options, max) {
1073
1155
  options.yAxis.max = max;
1074
- };
1156
+ }
1075
1157
 
1076
- var setStacked$1 = function (options, stacked) {
1158
+ function setStacked$1(options, stacked) {
1077
1159
  var stackedValue = stacked ? (stacked === true ? "normal" : stacked) : null;
1078
1160
  options.plotOptions.series.stacking = stackedValue;
1079
1161
  options.plotOptions.area.stacking = stackedValue;
1080
1162
  options.plotOptions.areaspline.stacking = stackedValue;
1081
- };
1163
+ }
1082
1164
 
1083
- var setXtitle$1 = function (options, title) {
1165
+ function setXtitle$1(options, title) {
1084
1166
  options.xAxis.title.text = title;
1085
- };
1167
+ }
1086
1168
 
1087
- var setYtitle$1 = function (options, title) {
1169
+ function setYtitle$1(options, title) {
1088
1170
  options.yAxis.title.text = title;
1089
- };
1171
+ }
1090
1172
 
1091
1173
  var jsOptions$1 = jsOptionsFunc(defaultOptions$1, hideLegend$1, setTitle$1, setMin$1, setMax$1, setStacked$1, setXtitle$1, setYtitle$1);
1092
1174
 
1093
- var setFormatOptions = function(chart, options, chartType) {
1175
+ function setFormatOptions(chart, options, chartType) {
1094
1176
  var formatOptions = {
1095
1177
  prefix: chart.options.prefix,
1096
1178
  suffix: chart.options.suffix,
@@ -1113,7 +1195,7 @@
1113
1195
  return '<span style="color:' + this.color + '">\u25CF</span> ' + formatValue(this.series.name + ': <b>', this.y, formatOptions) + '</b><br/>';
1114
1196
  };
1115
1197
  }
1116
- };
1198
+ }
1117
1199
 
1118
1200
  var defaultExport$1 = function defaultExport(library) {
1119
1201
  this.name = "highcharts";
@@ -1149,7 +1231,7 @@
1149
1231
  }
1150
1232
  }
1151
1233
 
1152
- var options = jsOptions$1(chart, chart.options, chartOptions), data, i, j;
1234
+ var options = jsOptions$1(chart, chart.options, chartOptions);
1153
1235
  if (chart.xtype === "number") {
1154
1236
  options.xAxis.type = options.xAxis.type || "linear";
1155
1237
  } else {
@@ -1161,13 +1243,15 @@
1161
1243
  setFormatOptions(chart, options, chartType);
1162
1244
 
1163
1245
  var series = chart.data;
1164
- for (i = 0; i < series.length; i++) {
1246
+ for (var i = 0; i < series.length; i++) {
1165
1247
  series[i].name = series[i].name || "Value";
1166
- data = series[i].data;
1248
+ var data = series[i].data;
1167
1249
  if (chart.xtype === "datetime") {
1168
- for (j = 0; j < data.length; j++) {
1250
+ for (var j = 0; j < data.length; j++) {
1169
1251
  data[j][0] = data[j][0].getTime();
1170
1252
  }
1253
+ } else if (chart.xtype === "number") {
1254
+ data.sort(sortByNumberSeries);
1171
1255
  }
1172
1256
  series[i].marker = {symbol: "circle"};
1173
1257
  if (chart.options.points === false) {
@@ -1216,15 +1300,17 @@
1216
1300
  defaultExport$1.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
1217
1301
  chartType = chartType || "column";
1218
1302
  var series = chart.data;
1219
- var options = jsOptions$1(chart, chart.options), i, j, s, d, rows = [], categories = [];
1303
+ var options = jsOptions$1(chart, chart.options);
1304
+ var rows = [];
1305
+ var categories = [];
1220
1306
  options.chart.type = chartType;
1221
1307
  setFormatOptions(chart, options, chartType);
1222
1308
 
1223
- for (i = 0; i < series.length; i++) {
1224
- s = series[i];
1309
+ for (var i = 0; i < series.length; i++) {
1310
+ var s = series[i];
1225
1311
 
1226
- for (j = 0; j < s.data.length; j++) {
1227
- d = s.data[j];
1312
+ for (var j = 0; j < s.data.length; j++) {
1313
+ var d = s.data[j];
1228
1314
  if (!rows[d[0]]) {
1229
1315
  rows[d[0]] = new Array(series.length);
1230
1316
  categories.push(d[0]);
@@ -1239,19 +1325,19 @@
1239
1325
 
1240
1326
  options.xAxis.categories = categories;
1241
1327
 
1242
- var newSeries = [], d2;
1243
- for (i = 0; i < series.length; i++) {
1244
- d = [];
1245
- for (j = 0; j < categories.length; j++) {
1246
- d.push(rows[categories[j]][i] || 0);
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);
1247
1333
  }
1248
1334
 
1249
- d2 = {
1250
- name: series[i].name || "Value",
1251
- data: d
1335
+ var d2 = {
1336
+ name: series[i$1].name || "Value",
1337
+ data: d$1
1252
1338
  };
1253
- if (series[i].stack) {
1254
- d2.stack = series[i].stack;
1339
+ if (series[i$1].stack) {
1340
+ d2.stack = series[i$1].stack;
1255
1341
  }
1256
1342
 
1257
1343
  newSeries.push(d2);
@@ -1334,7 +1420,7 @@
1334
1420
  }
1335
1421
  };
1336
1422
 
1337
- var hideLegend = function (options, legend, hideLegend) {
1423
+ function hideLegend(options, legend, hideLegend) {
1338
1424
  if (legend !== undefined) {
1339
1425
  var position;
1340
1426
  if (!legend) {
@@ -1348,53 +1434,53 @@
1348
1434
  } else if (hideLegend) {
1349
1435
  options.legend.position = "none";
1350
1436
  }
1351
- };
1437
+ }
1352
1438
 
1353
- var setTitle = function (options, title) {
1439
+ function setTitle(options, title) {
1354
1440
  options.title = title;
1355
1441
  options.titleTextStyle = {color: "#333", fontSize: "20px"};
1356
- };
1442
+ }
1357
1443
 
1358
- var setMin = function (options, min) {
1444
+ function setMin(options, min) {
1359
1445
  options.vAxis.viewWindow.min = min;
1360
- };
1446
+ }
1361
1447
 
1362
- var setMax = function (options, max) {
1448
+ function setMax(options, max) {
1363
1449
  options.vAxis.viewWindow.max = max;
1364
- };
1450
+ }
1365
1451
 
1366
- var setBarMin = function (options, min) {
1452
+ function setBarMin(options, min) {
1367
1453
  options.hAxis.viewWindow.min = min;
1368
- };
1454
+ }
1369
1455
 
1370
- var setBarMax = function (options, max) {
1456
+ function setBarMax(options, max) {
1371
1457
  options.hAxis.viewWindow.max = max;
1372
- };
1458
+ }
1373
1459
 
1374
- var setStacked = function (options, stacked) {
1375
- options.isStacked = stacked ? stacked : false;
1376
- };
1460
+ function setStacked(options, stacked) {
1461
+ options.isStacked = stacked || false;
1462
+ }
1377
1463
 
1378
- var setXtitle = function (options, title) {
1464
+ function setXtitle(options, title) {
1379
1465
  options.hAxis.title = title;
1380
1466
  options.hAxis.titleTextStyle.italic = false;
1381
- };
1467
+ }
1382
1468
 
1383
- var setYtitle = function (options, title) {
1469
+ function setYtitle(options, title) {
1384
1470
  options.vAxis.title = title;
1385
1471
  options.vAxis.titleTextStyle.italic = false;
1386
- };
1472
+ }
1387
1473
 
1388
1474
  var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
1389
1475
 
1390
- var resize = function (callback) {
1476
+ function resize(callback) {
1391
1477
  if (window.attachEvent) {
1392
1478
  window.attachEvent("onresize", callback);
1393
1479
  } else if (window.addEventListener) {
1394
1480
  window.addEventListener("resize", callback, true);
1395
1481
  }
1396
1482
  callback();
1397
- };
1483
+ }
1398
1484
 
1399
1485
  var defaultExport = function defaultExport(library) {
1400
1486
  this.name = "google";
@@ -1530,11 +1616,12 @@
1530
1616
  var chartOptions = {};
1531
1617
  var options = jsOptions(chart, chart.options, chartOptions);
1532
1618
 
1533
- var series = chart.data, rows2 = [], i, j, data, d;
1534
- for (i = 0; i < series.length; i++) {
1619
+ var series = chart.data;
1620
+ var rows2 = [];
1621
+ for (var i = 0; i < series.length; i++) {
1535
1622
  series[i].name = series[i].name || "Value";
1536
- d = series[i].data;
1537
- for (j = 0; j < d.length; j++) {
1623
+ var d = series[i].data;
1624
+ for (var j = 0; j < d.length; j++) {
1538
1625
  var row = new Array(series.length + 1);
1539
1626
  row[0] = d[j][0];
1540
1627
  row[i + 1] = d[j][1];
@@ -1542,10 +1629,10 @@
1542
1629
  }
1543
1630
  }
1544
1631
 
1545
- data = new this$1$1.library.visualization.DataTable();
1632
+ var data = new this$1$1.library.visualization.DataTable();
1546
1633
  data.addColumn("number", "");
1547
- for (i = 0; i < series.length; i++) {
1548
- data.addColumn("number", series[i].name);
1634
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
1635
+ data.addColumn("number", series[i$1].name);
1549
1636
  }
1550
1637
  data.addRows(rows2);
1551
1638
 
@@ -1632,10 +1719,9 @@
1632
1719
  };
1633
1720
 
1634
1721
  defaultExport.prototype.runCallbacks = function runCallbacks () {
1635
- var cb, call;
1636
1722
  for (var i = 0; i < callbacks.length; i++) {
1637
- cb = callbacks[i];
1638
- 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));
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));
1639
1725
  if (call) {
1640
1726
  cb.callback();
1641
1727
  callbacks.splice(i, 1);
@@ -1646,44 +1732,48 @@
1646
1732
 
1647
1733
  // cant use object as key
1648
1734
  defaultExport.prototype.createDataTable = function createDataTable (series, columnType) {
1649
- var i, j, s, d, key, rows = [], sortedLabels = [];
1650
- for (i = 0; i < series.length; i++) {
1651
- s = series[i];
1735
+ var rows = [];
1736
+ var sortedLabels = [];
1737
+ for (var i = 0; i < series.length; i++) {
1738
+ var s = series[i];
1652
1739
  series[i].name = series[i].name || "Value";
1653
1740
 
1654
- for (j = 0; j < s.data.length; j++) {
1655
- d = s.data[j];
1656
- key = (columnType === "datetime") ? d[0].getTime() : d[0];
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];
1657
1744
  if (!rows[key]) {
1658
1745
  rows[key] = new Array(series.length);
1659
1746
  sortedLabels.push(key);
1660
1747
  }
1661
- rows[key][i] = toFloat(d[1]);
1748
+ rows[key][i] = d[1];
1662
1749
  }
1663
1750
  }
1664
1751
 
1665
1752
  var rows2 = [];
1666
- var day = true;
1667
- var value;
1668
- for (j = 0; j < sortedLabels.length; j++) {
1669
- i = sortedLabels[j];
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);
1670
1757
  if (columnType === "datetime") {
1671
- value = new Date(toFloat(i));
1672
- day = day && isDay(value);
1673
- } else if (columnType === "number") {
1674
- value = toFloat(i);
1758
+ value = new Date(i$1);
1759
+ values.push(value);
1675
1760
  } else {
1676
- value = i;
1761
+ value = i$1;
1677
1762
  }
1678
- rows2.push([value].concat(rows[i]));
1763
+ rows2.push([value].concat(rows[i$1]));
1679
1764
  }
1765
+
1766
+ var day = true;
1680
1767
  if (columnType === "datetime") {
1681
1768
  rows2.sort(sortByTime);
1769
+
1770
+ var timeUnit = calculateTimeUnit(values, true);
1771
+ day = isDay(timeUnit);
1682
1772
  } else if (columnType === "number") {
1683
1773
  rows2.sort(sortByNumberSeries);
1684
1774
 
1685
- for (i = 0; i < rows2.length; i++) {
1686
- rows2[i][0] = toStr(rows2[i][0]);
1775
+ for (var i$2 = 0; i$2 < rows2.length; i$2++) {
1776
+ rows2[i$2][0] = toStr(rows2[i$2][0]);
1687
1777
  }
1688
1778
 
1689
1779
  columnType = "string";
@@ -1693,17 +1783,132 @@
1693
1783
  var data = new this.library.visualization.DataTable();
1694
1784
  columnType = columnType === "datetime" && day ? "date" : columnType;
1695
1785
  data.addColumn(columnType, "");
1696
- for (i = 0; i < series.length; i++) {
1697
- data.addColumn("number", series[i].name);
1786
+ for (var i$3 = 0; i$3 < series.length; i$3++) {
1787
+ data.addColumn("number", series[i$3].name);
1698
1788
  }
1699
1789
  data.addRows(rows2);
1700
1790
 
1701
1791
  return data;
1702
1792
  };
1703
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
1704
1906
  function formatSeriesData(data, keyType) {
1705
- var r = [], j, keyFunc;
1907
+ if (keyType === "bubble") {
1908
+ return formatSeriesBubble(data);
1909
+ }
1706
1910
 
1911
+ var keyFunc;
1707
1912
  if (keyType === "number") {
1708
1913
  keyFunc = toFloat;
1709
1914
  } else if (keyType === "datetime") {
@@ -1712,22 +1917,10 @@
1712
1917
  keyFunc = toStr;
1713
1918
  }
1714
1919
 
1715
- if (keyType === "bubble") {
1716
- for (j = 0; j < data.length; j++) {
1717
- r.push([toFloat(data[j][0]), toFloat(data[j][1]), toFloat(data[j][2])]);
1718
- }
1719
- } else {
1720
- for (j = 0; j < data.length; j++) {
1721
- r.push([keyFunc(data[j][0]), toFloat(data[j][1])]);
1722
- }
1920
+ var r = [];
1921
+ for (var i = 0; i < data.length; i++) {
1922
+ r.push([keyFunc(data[i][0]), toFloat(data[i][1])]);
1723
1923
  }
1724
-
1725
- if (keyType === "datetime") {
1726
- r.sort(sortByTime);
1727
- } else if (keyType === "number") {
1728
- r.sort(sortByNumberSeries);
1729
- }
1730
-
1731
1924
  return r;
1732
1925
  }
1733
1926
 
@@ -1748,10 +1941,9 @@
1748
1941
  }
1749
1942
 
1750
1943
  function detectXTypeWithFunction(series, func) {
1751
- var i, j, data;
1752
- for (i = 0; i < series.length; i++) {
1753
- data = toArr(series[i].data);
1754
- for (j = 0; j < data.length; j++) {
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++) {
1755
1947
  if (!func(data[j][0])) {
1756
1948
  return false;
1757
1949
  }
@@ -1763,11 +1955,11 @@
1763
1955
  // creates a shallow copy of each element of the array
1764
1956
  // elements are expected to be objects
1765
1957
  function copySeries(series) {
1766
- var newSeries = [], i, j;
1767
- for (i = 0; i < series.length; i++) {
1958
+ var newSeries = [];
1959
+ for (var i = 0; i < series.length; i++) {
1768
1960
  var copy = {};
1769
- for (j in series[i]) {
1770
- if (series[i].hasOwnProperty(j)) {
1961
+ for (var j in series[i]) {
1962
+ if (Object.prototype.hasOwnProperty.call(series[i], j)) {
1771
1963
  copy[j] = series[i][j];
1772
1964
  }
1773
1965
  }
@@ -1777,13 +1969,11 @@
1777
1969
  }
1778
1970
 
1779
1971
  function processSeries(chart, keyType, noDatetime) {
1780
- var i;
1781
-
1782
1972
  var opts = chart.options;
1783
1973
  var series = chart.rawData;
1784
1974
 
1785
1975
  // see if one series or multiple
1786
- chart.singleSeriesFormat = (!isArray(series) || typeof series[0] !== "object" || isArray(series[0]));
1976
+ chart.singleSeriesFormat = !isArray(series) || !isPlainObject(series[0]);
1787
1977
  if (chart.singleSeriesFormat) {
1788
1978
  series = [{name: opts.label, data: series}];
1789
1979
  }
@@ -1791,23 +1981,23 @@
1791
1981
  // convert to array
1792
1982
  // must come before dataEmpty check
1793
1983
  series = copySeries(series);
1794
- for (i = 0; i < series.length; i++) {
1984
+ for (var i = 0; i < series.length; i++) {
1795
1985
  series[i].data = toArr(series[i].data);
1796
1986
  }
1797
1987
 
1798
- chart.xtype = keyType ? keyType : (opts.discrete ? "string" : detectXType(series, noDatetime, opts));
1988
+ chart.xtype = keyType || (opts.discrete ? "string" : detectXType(series, noDatetime, opts));
1799
1989
 
1800
1990
  // right format
1801
- for (i = 0; i < series.length; i++) {
1802
- series[i].data = formatSeriesData(series[i].data, chart.xtype);
1991
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
1992
+ series[i$1].data = formatSeriesData(series[i$1].data, chart.xtype);
1803
1993
  }
1804
1994
 
1805
1995
  return series;
1806
1996
  }
1807
1997
 
1808
1998
  function processSimple(chart) {
1809
- var perfectData = toArr(chart.rawData), i;
1810
- for (i = 0; i < perfectData.length; i++) {
1999
+ var perfectData = toArr(chart.rawData);
2000
+ for (var i = 0; i < perfectData.length; i++) {
1811
2001
  perfectData[i] = [toStr(perfectData[i][0]), toFloat(perfectData[i][1])];
1812
2002
  }
1813
2003
  return perfectData;
@@ -1827,48 +2017,51 @@
1827
2017
  }
1828
2018
 
1829
2019
  function addDownloadButton(chart) {
1830
- var element = chart.element;
1831
- var link = document.createElement("a");
1832
-
1833
2020
  var download = chart.options.download;
1834
2021
  if (download === true) {
1835
2022
  download = {};
1836
2023
  } else if (typeof download === "string") {
1837
2024
  download = {filename: download};
1838
2025
  }
1839
- link.download = download.filename || "chart.png"; // https://caniuse.com/download
1840
2026
 
2027
+ var link = document.createElement("a");
2028
+ link.download = download.filename || "chart.png";
1841
2029
  link.style.position = "absolute";
1842
2030
  link.style.top = "20px";
1843
2031
  link.style.right = "20px";
1844
2032
  link.style.zIndex = 1000;
1845
2033
  link.style.lineHeight = "20px";
1846
2034
  link.target = "_blank"; // for safari
2035
+
1847
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));
1848
2040
  image.alt = "Download";
2041
+ image.style.width = "20px";
2042
+ image.style.height = "20px";
1849
2043
  image.style.border = "none";
1850
- // icon from font-awesome
1851
- // http://fa2png.io/
1852
- image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABCFBMVEUAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMywEsqxAAAAV3RSTlMAAQIDBggJCgsMDQ4PERQaHB0eISIjJCouLzE0OTo/QUJHSUpLTU5PUllhYmltcHh5foWLjI+SlaCio6atr7S1t7m6vsHHyM7R2tze5Obo7fHz9ff5+/1hlxK2AAAA30lEQVQYGUXBhVYCQQBA0TdYWAt2d3d3YWAHyur7/z9xgD16Lw0DW+XKx+1GgX+FRzM3HWQWrHl5N/oapW5RPe0PkBu+UYeICvozTWZVK23Ao04B79oJrOsJDOoxkZoQPWgX29pHpCZEk7rEvQYiNSFq1UMqvlCjJkRBS1R8hb00Vb/TajtBL7nTHE1X1vyMQF732dQhyF2o6SAwrzP06iUQzvwsArlnzcOdrgBhJyHa1QOgO9U1GsKuvjUTjavliZYQ8nNPapG6sap/3nrIdJ6bOWzmX/fy0XVpfzZP3S8OJT3g9EEiJwAAAABJRU5ErkJggg==";
1853
2044
  link.appendChild(image);
2045
+
2046
+ var element = chart.element;
1854
2047
  element.style.position = "relative";
1855
2048
 
1856
2049
  chart.__downloadAttached = true;
1857
2050
 
1858
2051
  // mouseenter
1859
- chart.__enterEvent = addEvent(element, "mouseover", function(e) {
2052
+ chart.__enterEvent = element.addEventListener("mouseover", function (e) {
1860
2053
  var related = e.relatedTarget;
1861
2054
  // check download option again to ensure it wasn't changed
1862
- if ((!related || (related !== this && !childOf(this, related))) && chart.options.download) {
2055
+ if ((!related || (related !== this && !this.contains(related))) && chart.options.download) {
1863
2056
  link.href = chart.toImage(download);
1864
2057
  element.appendChild(link);
1865
2058
  }
1866
2059
  });
1867
2060
 
1868
2061
  // mouseleave
1869
- chart.__leaveEvent = addEvent(element, "mouseout", function(e) {
2062
+ chart.__leaveEvent = element.addEventListener("mouseout", function (e) {
1870
2063
  var related = e.relatedTarget;
1871
- if (!related || (related !== this && !childOf(this, related))) {
2064
+ if (!related || (related !== this && !this.contains(related))) {
1872
2065
  if (link.parentNode) {
1873
2066
  link.parentNode.removeChild(link);
1874
2067
  }
@@ -1876,37 +2069,9 @@
1876
2069
  });
1877
2070
  }
1878
2071
 
1879
- // https://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
1880
- function addEvent(elem, event, fn) {
1881
- if (elem.addEventListener) {
1882
- elem.addEventListener(event, fn, false);
1883
- return fn;
1884
- } else {
1885
- var fn2 = function() {
1886
- // set the this pointer same as addEventListener when fn is called
1887
- return(fn.call(elem, window.event));
1888
- };
1889
- elem.attachEvent("on" + event, fn2);
1890
- return fn2;
1891
- }
1892
- }
1893
-
1894
- function removeEvent(elem, event, fn) {
1895
- if (elem.removeEventListener) {
1896
- elem.removeEventListener(event, fn, false);
1897
- } else {
1898
- elem.detachEvent("on" + event, fn);
1899
- }
1900
- }
1901
-
1902
- // https://gist.github.com/shawnbot/4166283
1903
- function childOf(p, c) {
1904
- if (p === c) { return false; }
1905
- while (c && c !== p) { c = c.parentNode; }
1906
- return c === p;
1907
- }
1908
-
1909
- var pendingRequests = [], runningRequests = 0, maxRequests = 4;
2072
+ var pendingRequests = [];
2073
+ var runningRequests = 0;
2074
+ var maxRequests = 4;
1910
2075
 
1911
2076
  function pushRequest(url, success, error) {
1912
2077
  pendingRequests.push([url, success, error]);
@@ -1930,50 +2095,24 @@
1930
2095
  }
1931
2096
 
1932
2097
  function getJSON(url, success, error) {
1933
- ajaxCall(url, success, function (jqXHR, textStatus, errorThrown) {
1934
- var message = (typeof errorThrown === "string") ? errorThrown : errorThrown.message;
1935
- error(message);
1936
- });
1937
- }
1938
-
1939
- function ajaxCall(url, success, error) {
1940
- var $ = window.jQuery || window.Zepto || window.$;
1941
-
1942
- if ($ && $.ajax) {
1943
- $.ajax({
1944
- dataType: "json",
1945
- url: url,
1946
- success: success,
1947
- error: error,
1948
- complete: requestComplete
1949
- });
1950
- } else {
1951
- var xhr = new XMLHttpRequest();
1952
- xhr.open("GET", url, true);
1953
- xhr.setRequestHeader("Content-Type", "application/json");
1954
- xhr.onload = function () {
1955
- requestComplete();
1956
- if (xhr.status === 200) {
1957
- success(JSON.parse(xhr.responseText), xhr.statusText, xhr);
1958
- } else {
1959
- error(xhr, "error", xhr.statusText);
1960
- }
1961
- };
1962
- xhr.send();
1963
- }
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();
1964
2110
  }
1965
2111
 
1966
- var config = {};
1967
- var adapters = [];
1968
-
1969
2112
  // helpers
1970
2113
 
1971
2114
  function setText(element, text) {
1972
- if (document.body.innerText) {
1973
- element.innerText = text;
1974
- } else {
1975
- element.textContent = text;
1976
- }
2115
+ element.textContent = text;
1977
2116
  }
1978
2117
 
1979
2118
  // TODO remove prefix for all messages
@@ -2024,95 +2163,41 @@
2024
2163
  }
2025
2164
  }
2026
2165
 
2027
- function getAdapterType(library) {
2028
- if (library) {
2029
- if (library.product === "Highcharts") {
2030
- return defaultExport$1;
2031
- } else if (library.charts) {
2032
- return defaultExport;
2033
- } else if (isFunction(library)) {
2034
- return defaultExport$2;
2035
- }
2036
- }
2037
- throw new Error("Unknown adapter");
2038
- }
2039
-
2040
- function addAdapter(library) {
2041
- var adapterType = getAdapterType(library);
2042
- var adapter = new adapterType(library);
2043
-
2044
- if (adapters.indexOf(adapter) === -1) {
2045
- adapters.push(adapter);
2046
- }
2047
- }
2048
-
2049
- function loadAdapters() {
2050
- if ("Chart" in window) {
2051
- addAdapter(window.Chart);
2052
- }
2053
-
2054
- if ("Highcharts" in window) {
2055
- addAdapter(window.Highcharts);
2056
- }
2057
-
2058
- if (window.google && window.google.charts) {
2059
- addAdapter(window.google);
2060
- }
2061
- }
2062
-
2063
2166
  function renderChart(chartType, chart) {
2064
2167
  if (dataEmpty(chart.data, chartType)) {
2065
2168
  var message = chart.options.empty || (chart.options.messages && chart.options.messages.empty) || "No data";
2066
2169
  setText(chart.element, message);
2067
2170
  } else {
2068
2171
  callAdapter(chartType, chart);
2172
+ // TODO add downloadSupported method to adapter
2069
2173
  if (chart.options.download && !chart.__downloadAttached && chart.adapter === "chartjs") {
2070
2174
  addDownloadButton(chart);
2071
2175
  }
2072
2176
  }
2073
2177
  }
2074
2178
 
2075
- // TODO remove chartType if cross-browser way
2076
- // to get the name of the chart class
2077
- function callAdapter(chartType, chart) {
2078
- var i, adapter, fnName, adapterName;
2079
- fnName = "render" + chartType;
2080
- adapterName = chart.options.adapter;
2081
-
2082
- loadAdapters();
2083
-
2084
- for (i = 0; i < adapters.length; i++) {
2085
- adapter = adapters[i];
2086
- if ((!adapterName || adapterName === adapter.name) && isFunction(adapter[fnName])) {
2087
- chart.adapter = adapter.name;
2088
- chart.__adapterObject = adapter;
2089
- return adapter[fnName](chart);
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);
2090
2185
  }
2091
2186
  }
2092
-
2093
- if (adapters.length > 0) {
2094
- throw new Error("No charting library found for " + chartType);
2095
- } else {
2096
- throw new Error("No charting libraries found - be sure to include one before your charts");
2097
- }
2187
+ return element;
2098
2188
  }
2099
2189
 
2100
2190
  // define classes
2101
2191
 
2102
2192
  var Chart = function Chart(element, dataSource, options) {
2103
- var elementId;
2104
- if (typeof element === "string") {
2105
- elementId = element;
2106
- element = document.getElementById(element);
2107
- if (!element) {
2108
- throw new Error("No element with id " + elementId);
2109
- }
2110
- }
2111
- this.element = element;
2193
+ this.element = getElement(element);
2112
2194
  this.options = merge(Chartkick.options, options || {});
2113
2195
  this.dataSource = dataSource;
2114
2196
 
2115
- Chartkick.charts[element.id] = this;
2197
+ // TODO handle charts without an id for eachChart and destroyAll
2198
+ if (this.element.id) {
2199
+ Chartkick.charts[this.element.id] = this;
2200
+ }
2116
2201
 
2117
2202
  fetchDataSource(this, dataSource, true);
2118
2203
 
@@ -2184,7 +2269,7 @@
2184
2269
 
2185
2270
  if (!this.intervalId) {
2186
2271
  if (refresh) {
2187
- this.intervalId = setInterval( function () {
2272
+ this.intervalId = setInterval(function () {
2188
2273
  this$1$1.refreshData();
2189
2274
  }, refresh * 1000);
2190
2275
  } else {
@@ -2201,6 +2286,7 @@
2201
2286
  };
2202
2287
 
2203
2288
  Chart.prototype.toImage = function toImage (download) {
2289
+ // TODO move logic to adapter
2204
2290
  if (this.adapter === "chartjs") {
2205
2291
  if (download && download.background && download.background !== "transparent") {
2206
2292
  // https://stackoverflow.com/questions/30464750/chartjs-line-chart-set-background-color
@@ -2231,11 +2317,11 @@
2231
2317
  }
2232
2318
 
2233
2319
  if (this.__enterEvent) {
2234
- removeEvent(this.element, "mouseover", this.__enterEvent);
2320
+ this.element.removeEventListener("mouseover", this.__enterEvent);
2235
2321
  }
2236
2322
 
2237
2323
  if (this.__leaveEvent) {
2238
- removeEvent(this.element, "mouseout", this.__leaveEvent);
2324
+ this.element.removeEventListener("mouseout", this.__leaveEvent);
2239
2325
  }
2240
2326
  };
2241
2327
 
@@ -2254,7 +2340,7 @@
2254
2340
  };
2255
2341
 
2256
2342
  Chart.prototype.__config = function __config () {
2257
- return config;
2343
+ return Chartkick.config;
2258
2344
  };
2259
2345
 
2260
2346
  var LineChart = /*@__PURE__*/(function (Chart) {
@@ -2427,8 +2513,8 @@
2427
2513
  Timeline.prototype.constructor = Timeline;
2428
2514
 
2429
2515
  Timeline.prototype.__processData = function __processData () {
2430
- var i, data = this.rawData;
2431
- for (i = 0; i < data.length; i++) {
2516
+ var data = this.rawData;
2517
+ for (var i = 0; i < data.length; i++) {
2432
2518
  data[i][1] = toDate(data[i][1]);
2433
2519
  data[i][2] = toDate(data[i][2]);
2434
2520
  }
@@ -2442,70 +2528,36 @@
2442
2528
  return Timeline;
2443
2529
  }(Chart));
2444
2530
 
2445
- var Chartkick = {
2446
- LineChart: LineChart,
2447
- PieChart: PieChart,
2448
- ColumnChart: ColumnChart,
2449
- BarChart: BarChart,
2450
- AreaChart: AreaChart,
2451
- GeoChart: GeoChart,
2452
- ScatterChart: ScatterChart,
2453
- BubbleChart: BubbleChart,
2454
- Timeline: Timeline,
2455
- charts: {},
2456
- configure: function (options) {
2457
- for (var key in options) {
2458
- if (options.hasOwnProperty(key)) {
2459
- config[key] = options[key];
2460
- }
2461
- }
2462
- },
2463
- setDefaultOptions: function (opts) {
2464
- Chartkick.options = opts;
2465
- },
2466
- eachChart: function (callback) {
2467
- for (var chartId in Chartkick.charts) {
2468
- if (Chartkick.charts.hasOwnProperty(chartId)) {
2469
- callback(Chartkick.charts[chartId]);
2470
- }
2471
- }
2472
- },
2473
- destroyAll: function() {
2474
- for (var chartId in Chartkick.charts) {
2475
- if (Chartkick.charts.hasOwnProperty(chartId)) {
2476
- Chartkick.charts[chartId].destroy();
2477
- delete Chartkick.charts[chartId];
2478
- }
2479
- }
2480
- },
2481
- config: config,
2482
- options: {},
2483
- adapters: adapters,
2484
- addAdapter: addAdapter,
2485
- use: function(adapter) {
2486
- addAdapter(adapter);
2487
- return Chartkick;
2488
- }
2489
- };
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;
2490
2540
 
2491
2541
  // not ideal, but allows for simpler integration
2492
2542
  if (typeof window !== "undefined" && !window.Chartkick) {
2493
2543
  window.Chartkick = Chartkick;
2494
2544
 
2495
2545
  // clean up previous charts before Turbolinks loads new page
2496
- document.addEventListener("turbolinks:before-render", function() {
2497
- if (config.autoDestroy !== false) {
2546
+ document.addEventListener("turbolinks:before-render", function () {
2547
+ if (Chartkick.config.autoDestroy !== false) {
2498
2548
  Chartkick.destroyAll();
2499
2549
  }
2500
2550
  });
2501
- document.addEventListener("turbo:before-render", function() {
2502
- if (config.autoDestroy !== false) {
2551
+
2552
+ // clean up previous charts before Turbo loads new page
2553
+ document.addEventListener("turbo:before-render", function () {
2554
+ if (Chartkick.config.autoDestroy !== false) {
2503
2555
  Chartkick.destroyAll();
2504
2556
  }
2505
2557
  });
2506
2558
 
2507
2559
  // use setTimeout so charting library can come later in same JS file
2508
- setTimeout(function() {
2560
+ setTimeout(function () {
2509
2561
  window.dispatchEvent(new Event("chartkick:load"));
2510
2562
  }, 0);
2511
2563
  }