chartkick 2.3.5 → 3.4.2

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.
@@ -2,14 +2,14 @@
2
2
  * Chartkick.js
3
3
  * Create beautiful charts with one line of JavaScript
4
4
  * https://github.com/ankane/chartkick.js
5
- * v2.3.6
5
+ * v3.2.1
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.Chartkick = factory());
12
+ (global = global || self, global.Chartkick = factory());
13
13
  }(this, (function () { 'use strict';
14
14
 
15
15
  function isArray(variable) {
@@ -21,13 +21,17 @@
21
21
  }
22
22
 
23
23
  function isPlainObject(variable) {
24
- return !isFunction(variable) && variable instanceof Object;
24
+ // protect against prototype pollution, defense 2
25
+ return Object.prototype.toString.call(variable) === "[object Object]" && !isFunction(variable) && variable instanceof Object;
25
26
  }
26
27
 
27
28
  // https://github.com/madrobby/zepto/blob/master/src/zepto.js
28
29
  function extend(target, source) {
29
30
  var key;
30
31
  for (key in source) {
32
+ // protect against prototype pollution, defense 1
33
+ if (key === "__proto__") { continue; }
34
+
31
35
  if (isPlainObject(source[key]) || isArray(source[key])) {
32
36
  if (isPlainObject(source[key]) && !isPlainObject(target[key])) {
33
37
  target[key] = {};
@@ -233,7 +237,13 @@
233
237
  return !isNaN(toDate(obj)) && toStr(obj).length >= 6;
234
238
  }
235
239
 
236
- function formatValue(pre, value, options) {
240
+ function isNumber(obj) {
241
+ return typeof obj === "number";
242
+ }
243
+
244
+ var byteSuffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB"];
245
+
246
+ function formatValue(pre, value, options, axis) {
237
247
  pre = pre || "";
238
248
  if (options.prefix) {
239
249
  if (value < 0) {
@@ -243,6 +253,74 @@
243
253
  pre += options.prefix;
244
254
  }
245
255
 
256
+ var suffix = options.suffix || "";
257
+ var precision = options.precision;
258
+ var round = options.round;
259
+
260
+ if (options.byteScale) {
261
+ var suffixIdx;
262
+ var baseValue = axis ? options.byteScale : value;
263
+
264
+ if (baseValue >= 1152921504606846976) {
265
+ value /= 1152921504606846976;
266
+ suffixIdx = 6;
267
+ } else if (baseValue >= 1125899906842624) {
268
+ value /= 1125899906842624;
269
+ suffixIdx = 5;
270
+ } else if (baseValue >= 1099511627776) {
271
+ value /= 1099511627776;
272
+ suffixIdx = 4;
273
+ } else if (baseValue >= 1073741824) {
274
+ value /= 1073741824;
275
+ suffixIdx = 3;
276
+ } else if (baseValue >= 1048576) {
277
+ value /= 1048576;
278
+ suffixIdx = 2;
279
+ } else if (baseValue >= 1024) {
280
+ value /= 1024;
281
+ suffixIdx = 1;
282
+ } else {
283
+ suffixIdx = 0;
284
+ }
285
+
286
+ // TODO handle manual precision case
287
+ if (precision === undefined && round === undefined) {
288
+ if (value >= 1023.5) {
289
+ if (suffixIdx < byteSuffixes.length - 1) {
290
+ value = 1.0;
291
+ suffixIdx += 1;
292
+ }
293
+ }
294
+ precision = value >= 1000 ? 4 : 3;
295
+ }
296
+ suffix = " " + byteSuffixes[suffixIdx];
297
+ }
298
+
299
+ if (precision !== undefined && round !== undefined) {
300
+ throw Error("Use either round or precision, not both");
301
+ }
302
+
303
+ if (!axis) {
304
+ if (precision !== undefined) {
305
+ value = value.toPrecision(precision);
306
+ if (!options.zeros) {
307
+ value = parseFloat(value);
308
+ }
309
+ }
310
+
311
+ if (round !== undefined) {
312
+ if (round < 0) {
313
+ var num = Math.pow(10, -1 * round);
314
+ value = parseInt((1.0 * value / num).toFixed(0)) * num;
315
+ } else {
316
+ value = value.toFixed(round);
317
+ if (!options.zeros) {
318
+ value = parseFloat(value);
319
+ }
320
+ }
321
+ }
322
+ }
323
+
246
324
  if (options.thousands || options.decimal) {
247
325
  value = toStr(value);
248
326
  var parts = value.split(".");
@@ -255,7 +333,16 @@
255
333
  }
256
334
  }
257
335
 
258
- return pre + value + (options.suffix || "");
336
+ return pre + value + suffix;
337
+ }
338
+
339
+ function seriesOption(chart, series, option) {
340
+ if (option in series) {
341
+ return series[option];
342
+ } else if (option in chart.options) {
343
+ return chart.options[option];
344
+ }
345
+ return null;
259
346
  }
260
347
 
261
348
  function allZeros(data) {
@@ -371,25 +458,35 @@
371
458
  options.scales.yAxes[0].scaleLabel.labelString = title;
372
459
  };
373
460
 
374
- // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
461
+ // https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
375
462
  var addOpacity = function(hex, opacity) {
376
463
  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
377
464
  return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
378
465
  };
379
466
 
467
+ // check if not null or undefined
468
+ // https://stackoverflow.com/a/27757708/1177228
469
+ var notnull = function(x) {
470
+ return x != null;
471
+ };
472
+
380
473
  var setLabelSize = function (chart, data, options) {
381
474
  var maxLabelSize = Math.ceil(chart.element.offsetWidth / 4.0 / data.labels.length);
382
475
  if (maxLabelSize > 25) {
383
476
  maxLabelSize = 25;
477
+ } else if (maxLabelSize < 10) {
478
+ maxLabelSize = 10;
479
+ }
480
+ if (!options.scales.xAxes[0].ticks.callback) {
481
+ options.scales.xAxes[0].ticks.callback = function (value) {
482
+ value = toStr(value);
483
+ if (value.length > maxLabelSize) {
484
+ return value.substring(0, maxLabelSize - 2) + "...";
485
+ } else {
486
+ return value;
487
+ }
488
+ };
384
489
  }
385
- options.scales.xAxes[0].ticks.callback = function (value) {
386
- value = toStr(value);
387
- if (value.length > maxLabelSize) {
388
- return value.substring(0, maxLabelSize - 2) + "...";
389
- } else {
390
- return value;
391
- }
392
- };
393
490
  };
394
491
 
395
492
  var setFormatOptions = function(chart, options, chartType) {
@@ -397,58 +494,113 @@
397
494
  prefix: chart.options.prefix,
398
495
  suffix: chart.options.suffix,
399
496
  thousands: chart.options.thousands,
400
- decimal: chart.options.decimal
497
+ decimal: chart.options.decimal,
498
+ precision: chart.options.precision,
499
+ round: chart.options.round,
500
+ zeros: chart.options.zeros
401
501
  };
402
502
 
403
- if (formatOptions.prefix || formatOptions.suffix || formatOptions.thousands || formatOptions.decimal) {
404
- if (chartType !== "pie") {
405
- var myAxes = options.scales.yAxes;
406
- if (chartType === "bar") {
407
- myAxes = options.scales.xAxes;
408
- }
503
+ if (chart.options.bytes) {
504
+ var series = chart.data;
505
+ if (chartType === "pie") {
506
+ series = [{data: series}];
507
+ }
409
508
 
410
- if (!myAxes[0].ticks.callback) {
411
- myAxes[0].ticks.callback = function (value) {
412
- return formatValue("", value, formatOptions);
413
- };
509
+ // calculate max
510
+ var max = 0;
511
+ for (var i = 0; i < series.length; i++) {
512
+ var s = series[i];
513
+ for (var j = 0; j < s.data.length; j++) {
514
+ if (s.data[j][1] > max) {
515
+ max = s.data[j][1];
516
+ }
414
517
  }
415
518
  }
416
519
 
417
- if (!options.tooltips.callbacks.label) {
418
- if (chartType !== "pie") {
419
- var valueLabel = chartType === "bar" ? "xLabel" : "yLabel";
420
- options.tooltips.callbacks.label = function (tooltipItem, data) {
421
- var label = data.datasets[tooltipItem.datasetIndex].label || '';
422
- if (label) {
423
- label += ': ';
424
- }
425
- return formatValue(label, tooltipItem[valueLabel], formatOptions);
426
- };
427
- } else {
428
- // need to use separate label for pie charts
429
- options.tooltips.callbacks.label = function (tooltipItem, data) {
430
- var dataLabel = data.labels[tooltipItem.index];
431
- var value = ': ';
432
-
433
- if (isArray(dataLabel)) {
434
- // show value on first line of multiline label
435
- // need to clone because we are changing the value
436
- dataLabel = dataLabel.slice();
437
- dataLabel[0] += value;
438
- } else {
439
- dataLabel += value;
440
- }
520
+ // calculate scale
521
+ var scale = 1;
522
+ while (max >= 1024) {
523
+ scale *= 1024;
524
+ max /= 1024;
525
+ }
441
526
 
442
- return formatValue(dataLabel, data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], formatOptions);
443
- };
527
+ // set step size
528
+ formatOptions.byteScale = scale;
529
+ }
530
+
531
+ if (chartType !== "pie") {
532
+ var myAxes = options.scales.yAxes;
533
+ if (chartType === "bar") {
534
+ myAxes = options.scales.xAxes;
535
+ }
536
+
537
+ if (formatOptions.byteScale) {
538
+ if (!myAxes[0].ticks.stepSize) {
539
+ myAxes[0].ticks.stepSize = formatOptions.byteScale / 2;
540
+ }
541
+ if (!myAxes[0].ticks.maxTicksLimit) {
542
+ myAxes[0].ticks.maxTicksLimit = 4;
444
543
  }
445
544
  }
545
+
546
+ if (!myAxes[0].ticks.callback) {
547
+ myAxes[0].ticks.callback = function (value) {
548
+ return formatValue("", value, formatOptions, true);
549
+ };
550
+ }
551
+ }
552
+
553
+ if (!options.tooltips.callbacks.label) {
554
+ if (chartType === "scatter") {
555
+ options.tooltips.callbacks.label = function (item, data) {
556
+ var label = data.datasets[item.datasetIndex].label || '';
557
+ if (label) {
558
+ label += ': ';
559
+ }
560
+ return label + '(' + item.xLabel + ', ' + item.yLabel + ')';
561
+ };
562
+ } else if (chartType === "bubble") {
563
+ options.tooltips.callbacks.label = function (item, data) {
564
+ var label = data.datasets[item.datasetIndex].label || '';
565
+ if (label) {
566
+ label += ': ';
567
+ }
568
+ var dataPoint = data.datasets[item.datasetIndex].data[item.index];
569
+ return label + '(' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.v + ')';
570
+ };
571
+ } else if (chartType === "pie") {
572
+ // need to use separate label for pie charts
573
+ options.tooltips.callbacks.label = function (tooltipItem, data) {
574
+ var dataLabel = data.labels[tooltipItem.index];
575
+ var value = ': ';
576
+
577
+ if (isArray(dataLabel)) {
578
+ // show value on first line of multiline label
579
+ // need to clone because we are changing the value
580
+ dataLabel = dataLabel.slice();
581
+ dataLabel[0] += value;
582
+ } else {
583
+ dataLabel += value;
584
+ }
585
+
586
+ return formatValue(dataLabel, data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], formatOptions);
587
+ };
588
+ } else {
589
+ var valueLabel = chartType === "bar" ? "xLabel" : "yLabel";
590
+ options.tooltips.callbacks.label = function (tooltipItem, data) {
591
+ var label = data.datasets[tooltipItem.datasetIndex].label || '';
592
+ if (label) {
593
+ label += ': ';
594
+ }
595
+ return formatValue(label, tooltipItem[valueLabel], formatOptions);
596
+ };
597
+ }
446
598
  }
447
599
  };
448
600
 
449
601
  var jsOptions = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
450
602
 
451
- var createDataTable = function (chart, options, chartType) {
603
+ var createDataTable = function (chart, options, chartType, library) {
452
604
  var datasets = [];
453
605
  var labels = [];
454
606
 
@@ -461,61 +613,92 @@
461
613
  var year = true;
462
614
  var hour = true;
463
615
  var minute = true;
464
- var detectType = (chartType === "line" || chartType === "area") && !chart.discrete;
465
616
 
466
617
  var series = chart.data;
467
618
 
468
- var sortedLabels = [];
469
-
470
- var i, j, s, d, key, rows = [];
471
- for (i = 0; i < series.length; i++) {
472
- s = series[i];
473
-
474
- for (j = 0; j < s.data.length; j++) {
475
- d = s.data[j];
476
- key = detectType ? d[0].getTime() : d[0];
477
- if (!rows[key]) {
478
- rows[key] = new Array(series.length);
479
- }
480
- rows[key][i] = toFloat(d[1]);
481
- if (sortedLabels.indexOf(key) === -1) {
482
- sortedLabels.push(key);
619
+ var max = 0;
620
+ if (chartType === "bubble") {
621
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
622
+ var s$1 = series[i$1];
623
+ for (var j$1 = 0; j$1 < s$1.data.length; j$1++) {
624
+ if (s$1.data[j$1][2] > max) {
625
+ max = s$1.data[j$1][2];
626
+ }
483
627
  }
484
628
  }
485
629
  }
486
630
 
487
- if (detectType || chart.options.xtype === "number") {
488
- sortedLabels.sort(sortByNumber);
489
- }
631
+ var i, j, s, d, key, rows = [], rows2 = [];
490
632
 
491
- var rows2 = [];
492
- for (j = 0; j < series.length; j++) {
493
- rows2.push([]);
494
- }
633
+ if (chartType === "bar" || chartType === "column" || (chart.xtype !== "number" && chart.xtype !== "bubble")) {
634
+ var sortedLabels = [];
495
635
 
496
- var value;
497
- var k;
498
- for (k = 0; k < sortedLabels.length; k++) {
499
- i = sortedLabels[k];
500
- if (detectType) {
501
- value = new Date(toFloat(i));
502
- // TODO make this efficient
503
- day = day && isDay(value);
504
- if (!dayOfWeek) {
505
- dayOfWeek = value.getDay();
636
+ for (i = 0; i < series.length; i++) {
637
+ s = series[i];
638
+
639
+ for (j = 0; j < s.data.length; j++) {
640
+ d = s.data[j];
641
+ key = chart.xtype == "datetime" ? d[0].getTime() : d[0];
642
+ if (!rows[key]) {
643
+ rows[key] = new Array(series.length);
644
+ }
645
+ rows[key][i] = toFloat(d[1]);
646
+ if (sortedLabels.indexOf(key) === -1) {
647
+ sortedLabels.push(key);
648
+ }
506
649
  }
507
- week = week && isWeek(value, dayOfWeek);
508
- month = month && isMonth(value);
509
- year = year && isYear(value);
510
- hour = hour && isHour(value);
511
- minute = minute && isMinute(value);
512
- } else {
513
- value = i;
514
650
  }
515
- labels.push(value);
651
+
652
+ if (chart.xtype === "datetime" || chart.xtype === "number") {
653
+ sortedLabels.sort(sortByNumber);
654
+ }
655
+
516
656
  for (j = 0; j < series.length; j++) {
517
- // Chart.js doesn't like undefined
518
- rows2[j].push(rows[i][j] === undefined ? null : rows[i][j]);
657
+ rows2.push([]);
658
+ }
659
+
660
+ var value;
661
+ var k;
662
+ for (k = 0; k < sortedLabels.length; k++) {
663
+ i = sortedLabels[k];
664
+ if (chart.xtype === "datetime") {
665
+ value = new Date(toFloat(i));
666
+ // TODO make this efficient
667
+ day = day && isDay(value);
668
+ if (!dayOfWeek) {
669
+ dayOfWeek = value.getDay();
670
+ }
671
+ week = week && isWeek(value, dayOfWeek);
672
+ month = month && isMonth(value);
673
+ year = year && isYear(value);
674
+ hour = hour && isHour(value);
675
+ minute = minute && isMinute(value);
676
+ } else {
677
+ value = i;
678
+ }
679
+ labels.push(value);
680
+ for (j = 0; j < series.length; j++) {
681
+ // Chart.js doesn't like undefined
682
+ rows2[j].push(rows[i][j] === undefined ? null : rows[i][j]);
683
+ }
684
+ }
685
+ } else {
686
+ for (var i$2 = 0; i$2 < series.length; i$2++) {
687
+ var s$2 = series[i$2];
688
+ var d$1 = [];
689
+ for (var j$2 = 0; j$2 < s$2.data.length; j$2++) {
690
+ var point = {
691
+ x: toFloat(s$2.data[j$2][0]),
692
+ y: toFloat(s$2.data[j$2][1])
693
+ };
694
+ if (chartType === "bubble") {
695
+ point.r = toFloat(s$2.data[j$2][2]) * 20 / max;
696
+ // custom attribute, for tooltip
697
+ point.v = s$2.data[j$2][2];
698
+ }
699
+ d$1.push(point);
700
+ }
701
+ rows2.push(d$1);
519
702
  }
520
703
  }
521
704
 
@@ -526,25 +709,27 @@
526
709
  var backgroundColor = chartType !== "line" ? addOpacity(color, 0.5) : color;
527
710
 
528
711
  var dataset = {
529
- label: s.name,
712
+ label: s.name || "",
530
713
  data: rows2[i],
531
714
  fill: chartType === "area",
532
715
  borderColor: color,
533
716
  backgroundColor: backgroundColor,
534
717
  pointBackgroundColor: color,
535
- pointHoverBackgroundColor: color,
536
- borderWidth: 2
718
+ borderWidth: 2,
719
+ pointHoverBackgroundColor: color
537
720
  };
538
721
 
539
722
  if (s.stack) {
540
723
  dataset.stack = s.stack;
541
724
  }
542
725
 
543
- if (chart.options.curve === false) {
726
+ var curve = seriesOption(chart, s, "curve");
727
+ if (curve === false) {
544
728
  dataset.lineTension = 0;
545
729
  }
546
730
 
547
- if (chart.options.points === false) {
731
+ var points = seriesOption(chart, s, "points");
732
+ if (points === false) {
548
733
  dataset.pointRadius = 0;
549
734
  dataset.pointHitRadius = 5;
550
735
  }
@@ -556,16 +741,56 @@
556
741
  datasets.push(dataset);
557
742
  }
558
743
 
559
- if (detectType && labels.length > 0) {
560
- var minTime = labels[0].getTime();
561
- var maxTime = labels[0].getTime();
744
+ var xmin = chart.options.xmin;
745
+ var xmax = chart.options.xmax;
746
+
747
+ if (chart.xtype === "datetime") {
748
+ // hacky check for Chart.js >= 2.9.0
749
+ // https://github.com/chartjs/Chart.js/compare/v2.8.0...v2.9.0
750
+ var gte29 = "math" in library.helpers;
751
+ var ticksKey = gte29 ? "ticks" : "time";
752
+ if (notnull(xmin)) {
753
+ options.scales.xAxes[0][ticksKey].min = toDate(xmin).getTime();
754
+ }
755
+ if (notnull(xmax)) {
756
+ options.scales.xAxes[0][ticksKey].max = toDate(xmax).getTime();
757
+ }
758
+ } else if (chart.xtype === "number") {
759
+ if (notnull(xmin)) {
760
+ options.scales.xAxes[0].ticks.min = xmin;
761
+ }
762
+ if (notnull(xmax)) {
763
+ options.scales.xAxes[0].ticks.max = xmax;
764
+ }
765
+ }
766
+
767
+ // for empty datetime chart
768
+ if (chart.xtype === "datetime" && labels.length === 0) {
769
+ if (notnull(xmin)) {
770
+ labels.push(toDate(xmin));
771
+ }
772
+ if (notnull(xmax)) {
773
+ labels.push(toDate(xmax));
774
+ }
775
+ day = false;
776
+ week = false;
777
+ month = false;
778
+ year = false;
779
+ hour = false;
780
+ minute = false;
781
+ }
782
+
783
+ if (chart.xtype === "datetime" && labels.length > 0) {
784
+ var minTime = (notnull(xmin) ? toDate(xmin) : labels[0]).getTime();
785
+ var maxTime = (notnull(xmax) ? toDate(xmax) : labels[0]).getTime();
786
+
562
787
  for (i = 1; i < labels.length; i++) {
563
- value = labels[i].getTime();
564
- if (value < minTime) {
565
- minTime = value;
788
+ var value$1 = labels[i].getTime();
789
+ if (value$1 < minTime) {
790
+ minTime = value$1;
566
791
  }
567
- if (value > maxTime) {
568
- maxTime = value;
792
+ if (value$1 > maxTime) {
793
+ maxTime = value$1;
569
794
  }
570
795
  }
571
796
 
@@ -626,10 +851,6 @@
626
851
  };
627
852
 
628
853
  defaultExport.prototype.renderLineChart = function renderLineChart (chart, chartType) {
629
- if (chart.options.xtype === "number") {
630
- return this.renderScatterChart(chart, chartType, true);
631
- }
632
-
633
854
  var chartOptions = {};
634
855
  // fix for https://github.com/chartjs/Chart.js/issues/2441
635
856
  if (!chart.options.max && allZeros(chart.data)) {
@@ -639,9 +860,14 @@
639
860
  var options = jsOptions(chart, merge(chartOptions, chart.options));
640
861
  setFormatOptions(chart, options, chartType);
641
862
 
642
- var data = createDataTable(chart, options, chartType || "line");
863
+ var data = createDataTable(chart, options, chartType || "line", this.library);
643
864
 
644
- options.scales.xAxes[0].type = chart.discrete ? "category" : "time";
865
+ if (chart.xtype === "number") {
866
+ options.scales.xAxes[0].type = "linear";
867
+ options.scales.xAxes[0].position = "bottom";
868
+ } else {
869
+ options.scales.xAxes[0].type = chart.xtype === "string" ? "category" : "time";
870
+ }
645
871
 
646
872
  this.drawChart(chart, "line", data, options);
647
873
  };
@@ -688,12 +914,14 @@
688
914
  defaultExport.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
689
915
  var options;
690
916
  if (chartType === "bar") {
691
- options = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options);
917
+ var barOptions = merge(baseOptions, defaultOptions);
918
+ delete barOptions.scales.yAxes[0].ticks.maxTicksLimit;
919
+ options = jsOptionsFunc(barOptions, hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options);
692
920
  } else {
693
921
  options = jsOptions(chart, chart.options);
694
922
  }
695
923
  setFormatOptions(chart, options, chartType);
696
- var data = createDataTable(chart, options, "column");
924
+ var data = createDataTable(chart, options, "column", this.library);
697
925
  if (chartType !== "bar") {
698
926
  setLabelSize(chart, data, options);
699
927
  }
@@ -708,51 +936,17 @@
708
936
  this.renderColumnChart(chart, "bar");
709
937
  };
710
938
 
711
- defaultExport.prototype.renderScatterChart = function renderScatterChart (chart, chartType, lineChart) {
712
- chartType = chartType || "line";
939
+ defaultExport.prototype.renderScatterChart = function renderScatterChart (chart, chartType) {
940
+ chartType = chartType || "scatter";
713
941
 
714
942
  var options = jsOptions(chart, chart.options);
715
- if (!lineChart) {
716
- setFormatOptions(chart, options, chartType);
717
- }
718
-
719
- var colors = chart.options.colors || defaultColors;
720
-
721
- var datasets = [];
722
- var series = chart.data;
723
- for (var i = 0; i < series.length; i++) {
724
- var s = series[i];
725
- var d = [];
726
- for (var j = 0; j < s.data.length; j++) {
727
- var point = {
728
- x: toFloat(s.data[j][0]),
729
- y: toFloat(s.data[j][1])
730
- };
731
- if (chartType === "bubble") {
732
- point.r = toFloat(s.data[j][2]);
733
- }
734
- d.push(point);
735
- }
736
-
737
- var color = s.color || colors[i];
738
- var backgroundColor = chartType === "area" ? addOpacity(color, 0.5) : color;
739
-
740
- datasets.push({
741
- label: s.name,
742
- showLine: lineChart || false,
743
- data: d,
744
- borderColor: color,
745
- backgroundColor: backgroundColor,
746
- pointBackgroundColor: color,
747
- fill: chartType === "area"
748
- });
749
- }
943
+ setFormatOptions(chart, options, chartType);
750
944
 
751
- if (chartType === "area") {
752
- chartType = "line";
945
+ if (!("showLines" in options)) {
946
+ options.showLines = false;
753
947
  }
754
948
 
755
- var data = {datasets: datasets};
949
+ var data = createDataTable(chart, options, chartType, this.library);
756
950
 
757
951
  options.scales.xAxes[0].type = "linear";
758
952
  options.scales.xAxes[0].position = "bottom";
@@ -773,13 +967,19 @@
773
967
  defaultExport.prototype.drawChart = function drawChart (chart, type, data, options) {
774
968
  this.destroy(chart);
775
969
 
776
- chart.element.innerHTML = "<canvas></canvas>";
777
- var ctx = chart.element.getElementsByTagName("CANVAS")[0];
778
- chart.chart = new this.library(ctx, {
970
+ var chartOptions = {
779
971
  type: type,
780
972
  data: data,
781
973
  options: options
782
- });
974
+ };
975
+
976
+ if (chart.options.code) {
977
+ window.console.log("new Chart(ctx, " + JSON.stringify(chartOptions) + ");");
978
+ }
979
+
980
+ chart.element.innerHTML = "<canvas></canvas>";
981
+ var ctx = chart.element.getElementsByTagName("CANVAS")[0];
982
+ chart.chart = new this.library(ctx, chartOptions);
783
983
  };
784
984
 
785
985
  var defaultOptions$1 = {
@@ -820,6 +1020,7 @@
820
1020
  },
821
1021
  plotOptions: {
822
1022
  areaspline: {},
1023
+ area: {},
823
1024
  series: {
824
1025
  marker: {}
825
1026
  }
@@ -856,7 +1057,10 @@
856
1057
  };
857
1058
 
858
1059
  var setStacked$1 = function (options, stacked) {
859
- options.plotOptions.series.stacking = stacked ? (stacked === true ? "normal" : stacked) : null;
1060
+ var stackedValue = stacked ? (stacked === true ? "normal" : stacked) : null;
1061
+ options.plotOptions.series.stacking = stackedValue;
1062
+ options.plotOptions.area.stacking = stackedValue;
1063
+ options.plotOptions.areaspline.stacking = stackedValue;
860
1064
  };
861
1065
 
862
1066
  var setXtitle$1 = function (options, title) {
@@ -874,21 +1078,22 @@
874
1078
  prefix: chart.options.prefix,
875
1079
  suffix: chart.options.suffix,
876
1080
  thousands: chart.options.thousands,
877
- decimal: chart.options.decimal
1081
+ decimal: chart.options.decimal,
1082
+ precision: chart.options.precision,
1083
+ round: chart.options.round,
1084
+ zeros: chart.options.zeros
878
1085
  };
879
1086
 
880
- if (formatOptions.prefix || formatOptions.suffix || formatOptions.thousands || formatOptions.decimal) {
881
- if (chartType !== "pie" && !options.yAxis.labels.formatter) {
882
- options.yAxis.labels.formatter = function () {
883
- return formatValue("", this.value, formatOptions);
884
- };
885
- }
1087
+ if (chartType !== "pie" && !options.yAxis.labels.formatter) {
1088
+ options.yAxis.labels.formatter = function () {
1089
+ return formatValue("", this.value, formatOptions);
1090
+ };
1091
+ }
886
1092
 
887
- if (!options.tooltip.pointFormatter) {
888
- options.tooltip.pointFormatter = function () {
889
- return '<span style="color:' + this.color + '>\u25CF</span> ' + formatValue(this.series.name + ': <b>', this.y, formatOptions) + '</b><br/>';
890
- };
891
- }
1093
+ if (!options.tooltip.pointFormatter) {
1094
+ options.tooltip.pointFormatter = function () {
1095
+ return '<span style="color:' + this.color + '">\u25CF</span> ' + formatValue(this.series.name + ': <b>', this.y, formatOptions) + '</b><br/>';
1096
+ };
892
1097
  }
893
1098
  };
894
1099
 
@@ -927,7 +1132,7 @@
927
1132
  }
928
1133
 
929
1134
  var options = jsOptions$1(chart, chart.options, chartOptions), data, i, j;
930
- options.xAxis.type = chart.discrete ? "category" : "datetime";
1135
+ options.xAxis.type = chart.xtype === "string" ? "category" : (chart.xtype === "number" ? "linear" : "datetime");
931
1136
  if (!options.chart.type) {
932
1137
  options.chart.type = chartType;
933
1138
  }
@@ -935,8 +1140,9 @@
935
1140
 
936
1141
  var series = chart.data;
937
1142
  for (i = 0; i < series.length; i++) {
1143
+ series[i].name = series[i].name || "Value";
938
1144
  data = series[i].data;
939
- if (!chart.discrete) {
1145
+ if (chart.xtype === "datetime") {
940
1146
  for (j = 0; j < data.length; j++) {
941
1147
  data[j][0] = data[j][0].getTime();
942
1148
  }
@@ -1005,7 +1211,7 @@
1005
1211
  }
1006
1212
  }
1007
1213
 
1008
- if (chart.options.xtype === "number") {
1214
+ if (chart.xtype === "number") {
1009
1215
  categories.sort(sortByNumber);
1010
1216
  }
1011
1217
 
@@ -1019,7 +1225,7 @@
1019
1225
  }
1020
1226
 
1021
1227
  d2 = {
1022
- name: series[i].name,
1228
+ name: series[i].name || "Value",
1023
1229
  data: d
1024
1230
  };
1025
1231
  if (series[i].stack) {
@@ -1051,6 +1257,11 @@
1051
1257
 
1052
1258
  options.chart.renderTo = chart.element.id;
1053
1259
  options.series = data;
1260
+
1261
+ if (chart.options.code) {
1262
+ window.console.log("new Highcharts.Chart(" + JSON.stringify(options) + ");");
1263
+ }
1264
+
1054
1265
  chart.chart = new this.library.Chart(options);
1055
1266
  };
1056
1267
 
@@ -1182,13 +1393,9 @@
1182
1393
  }
1183
1394
 
1184
1395
  var options = jsOptions$2(chart, chart.options, chartOptions);
1185
- var columnType = chart.discrete ? "string" : "datetime";
1186
- if (chart.options.xtype === "number") {
1187
- columnType = "number";
1188
- }
1189
- var data = this$1.createDataTable(chart.data, columnType);
1396
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1190
1397
 
1191
- this$1.drawChart(chart, this$1.library.visualization.LineChart, data, options);
1398
+ this$1.drawChart(chart, "LineChart", data, options);
1192
1399
  });
1193
1400
  };
1194
1401
 
@@ -1222,7 +1429,7 @@
1222
1429
  data.addColumn("number", "Value");
1223
1430
  data.addRows(chart.data);
1224
1431
 
1225
- this$1.drawChart(chart, this$1.library.visualization.PieChart, data, options);
1432
+ this$1.drawChart(chart, "PieChart", data, options);
1226
1433
  });
1227
1434
  };
1228
1435
 
@@ -1231,9 +1438,9 @@
1231
1438
 
1232
1439
  this.waitForLoaded(chart, function () {
1233
1440
  var options = jsOptions$2(chart, chart.options);
1234
- var data = this$1.createDataTable(chart.data, "string", chart.options.xtype);
1441
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1235
1442
 
1236
- this$1.drawChart(chart, this$1.library.visualization.ColumnChart, data, options);
1443
+ this$1.drawChart(chart, "ColumnChart", data, options);
1237
1444
  });
1238
1445
  };
1239
1446
 
@@ -1249,9 +1456,9 @@
1249
1456
  }
1250
1457
  };
1251
1458
  var options = jsOptionsFunc(defaultOptions$2, hideLegend$2, setTitle$2, setBarMin$1, setBarMax$1, setStacked$2, setXtitle$2, setYtitle$2)(chart, chart.options, chartOptions);
1252
- var data = this$1.createDataTable(chart.data, "string", chart.options.xtype);
1459
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1253
1460
 
1254
- this$1.drawChart(chart, this$1.library.visualization.BarChart, data, options);
1461
+ this$1.drawChart(chart, "BarChart", data, options);
1255
1462
  });
1256
1463
  };
1257
1464
 
@@ -1266,20 +1473,16 @@
1266
1473
  };
1267
1474
 
1268
1475
  var options = jsOptions$2(chart, chart.options, chartOptions);
1269
- var columnType = chart.discrete ? "string" : "datetime";
1270
- if (chart.options.xtype === "number") {
1271
- columnType = "number";
1272
- }
1273
- var data = this$1.createDataTable(chart.data, columnType);
1476
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1274
1477
 
1275
- this$1.drawChart(chart, this$1.library.visualization.AreaChart, data, options);
1478
+ this$1.drawChart(chart, "AreaChart", data, options);
1276
1479
  });
1277
1480
  };
1278
1481
 
1279
1482
  defaultExport$2.prototype.renderGeoChart = function renderGeoChart (chart) {
1280
1483
  var this$1 = this;
1281
1484
 
1282
- this.waitForLoaded(chart, function () {
1485
+ this.waitForLoaded(chart, "geochart", function () {
1283
1486
  var chartOptions = {
1284
1487
  legend: "none",
1285
1488
  colorAxis: {
@@ -1293,7 +1496,7 @@
1293
1496
  data.addColumn("number", chart.options.label || "Value");
1294
1497
  data.addRows(chart.data);
1295
1498
 
1296
- this$1.drawChart(chart, this$1.library.visualization.GeoChart, data, options);
1499
+ this$1.drawChart(chart, "GeoChart", data, options);
1297
1500
  });
1298
1501
  };
1299
1502
 
@@ -1306,6 +1509,7 @@
1306
1509
 
1307
1510
  var series = chart.data, rows2 = [], i, j, data, d;
1308
1511
  for (i = 0; i < series.length; i++) {
1512
+ series[i].name = series[i].name || "Value";
1309
1513
  d = series[i].data;
1310
1514
  for (j = 0; j < d.length; j++) {
1311
1515
  var row = new Array(series.length + 1);
@@ -1322,7 +1526,7 @@
1322
1526
  }
1323
1527
  data.addRows(rows2);
1324
1528
 
1325
- this$1.drawChart(chart, this$1.library.visualization.ScatterChart, data, options);
1529
+ this$1.drawChart(chart, "ScatterChart", data, options);
1326
1530
  });
1327
1531
  };
1328
1532
 
@@ -1347,7 +1551,7 @@
1347
1551
 
1348
1552
  chart.element.style.lineHeight = "normal";
1349
1553
 
1350
- this$1.drawChart(chart, this$1.library.visualization.Timeline, data, options);
1554
+ this$1.drawChart(chart, "Timeline", data, options);
1351
1555
  });
1352
1556
  };
1353
1557
 
@@ -1360,7 +1564,11 @@
1360
1564
  defaultExport$2.prototype.drawChart = function drawChart (chart, type, data, options) {
1361
1565
  this.destroy(chart);
1362
1566
 
1363
- chart.chart = new type(chart.element);
1567
+ if (chart.options.code) {
1568
+ window.console.log("var data = new google.visualization.DataTable(" + data.toJSON() + ");\nvar chart = new google.visualization." + type + "(element);\nchart.draw(data, " + JSON.stringify(options) + ");");
1569
+ }
1570
+
1571
+ chart.chart = new this.library.visualization[type](chart.element);
1364
1572
  resize(function () {
1365
1573
  chart.chart.draw(data, options);
1366
1574
  });
@@ -1390,25 +1598,19 @@
1390
1598
  if (config.language) {
1391
1599
  loadOptions.language = config.language;
1392
1600
  }
1393
- if (pack === "corechart" && config.mapsApiKey) {
1601
+ if (pack === "geochart" && config.mapsApiKey) {
1394
1602
  loadOptions.mapsApiKey = config.mapsApiKey;
1395
1603
  }
1396
1604
 
1397
- if (this.library.setOnLoadCallback) {
1398
- this.library.load("visualization", "1", loadOptions);
1399
- } else {
1400
- this.library.charts.load("current", loadOptions);
1401
- }
1605
+ this.library.charts.load("current", loadOptions);
1402
1606
  }
1403
1607
  };
1404
1608
 
1405
1609
  defaultExport$2.prototype.runCallbacks = function runCallbacks () {
1406
- var this$1 = this;
1407
-
1408
1610
  var cb, call;
1409
1611
  for (var i = 0; i < callbacks.length; i++) {
1410
1612
  cb = callbacks[i];
1411
- call = this$1.library.visualization && ((cb.pack === "corechart" && this$1.library.visualization.LineChart) || (cb.pack === "timeline" && this$1.library.visualization.Timeline));
1613
+ 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));
1412
1614
  if (call) {
1413
1615
  cb.callback();
1414
1616
  callbacks.splice(i, 1);
@@ -1418,10 +1620,11 @@
1418
1620
  };
1419
1621
 
1420
1622
  // cant use object as key
1421
- defaultExport$2.prototype.createDataTable = function createDataTable (series, columnType, xtype) {
1623
+ defaultExport$2.prototype.createDataTable = function createDataTable (series, columnType) {
1422
1624
  var i, j, s, d, key, rows = [], sortedLabels = [];
1423
1625
  for (i = 0; i < series.length; i++) {
1424
1626
  s = series[i];
1627
+ series[i].name = series[i].name || "Value";
1425
1628
 
1426
1629
  for (j = 0; j < s.data.length; j++) {
1427
1630
  d = s.data[j];
@@ -1453,14 +1656,12 @@
1453
1656
  rows2.sort(sortByTime);
1454
1657
  } else if (columnType === "number") {
1455
1658
  rows2.sort(sortByNumberSeries);
1456
- }
1457
-
1458
- if (xtype === "number") {
1459
- rows2.sort(sortByNumberSeries);
1460
1659
 
1461
1660
  for (i = 0; i < rows2.length; i++) {
1462
1661
  rows2[i][0] = toStr(rows2[i][0]);
1463
1662
  }
1663
+
1664
+ columnType = "string";
1464
1665
  }
1465
1666
 
1466
1667
  // create datatable
@@ -1508,7 +1709,7 @@
1508
1709
  function ajaxCall(url, success, error) {
1509
1710
  var $ = window.jQuery || window.Zepto || window.$;
1510
1711
 
1511
- if ($) {
1712
+ if ($ && $.ajax) {
1512
1713
  $.ajax({
1513
1714
  dataType: "json",
1514
1715
  url: url,
@@ -1532,7 +1733,7 @@
1532
1733
  }
1533
1734
  }
1534
1735
 
1535
- var config = (typeof window !== "undefined" && window.Chartkick) || {};
1736
+ var config = {};
1536
1737
  var adapters = [];
1537
1738
 
1538
1739
  // helpers
@@ -1545,8 +1746,12 @@
1545
1746
  }
1546
1747
  }
1547
1748
 
1548
- function chartError(element, message) {
1549
- setText(element, "Error Loading Chart: " + message);
1749
+ // TODO remove prefix for all messages
1750
+ function chartError(element, message, noPrefix) {
1751
+ if (!noPrefix) {
1752
+ message = "Error Loading Chart: " + message;
1753
+ }
1754
+ setText(element, message);
1550
1755
  element.style.color = "#ff0000";
1551
1756
  }
1552
1757
 
@@ -1567,6 +1772,17 @@
1567
1772
  }, function (message) {
1568
1773
  chartError(chart.element, message);
1569
1774
  });
1775
+ } else if (typeof dataSource === "function") {
1776
+ try {
1777
+ dataSource(function (data) {
1778
+ chart.rawData = data;
1779
+ errorCatcher(chart);
1780
+ }, function (message) {
1781
+ chartError(chart.element, message, true);
1782
+ });
1783
+ } catch (err) {
1784
+ chartError(chart.element, err, true);
1785
+ }
1570
1786
  } else {
1571
1787
  chart.rawData = dataSource;
1572
1788
  errorCatcher(chart);
@@ -1576,7 +1792,15 @@
1576
1792
  function addDownloadButton(chart) {
1577
1793
  var element = chart.element;
1578
1794
  var link = document.createElement("a");
1579
- link.download = chart.options.download === true ? "chart.png" : chart.options.download; // http://caniuse.com/download
1795
+
1796
+ var download = chart.options.download;
1797
+ if (download === true) {
1798
+ download = {};
1799
+ } else if (typeof download === "string") {
1800
+ download = {filename: download};
1801
+ }
1802
+ link.download = download.filename || "chart.png"; // https://caniuse.com/download
1803
+
1580
1804
  link.style.position = "absolute";
1581
1805
  link.style.top = "20px";
1582
1806
  link.style.right = "20px";
@@ -1599,7 +1823,7 @@
1599
1823
  var related = e.relatedTarget;
1600
1824
  // check download option again to ensure it wasn't changed
1601
1825
  if ((!related || (related !== this && !childOf(this, related))) && chart.options.download) {
1602
- link.href = chart.toImage();
1826
+ link.href = chart.toImage(download);
1603
1827
  element.appendChild(link);
1604
1828
  }
1605
1829
  });
@@ -1615,7 +1839,7 @@
1615
1839
  });
1616
1840
  }
1617
1841
 
1618
- // http://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
1842
+ // https://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
1619
1843
  function addEvent(elem, event, fn) {
1620
1844
  if (elem.addEventListener) {
1621
1845
  elem.addEventListener(event, fn, false);
@@ -1649,7 +1873,7 @@
1649
1873
  if (library) {
1650
1874
  if (library.product === "Highcharts") {
1651
1875
  return defaultExport$1;
1652
- } else if (library.setOnLoadCallback || library.charts) {
1876
+ } else if (library.charts) {
1653
1877
  return defaultExport$2;
1654
1878
  } else if (isFunction(library)) {
1655
1879
  return defaultExport;
@@ -1676,7 +1900,7 @@
1676
1900
  addAdapter(window.Highcharts);
1677
1901
  }
1678
1902
 
1679
- if (window.google && (window.google.setOnLoadCallback || window.google.charts)) {
1903
+ if (window.google && window.google.charts) {
1680
1904
  addAdapter(window.google);
1681
1905
  }
1682
1906
  }
@@ -1761,17 +1985,33 @@
1761
1985
  return r;
1762
1986
  };
1763
1987
 
1764
- function detectDiscrete(series) {
1988
+ function detectXType(series, noDatetime, options) {
1989
+ if (dataEmpty(series)) {
1990
+ if ((options.xmin || options.xmax) && (!options.xmin || isDate(options.xmin)) && (!options.xmax || isDate(options.xmax))) {
1991
+ return "datetime";
1992
+ } else {
1993
+ return "number";
1994
+ }
1995
+ } else if (detectXTypeWithFunction(series, isNumber)) {
1996
+ return "number";
1997
+ } else if (!noDatetime && detectXTypeWithFunction(series, isDate)) {
1998
+ return "datetime";
1999
+ } else {
2000
+ return "string";
2001
+ }
2002
+ }
2003
+
2004
+ function detectXTypeWithFunction(series, func) {
1765
2005
  var i, j, data;
1766
2006
  for (i = 0; i < series.length; i++) {
1767
2007
  data = toArr(series[i].data);
1768
2008
  for (j = 0; j < data.length; j++) {
1769
- if (!isDate(data[j][0])) {
1770
- return true;
2009
+ if (!func(data[j][0])) {
2010
+ return false;
1771
2011
  }
1772
2012
  }
1773
2013
  }
1774
- return false;
2014
+ return true;
1775
2015
  }
1776
2016
 
1777
2017
  // creates a shallow copy of each element of the array
@@ -1790,7 +2030,7 @@
1790
2030
  return newSeries;
1791
2031
  }
1792
2032
 
1793
- function processSeries(chart, keyType) {
2033
+ function processSeries(chart, keyType, noDatetime) {
1794
2034
  var i;
1795
2035
 
1796
2036
  var opts = chart.options;
@@ -1798,27 +2038,24 @@
1798
2038
 
1799
2039
  // see if one series or multiple
1800
2040
  if (!isArray(series) || typeof series[0] !== "object" || isArray(series[0])) {
1801
- series = [{name: opts.label || "Value", data: series}];
2041
+ series = [{name: opts.label, data: series}];
1802
2042
  chart.hideLegend = true;
1803
2043
  } else {
1804
2044
  chart.hideLegend = false;
1805
2045
  }
1806
- if ((opts.discrete === null || opts.discrete === undefined) && keyType !== "bubble" && keyType !== "number") {
1807
- chart.discrete = detectDiscrete(series);
1808
- } else {
1809
- chart.discrete = opts.discrete;
1810
- }
1811
- if (chart.discrete) {
1812
- keyType = "string";
1813
- }
1814
- if (chart.options.xtype) {
1815
- keyType = chart.options.xtype;
2046
+
2047
+ // convert to array
2048
+ // must come before dataEmpty check
2049
+ series = copySeries(series);
2050
+ for (i = 0; i < series.length; i++) {
2051
+ series[i].data = toArr(series[i].data);
1816
2052
  }
1817
2053
 
2054
+ chart.xtype = keyType ? keyType : (opts.discrete ? "string" : detectXType(series, noDatetime, opts));
2055
+
1818
2056
  // right format
1819
- series = copySeries(series);
1820
2057
  for (i = 0; i < series.length; i++) {
1821
- series[i].data = formatSeriesData(toArr(series[i].data), keyType);
2058
+ series[i].data = formatSeriesData(series[i].data, chart.xtype);
1822
2059
  }
1823
2060
 
1824
2061
  return series;
@@ -1903,6 +2140,8 @@
1903
2140
  var sep = this.dataSource.indexOf("?") === -1 ? "?" : "&";
1904
2141
  var url = this.dataSource + sep + "_=" + (new Date()).getTime();
1905
2142
  fetchDataSource(this, url);
2143
+ } else if (typeof this.dataSource === "function") {
2144
+ fetchDataSource(this, this.dataSource);
1906
2145
  }
1907
2146
  };
1908
2147
 
@@ -1911,6 +2150,10 @@
1911
2150
 
1912
2151
  var refresh = this.options.refresh;
1913
2152
 
2153
+ if (refresh && typeof this.dataSource !== "string" && typeof this.dataSource !== "function") {
2154
+ throw new Error("Data source must be a URL or callback for refresh");
2155
+ }
2156
+
1914
2157
  if (!this.intervalId) {
1915
2158
  if (refresh) {
1916
2159
  this.intervalId = setInterval( function () {
@@ -1929,10 +2172,26 @@
1929
2172
  }
1930
2173
  };
1931
2174
 
1932
- Chart.prototype.toImage = function toImage () {
2175
+ Chart.prototype.toImage = function toImage (download) {
1933
2176
  if (this.adapter === "chartjs") {
1934
- return this.chart.toBase64Image();
2177
+ if (download && download.background && download.background !== "transparent") {
2178
+ // https://stackoverflow.com/questions/30464750/chartjs-line-chart-set-background-color
2179
+ var canvas = this.chart.chart.canvas;
2180
+ var ctx = this.chart.chart.ctx;
2181
+ var tmpCanvas = document.createElement("canvas");
2182
+ var tmpCtx = tmpCanvas.getContext("2d");
2183
+ tmpCanvas.width = ctx.canvas.width;
2184
+ tmpCanvas.height = ctx.canvas.height;
2185
+ tmpCtx.fillStyle = download.background;
2186
+ tmpCtx.fillRect(0, 0, tmpCanvas.width, tmpCanvas.height);
2187
+ tmpCtx.drawImage(canvas, 0, 0);
2188
+ return tmpCanvas.toDataURL("image/png");
2189
+ } else {
2190
+ return this.chart.toBase64Image();
2191
+ }
1935
2192
  } else {
2193
+ // TODO throw error in next major version
2194
+ // throw new Error("Feature only available for Chart.js");
1936
2195
  return null;
1937
2196
  }
1938
2197
  };
@@ -1969,7 +2228,7 @@
1969
2228
  return config;
1970
2229
  };
1971
2230
 
1972
- var LineChart = (function (Chart) {
2231
+ var LineChart = /*@__PURE__*/(function (Chart) {
1973
2232
  function LineChart () {
1974
2233
  Chart.apply(this, arguments);
1975
2234
  }
@@ -1979,7 +2238,7 @@
1979
2238
  LineChart.prototype.constructor = LineChart;
1980
2239
 
1981
2240
  LineChart.prototype.__processData = function __processData () {
1982
- return processSeries(this, "datetime");
2241
+ return processSeries(this);
1983
2242
  };
1984
2243
 
1985
2244
  LineChart.prototype.__chartName = function __chartName () {
@@ -1989,7 +2248,7 @@
1989
2248
  return LineChart;
1990
2249
  }(Chart));
1991
2250
 
1992
- var PieChart = (function (Chart) {
2251
+ var PieChart = /*@__PURE__*/(function (Chart) {
1993
2252
  function PieChart () {
1994
2253
  Chart.apply(this, arguments);
1995
2254
  }
@@ -2009,7 +2268,7 @@
2009
2268
  return PieChart;
2010
2269
  }(Chart));
2011
2270
 
2012
- var ColumnChart = (function (Chart) {
2271
+ var ColumnChart = /*@__PURE__*/(function (Chart) {
2013
2272
  function ColumnChart () {
2014
2273
  Chart.apply(this, arguments);
2015
2274
  }
@@ -2019,7 +2278,7 @@
2019
2278
  ColumnChart.prototype.constructor = ColumnChart;
2020
2279
 
2021
2280
  ColumnChart.prototype.__processData = function __processData () {
2022
- return processSeries(this, "string");
2281
+ return processSeries(this, null, true);
2023
2282
  };
2024
2283
 
2025
2284
  ColumnChart.prototype.__chartName = function __chartName () {
@@ -2029,7 +2288,7 @@
2029
2288
  return ColumnChart;
2030
2289
  }(Chart));
2031
2290
 
2032
- var BarChart = (function (Chart) {
2291
+ var BarChart = /*@__PURE__*/(function (Chart) {
2033
2292
  function BarChart () {
2034
2293
  Chart.apply(this, arguments);
2035
2294
  }
@@ -2039,7 +2298,7 @@
2039
2298
  BarChart.prototype.constructor = BarChart;
2040
2299
 
2041
2300
  BarChart.prototype.__processData = function __processData () {
2042
- return processSeries(this, "string");
2301
+ return processSeries(this, null, true);
2043
2302
  };
2044
2303
 
2045
2304
  BarChart.prototype.__chartName = function __chartName () {
@@ -2049,7 +2308,7 @@
2049
2308
  return BarChart;
2050
2309
  }(Chart));
2051
2310
 
2052
- var AreaChart = (function (Chart) {
2311
+ var AreaChart = /*@__PURE__*/(function (Chart) {
2053
2312
  function AreaChart () {
2054
2313
  Chart.apply(this, arguments);
2055
2314
  }
@@ -2059,7 +2318,7 @@
2059
2318
  AreaChart.prototype.constructor = AreaChart;
2060
2319
 
2061
2320
  AreaChart.prototype.__processData = function __processData () {
2062
- return processSeries(this, "datetime");
2321
+ return processSeries(this);
2063
2322
  };
2064
2323
 
2065
2324
  AreaChart.prototype.__chartName = function __chartName () {
@@ -2069,7 +2328,7 @@
2069
2328
  return AreaChart;
2070
2329
  }(Chart));
2071
2330
 
2072
- var GeoChart = (function (Chart) {
2331
+ var GeoChart = /*@__PURE__*/(function (Chart) {
2073
2332
  function GeoChart () {
2074
2333
  Chart.apply(this, arguments);
2075
2334
  }
@@ -2089,7 +2348,7 @@
2089
2348
  return GeoChart;
2090
2349
  }(Chart));
2091
2350
 
2092
- var ScatterChart = (function (Chart) {
2351
+ var ScatterChart = /*@__PURE__*/(function (Chart) {
2093
2352
  function ScatterChart () {
2094
2353
  Chart.apply(this, arguments);
2095
2354
  }
@@ -2109,7 +2368,7 @@
2109
2368
  return ScatterChart;
2110
2369
  }(Chart));
2111
2370
 
2112
- var BubbleChart = (function (Chart) {
2371
+ var BubbleChart = /*@__PURE__*/(function (Chart) {
2113
2372
  function BubbleChart () {
2114
2373
  Chart.apply(this, arguments);
2115
2374
  }
@@ -2129,7 +2388,7 @@
2129
2388
  return BubbleChart;
2130
2389
  }(Chart));
2131
2390
 
2132
- var Timeline = (function (Chart) {
2391
+ var Timeline = /*@__PURE__*/(function (Chart) {
2133
2392
  function Timeline () {
2134
2393
  Chart.apply(this, arguments);
2135
2394
  }
@@ -2172,6 +2431,9 @@
2172
2431
  }
2173
2432
  }
2174
2433
  },
2434
+ setDefaultOptions: function (opts) {
2435
+ Chartkick.options = opts;
2436
+ },
2175
2437
  eachChart: function (callback) {
2176
2438
  for (var chartId in Chartkick.charts) {
2177
2439
  if (Chartkick.charts.hasOwnProperty(chartId)) {
@@ -2182,9 +2444,21 @@
2182
2444
  config: config,
2183
2445
  options: {},
2184
2446
  adapters: adapters,
2185
- addAdapter: addAdapter
2447
+ addAdapter: addAdapter,
2448
+ use: function(adapter) {
2449
+ addAdapter(adapter);
2450
+ return Chartkick;
2451
+ }
2186
2452
  };
2187
2453
 
2454
+ // not ideal, but allows for simpler integration
2455
+ if (typeof window !== "undefined" && !window.Chartkick) {
2456
+ window.Chartkick = Chartkick;
2457
+ }
2458
+
2459
+ // backwards compatibility for esm require
2460
+ Chartkick.default = Chartkick;
2461
+
2188
2462
  return Chartkick;
2189
2463
 
2190
2464
  })));