chartkick 3.3.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,15 +1,15 @@
1
- /*
1
+ /*!
2
2
  * Chartkick.js
3
3
  * Create beautiful charts with one line of JavaScript
4
4
  * https://github.com/ankane/chartkick.js
5
- * v3.2.0
5
+ * v4.0.0
6
6
  * MIT License
7
7
  */
8
8
 
9
9
  (function (global, factory) {
10
10
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
11
11
  typeof define === 'function' && define.amd ? define(factory) :
12
- (global = global || self, global.Chartkick = factory());
12
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chartkick = factory());
13
13
  }(this, (function () { 'use strict';
14
14
 
15
15
  function isArray(variable) {
@@ -55,42 +55,6 @@
55
55
 
56
56
  var DATE_PATTERN = /^(\d\d\d\d)(-)?(\d\d)(-)?(\d\d)$/i;
57
57
 
58
- // https://github.com/Do/iso8601.js
59
- var ISO8601_PATTERN = /(\d\d\d\d)(-)?(\d\d)(-)?(\d\d)(T)?(\d\d)(:)?(\d\d)?(:)?(\d\d)?([.,]\d+)?($|Z|([+-])(\d\d)(:)?(\d\d)?)/i;
60
- var DECIMAL_SEPARATOR = String(1.5).charAt(1);
61
-
62
- function parseISO8601(input) {
63
- var day, hour, matches, milliseconds, minutes, month, offset, result, seconds, type, year;
64
- type = Object.prototype.toString.call(input);
65
- if (type === "[object Date]") {
66
- return input;
67
- }
68
- if (type !== "[object String]") {
69
- return;
70
- }
71
- matches = input.match(ISO8601_PATTERN);
72
- if (matches) {
73
- year = parseInt(matches[1], 10);
74
- month = parseInt(matches[3], 10) - 1;
75
- day = parseInt(matches[5], 10);
76
- hour = parseInt(matches[7], 10);
77
- minutes = matches[9] ? parseInt(matches[9], 10) : 0;
78
- seconds = matches[11] ? parseInt(matches[11], 10) : 0;
79
- milliseconds = matches[12] ? parseFloat(DECIMAL_SEPARATOR + matches[12].slice(1)) * 1000 : 0;
80
- result = Date.UTC(year, month, day, hour, minutes, seconds, milliseconds);
81
- if (matches[13] && matches[14]) {
82
- offset = matches[15] * 60;
83
- if (matches[17]) {
84
- offset += parseInt(matches[17], 10);
85
- }
86
- offset *= matches[14] === "-" ? -1 : 1;
87
- result -= offset * 60 * 1000;
88
- }
89
- return new Date(result);
90
- }
91
- }
92
- // end iso8601.js
93
-
94
58
  function negativeValues(series) {
95
59
  var i, j, data;
96
60
  for (i = 0; i < series.length; i++) {
@@ -120,15 +84,15 @@
120
84
  } else {
121
85
  n = toStr(n);
122
86
  if ((matches = n.match(DATE_PATTERN))) {
123
- year = parseInt(matches[1], 10);
124
- month = parseInt(matches[3], 10) - 1;
125
- day = parseInt(matches[5], 10);
126
- return new Date(year, month, day);
127
- } else { // str
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 {
128
92
  // try our best to get the str into iso8601
129
93
  // TODO be smarter about this
130
94
  var str = n.replace(/ /, "T").replace(" ", "").replace("UTC", "Z");
131
- n = parseISO8601(str) || new Date(n);
95
+ n = new Date(str) || new Date(n);
132
96
  }
133
97
  }
134
98
  }
@@ -154,8 +118,8 @@
154
118
  var options = merge({}, defaultOptions);
155
119
  options = merge(options, chartOptions || {});
156
120
 
157
- if (chart.hideLegend || "legend" in opts) {
158
- hideLegend(options, opts.legend, chart.hideLegend);
121
+ if (chart.singleSeriesFormat || "legend" in opts) {
122
+ hideLegend(options, opts.legend, chart.singleSeriesFormat);
159
123
  }
160
124
 
161
125
  if (opts.title) {
@@ -241,6 +205,8 @@
241
205
  return typeof obj === "number";
242
206
  }
243
207
 
208
+ var byteSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB"];
209
+
244
210
  function formatValue(pre, value, options, axis) {
245
211
  pre = pre || "";
246
212
  if (options.prefix) {
@@ -256,26 +222,42 @@
256
222
  var round = options.round;
257
223
 
258
224
  if (options.byteScale) {
225
+ var suffixIdx;
259
226
  var baseValue = axis ? options.byteScale : value;
260
- if (baseValue >= 1099511627776) {
227
+
228
+ if (baseValue >= 1152921504606846976) {
229
+ value /= 1152921504606846976;
230
+ suffixIdx = 6;
231
+ } else if (baseValue >= 1125899906842624) {
232
+ value /= 1125899906842624;
233
+ suffixIdx = 5;
234
+ } else if (baseValue >= 1099511627776) {
261
235
  value /= 1099511627776;
262
- suffix = " TB";
236
+ suffixIdx = 4;
263
237
  } else if (baseValue >= 1073741824) {
264
238
  value /= 1073741824;
265
- suffix = " GB";
239
+ suffixIdx = 3;
266
240
  } else if (baseValue >= 1048576) {
267
241
  value /= 1048576;
268
- suffix = " MB";
242
+ suffixIdx = 2;
269
243
  } else if (baseValue >= 1024) {
270
244
  value /= 1024;
271
- suffix = " KB";
245
+ suffixIdx = 1;
272
246
  } else {
273
- suffix = " bytes";
247
+ suffixIdx = 0;
274
248
  }
275
249
 
250
+ // TODO handle manual precision case
276
251
  if (precision === undefined && round === undefined) {
277
- precision = 3;
252
+ if (value >= 1023.5) {
253
+ if (suffixIdx < byteSuffixes.length - 1) {
254
+ value = 1.0;
255
+ suffixIdx += 1;
256
+ }
257
+ }
258
+ precision = value >= 1000 ? 4 : 3;
278
259
  }
260
+ suffix = " " + byteSuffixes[suffixIdx];
279
261
  }
280
262
 
281
263
  if (precision !== undefined && round !== undefined) {
@@ -343,42 +325,49 @@
343
325
  var baseOptions = {
344
326
  maintainAspectRatio: false,
345
327
  animation: false,
346
- tooltips: {
347
- displayColors: false,
348
- callbacks: {}
328
+ plugins: {
329
+ legend: {},
330
+ tooltip: {
331
+ displayColors: false,
332
+ callbacks: {}
333
+ },
334
+ title: {
335
+ font: {
336
+ size: 20
337
+ },
338
+ color: "#333"
339
+ }
349
340
  },
350
- legend: {},
351
- title: {fontSize: 20, fontColor: "#333"}
341
+ interaction: {}
352
342
  };
353
343
 
354
- var defaultOptions = {
344
+ var defaultOptions$2 = {
355
345
  scales: {
356
- yAxes: [
357
- {
358
- ticks: {
359
- maxTicksLimit: 4
360
- },
361
- scaleLabel: {
362
- fontSize: 16,
363
- // fontStyle: "bold",
364
- fontColor: "#333"
365
- }
366
- }
367
- ],
368
- xAxes: [
369
- {
370
- gridLines: {
371
- drawOnChartArea: false
346
+ y: {
347
+ ticks: {
348
+ maxTicksLimit: 4
349
+ },
350
+ title: {
351
+ font: {
352
+ size: 16
372
353
  },
373
- scaleLabel: {
374
- fontSize: 16,
375
- // fontStyle: "bold",
376
- fontColor: "#333"
354
+ color: "#333"
355
+ },
356
+ grid: {}
357
+ },
358
+ x: {
359
+ grid: {
360
+ drawOnChartArea: false
361
+ },
362
+ title: {
363
+ font: {
364
+ size: 16
377
365
  },
378
- time: {},
379
- ticks: {}
380
- }
381
- ]
366
+ color: "#333"
367
+ },
368
+ time: {},
369
+ ticks: {}
370
+ }
382
371
  }
383
372
  };
384
373
 
@@ -389,66 +378,66 @@
389
378
  "#6633CC", "#E67300", "#8B0707", "#329262", "#5574A6", "#651067"
390
379
  ];
391
380
 
392
- var hideLegend = function (options, legend, hideLegend) {
381
+ var hideLegend$2 = function (options, legend, hideLegend) {
393
382
  if (legend !== undefined) {
394
- options.legend.display = !!legend;
383
+ options.plugins.legend.display = !!legend;
395
384
  if (legend && legend !== true) {
396
- options.legend.position = legend;
385
+ options.plugins.legend.position = legend;
397
386
  }
398
387
  } else if (hideLegend) {
399
- options.legend.display = false;
388
+ options.plugins.legend.display = false;
400
389
  }
401
390
  };
402
391
 
403
- var setTitle = function (options, title) {
404
- options.title.display = true;
405
- options.title.text = title;
392
+ var setTitle$2 = function (options, title) {
393
+ options.plugins.title.display = true;
394
+ options.plugins.title.text = title;
406
395
  };
407
396
 
408
- var setMin = function (options, min) {
397
+ var setMin$2 = function (options, min) {
409
398
  if (min !== null) {
410
- options.scales.yAxes[0].ticks.min = toFloat(min);
399
+ options.scales.y.min = toFloat(min);
411
400
  }
412
401
  };
413
402
 
414
- var setMax = function (options, max) {
415
- options.scales.yAxes[0].ticks.max = toFloat(max);
403
+ var setMax$2 = function (options, max) {
404
+ options.scales.y.max = toFloat(max);
416
405
  };
417
406
 
418
- var setBarMin = function (options, min) {
407
+ var setBarMin$1 = function (options, min) {
419
408
  if (min !== null) {
420
- options.scales.xAxes[0].ticks.min = toFloat(min);
409
+ options.scales.x.min = toFloat(min);
421
410
  }
422
411
  };
423
412
 
424
- var setBarMax = function (options, max) {
425
- options.scales.xAxes[0].ticks.max = toFloat(max);
413
+ var setBarMax$1 = function (options, max) {
414
+ options.scales.x.max = toFloat(max);
426
415
  };
427
416
 
428
- var setStacked = function (options, stacked) {
429
- options.scales.xAxes[0].stacked = !!stacked;
430
- options.scales.yAxes[0].stacked = !!stacked;
417
+ var setStacked$2 = function (options, stacked) {
418
+ options.scales.x.stacked = !!stacked;
419
+ options.scales.y.stacked = !!stacked;
431
420
  };
432
421
 
433
- var setXtitle = function (options, title) {
434
- options.scales.xAxes[0].scaleLabel.display = true;
435
- options.scales.xAxes[0].scaleLabel.labelString = title;
422
+ var setXtitle$2 = function (options, title) {
423
+ options.scales.x.title.display = true;
424
+ options.scales.x.title.text = title;
436
425
  };
437
426
 
438
- var setYtitle = function (options, title) {
439
- options.scales.yAxes[0].scaleLabel.display = true;
440
- options.scales.yAxes[0].scaleLabel.labelString = title;
427
+ var setYtitle$2 = function (options, title) {
428
+ options.scales.y.title.display = true;
429
+ options.scales.y.title.text = title;
441
430
  };
442
431
 
443
432
  // https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
444
- var addOpacity = function(hex, opacity) {
433
+ var addOpacity = function (hex, opacity) {
445
434
  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
446
435
  return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
447
436
  };
448
437
 
449
438
  // check if not null or undefined
450
439
  // https://stackoverflow.com/a/27757708/1177228
451
- var notnull = function(x) {
440
+ var notnull = function (x) {
452
441
  return x != null;
453
442
  };
454
443
 
@@ -459,9 +448,9 @@
459
448
  } else if (maxLabelSize < 10) {
460
449
  maxLabelSize = 10;
461
450
  }
462
- if (!options.scales.xAxes[0].ticks.callback) {
463
- options.scales.xAxes[0].ticks.callback = function (value) {
464
- value = toStr(value);
451
+ if (!options.scales.x.ticks.callback) {
452
+ options.scales.x.ticks.callback = function (value) {
453
+ value = toStr(this.getLabelForValue(value));
465
454
  if (value.length > maxLabelSize) {
466
455
  return value.substring(0, maxLabelSize - 2) + "...";
467
456
  } else {
@@ -471,7 +460,7 @@
471
460
  }
472
461
  };
473
462
 
474
- var setFormatOptions = function(chart, options, chartType) {
463
+ var setFormatOptions$1 = function (chart, options, chartType) {
475
464
  var formatOptions = {
476
465
  prefix: chart.options.prefix,
477
466
  suffix: chart.options.suffix,
@@ -511,49 +500,49 @@
511
500
  }
512
501
 
513
502
  if (chartType !== "pie") {
514
- var myAxes = options.scales.yAxes;
503
+ var axis = options.scales.y;
515
504
  if (chartType === "bar") {
516
- myAxes = options.scales.xAxes;
505
+ axis = options.scales.x;
517
506
  }
518
507
 
519
508
  if (formatOptions.byteScale) {
520
- if (!myAxes[0].ticks.stepSize) {
521
- myAxes[0].ticks.stepSize = formatOptions.byteScale / 2;
509
+ if (!axis.ticks.stepSize) {
510
+ axis.ticks.stepSize = formatOptions.byteScale / 2;
522
511
  }
523
- if (!myAxes[0].ticks.maxTicksLimit) {
524
- myAxes[0].ticks.maxTicksLimit = 4;
512
+ if (!axis.ticks.maxTicksLimit) {
513
+ axis.ticks.maxTicksLimit = 4;
525
514
  }
526
515
  }
527
516
 
528
- if (!myAxes[0].ticks.callback) {
529
- myAxes[0].ticks.callback = function (value) {
517
+ if (!axis.ticks.callback) {
518
+ axis.ticks.callback = function (value) {
530
519
  return formatValue("", value, formatOptions, true);
531
520
  };
532
521
  }
533
522
  }
534
523
 
535
- if (!options.tooltips.callbacks.label) {
524
+ if (!options.plugins.tooltip.callbacks.label) {
536
525
  if (chartType === "scatter") {
537
- options.tooltips.callbacks.label = function (item, data) {
538
- var label = data.datasets[item.datasetIndex].label || '';
526
+ options.plugins.tooltip.callbacks.label = function (context) {
527
+ var label = context.dataset.label || '';
539
528
  if (label) {
540
529
  label += ': ';
541
530
  }
542
- return label + '(' + item.xLabel + ', ' + item.yLabel + ')';
531
+ return label + '(' + context.label + ', ' + context.formattedValue + ')';
543
532
  };
544
533
  } else if (chartType === "bubble") {
545
- options.tooltips.callbacks.label = function (item, data) {
546
- var label = data.datasets[item.datasetIndex].label || '';
534
+ options.plugins.tooltip.callbacks.label = function (context) {
535
+ var label = context.dataset.label || '';
547
536
  if (label) {
548
537
  label += ': ';
549
538
  }
550
- var dataPoint = data.datasets[item.datasetIndex].data[item.index];
551
- return label + '(' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.v + ')';
539
+ var dataPoint = context.raw;
540
+ return label + '(' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.v + ')';
552
541
  };
553
542
  } else if (chartType === "pie") {
554
543
  // need to use separate label for pie charts
555
- options.tooltips.callbacks.label = function (tooltipItem, data) {
556
- var dataLabel = data.labels[tooltipItem.index];
544
+ options.plugins.tooltip.callbacks.label = function (context) {
545
+ var dataLabel = context.label;
557
546
  var value = ': ';
558
547
 
559
548
  if (isArray(dataLabel)) {
@@ -565,24 +554,24 @@
565
554
  dataLabel += value;
566
555
  }
567
556
 
568
- return formatValue(dataLabel, data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], formatOptions);
557
+ return formatValue(dataLabel, context.parsed, formatOptions);
569
558
  };
570
559
  } else {
571
- var valueLabel = chartType === "bar" ? "xLabel" : "yLabel";
572
- options.tooltips.callbacks.label = function (tooltipItem, data) {
573
- var label = data.datasets[tooltipItem.datasetIndex].label || '';
560
+ var valueLabel = chartType === "bar" ? "x" : "y";
561
+ options.plugins.tooltip.callbacks.label = function (context) {
562
+ var label = context.dataset.label || '';
574
563
  if (label) {
575
564
  label += ': ';
576
565
  }
577
- return formatValue(label, tooltipItem[valueLabel], formatOptions);
566
+ return formatValue(label, context.parsed[valueLabel], formatOptions);
578
567
  };
579
568
  }
580
569
  }
581
570
  };
582
571
 
583
- var jsOptions = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
572
+ var jsOptions$2 = jsOptionsFunc(merge(baseOptions, defaultOptions$2), hideLegend$2, setTitle$2, setMin$2, setMax$2, setStacked$2, setXtitle$2, setYtitle$2);
584
573
 
585
- var createDataTable = function (chart, options, chartType, library) {
574
+ var createDataTable = function (chart, options, chartType) {
586
575
  var datasets = [];
587
576
  var labels = [];
588
577
 
@@ -684,11 +673,23 @@
684
673
  }
685
674
  }
686
675
 
676
+ var color;
677
+ var backgroundColor;
678
+
687
679
  for (i = 0; i < series.length; i++) {
688
680
  s = series[i];
689
681
 
690
- var color = s.color || colors[i];
691
- var backgroundColor = chartType !== "line" ? addOpacity(color, 0.5) : color;
682
+ // use colors for each bar for single series format
683
+ if (chart.options.colors && chart.singleSeriesFormat && (chartType === "bar" || chartType === "column") && !s.color) {
684
+ color = colors;
685
+ backgroundColor = [];
686
+ for (var j$3 = 0; j$3 < colors.length; j$3++) {
687
+ backgroundColor[j$3] = addOpacity(color[j$3], 0.5);
688
+ }
689
+ } else {
690
+ color = s.color || colors[i];
691
+ backgroundColor = chartType !== "line" ? addOpacity(color, 0.5) : color;
692
+ }
692
693
 
693
694
  var dataset = {
694
695
  label: s.name || "",
@@ -696,24 +697,37 @@
696
697
  fill: chartType === "area",
697
698
  borderColor: color,
698
699
  backgroundColor: backgroundColor,
699
- pointBackgroundColor: color,
700
- borderWidth: 2,
701
- pointHoverBackgroundColor: color
700
+ borderWidth: 2
702
701
  };
703
702
 
703
+ var pointChart = chartType === "line" || chartType === "area" || chartType === "scatter" || chartType === "bubble";
704
+ if (pointChart) {
705
+ dataset.pointBackgroundColor = color;
706
+ dataset.pointHoverBackgroundColor = color;
707
+ dataset.pointHitRadius = 50;
708
+ }
709
+
710
+ if (chartType === "bubble") {
711
+ dataset.pointBackgroundColor = backgroundColor;
712
+ dataset.pointHoverBackgroundColor = backgroundColor;
713
+ dataset.pointHoverBorderWidth = 2;
714
+ }
715
+
704
716
  if (s.stack) {
705
717
  dataset.stack = s.stack;
706
718
  }
707
719
 
708
720
  var curve = seriesOption(chart, s, "curve");
709
721
  if (curve === false) {
710
- dataset.lineTension = 0;
722
+ dataset.tension = 0;
723
+ } else if (pointChart) {
724
+ dataset.tension = 0.4;
711
725
  }
712
726
 
713
727
  var points = seriesOption(chart, s, "points");
714
728
  if (points === false) {
715
729
  dataset.pointRadius = 0;
716
- dataset.pointHitRadius = 5;
730
+ dataset.pointHoverRadius = 0;
717
731
  }
718
732
 
719
733
  dataset = merge(dataset, chart.options.dataset || {});
@@ -727,25 +741,37 @@
727
741
  var xmax = chart.options.xmax;
728
742
 
729
743
  if (chart.xtype === "datetime") {
730
- // hacky check for Chart.js >= 2.9.0
731
- // https://github.com/chartjs/Chart.js/compare/v2.8.0...v2.9.0
732
- var gte29 = "math" in library.helpers;
733
- var ticksKey = gte29 ? "ticks" : "time";
734
744
  if (notnull(xmin)) {
735
- options.scales.xAxes[0][ticksKey].min = toDate(xmin).getTime();
745
+ options.scales.x.ticks.min = toDate(xmin).getTime();
736
746
  }
737
747
  if (notnull(xmax)) {
738
- options.scales.xAxes[0][ticksKey].max = toDate(xmax).getTime();
748
+ options.scales.x.ticks.max = toDate(xmax).getTime();
739
749
  }
740
750
  } else if (chart.xtype === "number") {
741
751
  if (notnull(xmin)) {
742
- options.scales.xAxes[0].ticks.min = xmin;
752
+ options.scales.x.ticks.min = xmin;
743
753
  }
744
754
  if (notnull(xmax)) {
745
- options.scales.xAxes[0].ticks.max = xmax;
755
+ options.scales.x.ticks.max = xmax;
746
756
  }
747
757
  }
748
758
 
759
+ // for empty datetime chart
760
+ if (chart.xtype === "datetime" && labels.length === 0) {
761
+ if (notnull(xmin)) {
762
+ labels.push(toDate(xmin));
763
+ }
764
+ if (notnull(xmax)) {
765
+ labels.push(toDate(xmax));
766
+ }
767
+ day = false;
768
+ week = false;
769
+ month = false;
770
+ year = false;
771
+ hour = false;
772
+ minute = false;
773
+ }
774
+
749
775
  if (chart.xtype === "datetime" && labels.length > 0) {
750
776
  var minTime = (notnull(xmin) ? toDate(xmin) : labels[0]).getTime();
751
777
  var maxTime = (notnull(xmax) ? toDate(xmax) : labels[0]).getTime();
@@ -762,24 +788,24 @@
762
788
 
763
789
  var timeDiff = (maxTime - minTime) / (86400 * 1000.0);
764
790
 
765
- if (!options.scales.xAxes[0].time.unit) {
791
+ if (!options.scales.x.time.unit) {
766
792
  var step;
767
793
  if (year || timeDiff > 365 * 10) {
768
- options.scales.xAxes[0].time.unit = "year";
794
+ options.scales.x.time.unit = "year";
769
795
  step = 365;
770
796
  } else if (month || timeDiff > 30 * 10) {
771
- options.scales.xAxes[0].time.unit = "month";
797
+ options.scales.x.time.unit = "month";
772
798
  step = 30;
773
799
  } else if (day || timeDiff > 10) {
774
- options.scales.xAxes[0].time.unit = "day";
800
+ options.scales.x.time.unit = "day";
775
801
  step = 1;
776
802
  } else if (hour || timeDiff > 0.5) {
777
- options.scales.xAxes[0].time.displayFormats = {hour: "MMM D, h a"};
778
- options.scales.xAxes[0].time.unit = "hour";
803
+ options.scales.x.time.displayFormats = {hour: "MMM d, h a"};
804
+ options.scales.x.time.unit = "hour";
779
805
  step = 1 / 24.0;
780
806
  } else if (minute) {
781
- options.scales.xAxes[0].time.displayFormats = {minute: "h:mm a"};
782
- options.scales.xAxes[0].time.unit = "minute";
807
+ options.scales.x.time.displayFormats = {minute: "h:mm a"};
808
+ options.scales.x.time.unit = "minute";
783
809
  step = 1 / 24.0 / 60.0;
784
810
  }
785
811
 
@@ -788,17 +814,17 @@
788
814
  if (week && step === 1) {
789
815
  unitStepSize = Math.ceil(unitStepSize / 7.0) * 7;
790
816
  }
791
- options.scales.xAxes[0].time.unitStepSize = unitStepSize;
817
+ options.scales.x.time.stepSize = unitStepSize;
792
818
  }
793
819
  }
794
820
 
795
- if (!options.scales.xAxes[0].time.tooltipFormat) {
821
+ if (!options.scales.x.time.tooltipFormat) {
796
822
  if (day) {
797
- options.scales.xAxes[0].time.tooltipFormat = "ll";
823
+ options.scales.x.time.tooltipFormat = "PP";
798
824
  } else if (hour) {
799
- options.scales.xAxes[0].time.tooltipFormat = "MMM D, h a";
825
+ options.scales.x.time.tooltipFormat = "MMM d, h a";
800
826
  } else if (minute) {
801
- options.scales.xAxes[0].time.tooltipFormat = "h:mm a";
827
+ options.scales.x.time.tooltipFormat = "h:mm a";
802
828
  }
803
829
  }
804
830
  }
@@ -811,49 +837,49 @@
811
837
  return data;
812
838
  };
813
839
 
814
- var defaultExport = function defaultExport(library) {
840
+ var defaultExport$2 = function defaultExport(library) {
815
841
  this.name = "chartjs";
816
842
  this.library = library;
817
843
  };
818
844
 
819
- defaultExport.prototype.renderLineChart = function renderLineChart (chart, chartType) {
845
+ defaultExport$2.prototype.renderLineChart = function renderLineChart (chart, chartType) {
820
846
  var chartOptions = {};
821
847
  // fix for https://github.com/chartjs/Chart.js/issues/2441
822
848
  if (!chart.options.max && allZeros(chart.data)) {
823
849
  chartOptions.max = 1;
824
850
  }
825
851
 
826
- var options = jsOptions(chart, merge(chartOptions, chart.options));
827
- setFormatOptions(chart, options, chartType);
852
+ var options = jsOptions$2(chart, merge(chartOptions, chart.options));
853
+ setFormatOptions$1(chart, options, chartType);
828
854
 
829
- var data = createDataTable(chart, options, chartType || "line", this.library);
855
+ var data = createDataTable(chart, options, chartType || "line");
830
856
 
831
857
  if (chart.xtype === "number") {
832
- options.scales.xAxes[0].type = "linear";
833
- options.scales.xAxes[0].position = "bottom";
858
+ options.scales.x.type = "linear";
859
+ options.scales.x.position = "bottom";
834
860
  } else {
835
- options.scales.xAxes[0].type = chart.xtype === "string" ? "category" : "time";
861
+ options.scales.x.type = chart.xtype === "string" ? "category" : "time";
836
862
  }
837
863
 
838
864
  this.drawChart(chart, "line", data, options);
839
865
  };
840
866
 
841
- defaultExport.prototype.renderPieChart = function renderPieChart (chart) {
867
+ defaultExport$2.prototype.renderPieChart = function renderPieChart (chart) {
842
868
  var options = merge({}, baseOptions);
843
869
  if (chart.options.donut) {
844
- options.cutoutPercentage = 50;
870
+ options.cutout = "50%";
845
871
  }
846
872
 
847
873
  if ("legend" in chart.options) {
848
- hideLegend(options, chart.options.legend);
874
+ hideLegend$2(options, chart.options.legend);
849
875
  }
850
876
 
851
877
  if (chart.options.title) {
852
- setTitle(options, chart.options.title);
878
+ setTitle$2(options, chart.options.title);
853
879
  }
854
880
 
855
881
  options = merge(options, chart.options.library || {});
856
- setFormatOptions(chart, options, "pie");
882
+ setFormatOptions$1(chart, options, "pie");
857
883
 
858
884
  var labels = [];
859
885
  var values = [];
@@ -877,61 +903,73 @@
877
903
  this.drawChart(chart, "pie", data, options);
878
904
  };
879
905
 
880
- defaultExport.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
906
+ defaultExport$2.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
881
907
  var options;
882
908
  if (chartType === "bar") {
883
- var barOptions = merge(baseOptions, defaultOptions);
884
- delete barOptions.scales.yAxes[0].ticks.maxTicksLimit;
885
- options = jsOptionsFunc(barOptions, hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options);
909
+ var barOptions = merge(baseOptions, defaultOptions$2);
910
+ barOptions.indexAxis = "y";
911
+
912
+ // ensure gridlines have proper orientation
913
+ barOptions.scales.x.grid.drawOnChartArea = true;
914
+ barOptions.scales.y.grid.drawOnChartArea = false;
915
+ delete barOptions.scales.y.ticks.maxTicksLimit;
916
+
917
+ options = jsOptionsFunc(barOptions, hideLegend$2, setTitle$2, setBarMin$1, setBarMax$1, setStacked$2, setXtitle$2, setYtitle$2)(chart, chart.options);
886
918
  } else {
887
- options = jsOptions(chart, chart.options);
919
+ options = jsOptions$2(chart, chart.options);
888
920
  }
889
- setFormatOptions(chart, options, chartType);
890
- var data = createDataTable(chart, options, "column", this.library);
921
+ setFormatOptions$1(chart, options, chartType);
922
+ var data = createDataTable(chart, options, "column");
891
923
  if (chartType !== "bar") {
892
924
  setLabelSize(chart, data, options);
893
925
  }
894
- this.drawChart(chart, (chartType === "bar" ? "horizontalBar" : "bar"), data, options);
926
+ this.drawChart(chart, "bar", data, options);
895
927
  };
896
928
 
897
- defaultExport.prototype.renderAreaChart = function renderAreaChart (chart) {
929
+ defaultExport$2.prototype.renderAreaChart = function renderAreaChart (chart) {
898
930
  this.renderLineChart(chart, "area");
899
931
  };
900
932
 
901
- defaultExport.prototype.renderBarChart = function renderBarChart (chart) {
933
+ defaultExport$2.prototype.renderBarChart = function renderBarChart (chart) {
902
934
  this.renderColumnChart(chart, "bar");
903
935
  };
904
936
 
905
- defaultExport.prototype.renderScatterChart = function renderScatterChart (chart, chartType) {
937
+ defaultExport$2.prototype.renderScatterChart = function renderScatterChart (chart, chartType) {
906
938
  chartType = chartType || "scatter";
907
939
 
908
- var options = jsOptions(chart, chart.options);
909
- setFormatOptions(chart, options, chartType);
940
+ var options = jsOptions$2(chart, chart.options);
941
+ setFormatOptions$1(chart, options, chartType);
910
942
 
911
- if (!("showLines" in options)) {
912
- options.showLines = false;
943
+ if (!("showLine" in options)) {
944
+ options.showLine = false;
913
945
  }
914
946
 
915
- var data = createDataTable(chart, options, chartType, this.library);
947
+ var data = createDataTable(chart, options, chartType);
948
+
949
+ options.scales.x.type = "linear";
950
+ options.scales.x.position = "bottom";
916
951
 
917
- options.scales.xAxes[0].type = "linear";
918
- options.scales.xAxes[0].position = "bottom";
952
+ // prevent grouping hover and tooltips
953
+ if (!("mode" in options.interaction)) {
954
+ options.interaction.mode = "nearest";
955
+ }
919
956
 
920
957
  this.drawChart(chart, chartType, data, options);
921
958
  };
922
959
 
923
- defaultExport.prototype.renderBubbleChart = function renderBubbleChart (chart) {
960
+ defaultExport$2.prototype.renderBubbleChart = function renderBubbleChart (chart) {
924
961
  this.renderScatterChart(chart, "bubble");
925
962
  };
926
963
 
927
- defaultExport.prototype.destroy = function destroy (chart) {
964
+ defaultExport$2.prototype.destroy = function destroy (chart) {
928
965
  if (chart.chart) {
929
966
  chart.chart.destroy();
930
967
  }
931
968
  };
932
969
 
933
- defaultExport.prototype.drawChart = function drawChart (chart, type, data, options) {
970
+ defaultExport$2.prototype.drawChart = function drawChart (chart, type, data, options) {
934
971
  this.destroy(chart);
972
+ if (chart.destroyed) { return; }
935
973
 
936
974
  var chartOptions = {
937
975
  type: type,
@@ -990,6 +1028,9 @@
990
1028
  series: {
991
1029
  marker: {}
992
1030
  }
1031
+ },
1032
+ time: {
1033
+ useUTC: false
993
1034
  }
994
1035
  };
995
1036
 
@@ -1039,7 +1080,7 @@
1039
1080
 
1040
1081
  var jsOptions$1 = jsOptionsFunc(defaultOptions$1, hideLegend$1, setTitle$1, setMin$1, setMax$1, setStacked$1, setXtitle$1, setYtitle$1);
1041
1082
 
1042
- var setFormatOptions$1 = function(chart, options, chartType) {
1083
+ var setFormatOptions = function(chart, options, chartType) {
1043
1084
  var formatOptions = {
1044
1085
  prefix: chart.options.prefix,
1045
1086
  suffix: chart.options.suffix,
@@ -1102,7 +1143,7 @@
1102
1143
  if (!options.chart.type) {
1103
1144
  options.chart.type = chartType;
1104
1145
  }
1105
- setFormatOptions$1(chart, options, chartType);
1146
+ setFormatOptions(chart, options, chartType);
1106
1147
 
1107
1148
  var series = chart.data;
1108
1149
  for (i = 0; i < series.length; i++) {
@@ -1147,7 +1188,7 @@
1147
1188
  }
1148
1189
 
1149
1190
  var options = merge(chartOptions, chart.options.library || {});
1150
- setFormatOptions$1(chart, options, "pie");
1191
+ setFormatOptions(chart, options, "pie");
1151
1192
  var series = [{
1152
1193
  type: "pie",
1153
1194
  name: chart.options.label || "Value",
@@ -1162,7 +1203,7 @@
1162
1203
  var series = chart.data;
1163
1204
  var options = jsOptions$1(chart, chart.options), i, j, s, d, rows = [], categories = [];
1164
1205
  options.chart.type = chartType;
1165
- setFormatOptions$1(chart, options, chartType);
1206
+ setFormatOptions(chart, options, chartType);
1166
1207
 
1167
1208
  for (i = 0; i < series.length; i++) {
1168
1209
  s = series[i];
@@ -1220,6 +1261,7 @@
1220
1261
 
1221
1262
  defaultExport$1.prototype.drawChart = function drawChart (chart, data, options) {
1222
1263
  this.destroy(chart);
1264
+ if (chart.destroyed) { return; }
1223
1265
 
1224
1266
  options.chart.renderTo = chart.element.id;
1225
1267
  options.series = data;
@@ -1235,7 +1277,7 @@
1235
1277
  var callbacks = [];
1236
1278
 
1237
1279
  // Set chart options
1238
- var defaultOptions$2 = {
1280
+ var defaultOptions = {
1239
1281
  chartArea: {},
1240
1282
  fontName: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",
1241
1283
  pointSize: 6,
@@ -1277,7 +1319,7 @@
1277
1319
  }
1278
1320
  };
1279
1321
 
1280
- var hideLegend$2 = function (options, legend, hideLegend) {
1322
+ var hideLegend = function (options, legend, hideLegend) {
1281
1323
  if (legend !== undefined) {
1282
1324
  var position;
1283
1325
  if (!legend) {
@@ -1293,42 +1335,42 @@
1293
1335
  }
1294
1336
  };
1295
1337
 
1296
- var setTitle$2 = function (options, title) {
1338
+ var setTitle = function (options, title) {
1297
1339
  options.title = title;
1298
1340
  options.titleTextStyle = {color: "#333", fontSize: "20px"};
1299
1341
  };
1300
1342
 
1301
- var setMin$2 = function (options, min) {
1343
+ var setMin = function (options, min) {
1302
1344
  options.vAxis.viewWindow.min = min;
1303
1345
  };
1304
1346
 
1305
- var setMax$2 = function (options, max) {
1347
+ var setMax = function (options, max) {
1306
1348
  options.vAxis.viewWindow.max = max;
1307
1349
  };
1308
1350
 
1309
- var setBarMin$1 = function (options, min) {
1351
+ var setBarMin = function (options, min) {
1310
1352
  options.hAxis.viewWindow.min = min;
1311
1353
  };
1312
1354
 
1313
- var setBarMax$1 = function (options, max) {
1355
+ var setBarMax = function (options, max) {
1314
1356
  options.hAxis.viewWindow.max = max;
1315
1357
  };
1316
1358
 
1317
- var setStacked$2 = function (options, stacked) {
1359
+ var setStacked = function (options, stacked) {
1318
1360
  options.isStacked = stacked ? stacked : false;
1319
1361
  };
1320
1362
 
1321
- var setXtitle$2 = function (options, title) {
1363
+ var setXtitle = function (options, title) {
1322
1364
  options.hAxis.title = title;
1323
1365
  options.hAxis.titleTextStyle.italic = false;
1324
1366
  };
1325
1367
 
1326
- var setYtitle$2 = function (options, title) {
1368
+ var setYtitle = function (options, title) {
1327
1369
  options.vAxis.title = title;
1328
1370
  options.vAxis.titleTextStyle.italic = false;
1329
1371
  };
1330
1372
 
1331
- var jsOptions$2 = jsOptionsFunc(defaultOptions$2, hideLegend$2, setTitle$2, setMin$2, setMax$2, setStacked$2, setXtitle$2, setYtitle$2);
1373
+ var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
1332
1374
 
1333
1375
  var resize = function (callback) {
1334
1376
  if (window.attachEvent) {
@@ -1339,12 +1381,12 @@
1339
1381
  callback();
1340
1382
  };
1341
1383
 
1342
- var defaultExport$2 = function defaultExport(library) {
1384
+ var defaultExport = function defaultExport(library) {
1343
1385
  this.name = "google";
1344
1386
  this.library = library;
1345
1387
  };
1346
1388
 
1347
- defaultExport$2.prototype.renderLineChart = function renderLineChart (chart) {
1389
+ defaultExport.prototype.renderLineChart = function renderLineChart (chart) {
1348
1390
  var this$1 = this;
1349
1391
 
1350
1392
  this.waitForLoaded(chart, function () {
@@ -1358,14 +1400,14 @@
1358
1400
  chartOptions.pointSize = 0;
1359
1401
  }
1360
1402
 
1361
- var options = jsOptions$2(chart, chart.options, chartOptions);
1403
+ var options = jsOptions(chart, chart.options, chartOptions);
1362
1404
  var data = this$1.createDataTable(chart.data, chart.xtype);
1363
1405
 
1364
1406
  this$1.drawChart(chart, "LineChart", data, options);
1365
1407
  });
1366
1408
  };
1367
1409
 
1368
- defaultExport$2.prototype.renderPieChart = function renderPieChart (chart) {
1410
+ defaultExport.prototype.renderPieChart = function renderPieChart (chart) {
1369
1411
  var this$1 = this;
1370
1412
 
1371
1413
  this.waitForLoaded(chart, function () {
@@ -1383,12 +1425,12 @@
1383
1425
  chartOptions.pieHole = 0.5;
1384
1426
  }
1385
1427
  if ("legend" in chart.options) {
1386
- hideLegend$2(chartOptions, chart.options.legend);
1428
+ hideLegend(chartOptions, chart.options.legend);
1387
1429
  }
1388
1430
  if (chart.options.title) {
1389
- setTitle$2(chartOptions, chart.options.title);
1431
+ setTitle(chartOptions, chart.options.title);
1390
1432
  }
1391
- var options = merge(merge(defaultOptions$2, chartOptions), chart.options.library || {});
1433
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
1392
1434
 
1393
1435
  var data = new this$1.library.visualization.DataTable();
1394
1436
  data.addColumn("string", "");
@@ -1399,18 +1441,18 @@
1399
1441
  });
1400
1442
  };
1401
1443
 
1402
- defaultExport$2.prototype.renderColumnChart = function renderColumnChart (chart) {
1444
+ defaultExport.prototype.renderColumnChart = function renderColumnChart (chart) {
1403
1445
  var this$1 = this;
1404
1446
 
1405
1447
  this.waitForLoaded(chart, function () {
1406
- var options = jsOptions$2(chart, chart.options);
1448
+ var options = jsOptions(chart, chart.options);
1407
1449
  var data = this$1.createDataTable(chart.data, chart.xtype);
1408
1450
 
1409
1451
  this$1.drawChart(chart, "ColumnChart", data, options);
1410
1452
  });
1411
1453
  };
1412
1454
 
1413
- defaultExport$2.prototype.renderBarChart = function renderBarChart (chart) {
1455
+ defaultExport.prototype.renderBarChart = function renderBarChart (chart) {
1414
1456
  var this$1 = this;
1415
1457
 
1416
1458
  this.waitForLoaded(chart, function () {
@@ -1421,14 +1463,14 @@
1421
1463
  }
1422
1464
  }
1423
1465
  };
1424
- var options = jsOptionsFunc(defaultOptions$2, hideLegend$2, setTitle$2, setBarMin$1, setBarMax$1, setStacked$2, setXtitle$2, setYtitle$2)(chart, chart.options, chartOptions);
1466
+ var options = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options, chartOptions);
1425
1467
  var data = this$1.createDataTable(chart.data, chart.xtype);
1426
1468
 
1427
1469
  this$1.drawChart(chart, "BarChart", data, options);
1428
1470
  });
1429
1471
  };
1430
1472
 
1431
- defaultExport$2.prototype.renderAreaChart = function renderAreaChart (chart) {
1473
+ defaultExport.prototype.renderAreaChart = function renderAreaChart (chart) {
1432
1474
  var this$1 = this;
1433
1475
 
1434
1476
  this.waitForLoaded(chart, function () {
@@ -1438,24 +1480,24 @@
1438
1480
  areaOpacity: 0.5
1439
1481
  };
1440
1482
 
1441
- var options = jsOptions$2(chart, chart.options, chartOptions);
1483
+ var options = jsOptions(chart, chart.options, chartOptions);
1442
1484
  var data = this$1.createDataTable(chart.data, chart.xtype);
1443
1485
 
1444
1486
  this$1.drawChart(chart, "AreaChart", data, options);
1445
1487
  });
1446
1488
  };
1447
1489
 
1448
- defaultExport$2.prototype.renderGeoChart = function renderGeoChart (chart) {
1490
+ defaultExport.prototype.renderGeoChart = function renderGeoChart (chart) {
1449
1491
  var this$1 = this;
1450
1492
 
1451
- this.waitForLoaded(chart, function () {
1493
+ this.waitForLoaded(chart, "geochart", function () {
1452
1494
  var chartOptions = {
1453
1495
  legend: "none",
1454
1496
  colorAxis: {
1455
1497
  colors: chart.options.colors || ["#f6c7b6", "#ce502d"]
1456
1498
  }
1457
1499
  };
1458
- var options = merge(merge(defaultOptions$2, chartOptions), chart.options.library || {});
1500
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
1459
1501
 
1460
1502
  var data = new this$1.library.visualization.DataTable();
1461
1503
  data.addColumn("string", "");
@@ -1466,12 +1508,12 @@
1466
1508
  });
1467
1509
  };
1468
1510
 
1469
- defaultExport$2.prototype.renderScatterChart = function renderScatterChart (chart) {
1511
+ defaultExport.prototype.renderScatterChart = function renderScatterChart (chart) {
1470
1512
  var this$1 = this;
1471
1513
 
1472
1514
  this.waitForLoaded(chart, function () {
1473
1515
  var chartOptions = {};
1474
- var options = jsOptions$2(chart, chart.options, chartOptions);
1516
+ var options = jsOptions(chart, chart.options, chartOptions);
1475
1517
 
1476
1518
  var series = chart.data, rows2 = [], i, j, data, d;
1477
1519
  for (i = 0; i < series.length; i++) {
@@ -1496,7 +1538,7 @@
1496
1538
  });
1497
1539
  };
1498
1540
 
1499
- defaultExport$2.prototype.renderTimeline = function renderTimeline (chart) {
1541
+ defaultExport.prototype.renderTimeline = function renderTimeline (chart) {
1500
1542
  var this$1 = this;
1501
1543
 
1502
1544
  this.waitForLoaded(chart, "timeline", function () {
@@ -1507,7 +1549,7 @@
1507
1549
  if (chart.options.colors) {
1508
1550
  chartOptions.colors = chart.options.colors;
1509
1551
  }
1510
- var options = merge(merge(defaultOptions$2, chartOptions), chart.options.library || {});
1552
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
1511
1553
 
1512
1554
  var data = new this$1.library.visualization.DataTable();
1513
1555
  data.addColumn({type: "string", id: "Name"});
@@ -1521,14 +1563,16 @@
1521
1563
  });
1522
1564
  };
1523
1565
 
1524
- defaultExport$2.prototype.destroy = function destroy (chart) {
1566
+ // TODO remove resize events
1567
+ defaultExport.prototype.destroy = function destroy (chart) {
1525
1568
  if (chart.chart) {
1526
1569
  chart.chart.clearChart();
1527
1570
  }
1528
1571
  };
1529
1572
 
1530
- defaultExport$2.prototype.drawChart = function drawChart (chart, type, data, options) {
1573
+ defaultExport.prototype.drawChart = function drawChart (chart, type, data, options) {
1531
1574
  this.destroy(chart);
1575
+ if (chart.destroyed) { return; }
1532
1576
 
1533
1577
  if (chart.options.code) {
1534
1578
  window.console.log("var data = new google.visualization.DataTable(" + data.toJSON() + ");\nvar chart = new google.visualization." + type + "(element);\nchart.draw(data, " + JSON.stringify(options) + ");");
@@ -1540,7 +1584,7 @@
1540
1584
  });
1541
1585
  };
1542
1586
 
1543
- defaultExport$2.prototype.waitForLoaded = function waitForLoaded (chart, pack, callback) {
1587
+ defaultExport.prototype.waitForLoaded = function waitForLoaded (chart, pack, callback) {
1544
1588
  var this$1 = this;
1545
1589
 
1546
1590
  if (!callback) {
@@ -1564,7 +1608,7 @@
1564
1608
  if (config.language) {
1565
1609
  loadOptions.language = config.language;
1566
1610
  }
1567
- if (pack === "corechart" && config.mapsApiKey) {
1611
+ if (pack === "geochart" && config.mapsApiKey) {
1568
1612
  loadOptions.mapsApiKey = config.mapsApiKey;
1569
1613
  }
1570
1614
 
@@ -1572,11 +1616,11 @@
1572
1616
  }
1573
1617
  };
1574
1618
 
1575
- defaultExport$2.prototype.runCallbacks = function runCallbacks () {
1619
+ defaultExport.prototype.runCallbacks = function runCallbacks () {
1576
1620
  var cb, call;
1577
1621
  for (var i = 0; i < callbacks.length; i++) {
1578
1622
  cb = callbacks[i];
1579
- call = this.library.visualization && ((cb.pack === "corechart" && this.library.visualization.LineChart) || (cb.pack === "timeline" && this.library.visualization.Timeline));
1623
+ 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));
1580
1624
  if (call) {
1581
1625
  cb.callback();
1582
1626
  callbacks.splice(i, 1);
@@ -1586,7 +1630,7 @@
1586
1630
  };
1587
1631
 
1588
1632
  // cant use object as key
1589
- defaultExport$2.prototype.createDataTable = function createDataTable (series, columnType) {
1633
+ defaultExport.prototype.createDataTable = function createDataTable (series, columnType) {
1590
1634
  var i, j, s, d, key, rows = [], sortedLabels = [];
1591
1635
  for (i = 0; i < series.length; i++) {
1592
1636
  s = series[i];
@@ -1730,7 +1774,12 @@
1730
1774
  }
1731
1775
  }
1732
1776
 
1733
- function fetchDataSource(chart, dataSource) {
1777
+ function fetchDataSource(chart, dataSource, showLoading) {
1778
+ // only show loading message for urls and callbacks
1779
+ if (showLoading && chart.options.loading && (typeof dataSource === "string" || typeof dataSource === "function")) {
1780
+ setText(chart.element, chart.options.loading);
1781
+ }
1782
+
1734
1783
  if (typeof dataSource === "string") {
1735
1784
  pushRequest(dataSource, function (data) {
1736
1785
  chart.rawData = data;
@@ -1840,9 +1889,9 @@
1840
1889
  if (library.product === "Highcharts") {
1841
1890
  return defaultExport$1;
1842
1891
  } else if (library.charts) {
1843
- return defaultExport$2;
1844
- } else if (isFunction(library)) {
1845
1892
  return defaultExport;
1893
+ } else if (isFunction(library)) {
1894
+ return defaultExport$2;
1846
1895
  }
1847
1896
  }
1848
1897
  throw new Error("Unknown adapter");
@@ -1885,8 +1934,9 @@
1885
1934
  }
1886
1935
 
1887
1936
  function renderChart(chartType, chart) {
1888
- if (chart.options.messages && chart.options.messages.empty && dataEmpty(chart.data, chartType)) {
1889
- setText(chart.element, chart.options.messages.empty);
1937
+ if (dataEmpty(chart.data, chartType)) {
1938
+ var message = chart.options.empty || (chart.options.messages && chart.options.messages.empty) || "No data";
1939
+ setText(chart.element, message);
1890
1940
  } else {
1891
1941
  callAdapter(chartType, chart);
1892
1942
  if (chart.options.download && !chart.__downloadAttached && chart.adapter === "chartjs") {
@@ -1951,8 +2001,14 @@
1951
2001
  return r;
1952
2002
  };
1953
2003
 
1954
- function detectXType(series, noDatetime) {
1955
- if (detectXTypeWithFunction(series, isNumber)) {
2004
+ function detectXType(series, noDatetime, options) {
2005
+ if (dataEmpty(series)) {
2006
+ if ((options.xmin || options.xmax) && (!options.xmin || isDate(options.xmin)) && (!options.xmax || isDate(options.xmax))) {
2007
+ return "datetime";
2008
+ } else {
2009
+ return "number";
2010
+ }
2011
+ } else if (detectXTypeWithFunction(series, isNumber)) {
1956
2012
  return "number";
1957
2013
  } else if (!noDatetime && detectXTypeWithFunction(series, isDate)) {
1958
2014
  return "datetime";
@@ -1999,17 +2055,23 @@
1999
2055
  // see if one series or multiple
2000
2056
  if (!isArray(series) || typeof series[0] !== "object" || isArray(series[0])) {
2001
2057
  series = [{name: opts.label, data: series}];
2002
- chart.hideLegend = true;
2058
+ chart.singleSeriesFormat = true;
2003
2059
  } else {
2004
- chart.hideLegend = false;
2060
+ chart.singleSeriesFormat = false;
2005
2061
  }
2006
2062
 
2007
- chart.xtype = keyType ? keyType : (opts.discrete ? "string" : detectXType(series, noDatetime));
2063
+ // convert to array
2064
+ // must come before dataEmpty check
2065
+ series = copySeries(series);
2066
+ for (i = 0; i < series.length; i++) {
2067
+ series[i].data = toArr(series[i].data);
2068
+ }
2069
+
2070
+ chart.xtype = keyType ? keyType : (opts.discrete ? "string" : detectXType(series, noDatetime, opts));
2008
2071
 
2009
2072
  // right format
2010
- series = copySeries(series);
2011
2073
  for (i = 0; i < series.length; i++) {
2012
- series[i].data = formatSeriesData(toArr(series[i].data), chart.xtype);
2074
+ series[i].data = formatSeriesData(series[i].data, chart.xtype);
2013
2075
  }
2014
2076
 
2015
2077
  return series;
@@ -2040,7 +2102,7 @@
2040
2102
 
2041
2103
  Chartkick.charts[element.id] = this;
2042
2104
 
2043
- fetchDataSource(this, dataSource);
2105
+ fetchDataSource(this, dataSource, true);
2044
2106
 
2045
2107
  if (this.options.refresh) {
2046
2108
  this.startRefresh();
@@ -2076,7 +2138,7 @@
2076
2138
  if (options) {
2077
2139
  this.__updateOptions(options);
2078
2140
  }
2079
- fetchDataSource(this, dataSource);
2141
+ fetchDataSource(this, dataSource, true);
2080
2142
  };
2081
2143
 
2082
2144
  Chart.prototype.setOptions = function setOptions (options) {
@@ -2151,6 +2213,9 @@
2151
2213
  };
2152
2214
 
2153
2215
  Chart.prototype.destroy = function destroy () {
2216
+ this.destroyed = true;
2217
+ this.stopRefresh();
2218
+
2154
2219
  if (this.__adapterObject) {
2155
2220
  this.__adapterObject.destroy(this);
2156
2221
  }
@@ -2395,6 +2460,14 @@
2395
2460
  }
2396
2461
  }
2397
2462
  },
2463
+ destroyAll: function() {
2464
+ for (var chartId in Chartkick.charts) {
2465
+ if (Chartkick.charts.hasOwnProperty(chartId)) {
2466
+ Chartkick.charts[chartId].destroy();
2467
+ delete Chartkick.charts[chartId];
2468
+ }
2469
+ }
2470
+ },
2398
2471
  config: config,
2399
2472
  options: {},
2400
2473
  adapters: adapters,
@@ -2408,6 +2481,16 @@
2408
2481
  // not ideal, but allows for simpler integration
2409
2482
  if (typeof window !== "undefined" && !window.Chartkick) {
2410
2483
  window.Chartkick = Chartkick;
2484
+
2485
+ // clean up previous charts before Turbolinks loads new page
2486
+ document.addEventListener("turbolinks:before-render", function() {
2487
+ Chartkick.destroyAll();
2488
+ });
2489
+
2490
+ // use setTimeout so charting library can come later in same JS file
2491
+ setTimeout(function() {
2492
+ window.dispatchEvent(new Event("chartkick:load"));
2493
+ }, 0);
2411
2494
  }
2412
2495
 
2413
2496
  // backwards compatibility for esm require