chartkick 3.3.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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