sql-jarvis 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -1
  3. data/LICENSE.txt +1 -1
  4. data/README.md +153 -52
  5. data/app/assets/fonts/blazer/glyphicons-halflings-regular.eot +0 -0
  6. data/app/assets/fonts/blazer/glyphicons-halflings-regular.svg +0 -0
  7. data/app/assets/fonts/blazer/glyphicons-halflings-regular.ttf +0 -0
  8. data/app/assets/fonts/blazer/glyphicons-halflings-regular.woff +0 -0
  9. data/app/assets/fonts/blazer/glyphicons-halflings-regular.woff2 +0 -0
  10. data/app/assets/images/blazer/favicon.png +0 -0
  11. data/app/assets/javascripts/blazer/Chart.js +4195 -3884
  12. data/app/assets/javascripts/blazer/Sortable.js +1493 -1097
  13. data/app/assets/javascripts/blazer/ace/ace.js +21294 -4
  14. data/app/assets/javascripts/blazer/ace/ext-language_tools.js +1991 -3
  15. data/app/assets/javascripts/blazer/ace/mode-sql.js +110 -1
  16. data/app/assets/javascripts/blazer/ace/snippets/sql.js +40 -1
  17. data/app/assets/javascripts/blazer/ace/snippets/text.js +14 -1
  18. data/app/assets/javascripts/blazer/ace/theme-twilight.js +116 -1
  19. data/app/assets/javascripts/blazer/application.js +4 -3
  20. data/app/assets/javascripts/blazer/bootstrap.js +623 -612
  21. data/app/assets/javascripts/blazer/chartkick.js +1769 -1248
  22. data/app/assets/javascripts/blazer/daterangepicker.js +263 -115
  23. data/app/assets/javascripts/blazer/highlight.min.js +3 -0
  24. data/app/assets/javascripts/blazer/{jquery_ujs.js → jquery-ujs.js} +161 -75
  25. data/app/assets/javascripts/blazer/jquery.js +9506 -9450
  26. data/app/assets/javascripts/blazer/jquery.stickytableheaders.js +321 -259
  27. data/app/assets/javascripts/blazer/moment-timezone-with-data.js +1212 -0
  28. data/app/assets/javascripts/blazer/queries.js +1 -1
  29. data/app/assets/javascripts/blazer/routes.js +3 -0
  30. data/app/assets/javascripts/blazer/selectize.js +3828 -3604
  31. data/app/assets/javascripts/blazer/stupidtable.js +255 -88
  32. data/app/assets/javascripts/blazer/vue.js +8015 -4583
  33. data/app/assets/stylesheets/blazer/application.css +41 -5
  34. data/app/assets/stylesheets/blazer/bootstrap.css.erb +879 -325
  35. data/app/assets/stylesheets/blazer/daterangepicker.css +269 -0
  36. data/app/assets/stylesheets/blazer/selectize.default.css +26 -10
  37. data/app/controllers/blazer/base_controller.rb +7 -0
  38. data/app/controllers/blazer/checks_controller.rb +1 -1
  39. data/app/controllers/blazer/dashboards_controller.rb +0 -4
  40. data/app/controllers/blazer/queries_controller.rb +20 -12
  41. data/app/helpers/blazer/base_helper.rb +1 -1
  42. data/app/mailers/blazer/slack_notifier.rb +76 -0
  43. data/app/models/blazer/check.rb +9 -0
  44. data/app/views/blazer/_nav.html.erb +0 -1
  45. data/app/views/blazer/_variables.html.erb +41 -19
  46. data/app/views/blazer/checks/_form.html.erb +16 -8
  47. data/app/views/blazer/checks/edit.html.erb +2 -0
  48. data/app/views/blazer/checks/index.html.erb +33 -4
  49. data/app/views/blazer/checks/new.html.erb +2 -0
  50. data/app/views/blazer/dashboards/_form.html.erb +4 -4
  51. data/app/views/blazer/dashboards/edit.html.erb +2 -0
  52. data/app/views/blazer/dashboards/new.html.erb +2 -0
  53. data/app/views/blazer/dashboards/show.html.erb +7 -3
  54. data/app/views/blazer/queries/_form.html.erb +11 -6
  55. data/app/views/blazer/queries/docs.html.erb +131 -0
  56. data/app/views/blazer/queries/home.html.erb +12 -3
  57. data/app/views/blazer/queries/run.html.erb +36 -6
  58. data/app/views/blazer/queries/schema.html.erb +46 -8
  59. data/app/views/blazer/queries/show.html.erb +4 -4
  60. data/app/views/layouts/blazer/application.html.erb +3 -3
  61. data/config/routes.rb +5 -1
  62. data/lib/blazer.rb +32 -13
  63. data/lib/blazer/adapters/athena_adapter.rb +1 -1
  64. data/lib/blazer/adapters/elasticsearch_adapter.rb +14 -17
  65. data/lib/blazer/adapters/mongodb_adapter.rb +1 -1
  66. data/lib/blazer/adapters/sql_adapter.rb +7 -1
  67. data/lib/blazer/engine.rb +4 -0
  68. data/lib/blazer/result.rb +62 -29
  69. data/lib/blazer/run_statement_job.rb +6 -9
  70. data/lib/blazer/version.rb +1 -1
  71. data/lib/generators/blazer/templates/config.yml.tt +13 -2
  72. data/lib/generators/blazer/templates/install.rb.tt +1 -0
  73. data/lib/tasks/blazer.rake +1 -0
  74. metadata +33 -37
  75. data/.gitattributes +0 -1
  76. data/.github/ISSUE_TEMPLATE.md +0 -7
  77. data/.gitignore +0 -14
  78. data/Gemfile +0 -7
  79. data/Rakefile +0 -1
  80. data/app/assets/javascripts/blazer/highlight.pack.js +0 -1
  81. data/app/assets/javascripts/blazer/moment-timezone.js +0 -1007
  82. data/app/assets/stylesheets/blazer/daterangepicker-bs3.css +0 -375
  83. data/blazer.gemspec +0 -30
@@ -2,22 +2,15 @@
2
2
  * Chartkick.js
3
3
  * Create beautiful charts with one line of JavaScript
4
4
  * https://github.com/ankane/chartkick.js
5
- * v2.2.1
5
+ * v3.0.1
6
6
  * MIT License
7
7
  */
8
8
 
9
- /*jslint browser: true, indent: 2, plusplus: true, vars: true */
10
-
11
- (function (window) {
12
- 'use strict';
13
-
14
- var config = window.Chartkick || {};
15
- var Chartkick, ISO8601_PATTERN, DECIMAL_SEPARATOR, adapters = [];
16
- var DATE_PATTERN = /^(\d\d\d\d)(\-)?(\d\d)(\-)?(\d\d)$/i;
17
- var GoogleChartsAdapter, HighchartsAdapter, ChartjsAdapter;
18
- var pendingRequests = [], runningRequests = 0, maxRequests = 4;
19
-
20
- // helpers
9
+ (function (global, factory) {
10
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
11
+ typeof define === 'function' && define.amd ? define(factory) :
12
+ (global.Chartkick = factory());
13
+ }(this, (function () { 'use strict';
21
14
 
22
15
  function isArray(variable) {
23
16
  return Object.prototype.toString.call(variable) === "[object Array]";
@@ -56,9 +49,11 @@
56
49
  return target;
57
50
  }
58
51
 
52
+ var DATE_PATTERN = /^(\d\d\d\d)(-)?(\d\d)(-)?(\d\d)$/i;
53
+
59
54
  // https://github.com/Do/iso8601.js
60
- ISO8601_PATTERN = /(\d\d\d\d)(\-)?(\d\d)(\-)?(\d\d)(T)?(\d\d)(:)?(\d\d)?(:)?(\d\d)?([\.,]\d+)?($|Z|([\+\-])(\d\d)(:)?(\d\d)?)/i;
61
- DECIMAL_SEPARATOR = String(1.5).charAt(1);
55
+ 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;
56
+ var DECIMAL_SEPARATOR = String(1.5).charAt(1);
62
57
 
63
58
  function parseISO8601(input) {
64
59
  var day, hour, matches, milliseconds, minutes, month, offset, result, seconds, type, year;
@@ -105,6 +100,50 @@
105
100
  return false;
106
101
  }
107
102
 
103
+ function toStr(n) {
104
+ return "" + n;
105
+ }
106
+
107
+ function toFloat(n) {
108
+ return parseFloat(n);
109
+ }
110
+
111
+ function toDate(n) {
112
+ var matches, year, month, day;
113
+ if (typeof n !== "object") {
114
+ if (typeof n === "number") {
115
+ n = new Date(n * 1000); // ms
116
+ } else {
117
+ n = toStr(n);
118
+ if ((matches = n.match(DATE_PATTERN))) {
119
+ year = parseInt(matches[1], 10);
120
+ month = parseInt(matches[3], 10) - 1;
121
+ day = parseInt(matches[5], 10);
122
+ return new Date(year, month, day);
123
+ } else { // str
124
+ // try our best to get the str into iso8601
125
+ // TODO be smarter about this
126
+ var str = n.replace(/ /, "T").replace(" ", "").replace("UTC", "Z");
127
+ n = parseISO8601(str) || new Date(n);
128
+ }
129
+ }
130
+ }
131
+ return n;
132
+ }
133
+
134
+ function toArr(n) {
135
+ if (!isArray(n)) {
136
+ var arr = [], i;
137
+ for (i in n) {
138
+ if (n.hasOwnProperty(i)) {
139
+ arr.push([i, n[i]]);
140
+ }
141
+ }
142
+ n = arr;
143
+ }
144
+ return n;
145
+ }
146
+
108
147
  function jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle) {
109
148
  return function (chart, opts, chartOptions) {
110
149
  var series = chart.data;
@@ -154,1228 +193,1538 @@
154
193
  };
155
194
  }
156
195
 
157
- function setText(element, text) {
158
- if (document.body.innerText) {
159
- element.innerText = text;
160
- } else {
161
- element.textContent = text;
162
- }
163
- }
164
-
165
- function chartError(element, message) {
166
- setText(element, "Error Loading Chart: " + message);
167
- element.style.color = "#ff0000";
168
- }
169
-
170
- function pushRequest(element, url, success) {
171
- pendingRequests.push([element, url, success]);
172
- runNext();
196
+ function sortByTime(a, b) {
197
+ return a[0].getTime() - b[0].getTime();
173
198
  }
174
199
 
175
- function runNext() {
176
- if (runningRequests < maxRequests) {
177
- var request = pendingRequests.shift()
178
- if (request) {
179
- runningRequests++;
180
- getJSON(request[0], request[1], request[2]);
181
- runNext();
182
- }
183
- }
200
+ function sortByNumberSeries(a, b) {
201
+ return a[0] - b[0];
184
202
  }
185
203
 
186
- function requestComplete() {
187
- runningRequests--;
188
- runNext();
204
+ function sortByNumber(a, b) {
205
+ return a - b;
189
206
  }
190
207
 
191
- function getJSON(element, url, success) {
192
- ajaxCall(url, success, function (jqXHR, textStatus, errorThrown) {
193
- var message = (typeof errorThrown === "string") ? errorThrown : errorThrown.message;
194
- chartError(element, message);
195
- });
208
+ function isMinute(d) {
209
+ return d.getMilliseconds() === 0 && d.getSeconds() === 0;
196
210
  }
197
211
 
198
- function ajaxCall(url, success, error) {
199
- var $ = window.jQuery || window.Zepto || window.$;
200
-
201
- if ($) {
202
- $.ajax({
203
- dataType: "json",
204
- url: url,
205
- success: success,
206
- error: error,
207
- complete: requestComplete
208
- });
209
- } else {
210
- var xhr = new XMLHttpRequest();
211
- xhr.open("GET", url, true);
212
- xhr.setRequestHeader("Content-Type", "application/json");
213
- xhr.onload = function () {
214
- requestComplete();
215
- if (xhr.status === 200) {
216
- success(JSON.parse(xhr.responseText), xhr.statusText, xhr);
217
- } else {
218
- error(xhr, "error", xhr.statusText);
219
- }
220
- };
221
- xhr.send();
222
- }
212
+ function isHour(d) {
213
+ return isMinute(d) && d.getMinutes() === 0;
223
214
  }
224
215
 
225
- function errorCatcher(chart, callback) {
226
- try {
227
- callback(chart);
228
- } catch (err) {
229
- chartError(chart.element, err.message);
230
- throw err;
231
- }
216
+ function isDay(d) {
217
+ return isHour(d) && d.getHours() === 0;
232
218
  }
233
219
 
234
- function fetchDataSource(chart, callback, dataSource) {
235
- if (typeof dataSource === "string") {
236
- pushRequest(chart.element, dataSource, function (data, textStatus, jqXHR) {
237
- chart.rawData = data;
238
- errorCatcher(chart, callback);
239
- });
240
- } else {
241
- chart.rawData = dataSource;
242
- errorCatcher(chart, callback);
243
- }
220
+ function isWeek(d, dayOfWeek) {
221
+ return isDay(d) && d.getDay() === dayOfWeek;
244
222
  }
245
223
 
246
- function addDownloadButton(chart) {
247
- var element = chart.element;
248
- var link = document.createElement("a");
249
- link.download = chart.options.download === true ? "chart.png" : chart.options.download; // http://caniuse.com/download
250
- link.style.position = "absolute";
251
- link.style.top = "20px";
252
- link.style.right = "20px";
253
- link.style.zIndex = 1000;
254
- link.style.lineHeight = "20px";
255
- link.target = "_blank"; // for safari
256
- var image = document.createElement("img");
257
- image.alt = "Download";
258
- image.style.border = "none";
259
- // icon from font-awesome
260
- // http://fa2png.io/
261
- image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABCFBMVEUAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMywEsqxAAAAV3RSTlMAAQIDBggJCgsMDQ4PERQaHB0eISIjJCouLzE0OTo/QUJHSUpLTU5PUllhYmltcHh5foWLjI+SlaCio6atr7S1t7m6vsHHyM7R2tze5Obo7fHz9ff5+/1hlxK2AAAA30lEQVQYGUXBhVYCQQBA0TdYWAt2d3d3YWAHyur7/z9xgD16Lw0DW+XKx+1GgX+FRzM3HWQWrHl5N/oapW5RPe0PkBu+UYeICvozTWZVK23Ao04B79oJrOsJDOoxkZoQPWgX29pHpCZEk7rEvQYiNSFq1UMqvlCjJkRBS1R8hb00Vb/TajtBL7nTHE1X1vyMQF732dQhyF2o6SAwrzP06iUQzvwsArlnzcOdrgBhJyHa1QOgO9U1GsKuvjUTjavliZYQ8nNPapG6sap/3nrIdJ6bOWzmX/fy0XVpfzZP3S8OJT3g9EEiJwAAAABJRU5ErkJggg==";
262
- link.appendChild(image);
263
- element.style.position = "relative";
264
-
265
- chart.downloadAttached = true;
266
-
267
- // mouseenter
268
- addEvent(element, "mouseover", function(e) {
269
- var related = e.relatedTarget;
270
- // check download option again to ensure it wasn't changed
271
- if (!related || (related !== this && !childOf(this, related)) && chart.options.download) {
272
- link.href = chart.toImage();
273
- element.appendChild(link);
274
- }
275
- });
276
-
277
- // mouseleave
278
- addEvent(element, "mouseout", function(e) {
279
- var related = e.relatedTarget;
280
- if (!related || (related !== this && !childOf(this, related))) {
281
- if (link.parentNode) {
282
- link.parentNode.removeChild(link);
283
- }
284
- }
285
- });
224
+ function isMonth(d) {
225
+ return isDay(d) && d.getDate() === 1;
286
226
  }
287
227
 
288
- // http://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
289
- function addEvent(elem, event, fn) {
290
- if (elem.addEventListener) {
291
- elem.addEventListener(event, fn, false);
292
- } else {
293
- elem.attachEvent("on" + event, function() {
294
- // set the this pointer same as addEventListener when fn is called
295
- return(fn.call(elem, window.event));
296
- });
297
- }
228
+ function isYear(d) {
229
+ return isMonth(d) && d.getMonth() === 0;
298
230
  }
299
231
 
300
- // https://gist.github.com/shawnbot/4166283
301
- function childOf(p, c) {
302
- if (p === c) return false;
303
- while (c && c !== p) c = c.parentNode;
304
- return c === p;
232
+ function isDate(obj) {
233
+ return !isNaN(toDate(obj)) && toStr(obj).length >= 6;
305
234
  }
306
235
 
307
- // type conversions
308
-
309
- function toStr(n) {
310
- return "" + n;
236
+ function isNumber(obj) {
237
+ return typeof obj === "number";
311
238
  }
312
239
 
313
- function toFloat(n) {
314
- return parseFloat(n);
315
- }
240
+ function formatValue(pre, value, options) {
241
+ pre = pre || "";
242
+ if (options.prefix) {
243
+ if (value < 0) {
244
+ value = value * -1;
245
+ pre += "-";
246
+ }
247
+ pre += options.prefix;
248
+ }
316
249
 
317
- function toDate(n) {
318
- var matches, year, month, day;
319
- if (typeof n !== "object") {
320
- if (typeof n === "number") {
321
- n = new Date(n * 1000); // ms
322
- } else if ((matches = n.match(DATE_PATTERN))) {
323
- year = parseInt(matches[1], 10);
324
- month = parseInt(matches[3], 10) - 1;
325
- day = parseInt(matches[5], 10);
326
- return new Date(year, month, day);
327
- } else { // str
328
- // try our best to get the str into iso8601
329
- // TODO be smarter about this
330
- var str = n.replace(/ /, "T").replace(" ", "").replace("UTC", "Z");
331
- n = parseISO8601(str) || new Date(n);
250
+ if (options.thousands || options.decimal) {
251
+ value = toStr(value);
252
+ var parts = value.split(".");
253
+ value = parts[0];
254
+ if (options.thousands) {
255
+ value = value.replace(/\B(?=(\d{3})+(?!\d))/g, options.thousands);
256
+ }
257
+ if (parts.length > 1) {
258
+ value += (options.decimal || ".") + parts[1];
332
259
  }
333
260
  }
334
- return n;
261
+
262
+ return pre + value + (options.suffix || "");
335
263
  }
336
264
 
337
- function toArr(n) {
338
- if (!isArray(n)) {
339
- var arr = [], i;
340
- for (i in n) {
341
- if (n.hasOwnProperty(i)) {
342
- arr.push([i, n[i]]);
265
+ function allZeros(data) {
266
+ var i, j, d;
267
+ for (i = 0; i < data.length; i++) {
268
+ d = data[i].data;
269
+ for (j = 0; j < d.length; j++) {
270
+ if (d[j][1] != 0) {
271
+ return false;
343
272
  }
344
273
  }
345
- n = arr;
346
274
  }
347
- return n;
348
- }
349
-
350
- function sortByTime(a, b) {
351
- return a[0].getTime() - b[0].getTime();
275
+ return true;
352
276
  }
353
277
 
354
- function sortByNumber(a, b) {
355
- return a - b;
356
- }
278
+ var baseOptions = {
279
+ maintainAspectRatio: false,
280
+ animation: false,
281
+ tooltips: {
282
+ displayColors: false,
283
+ callbacks: {}
284
+ },
285
+ legend: {},
286
+ title: {fontSize: 20, fontColor: "#333"}
287
+ };
357
288
 
358
- function loadAdapters() {
359
- if (!HighchartsAdapter && "Highcharts" in window) {
360
- HighchartsAdapter = new function () {
361
- var Highcharts = window.Highcharts;
362
-
363
- this.name = "highcharts";
364
-
365
- var defaultOptions = {
366
- chart: {},
367
- xAxis: {
368
- title: {
369
- text: null
370
- },
371
- labels: {
372
- style: {
373
- fontSize: "12px"
374
- }
375
- }
376
- },
377
- yAxis: {
378
- title: {
379
- text: null
380
- },
381
- labels: {
382
- style: {
383
- fontSize: "12px"
384
- }
385
- }
289
+ var defaultOptions = {
290
+ scales: {
291
+ yAxes: [
292
+ {
293
+ ticks: {
294
+ maxTicksLimit: 4
386
295
  },
387
- title: {
388
- text: null
389
- },
390
- credits: {
391
- enabled: false
392
- },
393
- legend: {
394
- borderWidth: 0
296
+ scaleLabel: {
297
+ fontSize: 16,
298
+ // fontStyle: "bold",
299
+ fontColor: "#333"
300
+ }
301
+ }
302
+ ],
303
+ xAxes: [
304
+ {
305
+ gridLines: {
306
+ drawOnChartArea: false
395
307
  },
396
- tooltip: {
397
- style: {
398
- fontSize: "12px"
399
- }
308
+ scaleLabel: {
309
+ fontSize: 16,
310
+ // fontStyle: "bold",
311
+ fontColor: "#333"
400
312
  },
401
- plotOptions: {
402
- areaspline: {},
403
- series: {
404
- marker: {}
405
- }
406
- }
407
- };
313
+ time: {},
314
+ ticks: {}
315
+ }
316
+ ]
317
+ }
318
+ };
408
319
 
409
- var hideLegend = function (options, legend, hideLegend) {
410
- if (legend !== undefined) {
411
- options.legend.enabled = !!legend;
412
- if (legend && legend !== true) {
413
- if (legend === "top" || legend === "bottom") {
414
- options.legend.verticalAlign = legend;
415
- } else {
416
- options.legend.layout = "vertical";
417
- options.legend.verticalAlign = "middle";
418
- options.legend.align = legend;
419
- }
420
- }
421
- } else if (hideLegend) {
422
- options.legend.enabled = false;
423
- }
424
- };
320
+ // http://there4.io/2012/05/02/google-chart-color-list/
321
+ var defaultColors = [
322
+ "#3366CC", "#DC3912", "#FF9900", "#109618", "#990099", "#3B3EAC", "#0099C6",
323
+ "#DD4477", "#66AA00", "#B82E2E", "#316395", "#994499", "#22AA99", "#AAAA11",
324
+ "#6633CC", "#E67300", "#8B0707", "#329262", "#5574A6", "#651067"
325
+ ];
326
+
327
+ var hideLegend = function (options, legend, hideLegend) {
328
+ if (legend !== undefined) {
329
+ options.legend.display = !!legend;
330
+ if (legend && legend !== true) {
331
+ options.legend.position = legend;
332
+ }
333
+ } else if (hideLegend) {
334
+ options.legend.display = false;
335
+ }
336
+ };
425
337
 
426
- var setTitle = function (options, title) {
427
- options.title.text = title;
428
- };
338
+ var setTitle = function (options, title) {
339
+ options.title.display = true;
340
+ options.title.text = title;
341
+ };
429
342
 
430
- var setMin = function (options, min) {
431
- options.yAxis.min = min;
432
- };
343
+ var setMin = function (options, min) {
344
+ if (min !== null) {
345
+ options.scales.yAxes[0].ticks.min = toFloat(min);
346
+ }
347
+ };
433
348
 
434
- var setMax = function (options, max) {
435
- options.yAxis.max = max;
436
- };
349
+ var setMax = function (options, max) {
350
+ options.scales.yAxes[0].ticks.max = toFloat(max);
351
+ };
437
352
 
438
- var setStacked = function (options, stacked) {
439
- options.plotOptions.series.stacking = stacked ? "normal" : null;
440
- };
353
+ var setBarMin = function (options, min) {
354
+ if (min !== null) {
355
+ options.scales.xAxes[0].ticks.min = toFloat(min);
356
+ }
357
+ };
441
358
 
442
- var setXtitle = function (options, title) {
443
- options.xAxis.title.text = title;
444
- };
359
+ var setBarMax = function (options, max) {
360
+ options.scales.xAxes[0].ticks.max = toFloat(max);
361
+ };
445
362
 
446
- var setYtitle = function (options, title) {
447
- options.yAxis.title.text = title;
448
- };
363
+ var setStacked = function (options, stacked) {
364
+ options.scales.xAxes[0].stacked = !!stacked;
365
+ options.scales.yAxes[0].stacked = !!stacked;
366
+ };
449
367
 
450
- var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
451
-
452
- this.renderLineChart = function (chart, chartType) {
453
- chartType = chartType || "spline";
454
- var chartOptions = {};
455
- if (chartType === "areaspline") {
456
- chartOptions = {
457
- plotOptions: {
458
- areaspline: {
459
- stacking: "normal"
460
- },
461
- area: {
462
- stacking: "normal"
463
- },
464
- series: {
465
- marker: {
466
- enabled: false
467
- }
468
- }
469
- }
470
- };
471
- }
368
+ var setXtitle = function (options, title) {
369
+ options.scales.xAxes[0].scaleLabel.display = true;
370
+ options.scales.xAxes[0].scaleLabel.labelString = title;
371
+ };
472
372
 
473
- if (chart.options.curve === false) {
474
- if (chartType === "areaspline") {
475
- chartType = "area";
476
- } else if (chartType === "spline") {
477
- chartType = "line";
478
- }
479
- }
373
+ var setYtitle = function (options, title) {
374
+ options.scales.yAxes[0].scaleLabel.display = true;
375
+ options.scales.yAxes[0].scaleLabel.labelString = title;
376
+ };
480
377
 
481
- var options = jsOptions(chart, chart.options, chartOptions), data, i, j;
482
- options.xAxis.type = chart.discrete ? "category" : "datetime";
483
- if (!options.chart.type) {
484
- options.chart.type = chartType;
378
+ // https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
379
+ var addOpacity = function(hex, opacity) {
380
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
381
+ return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
382
+ };
383
+
384
+ var setLabelSize = function (chart, data, options) {
385
+ var maxLabelSize = Math.ceil(chart.element.offsetWidth / 4.0 / data.labels.length);
386
+ if (maxLabelSize > 25) {
387
+ maxLabelSize = 25;
388
+ } else if (maxLabelSize < 10) {
389
+ maxLabelSize = 10;
390
+ }
391
+ if (!options.scales.xAxes[0].ticks.callback) {
392
+ options.scales.xAxes[0].ticks.callback = function (value) {
393
+ value = toStr(value);
394
+ if (value.length > maxLabelSize) {
395
+ return value.substring(0, maxLabelSize - 2) + "...";
396
+ } else {
397
+ return value;
398
+ }
399
+ };
400
+ }
401
+ };
402
+
403
+ var setFormatOptions = function(chart, options, chartType) {
404
+ var formatOptions = {
405
+ prefix: chart.options.prefix,
406
+ suffix: chart.options.suffix,
407
+ thousands: chart.options.thousands,
408
+ decimal: chart.options.decimal
409
+ };
410
+
411
+ if (chartType !== "pie") {
412
+ var myAxes = options.scales.yAxes;
413
+ if (chartType === "bar") {
414
+ myAxes = options.scales.xAxes;
415
+ }
416
+
417
+ if (!myAxes[0].ticks.callback) {
418
+ myAxes[0].ticks.callback = function (value) {
419
+ return formatValue("", value, formatOptions);
420
+ };
421
+ }
422
+ }
423
+
424
+ if (!options.tooltips.callbacks.label) {
425
+ if (chartType === "scatter") {
426
+ options.tooltips.callbacks.label = function (item, data) {
427
+ var label = data.datasets[item.datasetIndex].label || '';
428
+ if (label) {
429
+ label += ': ';
485
430
  }
486
- options.chart.renderTo = chart.element.id;
487
-
488
- var series = chart.data;
489
- for (i = 0; i < series.length; i++) {
490
- data = series[i].data;
491
- if (!chart.discrete) {
492
- for (j = 0; j < data.length; j++) {
493
- data[j][0] = data[j][0].getTime();
494
- }
495
- }
496
- series[i].marker = {symbol: "circle"};
431
+ return label + '(' + item.xLabel + ', ' + item.yLabel + ')';
432
+ };
433
+ } else if (chartType === "bubble") {
434
+ options.tooltips.callbacks.label = function (item, data) {
435
+ var label = data.datasets[item.datasetIndex].label || '';
436
+ if (label) {
437
+ label += ': ';
497
438
  }
498
- options.series = series;
499
- chart.chart = new Highcharts.Chart(options);
439
+ var dataPoint = data.datasets[item.datasetIndex].data[item.index];
440
+ return label + '(' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.v + ')';
500
441
  };
442
+ } else if (chartType === "pie") {
443
+ // need to use separate label for pie charts
444
+ options.tooltips.callbacks.label = function (tooltipItem, data) {
445
+ var dataLabel = data.labels[tooltipItem.index];
446
+ var value = ': ';
447
+
448
+ if (isArray(dataLabel)) {
449
+ // show value on first line of multiline label
450
+ // need to clone because we are changing the value
451
+ dataLabel = dataLabel.slice();
452
+ dataLabel[0] += value;
453
+ } else {
454
+ dataLabel += value;
455
+ }
501
456
 
502
- this.renderScatterChart = function (chart) {
503
- var chartOptions = {};
504
- var options = jsOptions(chart, chart.options, chartOptions);
505
- options.chart.type = "scatter";
506
- options.chart.renderTo = chart.element.id;
507
- options.series = chart.data;
508
- chart.chart = new Highcharts.Chart(options);
457
+ return formatValue(dataLabel, data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], formatOptions);
458
+ };
459
+ } else {
460
+ var valueLabel = chartType === "bar" ? "xLabel" : "yLabel";
461
+ options.tooltips.callbacks.label = function (tooltipItem, data) {
462
+ var label = data.datasets[tooltipItem.datasetIndex].label || '';
463
+ if (label) {
464
+ label += ': ';
465
+ }
466
+ return formatValue(label, tooltipItem[valueLabel], formatOptions);
509
467
  };
468
+ }
469
+ }
470
+ };
510
471
 
511
- this.renderPieChart = function (chart) {
512
- var chartOptions = merge(defaultOptions, {});
472
+ var jsOptions = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
513
473
 
514
- if (chart.options.colors) {
515
- chartOptions.colors = chart.options.colors;
516
- }
517
- if (chart.options.donut) {
518
- chartOptions.plotOptions = {pie: {innerSize: "50%"}};
519
- }
474
+ var createDataTable = function (chart, options, chartType) {
475
+ var datasets = [];
476
+ var labels = [];
520
477
 
521
- if ("legend" in chart.options) {
522
- hideLegend(chartOptions, chart.options.legend);
523
- }
478
+ var colors = chart.options.colors || defaultColors;
524
479
 
525
- if (chart.options.title) {
526
- setTitle(chartOptions, chart.options.title);
527
- }
480
+ var day = true;
481
+ var week = true;
482
+ var dayOfWeek;
483
+ var month = true;
484
+ var year = true;
485
+ var hour = true;
486
+ var minute = true;
528
487
 
529
- var options = merge(chartOptions, chart.options.library || {});
530
- options.chart.renderTo = chart.element.id;
531
- options.series = [{
532
- type: "pie",
533
- name: chart.options.label || "Value",
534
- data: chart.data
535
- }];
536
- chart.chart = new Highcharts.Chart(options);
537
- };
488
+ var series = chart.data;
538
489
 
539
- this.renderColumnChart = function (chart, chartType) {
540
- chartType = chartType || "column";
541
- var series = chart.data;
542
- var options = jsOptions(chart, chart.options), i, j, s, d, rows = [], categories = [];
543
- options.chart.type = chartType;
544
- options.chart.renderTo = chart.element.id;
545
-
546
- for (i = 0; i < series.length; i++) {
547
- s = series[i];
548
-
549
- for (j = 0; j < s.data.length; j++) {
550
- d = s.data[j];
551
- if (!rows[d[0]]) {
552
- rows[d[0]] = new Array(series.length);
553
- categories.push(d[0]);
554
- }
555
- rows[d[0]][i] = d[1];
556
- }
490
+ var max = 0;
491
+ if (chartType === "bubble") {
492
+ for (var i$1 = 0; i$1 < series.length; i$1++) {
493
+ var s$1 = series[i$1];
494
+ for (var j$1 = 0; j$1 < s$1.data.length; j$1++) {
495
+ if (s$1.data[j$1][2] > max) {
496
+ max = s$1.data[j$1][2];
557
497
  }
498
+ }
499
+ }
500
+ }
558
501
 
559
- options.xAxis.categories = categories;
502
+ var i, j, s, d, key, rows = [], rows2 = [];
560
503
 
561
- var newSeries = [];
562
- for (i = 0; i < series.length; i++) {
563
- d = [];
564
- for (j = 0; j < categories.length; j++) {
565
- d.push(rows[categories[j]][i] || 0);
566
- }
504
+ if (chartType === "bar" || chartType === "column" || (chart.xtype !== "number" && chart.xtype !== "bubble")) {
505
+ var sortedLabels = [];
506
+
507
+ for (i = 0; i < series.length; i++) {
508
+ s = series[i];
567
509
 
568
- newSeries.push({
569
- name: series[i].name,
570
- data: d
571
- });
510
+ for (j = 0; j < s.data.length; j++) {
511
+ d = s.data[j];
512
+ key = chart.xtype == "datetime" ? d[0].getTime() : d[0];
513
+ if (!rows[key]) {
514
+ rows[key] = new Array(series.length);
572
515
  }
573
- options.series = newSeries;
516
+ rows[key][i] = toFloat(d[1]);
517
+ if (sortedLabels.indexOf(key) === -1) {
518
+ sortedLabels.push(key);
519
+ }
520
+ }
521
+ }
574
522
 
575
- chart.chart = new Highcharts.Chart(options);
576
- };
523
+ if (chart.xtype === "datetime" || chart.xtype === "number") {
524
+ sortedLabels.sort(sortByNumber);
525
+ }
577
526
 
578
- var self = this;
527
+ for (j = 0; j < series.length; j++) {
528
+ rows2.push([]);
529
+ }
579
530
 
580
- this.renderBarChart = function (chart) {
581
- self.renderColumnChart(chart, "bar");
582
- };
531
+ var value;
532
+ var k;
533
+ for (k = 0; k < sortedLabels.length; k++) {
534
+ i = sortedLabels[k];
535
+ if (chart.xtype === "datetime") {
536
+ value = new Date(toFloat(i));
537
+ // TODO make this efficient
538
+ day = day && isDay(value);
539
+ if (!dayOfWeek) {
540
+ dayOfWeek = value.getDay();
541
+ }
542
+ week = week && isWeek(value, dayOfWeek);
543
+ month = month && isMonth(value);
544
+ year = year && isYear(value);
545
+ hour = hour && isHour(value);
546
+ minute = minute && isMinute(value);
547
+ } else {
548
+ value = i;
549
+ }
550
+ labels.push(value);
551
+ for (j = 0; j < series.length; j++) {
552
+ // Chart.js doesn't like undefined
553
+ rows2[j].push(rows[i][j] === undefined ? null : rows[i][j]);
554
+ }
555
+ }
556
+ } else {
557
+ for (var i$2 = 0; i$2 < series.length; i$2++) {
558
+ var s$2 = series[i$2];
559
+ var d$1 = [];
560
+ for (var j$2 = 0; j$2 < s$2.data.length; j$2++) {
561
+ var point = {
562
+ x: toFloat(s$2.data[j$2][0]),
563
+ y: toFloat(s$2.data[j$2][1])
564
+ };
565
+ if (chartType === "bubble") {
566
+ point.r = toFloat(s$2.data[j$2][2]) * 20 / max;
567
+ // custom attribute, for tooltip
568
+ point.v = s$2.data[j$2][2];
569
+ }
570
+ d$1.push(point);
571
+ }
572
+ rows2.push(d$1);
573
+ }
574
+ }
583
575
 
584
- this.renderAreaChart = function (chart) {
585
- self.renderLineChart(chart, "areaspline");
586
- };
576
+ for (i = 0; i < series.length; i++) {
577
+ s = series[i];
578
+
579
+ var color = s.color || colors[i];
580
+ var backgroundColor = chartType !== "line" ? addOpacity(color, 0.5) : color;
581
+
582
+ var dataset = {
583
+ label: s.name || "",
584
+ data: rows2[i],
585
+ fill: chartType === "area",
586
+ borderColor: color,
587
+ backgroundColor: backgroundColor,
588
+ pointBackgroundColor: color,
589
+ borderWidth: 2,
590
+ pointHoverBackgroundColor: color
587
591
  };
588
- adapters.push(HighchartsAdapter);
589
- }
590
- if (!GoogleChartsAdapter && window.google && (window.google.setOnLoadCallback || window.google.charts)) {
591
- GoogleChartsAdapter = new function () {
592
- var google = window.google;
593
-
594
- this.name = "google";
595
-
596
- var loaded = {};
597
- var callbacks = [];
598
-
599
- var runCallbacks = function () {
600
- var cb, call;
601
- for (var i = 0; i < callbacks.length; i++) {
602
- cb = callbacks[i];
603
- call = google.visualization && ((cb.pack === "corechart" && google.visualization.LineChart) || (cb.pack === "timeline" && google.visualization.Timeline));
604
- if (call) {
605
- cb.callback();
606
- callbacks.splice(i, 1);
607
- i--;
608
- }
609
- }
610
- };
611
592
 
612
- var waitForLoaded = function (pack, callback) {
613
- if (!callback) {
614
- callback = pack;
615
- pack = "corechart";
616
- }
593
+ if (s.stack) {
594
+ dataset.stack = s.stack;
595
+ }
617
596
 
618
- callbacks.push({pack: pack, callback: callback});
597
+ if (chart.options.curve === false) {
598
+ dataset.lineTension = 0;
599
+ }
619
600
 
620
- if (loaded[pack]) {
621
- runCallbacks();
622
- } else {
623
- loaded[pack] = true;
624
-
625
- // https://groups.google.com/forum/#!topic/google-visualization-api/fMKJcyA2yyI
626
- var loadOptions = {
627
- packages: [pack],
628
- callback: runCallbacks
629
- };
630
- if (config.language) {
631
- loadOptions.language = config.language;
632
- }
601
+ if (chart.options.points === false) {
602
+ dataset.pointRadius = 0;
603
+ dataset.pointHitRadius = 5;
604
+ }
633
605
 
634
- if (window.google.setOnLoadCallback) {
635
- google.load("visualization", "1", loadOptions);
636
- } else {
637
- google.charts.load("current", loadOptions);
638
- }
606
+ dataset = merge(dataset, chart.options.dataset || {});
607
+ dataset = merge(dataset, s.library || {});
608
+ dataset = merge(dataset, s.dataset || {});
609
+
610
+ datasets.push(dataset);
611
+ }
612
+
613
+ if (chart.xtype === "datetime" && labels.length > 0) {
614
+ var minTime = labels[0].getTime();
615
+ var maxTime = labels[0].getTime();
616
+ for (i = 1; i < labels.length; i++) {
617
+ var value$1 = labels[i].getTime();
618
+ if (value$1 < minTime) {
619
+ minTime = value$1;
620
+ }
621
+ if (value$1 > maxTime) {
622
+ maxTime = value$1;
623
+ }
624
+ }
625
+
626
+ var timeDiff = (maxTime - minTime) / (86400 * 1000.0);
627
+
628
+ if (!options.scales.xAxes[0].time.unit) {
629
+ var step;
630
+ if (year || timeDiff > 365 * 10) {
631
+ options.scales.xAxes[0].time.unit = "year";
632
+ step = 365;
633
+ } else if (month || timeDiff > 30 * 10) {
634
+ options.scales.xAxes[0].time.unit = "month";
635
+ step = 30;
636
+ } else if (day || timeDiff > 10) {
637
+ options.scales.xAxes[0].time.unit = "day";
638
+ step = 1;
639
+ } else if (hour || timeDiff > 0.5) {
640
+ options.scales.xAxes[0].time.displayFormats = {hour: "MMM D, h a"};
641
+ options.scales.xAxes[0].time.unit = "hour";
642
+ step = 1 / 24.0;
643
+ } else if (minute) {
644
+ options.scales.xAxes[0].time.displayFormats = {minute: "h:mm a"};
645
+ options.scales.xAxes[0].time.unit = "minute";
646
+ step = 1 / 24.0 / 60.0;
647
+ }
648
+
649
+ if (step && timeDiff > 0) {
650
+ var unitStepSize = Math.ceil(timeDiff / step / (chart.element.offsetWidth / 100.0));
651
+ if (week && step === 1) {
652
+ unitStepSize = Math.ceil(unitStepSize / 7.0) * 7;
639
653
  }
640
- };
654
+ options.scales.xAxes[0].time.unitStepSize = unitStepSize;
655
+ }
656
+ }
641
657
 
642
- // Set chart options
643
- var defaultOptions = {
644
- chartArea: {},
645
- fontName: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",
646
- pointSize: 6,
647
- legend: {
648
- textStyle: {
649
- fontSize: 12,
650
- color: "#444"
651
- },
652
- alignment: "center",
653
- position: "right"
654
- },
655
- curveType: "function",
656
- hAxis: {
657
- textStyle: {
658
- color: "#666",
659
- fontSize: 12
660
- },
661
- titleTextStyle: {},
662
- gridlines: {
663
- color: "transparent"
664
- },
665
- baselineColor: "#ccc",
666
- viewWindow: {}
658
+ if (!options.scales.xAxes[0].time.tooltipFormat) {
659
+ if (day) {
660
+ options.scales.xAxes[0].time.tooltipFormat = "ll";
661
+ } else if (hour) {
662
+ options.scales.xAxes[0].time.tooltipFormat = "MMM D, h a";
663
+ } else if (minute) {
664
+ options.scales.xAxes[0].time.tooltipFormat = "h:mm a";
665
+ }
666
+ }
667
+ }
668
+
669
+ var data = {
670
+ labels: labels,
671
+ datasets: datasets
672
+ };
673
+
674
+ return data;
675
+ };
676
+
677
+ var defaultExport = function defaultExport(library) {
678
+ this.name = "chartjs";
679
+ this.library = library;
680
+ };
681
+
682
+ defaultExport.prototype.renderLineChart = function renderLineChart (chart, chartType) {
683
+ var chartOptions = {};
684
+ // fix for https://github.com/chartjs/Chart.js/issues/2441
685
+ if (!chart.options.max && allZeros(chart.data)) {
686
+ chartOptions.max = 1;
687
+ }
688
+
689
+ var options = jsOptions(chart, merge(chartOptions, chart.options));
690
+ setFormatOptions(chart, options, chartType);
691
+
692
+ var data = createDataTable(chart, options, chartType || "line");
693
+
694
+ if (chart.xtype === "number") {
695
+ options.scales.xAxes[0].type = "linear";
696
+ options.scales.xAxes[0].position = "bottom";
697
+ } else {
698
+ options.scales.xAxes[0].type = chart.xtype === "string" ? "category" : "time";
699
+ }
700
+
701
+ this.drawChart(chart, "line", data, options);
702
+ };
703
+
704
+ defaultExport.prototype.renderPieChart = function renderPieChart (chart) {
705
+ var options = merge({}, baseOptions);
706
+ if (chart.options.donut) {
707
+ options.cutoutPercentage = 50;
708
+ }
709
+
710
+ if ("legend" in chart.options) {
711
+ hideLegend(options, chart.options.legend);
712
+ }
713
+
714
+ if (chart.options.title) {
715
+ setTitle(options, chart.options.title);
716
+ }
717
+
718
+ options = merge(options, chart.options.library || {});
719
+ setFormatOptions(chart, options, "pie");
720
+
721
+ var labels = [];
722
+ var values = [];
723
+ for (var i = 0; i < chart.data.length; i++) {
724
+ var point = chart.data[i];
725
+ labels.push(point[0]);
726
+ values.push(point[1]);
727
+ }
728
+
729
+ var dataset = {
730
+ data: values,
731
+ backgroundColor: chart.options.colors || defaultColors
732
+ };
733
+ dataset = merge(dataset, chart.options.dataset || {});
734
+
735
+ var data = {
736
+ labels: labels,
737
+ datasets: [dataset]
738
+ };
739
+
740
+ this.drawChart(chart, "pie", data, options);
741
+ };
742
+
743
+ defaultExport.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
744
+ var options;
745
+ if (chartType === "bar") {
746
+ options = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options);
747
+ } else {
748
+ options = jsOptions(chart, chart.options);
749
+ }
750
+ setFormatOptions(chart, options, chartType);
751
+ var data = createDataTable(chart, options, "column");
752
+ if (chartType !== "bar") {
753
+ setLabelSize(chart, data, options);
754
+ }
755
+ this.drawChart(chart, (chartType === "bar" ? "horizontalBar" : "bar"), data, options);
756
+ };
757
+
758
+ defaultExport.prototype.renderAreaChart = function renderAreaChart (chart) {
759
+ this.renderLineChart(chart, "area");
760
+ };
761
+
762
+ defaultExport.prototype.renderBarChart = function renderBarChart (chart) {
763
+ this.renderColumnChart(chart, "bar");
764
+ };
765
+
766
+ defaultExport.prototype.renderScatterChart = function renderScatterChart (chart, chartType) {
767
+ chartType = chartType || "scatter";
768
+
769
+ var options = jsOptions(chart, chart.options);
770
+ setFormatOptions(chart, options, chartType);
771
+
772
+ if (!("showLines" in options)) {
773
+ options.showLines = false;
774
+ }
775
+
776
+ var data = createDataTable(chart, options, chartType);
777
+
778
+ options.scales.xAxes[0].type = "linear";
779
+ options.scales.xAxes[0].position = "bottom";
780
+
781
+ this.drawChart(chart, chartType, data, options);
782
+ };
783
+
784
+ defaultExport.prototype.renderBubbleChart = function renderBubbleChart (chart) {
785
+ this.renderScatterChart(chart, "bubble");
786
+ };
787
+
788
+ defaultExport.prototype.destroy = function destroy (chart) {
789
+ if (chart.chart) {
790
+ chart.chart.destroy();
791
+ }
792
+ };
793
+
794
+ defaultExport.prototype.drawChart = function drawChart (chart, type, data, options) {
795
+ this.destroy(chart);
796
+
797
+ var chartOptions = {
798
+ type: type,
799
+ data: data,
800
+ options: options
801
+ };
802
+
803
+ if (chart.options.code) {
804
+ window.console.log("new Chart(ctx, " + JSON.stringify(chartOptions) + ");");
805
+ }
806
+
807
+ chart.element.innerHTML = "<canvas></canvas>";
808
+ var ctx = chart.element.getElementsByTagName("CANVAS")[0];
809
+ chart.chart = new this.library(ctx, chartOptions);
810
+ };
811
+
812
+ var defaultOptions$1 = {
813
+ chart: {},
814
+ xAxis: {
815
+ title: {
816
+ text: null
817
+ },
818
+ labels: {
819
+ style: {
820
+ fontSize: "12px"
821
+ }
822
+ }
823
+ },
824
+ yAxis: {
825
+ title: {
826
+ text: null
827
+ },
828
+ labels: {
829
+ style: {
830
+ fontSize: "12px"
831
+ }
832
+ }
833
+ },
834
+ title: {
835
+ text: null
836
+ },
837
+ credits: {
838
+ enabled: false
839
+ },
840
+ legend: {
841
+ borderWidth: 0
842
+ },
843
+ tooltip: {
844
+ style: {
845
+ fontSize: "12px"
846
+ }
847
+ },
848
+ plotOptions: {
849
+ areaspline: {},
850
+ series: {
851
+ marker: {}
852
+ }
853
+ }
854
+ };
855
+
856
+ var hideLegend$1 = function (options, legend, hideLegend) {
857
+ if (legend !== undefined) {
858
+ options.legend.enabled = !!legend;
859
+ if (legend && legend !== true) {
860
+ if (legend === "top" || legend === "bottom") {
861
+ options.legend.verticalAlign = legend;
862
+ } else {
863
+ options.legend.layout = "vertical";
864
+ options.legend.verticalAlign = "middle";
865
+ options.legend.align = legend;
866
+ }
867
+ }
868
+ } else if (hideLegend) {
869
+ options.legend.enabled = false;
870
+ }
871
+ };
872
+
873
+ var setTitle$1 = function (options, title) {
874
+ options.title.text = title;
875
+ };
876
+
877
+ var setMin$1 = function (options, min) {
878
+ options.yAxis.min = min;
879
+ };
880
+
881
+ var setMax$1 = function (options, max) {
882
+ options.yAxis.max = max;
883
+ };
884
+
885
+ var setStacked$1 = function (options, stacked) {
886
+ options.plotOptions.series.stacking = stacked ? (stacked === true ? "normal" : stacked) : null;
887
+ };
888
+
889
+ var setXtitle$1 = function (options, title) {
890
+ options.xAxis.title.text = title;
891
+ };
892
+
893
+ var setYtitle$1 = function (options, title) {
894
+ options.yAxis.title.text = title;
895
+ };
896
+
897
+ var jsOptions$1 = jsOptionsFunc(defaultOptions$1, hideLegend$1, setTitle$1, setMin$1, setMax$1, setStacked$1, setXtitle$1, setYtitle$1);
898
+
899
+ var setFormatOptions$1 = function(chart, options, chartType) {
900
+ var formatOptions = {
901
+ prefix: chart.options.prefix,
902
+ suffix: chart.options.suffix,
903
+ thousands: chart.options.thousands,
904
+ decimal: chart.options.decimal
905
+ };
906
+
907
+ if (chartType !== "pie" && !options.yAxis.labels.formatter) {
908
+ options.yAxis.labels.formatter = function () {
909
+ return formatValue("", this.value, formatOptions);
910
+ };
911
+ }
912
+
913
+ if (!options.tooltip.pointFormatter) {
914
+ options.tooltip.pointFormatter = function () {
915
+ return '<span style="color:' + this.color + '>\u25CF</span> ' + formatValue(this.series.name + ': <b>', this.y, formatOptions) + '</b><br/>';
916
+ };
917
+ }
918
+ };
919
+
920
+ var defaultExport$1 = function defaultExport(library) {
921
+ this.name = "highcharts";
922
+ this.library = library;
923
+ };
924
+
925
+ defaultExport$1.prototype.renderLineChart = function renderLineChart (chart, chartType) {
926
+ chartType = chartType || "spline";
927
+ var chartOptions = {};
928
+ if (chartType === "areaspline") {
929
+ chartOptions = {
930
+ plotOptions: {
931
+ areaspline: {
932
+ stacking: "normal"
667
933
  },
668
- vAxis: {
669
- textStyle: {
670
- color: "#666",
671
- fontSize: 12
672
- },
673
- titleTextStyle: {},
674
- baselineColor: "#ccc",
675
- viewWindow: {}
934
+ area: {
935
+ stacking: "normal"
676
936
  },
677
- tooltip: {
678
- textStyle: {
679
- color: "#666",
680
- fontSize: 12
937
+ series: {
938
+ marker: {
939
+ enabled: false
681
940
  }
682
941
  }
683
- };
942
+ }
943
+ };
944
+ }
684
945
 
685
- var hideLegend = function (options, legend, hideLegend) {
686
- if (legend !== undefined) {
687
- var position;
688
- if (!legend) {
689
- position = "none";
690
- } else if (legend === true) {
691
- position = "right";
692
- } else {
693
- position = legend;
694
- }
695
- options.legend.position = position;
696
- } else if (hideLegend) {
697
- options.legend.position = "none";
698
- }
699
- };
946
+ if (chart.options.curve === false) {
947
+ if (chartType === "areaspline") {
948
+ chartType = "area";
949
+ } else if (chartType === "spline") {
950
+ chartType = "line";
951
+ }
952
+ }
700
953
 
701
- var setTitle = function (options, title) {
702
- options.title = title;
703
- options.titleTextStyle = {color: "#333", fontSize: "20px"};
704
- };
954
+ var options = jsOptions$1(chart, chart.options, chartOptions), data, i, j;
955
+ options.xAxis.type = chart.xtype === "string" ? "category" : (chart.xtype === "number" ? "linear" : "datetime");
956
+ if (!options.chart.type) {
957
+ options.chart.type = chartType;
958
+ }
959
+ setFormatOptions$1(chart, options, chartType);
705
960
 
706
- var setMin = function (options, min) {
707
- options.vAxis.viewWindow.min = min;
708
- };
961
+ var series = chart.data;
962
+ for (i = 0; i < series.length; i++) {
963
+ series[i].name = series[i].name || "Value";
964
+ data = series[i].data;
965
+ if (chart.xtype === "datetime") {
966
+ for (j = 0; j < data.length; j++) {
967
+ data[j][0] = data[j][0].getTime();
968
+ }
969
+ }
970
+ series[i].marker = {symbol: "circle"};
971
+ if (chart.options.points === false) {
972
+ series[i].marker.enabled = false;
973
+ }
974
+ }
709
975
 
710
- var setMax = function (options, max) {
711
- options.vAxis.viewWindow.max = max;
712
- };
976
+ this.drawChart(chart, series, options);
977
+ };
713
978
 
714
- var setBarMin = function (options, min) {
715
- options.hAxis.viewWindow.min = min;
716
- };
979
+ defaultExport$1.prototype.renderScatterChart = function renderScatterChart (chart) {
980
+ var options = jsOptions$1(chart, chart.options, {});
981
+ options.chart.type = "scatter";
982
+ this.drawChart(chart, chart.data, options);
983
+ };
717
984
 
718
- var setBarMax = function (options, max) {
719
- options.hAxis.viewWindow.max = max;
720
- };
985
+ defaultExport$1.prototype.renderPieChart = function renderPieChart (chart) {
986
+ var chartOptions = merge(defaultOptions$1, {});
721
987
 
722
- var setStacked = function (options, stacked) {
723
- options.isStacked = !!stacked;
724
- };
988
+ if (chart.options.colors) {
989
+ chartOptions.colors = chart.options.colors;
990
+ }
991
+ if (chart.options.donut) {
992
+ chartOptions.plotOptions = {pie: {innerSize: "50%"}};
993
+ }
725
994
 
726
- var setXtitle = function (options, title) {
727
- options.hAxis.title = title;
728
- options.hAxis.titleTextStyle.italic = false;
729
- };
995
+ if ("legend" in chart.options) {
996
+ hideLegend$1(chartOptions, chart.options.legend);
997
+ }
730
998
 
731
- var setYtitle = function (options, title) {
732
- options.vAxis.title = title;
733
- options.vAxis.titleTextStyle.italic = false;
734
- };
999
+ if (chart.options.title) {
1000
+ setTitle$1(chartOptions, chart.options.title);
1001
+ }
735
1002
 
736
- var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
737
-
738
- // cant use object as key
739
- var createDataTable = function (series, columnType) {
740
- var i, j, s, d, key, rows = [], sortedLabels = [];
741
- for (i = 0; i < series.length; i++) {
742
- s = series[i];
743
-
744
- for (j = 0; j < s.data.length; j++) {
745
- d = s.data[j];
746
- key = (columnType === "datetime") ? d[0].getTime() : d[0];
747
- if (!rows[key]) {
748
- rows[key] = new Array(series.length);
749
- sortedLabels.push(key);
750
- }
751
- rows[key][i] = toFloat(d[1]);
752
- }
753
- }
1003
+ var options = merge(chartOptions, chart.options.library || {});
1004
+ setFormatOptions$1(chart, options, "pie");
1005
+ var series = [{
1006
+ type: "pie",
1007
+ name: chart.options.label || "Value",
1008
+ data: chart.data
1009
+ }];
754
1010
 
755
- var rows2 = [];
756
- var day = true;
757
- var value;
758
- for (var j = 0; j < sortedLabels.length; j++) {
759
- var i = sortedLabels[j];
760
- if (columnType === "datetime") {
761
- value = new Date(toFloat(i));
762
- day = day && isDay(value);
763
- } else if (columnType === "number") {
764
- value = toFloat(i);
765
- } else {
766
- value = i;
767
- }
768
- rows2.push([value].concat(rows[i]));
769
- }
770
- if (columnType === "datetime") {
771
- rows2.sort(sortByTime);
772
- }
1011
+ this.drawChart(chart, series, options);
1012
+ };
773
1013
 
774
- // create datatable
775
- var data = new google.visualization.DataTable();
776
- columnType = columnType === "datetime" && day ? "date" : columnType;
777
- data.addColumn(columnType, "");
778
- for (i = 0; i < series.length; i++) {
779
- data.addColumn("number", series[i].name);
780
- }
781
- data.addRows(rows2);
1014
+ defaultExport$1.prototype.renderColumnChart = function renderColumnChart (chart, chartType) {
1015
+ chartType = chartType || "column";
1016
+ var series = chart.data;
1017
+ var options = jsOptions$1(chart, chart.options), i, j, s, d, rows = [], categories = [];
1018
+ options.chart.type = chartType;
1019
+ setFormatOptions$1(chart, options, chartType);
782
1020
 
783
- return data;
784
- };
1021
+ for (i = 0; i < series.length; i++) {
1022
+ s = series[i];
785
1023
 
786
- var resize = function (callback) {
787
- if (window.attachEvent) {
788
- window.attachEvent("onresize", callback);
789
- } else if (window.addEventListener) {
790
- window.addEventListener("resize", callback, true);
791
- }
792
- callback();
793
- };
1024
+ for (j = 0; j < s.data.length; j++) {
1025
+ d = s.data[j];
1026
+ if (!rows[d[0]]) {
1027
+ rows[d[0]] = new Array(series.length);
1028
+ categories.push(d[0]);
1029
+ }
1030
+ rows[d[0]][i] = d[1];
1031
+ }
1032
+ }
794
1033
 
795
- this.renderLineChart = function (chart) {
796
- waitForLoaded(function () {
797
- var chartOptions = {};
1034
+ if (chart.xtype === "number") {
1035
+ categories.sort(sortByNumber);
1036
+ }
798
1037
 
799
- if (chart.options.curve === false) {
800
- chartOptions.curveType = "none";
801
- }
1038
+ options.xAxis.categories = categories;
802
1039
 
803
- var options = jsOptions(chart, chart.options, chartOptions);
804
- var data = createDataTable(chart.data, chart.discrete ? "string" : "datetime");
805
- chart.chart = new google.visualization.LineChart(chart.element);
806
- resize(function () {
807
- chart.chart.draw(data, options);
808
- });
809
- });
810
- };
1040
+ var newSeries = [], d2;
1041
+ for (i = 0; i < series.length; i++) {
1042
+ d = [];
1043
+ for (j = 0; j < categories.length; j++) {
1044
+ d.push(rows[categories[j]][i] || 0);
1045
+ }
811
1046
 
812
- this.renderPieChart = function (chart) {
813
- waitForLoaded(function () {
814
- var chartOptions = {
815
- chartArea: {
816
- top: "10%",
817
- height: "80%"
818
- },
819
- legend: {}
820
- };
821
- if (chart.options.colors) {
822
- chartOptions.colors = chart.options.colors;
823
- }
824
- if (chart.options.donut) {
825
- chartOptions.pieHole = 0.5;
826
- }
827
- if ("legend" in chart.options) {
828
- hideLegend(chartOptions, chart.options.legend);
829
- }
830
- if (chart.options.title) {
831
- setTitle(chartOptions, chart.options.title);
832
- }
833
- var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
834
-
835
- var data = new google.visualization.DataTable();
836
- data.addColumn("string", "");
837
- data.addColumn("number", "Value");
838
- data.addRows(chart.data);
839
-
840
- chart.chart = new google.visualization.PieChart(chart.element);
841
- resize(function () {
842
- chart.chart.draw(data, options);
843
- });
844
- });
845
- };
1047
+ d2 = {
1048
+ name: series[i].name || "Value",
1049
+ data: d
1050
+ };
1051
+ if (series[i].stack) {
1052
+ d2.stack = series[i].stack;
1053
+ }
846
1054
 
847
- this.renderColumnChart = function (chart) {
848
- waitForLoaded(function () {
849
- var options = jsOptions(chart, chart.options);
850
- var data = createDataTable(chart.data, "string");
851
- chart.chart = new google.visualization.ColumnChart(chart.element);
852
- resize(function () {
853
- chart.chart.draw(data, options);
854
- });
855
- });
856
- };
1055
+ newSeries.push(d2);
1056
+ }
857
1057
 
858
- this.renderBarChart = function (chart) {
859
- waitForLoaded(function () {
860
- var chartOptions = {
861
- hAxis: {
862
- gridlines: {
863
- color: "#ccc"
864
- }
865
- }
866
- };
867
- var options = jsOptionsFunc(defaultOptions, hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options, chartOptions);
868
- var data = createDataTable(chart.data, "string");
869
- chart.chart = new google.visualization.BarChart(chart.element);
870
- resize(function () {
871
- chart.chart.draw(data, options);
872
- });
873
- });
874
- };
1058
+ this.drawChart(chart, newSeries, options);
1059
+ };
875
1060
 
876
- this.renderAreaChart = function (chart) {
877
- waitForLoaded(function () {
878
- var chartOptions = {
879
- isStacked: true,
880
- pointSize: 0,
881
- areaOpacity: 0.5
882
- };
883
- var options = jsOptions(chart, chart.options, chartOptions);
884
- var data = createDataTable(chart.data, chart.discrete ? "string" : "datetime");
885
- chart.chart = new google.visualization.AreaChart(chart.element);
886
- resize(function () {
887
- chart.chart.draw(data, options);
888
- });
889
- });
890
- };
1061
+ defaultExport$1.prototype.renderBarChart = function renderBarChart (chart) {
1062
+ this.renderColumnChart(chart, "bar");
1063
+ };
891
1064
 
892
- this.renderGeoChart = function (chart) {
893
- waitForLoaded(function () {
894
- var chartOptions = {
895
- legend: "none",
896
- colorAxis: {
897
- colors: chart.options.colors || ["#f6c7b6", "#ce502d"]
898
- }
899
- };
900
- var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
901
-
902
- var data = new google.visualization.DataTable();
903
- data.addColumn("string", "");
904
- data.addColumn("number", chart.options.label || "Value");
905
- data.addRows(chart.data);
906
-
907
- chart.chart = new google.visualization.GeoChart(chart.element);
908
- resize(function () {
909
- chart.chart.draw(data, options);
910
- });
911
- });
912
- };
1065
+ defaultExport$1.prototype.renderAreaChart = function renderAreaChart (chart) {
1066
+ this.renderLineChart(chart, "areaspline");
1067
+ };
913
1068
 
914
- this.renderScatterChart = function (chart) {
915
- waitForLoaded(function () {
916
- var chartOptions = {};
917
- var options = jsOptions(chart, chart.options, chartOptions);
918
- var data = createDataTable(chart.data, "number");
919
-
920
- chart.chart = new google.visualization.ScatterChart(chart.element);
921
- resize(function () {
922
- chart.chart.draw(data, options);
923
- });
924
- });
925
- };
1069
+ defaultExport$1.prototype.destroy = function destroy (chart) {
1070
+ if (chart.chart) {
1071
+ chart.chart.destroy();
1072
+ }
1073
+ };
926
1074
 
927
- this.renderTimeline = function (chart) {
928
- waitForLoaded("timeline", function () {
929
- var chartOptions = {
930
- legend: "none"
931
- };
1075
+ defaultExport$1.prototype.drawChart = function drawChart (chart, data, options) {
1076
+ this.destroy(chart);
932
1077
 
933
- if (chart.options.colors) {
934
- chartOptions.colors = chart.options.colors;
935
- }
936
- var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
1078
+ options.chart.renderTo = chart.element.id;
1079
+ options.series = data;
937
1080
 
938
- var data = new google.visualization.DataTable();
939
- data.addColumn({type: "string", id: "Name"});
940
- data.addColumn({type: "date", id: "Start"});
941
- data.addColumn({type: "date", id: "End"});
942
- data.addRows(chart.data);
1081
+ if (chart.options.code) {
1082
+ window.console.log("new Highcharts.Chart(" + JSON.stringify(options) + ");");
1083
+ }
943
1084
 
944
- chart.element.style.lineHeight = "normal";
945
- chart.chart = new google.visualization.Timeline(chart.element);
1085
+ chart.chart = new this.library.Chart(options);
1086
+ };
946
1087
 
947
- resize(function () {
948
- chart.chart.draw(data, options);
949
- });
950
- });
951
- };
952
- };
1088
+ var loaded = {};
1089
+ var callbacks = [];
1090
+
1091
+ // Set chart options
1092
+ var defaultOptions$2 = {
1093
+ chartArea: {},
1094
+ fontName: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",
1095
+ pointSize: 6,
1096
+ legend: {
1097
+ textStyle: {
1098
+ fontSize: 12,
1099
+ color: "#444"
1100
+ },
1101
+ alignment: "center",
1102
+ position: "right"
1103
+ },
1104
+ curveType: "function",
1105
+ hAxis: {
1106
+ textStyle: {
1107
+ color: "#666",
1108
+ fontSize: 12
1109
+ },
1110
+ titleTextStyle: {},
1111
+ gridlines: {
1112
+ color: "transparent"
1113
+ },
1114
+ baselineColor: "#ccc",
1115
+ viewWindow: {}
1116
+ },
1117
+ vAxis: {
1118
+ textStyle: {
1119
+ color: "#666",
1120
+ fontSize: 12
1121
+ },
1122
+ titleTextStyle: {},
1123
+ baselineColor: "#ccc",
1124
+ viewWindow: {}
1125
+ },
1126
+ tooltip: {
1127
+ textStyle: {
1128
+ color: "#666",
1129
+ fontSize: 12
1130
+ }
1131
+ }
1132
+ };
953
1133
 
954
- adapters.push(GoogleChartsAdapter);
1134
+ var hideLegend$2 = function (options, legend, hideLegend) {
1135
+ if (legend !== undefined) {
1136
+ var position;
1137
+ if (!legend) {
1138
+ position = "none";
1139
+ } else if (legend === true) {
1140
+ position = "right";
1141
+ } else {
1142
+ position = legend;
1143
+ }
1144
+ options.legend.position = position;
1145
+ } else if (hideLegend) {
1146
+ options.legend.position = "none";
955
1147
  }
956
- if (!ChartjsAdapter && "Chart" in window) {
957
- ChartjsAdapter = new function () {
958
- var Chart = window.Chart;
1148
+ };
959
1149
 
960
- this.name = "chartjs";
1150
+ var setTitle$2 = function (options, title) {
1151
+ options.title = title;
1152
+ options.titleTextStyle = {color: "#333", fontSize: "20px"};
1153
+ };
961
1154
 
962
- var baseOptions = {
963
- maintainAspectRatio: false,
964
- animation: false,
965
- tooltips: {
966
- displayColors: false
967
- },
968
- legend: {},
969
- title: {fontSize: 20, fontColor: "#333"}
970
- };
1155
+ var setMin$2 = function (options, min) {
1156
+ options.vAxis.viewWindow.min = min;
1157
+ };
971
1158
 
972
- var defaultOptions = {
973
- scales: {
974
- yAxes: [
975
- {
976
- ticks: {
977
- maxTicksLimit: 4
978
- },
979
- scaleLabel: {
980
- fontSize: 16,
981
- // fontStyle: "bold",
982
- fontColor: "#333"
983
- }
984
- }
985
- ],
986
- xAxes: [
987
- {
988
- gridLines: {
989
- drawOnChartArea: false
990
- },
991
- scaleLabel: {
992
- fontSize: 16,
993
- // fontStyle: "bold",
994
- fontColor: "#333"
995
- },
996
- time: {},
997
- ticks: {}
998
- }
999
- ]
1000
- }
1001
- };
1159
+ var setMax$2 = function (options, max) {
1160
+ options.vAxis.viewWindow.max = max;
1161
+ };
1002
1162
 
1003
- // http://there4.io/2012/05/02/google-chart-color-list/
1004
- var defaultColors = [
1005
- "#3366CC", "#DC3912", "#FF9900", "#109618", "#990099", "#3B3EAC", "#0099C6",
1006
- "#DD4477", "#66AA00", "#B82E2E", "#316395", "#994499", "#22AA99", "#AAAA11",
1007
- "#6633CC", "#E67300", "#8B0707", "#329262", "#5574A6", "#3B3EAC"
1008
- ];
1009
-
1010
- var hideLegend = function (options, legend, hideLegend) {
1011
- if (legend !== undefined) {
1012
- options.legend.display = !!legend;
1013
- if (legend && legend !== true) {
1014
- options.legend.position = legend;
1015
- }
1016
- } else if (hideLegend) {
1017
- options.legend.display = false;
1018
- }
1019
- };
1163
+ var setBarMin$1 = function (options, min) {
1164
+ options.hAxis.viewWindow.min = min;
1165
+ };
1020
1166
 
1021
- var setTitle = function (options, title) {
1022
- options.title.display = true;
1023
- options.title.text = title;
1024
- };
1167
+ var setBarMax$1 = function (options, max) {
1168
+ options.hAxis.viewWindow.max = max;
1169
+ };
1025
1170
 
1026
- var setMin = function (options, min) {
1027
- if (min !== null) {
1028
- options.scales.yAxes[0].ticks.min = toFloat(min);
1029
- }
1030
- };
1171
+ var setStacked$2 = function (options, stacked) {
1172
+ options.isStacked = stacked ? stacked : false;
1173
+ };
1031
1174
 
1032
- var setMax = function (options, max) {
1033
- options.scales.yAxes[0].ticks.max = toFloat(max);
1034
- };
1175
+ var setXtitle$2 = function (options, title) {
1176
+ options.hAxis.title = title;
1177
+ options.hAxis.titleTextStyle.italic = false;
1178
+ };
1035
1179
 
1036
- var setBarMin = function (options, min) {
1037
- if (min !== null) {
1038
- options.scales.xAxes[0].ticks.min = toFloat(min);
1039
- }
1040
- };
1180
+ var setYtitle$2 = function (options, title) {
1181
+ options.vAxis.title = title;
1182
+ options.vAxis.titleTextStyle.italic = false;
1183
+ };
1041
1184
 
1042
- var setBarMax = function (options, max) {
1043
- options.scales.xAxes[0].ticks.max = toFloat(max);
1044
- };
1185
+ var jsOptions$2 = jsOptionsFunc(defaultOptions$2, hideLegend$2, setTitle$2, setMin$2, setMax$2, setStacked$2, setXtitle$2, setYtitle$2);
1045
1186
 
1046
- var setStacked = function (options, stacked) {
1047
- options.scales.xAxes[0].stacked = !!stacked;
1048
- options.scales.yAxes[0].stacked = !!stacked;
1049
- };
1187
+ var resize = function (callback) {
1188
+ if (window.attachEvent) {
1189
+ window.attachEvent("onresize", callback);
1190
+ } else if (window.addEventListener) {
1191
+ window.addEventListener("resize", callback, true);
1192
+ }
1193
+ callback();
1194
+ };
1050
1195
 
1051
- var setXtitle = function (options, title) {
1052
- options.scales.xAxes[0].scaleLabel.display = true;
1053
- options.scales.xAxes[0].scaleLabel.labelString = title;
1054
- };
1196
+ var defaultExport$2 = function defaultExport(library) {
1197
+ this.name = "google";
1198
+ this.library = library;
1199
+ };
1055
1200
 
1056
- var setYtitle = function (options, title) {
1057
- options.scales.yAxes[0].scaleLabel.display = true;
1058
- options.scales.yAxes[0].scaleLabel.labelString = title;
1059
- };
1201
+ defaultExport$2.prototype.renderLineChart = function renderLineChart (chart) {
1202
+ var this$1 = this;
1060
1203
 
1061
- var drawChart = function(chart, type, data, options) {
1062
- if (chart.chart) {
1063
- chart.chart.destroy();
1064
- } else {
1065
- chart.element.innerHTML = "<canvas></canvas>";
1066
- }
1204
+ this.waitForLoaded(chart, function () {
1205
+ var chartOptions = {};
1067
1206
 
1068
- var ctx = chart.element.getElementsByTagName("CANVAS")[0];
1069
- chart.chart = new Chart(ctx, {
1070
- type: type,
1071
- data: data,
1072
- options: options
1073
- });
1074
- };
1207
+ if (chart.options.curve === false) {
1208
+ chartOptions.curveType = "none";
1209
+ }
1075
1210
 
1076
- // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
1077
- var addOpacity = function(hex, opacity) {
1078
- var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
1079
- return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
1080
- };
1211
+ if (chart.options.points === false) {
1212
+ chartOptions.pointSize = 0;
1213
+ }
1081
1214
 
1082
- var setLabelSize = function (chart, data, options) {
1083
- var maxLabelSize = Math.ceil(chart.element.offsetWidth / 4.0 / data.labels.length);
1084
- if (maxLabelSize > 25) {
1085
- maxLabelSize = 25;
1086
- }
1087
- options.scales.xAxes[0].ticks.callback = function (value) {
1088
- value = toStr(value);
1089
- if (value.length > maxLabelSize) {
1090
- return value.substring(0, maxLabelSize - 2) + "...";
1091
- } else {
1092
- return value;
1093
- }
1094
- };
1095
- };
1215
+ var options = jsOptions$2(chart, chart.options, chartOptions);
1216
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1096
1217
 
1097
- var jsOptions = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setTitle, setMin, setMax, setStacked, setXtitle, setYtitle);
1098
-
1099
- var createDataTable = function (chart, options, chartType) {
1100
- var datasets = [];
1101
- var labels = [];
1102
-
1103
- var colors = chart.options.colors || defaultColors;
1104
-
1105
- var day = true;
1106
- var week = true;
1107
- var dayOfWeek;
1108
- var month = true;
1109
- var year = true;
1110
- var hour = true;
1111
- var minute = true;
1112
- var detectType = (chartType === "line" || chartType === "area") && !chart.discrete;
1113
-
1114
- var series = chart.data;
1115
-
1116
- var sortedLabels = [];
1117
-
1118
- var i, j, s, d, key, rows = [];
1119
- for (i = 0; i < series.length; i++) {
1120
- s = series[i];
1121
-
1122
- for (j = 0; j < s.data.length; j++) {
1123
- d = s.data[j];
1124
- key = detectType ? d[0].getTime() : d[0];
1125
- if (!rows[key]) {
1126
- rows[key] = new Array(series.length);
1127
- }
1128
- rows[key][i] = toFloat(d[1]);
1129
- if (sortedLabels.indexOf(key) === -1) {
1130
- sortedLabels.push(key);
1131
- }
1132
- }
1133
- }
1218
+ this$1.drawChart(chart, "LineChart", data, options);
1219
+ });
1220
+ };
1134
1221
 
1135
- if (detectType) {
1136
- sortedLabels.sort(sortByNumber);
1137
- }
1222
+ defaultExport$2.prototype.renderPieChart = function renderPieChart (chart) {
1223
+ var this$1 = this;
1138
1224
 
1139
- var rows2 = [];
1140
- for (j = 0; j < series.length; j++) {
1141
- rows2.push([]);
1142
- }
1225
+ this.waitForLoaded(chart, function () {
1226
+ var chartOptions = {
1227
+ chartArea: {
1228
+ top: "10%",
1229
+ height: "80%"
1230
+ },
1231
+ legend: {}
1232
+ };
1233
+ if (chart.options.colors) {
1234
+ chartOptions.colors = chart.options.colors;
1235
+ }
1236
+ if (chart.options.donut) {
1237
+ chartOptions.pieHole = 0.5;
1238
+ }
1239
+ if ("legend" in chart.options) {
1240
+ hideLegend$2(chartOptions, chart.options.legend);
1241
+ }
1242
+ if (chart.options.title) {
1243
+ setTitle$2(chartOptions, chart.options.title);
1244
+ }
1245
+ var options = merge(merge(defaultOptions$2, chartOptions), chart.options.library || {});
1143
1246
 
1144
- var value;
1145
- var k;
1146
- for (k = 0; k < sortedLabels.length; k++) {
1147
- i = sortedLabels[k];
1148
- if (detectType) {
1149
- value = new Date(toFloat(i));
1150
- // TODO make this efficient
1151
- day = day && isDay(value);
1152
- if (!dayOfWeek) {
1153
- dayOfWeek = value.getDay();
1154
- }
1155
- week = week && isWeek(value, dayOfWeek);
1156
- month = month && isMonth(value);
1157
- year = year && isYear(value);
1158
- hour = hour && isHour(value);
1159
- minute = minute && isMinute(value);
1160
- } else {
1161
- value = i;
1162
- }
1163
- labels.push(value);
1164
- for (j = 0; j < series.length; j++) {
1165
- // Chart.js doesn't like undefined
1166
- rows2[j].push(rows[i][j] === undefined ? null : rows[i][j]);
1167
- }
1168
- }
1247
+ var data = new this$1.library.visualization.DataTable();
1248
+ data.addColumn("string", "");
1249
+ data.addColumn("number", "Value");
1250
+ data.addRows(chart.data);
1169
1251
 
1170
- for (i = 0; i < series.length; i++) {
1171
- s = series[i];
1252
+ this$1.drawChart(chart, "PieChart", data, options);
1253
+ });
1254
+ };
1172
1255
 
1173
- var backgroundColor = chartType !== "line" ? addOpacity(colors[i], 0.5) : colors[i];
1256
+ defaultExport$2.prototype.renderColumnChart = function renderColumnChart (chart) {
1257
+ var this$1 = this;
1174
1258
 
1175
- var dataset = {
1176
- label: s.name,
1177
- data: rows2[i],
1178
- fill: chartType === "area",
1179
- borderColor: colors[i],
1180
- backgroundColor: backgroundColor,
1181
- pointBackgroundColor: colors[i],
1182
- borderWidth: 2
1183
- };
1259
+ this.waitForLoaded(chart, function () {
1260
+ var options = jsOptions$2(chart, chart.options);
1261
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1184
1262
 
1185
- if (chart.options.curve === false) {
1186
- dataset.lineTension = 0;
1187
- }
1263
+ this$1.drawChart(chart, "ColumnChart", data, options);
1264
+ });
1265
+ };
1188
1266
 
1189
- datasets.push(merge(dataset, s.library || {}));
1267
+ defaultExport$2.prototype.renderBarChart = function renderBarChart (chart) {
1268
+ var this$1 = this;
1269
+
1270
+ this.waitForLoaded(chart, function () {
1271
+ var chartOptions = {
1272
+ hAxis: {
1273
+ gridlines: {
1274
+ color: "#ccc"
1190
1275
  }
1276
+ }
1277
+ };
1278
+ var options = jsOptionsFunc(defaultOptions$2, hideLegend$2, setTitle$2, setBarMin$1, setBarMax$1, setStacked$2, setXtitle$2, setYtitle$2)(chart, chart.options, chartOptions);
1279
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1191
1280
 
1192
- if (detectType && labels.length > 0) {
1193
- var minTime = labels[0].getTime();
1194
- var maxTime = labels[0].getTime();
1195
- for (i = 1; i < labels.length; i++) {
1196
- value = labels[i].getTime();
1197
- if (value < minTime) {
1198
- minTime = value;
1199
- }
1200
- if (value > maxTime) {
1201
- maxTime = value;
1202
- }
1203
- }
1281
+ this$1.drawChart(chart, "BarChart", data, options);
1282
+ });
1283
+ };
1204
1284
 
1205
- var timeDiff = (maxTime - minTime) / (86400 * 1000.0);
1206
-
1207
- if (!options.scales.xAxes[0].time.unit) {
1208
- var step;
1209
- if (year || timeDiff > 365 * 10) {
1210
- options.scales.xAxes[0].time.unit = "year";
1211
- step = 365;
1212
- } else if (month || timeDiff > 30 * 10) {
1213
- options.scales.xAxes[0].time.unit = "month";
1214
- step = 30;
1215
- } else if (day || timeDiff > 10) {
1216
- options.scales.xAxes[0].time.unit = "day";
1217
- step = 1;
1218
- } else if (hour || timeDiff > 0.5) {
1219
- options.scales.xAxes[0].time.displayFormats = {hour: "MMM D, h a"};
1220
- options.scales.xAxes[0].time.unit = "hour";
1221
- step = 1 / 24.0;
1222
- } else if (minute) {
1223
- options.scales.xAxes[0].time.displayFormats = {minute: "h:mm a"};
1224
- options.scales.xAxes[0].time.unit = "minute";
1225
- step = 1 / 24.0 / 60.0;
1226
- }
1227
-
1228
- if (step && timeDiff > 0) {
1229
- var unitStepSize = Math.ceil(timeDiff / step / (chart.element.offsetWidth / 100.0));
1230
- if (week && step === 1) {
1231
- unitStepSize = Math.ceil(unitStepSize / 7.0) * 7;
1232
- }
1233
- options.scales.xAxes[0].time.unitStepSize = unitStepSize;
1234
- }
1235
- }
1285
+ defaultExport$2.prototype.renderAreaChart = function renderAreaChart (chart) {
1286
+ var this$1 = this;
1236
1287
 
1237
- if (!options.scales.xAxes[0].time.tooltipFormat) {
1238
- if (day) {
1239
- options.scales.xAxes[0].time.tooltipFormat = "ll";
1240
- } else if (hour) {
1241
- options.scales.xAxes[0].time.tooltipFormat = "MMM D, h a";
1242
- } else if (minute) {
1243
- options.scales.xAxes[0].time.tooltipFormat = "h:mm a";
1244
- }
1245
- }
1246
- }
1288
+ this.waitForLoaded(chart, function () {
1289
+ var chartOptions = {
1290
+ isStacked: true,
1291
+ pointSize: 0,
1292
+ areaOpacity: 0.5
1293
+ };
1247
1294
 
1248
- var data = {
1249
- labels: labels,
1250
- datasets: datasets
1251
- };
1295
+ var options = jsOptions$2(chart, chart.options, chartOptions);
1296
+ var data = this$1.createDataTable(chart.data, chart.xtype);
1252
1297
 
1253
- return data;
1254
- };
1298
+ this$1.drawChart(chart, "AreaChart", data, options);
1299
+ });
1300
+ };
1255
1301
 
1256
- this.renderLineChart = function (chart, chartType) {
1257
- var chartOptions = {};
1258
- if (chartType === "area") {
1259
- // TODO fix area stacked
1260
- // chartOptions.stacked = true;
1261
- }
1262
- // fix for https://github.com/chartjs/Chart.js/issues/2441
1263
- if (!chart.options.max && allZeros(chart.data)) {
1264
- chartOptions.max = 1;
1265
- }
1302
+ defaultExport$2.prototype.renderGeoChart = function renderGeoChart (chart) {
1303
+ var this$1 = this;
1304
+
1305
+ this.waitForLoaded(chart, function () {
1306
+ var chartOptions = {
1307
+ legend: "none",
1308
+ colorAxis: {
1309
+ colors: chart.options.colors || ["#f6c7b6", "#ce502d"]
1310
+ }
1311
+ };
1312
+ var options = merge(merge(defaultOptions$2, chartOptions), chart.options.library || {});
1266
1313
 
1267
- var options = jsOptions(chart, merge(chartOptions, chart.options));
1314
+ var data = new this$1.library.visualization.DataTable();
1315
+ data.addColumn("string", "");
1316
+ data.addColumn("number", chart.options.label || "Value");
1317
+ data.addRows(chart.data);
1268
1318
 
1269
- var data = createDataTable(chart, options, chartType || "line");
1319
+ this$1.drawChart(chart, "GeoChart", data, options);
1320
+ });
1321
+ };
1270
1322
 
1271
- options.scales.xAxes[0].type = chart.discrete ? "category" : "time";
1323
+ defaultExport$2.prototype.renderScatterChart = function renderScatterChart (chart) {
1324
+ var this$1 = this;
1325
+
1326
+ this.waitForLoaded(chart, function () {
1327
+ var chartOptions = {};
1328
+ var options = jsOptions$2(chart, chart.options, chartOptions);
1329
+
1330
+ var series = chart.data, rows2 = [], i, j, data, d;
1331
+ for (i = 0; i < series.length; i++) {
1332
+ series[i].name = series[i].name || "Value";
1333
+ d = series[i].data;
1334
+ for (j = 0; j < d.length; j++) {
1335
+ var row = new Array(series.length + 1);
1336
+ row[0] = d[j][0];
1337
+ row[i + 1] = d[j][1];
1338
+ rows2.push(row);
1339
+ }
1340
+ }
1272
1341
 
1273
- drawChart(chart, "line", data, options);
1274
- };
1342
+ data = new this$1.library.visualization.DataTable();
1343
+ data.addColumn("number", "");
1344
+ for (i = 0; i < series.length; i++) {
1345
+ data.addColumn("number", series[i].name);
1346
+ }
1347
+ data.addRows(rows2);
1275
1348
 
1276
- this.renderPieChart = function (chart) {
1277
- var options = merge({}, baseOptions);
1278
- if (chart.options.donut) {
1279
- options.cutoutPercentage = 50;
1280
- }
1349
+ this$1.drawChart(chart, "ScatterChart", data, options);
1350
+ });
1351
+ };
1281
1352
 
1282
- if ("legend" in chart.options) {
1283
- hideLegend(options, chart.options.legend);
1284
- }
1353
+ defaultExport$2.prototype.renderTimeline = function renderTimeline (chart) {
1354
+ var this$1 = this;
1285
1355
 
1286
- if (chart.options.title) {
1287
- setTitle(options, chart.options.title);
1288
- }
1356
+ this.waitForLoaded(chart, "timeline", function () {
1357
+ var chartOptions = {
1358
+ legend: "none"
1359
+ };
1360
+
1361
+ if (chart.options.colors) {
1362
+ chartOptions.colors = chart.options.colors;
1363
+ }
1364
+ var options = merge(merge(defaultOptions$2, chartOptions), chart.options.library || {});
1365
+
1366
+ var data = new this$1.library.visualization.DataTable();
1367
+ data.addColumn({type: "string", id: "Name"});
1368
+ data.addColumn({type: "date", id: "Start"});
1369
+ data.addColumn({type: "date", id: "End"});
1370
+ data.addRows(chart.data);
1371
+
1372
+ chart.element.style.lineHeight = "normal";
1373
+
1374
+ this$1.drawChart(chart, "Timeline", data, options);
1375
+ });
1376
+ };
1377
+
1378
+ defaultExport$2.prototype.destroy = function destroy (chart) {
1379
+ if (chart.chart) {
1380
+ chart.chart.clearChart();
1381
+ }
1382
+ };
1383
+
1384
+ defaultExport$2.prototype.drawChart = function drawChart (chart, type, data, options) {
1385
+ this.destroy(chart);
1386
+
1387
+ if (chart.options.code) {
1388
+ window.console.log("var data = new google.visualization.DataTable(" + data.toJSON() + ");\nvar chart = new google.visualization." + type + "(element);\nchart.draw(data, " + JSON.stringify(options) + ");");
1389
+ }
1390
+
1391
+ chart.chart = new this.library.visualization[type](chart.element);
1392
+ resize(function () {
1393
+ chart.chart.draw(data, options);
1394
+ });
1395
+ };
1396
+
1397
+ defaultExport$2.prototype.waitForLoaded = function waitForLoaded (chart, pack, callback) {
1398
+ var this$1 = this;
1289
1399
 
1290
- options = merge(options, chart.options.library || {});
1400
+ if (!callback) {
1401
+ callback = pack;
1402
+ pack = "corechart";
1403
+ }
1404
+
1405
+ callbacks.push({pack: pack, callback: callback});
1406
+
1407
+ if (loaded[pack]) {
1408
+ this.runCallbacks();
1409
+ } else {
1410
+ loaded[pack] = true;
1411
+
1412
+ // https://groups.google.com/forum/#!topic/google-visualization-api/fMKJcyA2yyI
1413
+ var loadOptions = {
1414
+ packages: [pack],
1415
+ callback: function () { this$1.runCallbacks(); }
1416
+ };
1417
+ var config = chart.__config();
1418
+ if (config.language) {
1419
+ loadOptions.language = config.language;
1420
+ }
1421
+ if (pack === "corechart" && config.mapsApiKey) {
1422
+ loadOptions.mapsApiKey = config.mapsApiKey;
1423
+ }
1424
+
1425
+ this.library.charts.load("current", loadOptions);
1426
+ }
1427
+ };
1428
+
1429
+ defaultExport$2.prototype.runCallbacks = function runCallbacks () {
1430
+ var this$1 = this;
1431
+
1432
+ var cb, call;
1433
+ for (var i = 0; i < callbacks.length; i++) {
1434
+ cb = callbacks[i];
1435
+ call = this$1.library.visualization && ((cb.pack === "corechart" && this$1.library.visualization.LineChart) || (cb.pack === "timeline" && this$1.library.visualization.Timeline));
1436
+ if (call) {
1437
+ cb.callback();
1438
+ callbacks.splice(i, 1);
1439
+ i--;
1440
+ }
1441
+ }
1442
+ };
1443
+
1444
+ // cant use object as key
1445
+ defaultExport$2.prototype.createDataTable = function createDataTable (series, columnType) {
1446
+ var i, j, s, d, key, rows = [], sortedLabels = [];
1447
+ for (i = 0; i < series.length; i++) {
1448
+ s = series[i];
1449
+ series[i].name = series[i].name || "Value";
1450
+
1451
+ for (j = 0; j < s.data.length; j++) {
1452
+ d = s.data[j];
1453
+ key = (columnType === "datetime") ? d[0].getTime() : d[0];
1454
+ if (!rows[key]) {
1455
+ rows[key] = new Array(series.length);
1456
+ sortedLabels.push(key);
1457
+ }
1458
+ rows[key][i] = toFloat(d[1]);
1459
+ }
1460
+ }
1461
+
1462
+ var rows2 = [];
1463
+ var day = true;
1464
+ var value;
1465
+ for (j = 0; j < sortedLabels.length; j++) {
1466
+ i = sortedLabels[j];
1467
+ if (columnType === "datetime") {
1468
+ value = new Date(toFloat(i));
1469
+ day = day && isDay(value);
1470
+ } else if (columnType === "number") {
1471
+ value = toFloat(i);
1472
+ } else {
1473
+ value = i;
1474
+ }
1475
+ rows2.push([value].concat(rows[i]));
1476
+ }
1477
+ if (columnType === "datetime") {
1478
+ rows2.sort(sortByTime);
1479
+ } else if (columnType === "number") {
1480
+ rows2.sort(sortByNumberSeries);
1481
+
1482
+ for (i = 0; i < rows2.length; i++) {
1483
+ rows2[i][0] = toStr(rows2[i][0]);
1484
+ }
1485
+
1486
+ columnType = "string";
1487
+ }
1488
+
1489
+ // create datatable
1490
+ var data = new this.library.visualization.DataTable();
1491
+ columnType = columnType === "datetime" && day ? "date" : columnType;
1492
+ data.addColumn(columnType, "");
1493
+ for (i = 0; i < series.length; i++) {
1494
+ data.addColumn("number", series[i].name);
1495
+ }
1496
+ data.addRows(rows2);
1497
+
1498
+ return data;
1499
+ };
1500
+
1501
+ var pendingRequests = [], runningRequests = 0, maxRequests = 4;
1502
+
1503
+ function pushRequest(url, success, error) {
1504
+ pendingRequests.push([url, success, error]);
1505
+ runNext();
1506
+ }
1507
+
1508
+ function runNext() {
1509
+ if (runningRequests < maxRequests) {
1510
+ var request = pendingRequests.shift();
1511
+ if (request) {
1512
+ runningRequests++;
1513
+ getJSON(request[0], request[1], request[2]);
1514
+ runNext();
1515
+ }
1516
+ }
1517
+ }
1518
+
1519
+ function requestComplete() {
1520
+ runningRequests--;
1521
+ runNext();
1522
+ }
1523
+
1524
+ function getJSON(url, success, error) {
1525
+ ajaxCall(url, success, function (jqXHR, textStatus, errorThrown) {
1526
+ var message = (typeof errorThrown === "string") ? errorThrown : errorThrown.message;
1527
+ error(message);
1528
+ });
1529
+ }
1530
+
1531
+ function ajaxCall(url, success, error) {
1532
+ var $ = window.jQuery || window.Zepto || window.$;
1533
+
1534
+ if ($) {
1535
+ $.ajax({
1536
+ dataType: "json",
1537
+ url: url,
1538
+ success: success,
1539
+ error: error,
1540
+ complete: requestComplete
1541
+ });
1542
+ } else {
1543
+ var xhr = new XMLHttpRequest();
1544
+ xhr.open("GET", url, true);
1545
+ xhr.setRequestHeader("Content-Type", "application/json");
1546
+ xhr.onload = function () {
1547
+ requestComplete();
1548
+ if (xhr.status === 200) {
1549
+ success(JSON.parse(xhr.responseText), xhr.statusText, xhr);
1550
+ } else {
1551
+ error(xhr, "error", xhr.statusText);
1552
+ }
1553
+ };
1554
+ xhr.send();
1555
+ }
1556
+ }
1557
+
1558
+ var config = {};
1559
+ var adapters = [];
1560
+
1561
+ // helpers
1562
+
1563
+ function setText(element, text) {
1564
+ if (document.body.innerText) {
1565
+ element.innerText = text;
1566
+ } else {
1567
+ element.textContent = text;
1568
+ }
1569
+ }
1570
+
1571
+ function chartError(element, message) {
1572
+ setText(element, "Error Loading Chart: " + message);
1573
+ element.style.color = "#ff0000";
1574
+ }
1575
+
1576
+ function errorCatcher(chart) {
1577
+ try {
1578
+ chart.__render();
1579
+ } catch (err) {
1580
+ chartError(chart.element, err.message);
1581
+ throw err;
1582
+ }
1583
+ }
1584
+
1585
+ function fetchDataSource(chart, dataSource) {
1586
+ if (typeof dataSource === "string") {
1587
+ pushRequest(dataSource, function (data) {
1588
+ chart.rawData = data;
1589
+ errorCatcher(chart);
1590
+ }, function (message) {
1591
+ chartError(chart.element, message);
1592
+ });
1593
+ } else {
1594
+ chart.rawData = dataSource;
1595
+ errorCatcher(chart);
1596
+ }
1597
+ }
1598
+
1599
+ function addDownloadButton(chart) {
1600
+ var element = chart.element;
1601
+ var link = document.createElement("a");
1602
+ link.download = chart.options.download === true ? "chart.png" : chart.options.download; // https://caniuse.com/download
1603
+ link.style.position = "absolute";
1604
+ link.style.top = "20px";
1605
+ link.style.right = "20px";
1606
+ link.style.zIndex = 1000;
1607
+ link.style.lineHeight = "20px";
1608
+ link.target = "_blank"; // for safari
1609
+ var image = document.createElement("img");
1610
+ image.alt = "Download";
1611
+ image.style.border = "none";
1612
+ // icon from font-awesome
1613
+ // http://fa2png.io/
1614
+ image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABCFBMVEUAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMywEsqxAAAAV3RSTlMAAQIDBggJCgsMDQ4PERQaHB0eISIjJCouLzE0OTo/QUJHSUpLTU5PUllhYmltcHh5foWLjI+SlaCio6atr7S1t7m6vsHHyM7R2tze5Obo7fHz9ff5+/1hlxK2AAAA30lEQVQYGUXBhVYCQQBA0TdYWAt2d3d3YWAHyur7/z9xgD16Lw0DW+XKx+1GgX+FRzM3HWQWrHl5N/oapW5RPe0PkBu+UYeICvozTWZVK23Ao04B79oJrOsJDOoxkZoQPWgX29pHpCZEk7rEvQYiNSFq1UMqvlCjJkRBS1R8hb00Vb/TajtBL7nTHE1X1vyMQF732dQhyF2o6SAwrzP06iUQzvwsArlnzcOdrgBhJyHa1QOgO9U1GsKuvjUTjavliZYQ8nNPapG6sap/3nrIdJ6bOWzmX/fy0XVpfzZP3S8OJT3g9EEiJwAAAABJRU5ErkJggg==";
1615
+ link.appendChild(image);
1616
+ element.style.position = "relative";
1291
1617
 
1292
- var labels = [];
1293
- var values = [];
1294
- for (var i = 0; i < chart.data.length; i++) {
1295
- var point = chart.data[i];
1296
- labels.push(point[0]);
1297
- values.push(point[1]);
1298
- }
1618
+ chart.__downloadAttached = true;
1299
1619
 
1300
- var data = {
1301
- labels: labels,
1302
- datasets: [
1303
- {
1304
- data: values,
1305
- backgroundColor: chart.options.colors || defaultColors
1306
- }
1307
- ]
1308
- };
1620
+ // mouseenter
1621
+ chart.__enterEvent = addEvent(element, "mouseover", function(e) {
1622
+ var related = e.relatedTarget;
1623
+ // check download option again to ensure it wasn't changed
1624
+ if ((!related || (related !== this && !childOf(this, related))) && chart.options.download) {
1625
+ link.href = chart.toImage();
1626
+ element.appendChild(link);
1627
+ }
1628
+ });
1309
1629
 
1310
- drawChart(chart, "pie", data, options);
1311
- };
1630
+ // mouseleave
1631
+ chart.__leaveEvent = addEvent(element, "mouseout", function(e) {
1632
+ var related = e.relatedTarget;
1633
+ if (!related || (related !== this && !childOf(this, related))) {
1634
+ if (link.parentNode) {
1635
+ link.parentNode.removeChild(link);
1636
+ }
1637
+ }
1638
+ });
1639
+ }
1312
1640
 
1313
- this.renderColumnChart = function (chart, chartType) {
1314
- var options;
1315
- if (chartType === "bar") {
1316
- options = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setTitle, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options);
1317
- } else {
1318
- options = jsOptions(chart, chart.options);
1319
- }
1320
- var data = createDataTable(chart, options, "column");
1321
- setLabelSize(chart, data, options);
1322
- drawChart(chart, (chartType === "bar" ? "horizontalBar" : "bar"), data, options);
1323
- };
1641
+ // https://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
1642
+ function addEvent(elem, event, fn) {
1643
+ if (elem.addEventListener) {
1644
+ elem.addEventListener(event, fn, false);
1645
+ return fn;
1646
+ } else {
1647
+ var fn2 = function() {
1648
+ // set the this pointer same as addEventListener when fn is called
1649
+ return(fn.call(elem, window.event));
1650
+ };
1651
+ elem.attachEvent("on" + event, fn2);
1652
+ return fn2;
1653
+ }
1654
+ }
1324
1655
 
1325
- var self = this;
1656
+ function removeEvent(elem, event, fn) {
1657
+ if (elem.removeEventListener) {
1658
+ elem.removeEventListener(event, fn, false);
1659
+ } else {
1660
+ elem.detachEvent("on" + event, fn);
1661
+ }
1662
+ }
1326
1663
 
1327
- this.renderAreaChart = function (chart) {
1328
- self.renderLineChart(chart, "area");
1329
- };
1664
+ // https://gist.github.com/shawnbot/4166283
1665
+ function childOf(p, c) {
1666
+ if (p === c) { return false; }
1667
+ while (c && c !== p) { c = c.parentNode; }
1668
+ return c === p;
1669
+ }
1330
1670
 
1331
- this.renderBarChart = function (chart) {
1332
- self.renderColumnChart(chart, "bar");
1333
- };
1671
+ function getAdapterType(library) {
1672
+ if (library) {
1673
+ if (library.product === "Highcharts") {
1674
+ return defaultExport$1;
1675
+ } else if (library.charts) {
1676
+ return defaultExport$2;
1677
+ } else if (isFunction(library)) {
1678
+ return defaultExport;
1679
+ }
1680
+ }
1681
+ throw new Error("Unknown adapter");
1682
+ }
1334
1683
 
1335
- this.renderScatterChart = function (chart) {
1336
- var options = jsOptions(chart, chart.options);
1337
-
1338
- var colors = chart.options.colors || defaultColors;
1339
-
1340
- var datasets = [];
1341
- var series = chart.data;
1342
- for (var i = 0; i < series.length; i++) {
1343
- var s = series[i];
1344
- var d = [];
1345
- for (var j = 0; j < s.data.length; j++) {
1346
- d.push({
1347
- x: toFloat(s.data[j][0]),
1348
- y: toFloat(s.data[j][1])
1349
- });
1350
- }
1684
+ function addAdapter(library) {
1685
+ var adapterType = getAdapterType(library);
1686
+ var adapter = new adapterType(library);
1351
1687
 
1352
- datasets.push({
1353
- label: s.name,
1354
- showLine: false,
1355
- data: d,
1356
- borderColor: colors[i],
1357
- backgroundColor: colors[i],
1358
- pointBackgroundColor: colors[i]
1359
- })
1360
- }
1688
+ if (adapters.indexOf(adapter) === -1) {
1689
+ adapters.push(adapter);
1690
+ }
1691
+ }
1361
1692
 
1362
- var data = {datasets: datasets};
1693
+ function loadAdapters() {
1694
+ if ("Chart" in window) {
1695
+ addAdapter(window.Chart);
1696
+ }
1363
1697
 
1364
- options.scales.xAxes[0].type = "linear";
1365
- options.scales.xAxes[0].position = "bottom";
1698
+ if ("Highcharts" in window) {
1699
+ addAdapter(window.Highcharts);
1700
+ }
1366
1701
 
1367
- drawChart(chart, "line", data, options);
1368
- };
1369
- };
1702
+ if (window.google && window.google.charts) {
1703
+ addAdapter(window.google);
1704
+ }
1705
+ }
1370
1706
 
1371
- adapters.unshift(ChartjsAdapter);
1707
+ function dataEmpty(data, chartType) {
1708
+ if (chartType === "PieChart" || chartType === "GeoChart" || chartType === "Timeline") {
1709
+ return data.length === 0;
1710
+ } else {
1711
+ for (var i = 0; i < data.length; i++) {
1712
+ if (data[i].data.length > 0) {
1713
+ return false;
1714
+ }
1715
+ }
1716
+ return true;
1372
1717
  }
1373
1718
  }
1374
1719
 
1375
1720
  function renderChart(chartType, chart) {
1376
- callAdapter(chartType, chart);
1377
- if (chart.options.download && !chart.downloadAttached && chart.adapter === "chartjs") {
1378
- addDownloadButton(chart);
1721
+ if (chart.options.messages && chart.options.messages.empty && dataEmpty(chart.data, chartType)) {
1722
+ setText(chart.element, chart.options.messages.empty);
1723
+ } else {
1724
+ callAdapter(chartType, chart);
1725
+ if (chart.options.download && !chart.__downloadAttached && chart.adapter === "chartjs") {
1726
+ addDownloadButton(chart);
1727
+ }
1379
1728
  }
1380
1729
  }
1381
1730
 
@@ -1392,10 +1741,16 @@
1392
1741
  adapter = adapters[i];
1393
1742
  if ((!adapterName || adapterName === adapter.name) && isFunction(adapter[fnName])) {
1394
1743
  chart.adapter = adapter.name;
1744
+ chart.__adapterObject = adapter;
1395
1745
  return adapter[fnName](chart);
1396
1746
  }
1397
1747
  }
1398
- throw new Error("No adapter found");
1748
+
1749
+ if (adapters.length > 0) {
1750
+ throw new Error("No charting library found for " + chartType);
1751
+ } else {
1752
+ throw new Error("No charting libraries found - be sure to include one before your charts");
1753
+ }
1399
1754
  }
1400
1755
 
1401
1756
  // process data
@@ -1414,49 +1769,37 @@
1414
1769
  var formatSeriesData = function (data, keyType) {
1415
1770
  var r = [], key, j;
1416
1771
  for (j = 0; j < data.length; j++) {
1417
- key = toFormattedKey(data[j][0], keyType);
1418
- r.push([key, toFloat(data[j][1])]);
1772
+ if (keyType === "bubble") {
1773
+ r.push([toFloat(data[j][0]), toFloat(data[j][1]), toFloat(data[j][2])]);
1774
+ } else {
1775
+ key = toFormattedKey(data[j][0], keyType);
1776
+ r.push([key, toFloat(data[j][1])]);
1777
+ }
1419
1778
  }
1420
1779
  if (keyType === "datetime") {
1421
1780
  r.sort(sortByTime);
1781
+ } else if (keyType === "number") {
1782
+ r.sort(sortByNumberSeries);
1422
1783
  }
1423
1784
  return r;
1424
1785
  };
1425
1786
 
1426
- function isMinute(d) {
1427
- return d.getMilliseconds() === 0 && d.getSeconds() === 0;
1428
- }
1429
-
1430
- function isHour(d) {
1431
- return isMinute(d) && d.getMinutes() === 0;
1432
- }
1433
-
1434
- function isDay(d) {
1435
- return isHour(d) && d.getHours() === 0;
1436
- }
1437
-
1438
- function isWeek(d, dayOfWeek) {
1439
- return isDay(d) && d.getDay() === dayOfWeek;
1440
- }
1441
-
1442
- function isMonth(d) {
1443
- return isDay(d) && d.getDate() === 1;
1444
- }
1445
-
1446
- function isYear(d) {
1447
- return isMonth(d) && d.getMonth() === 0;
1448
- }
1449
-
1450
- function isDate(obj) {
1451
- return !isNaN(toDate(obj)) && toStr(obj).length >= 6;
1787
+ function detectXType(series, noDatetime) {
1788
+ if (detectXTypeWithFunction(series, isNumber)) {
1789
+ return "number";
1790
+ } else if (!noDatetime && detectXTypeWithFunction(series, isDate)) {
1791
+ return "datetime";
1792
+ } else {
1793
+ return "string";
1794
+ }
1452
1795
  }
1453
1796
 
1454
- function allZeros(data) {
1455
- var i, j, d;
1456
- for (i = 0; i < data.length; i++) {
1457
- d = data[i].data;
1458
- for (j = 0; j < d.length; j++) {
1459
- if (d[j][1] != 0) {
1797
+ function detectXTypeWithFunction(series, func) {
1798
+ var i, j, data;
1799
+ for (i = 0; i < series.length; i++) {
1800
+ data = toArr(series[i].data);
1801
+ for (j = 0; j < data.length; j++) {
1802
+ if (!func(data[j][0])) {
1460
1803
  return false;
1461
1804
  }
1462
1805
  }
@@ -1464,20 +1807,23 @@
1464
1807
  return true;
1465
1808
  }
1466
1809
 
1467
- function detectDiscrete(series) {
1468
- var i, j, data;
1810
+ // creates a shallow copy of each element of the array
1811
+ // elements are expected to be objects
1812
+ function copySeries(series) {
1813
+ var newSeries = [], i, j;
1469
1814
  for (i = 0; i < series.length; i++) {
1470
- data = toArr(series[i].data);
1471
- for (j = 0; j < data.length; j++) {
1472
- if (!isDate(data[j][0])) {
1473
- return true;
1815
+ var copy = {};
1816
+ for (j in series[i]) {
1817
+ if (series[i].hasOwnProperty(j)) {
1818
+ copy[j] = series[i][j];
1474
1819
  }
1475
1820
  }
1821
+ newSeries.push(copy);
1476
1822
  }
1477
- return false;
1823
+ return newSeries;
1478
1824
  }
1479
1825
 
1480
- function processSeries(chart, keyType) {
1826
+ function processSeries(chart, keyType, noDatetime) {
1481
1827
  var i;
1482
1828
 
1483
1829
  var opts = chart.options;
@@ -1485,23 +1831,18 @@
1485
1831
 
1486
1832
  // see if one series or multiple
1487
1833
  if (!isArray(series) || typeof series[0] !== "object" || isArray(series[0])) {
1488
- series = [{name: opts.label || "Value", data: series}];
1834
+ series = [{name: opts.label, data: series}];
1489
1835
  chart.hideLegend = true;
1490
1836
  } else {
1491
1837
  chart.hideLegend = false;
1492
1838
  }
1493
- if ((opts.discrete === null || opts.discrete === undefined)) {
1494
- chart.discrete = detectDiscrete(series);
1495
- } else {
1496
- chart.discrete = opts.discrete;
1497
- }
1498
- if (chart.discrete) {
1499
- keyType = "string";
1500
- }
1839
+
1840
+ chart.xtype = keyType ? keyType : (opts.discrete ? "string" : detectXType(series, noDatetime));
1501
1841
 
1502
1842
  // right format
1843
+ series = copySeries(series);
1503
1844
  for (i = 0; i < series.length; i++) {
1504
- series[i].data = formatSeriesData(toArr(series[i].data), keyType);
1845
+ series[i].data = formatSeriesData(toArr(series[i].data), chart.xtype);
1505
1846
  }
1506
1847
 
1507
1848
  return series;
@@ -1515,37 +1856,9 @@
1515
1856
  return perfectData;
1516
1857
  }
1517
1858
 
1518
- function processTime(chart)
1519
- {
1520
- var i, data = chart.rawData;
1521
- for (i = 0; i < data.length; i++) {
1522
- data[i][1] = toDate(data[i][1]);
1523
- data[i][2] = toDate(data[i][2]);
1524
- }
1525
- return data;
1526
- }
1527
-
1528
- function processLineData(chart) {
1529
- return processSeries(chart, "datetime");
1530
- }
1531
-
1532
- function processColumnData(chart) {
1533
- return processSeries(chart, "string");
1534
- }
1535
-
1536
- function processBarData(chart) {
1537
- return processSeries(chart, "string");
1538
- }
1539
-
1540
- function processAreaData(chart) {
1541
- return processSeries(chart, "datetime");
1542
- }
1543
-
1544
- function processScatterData(chart) {
1545
- return processSeries(chart, "number");
1546
- }
1859
+ // define classes
1547
1860
 
1548
- function createChart(chartType, chart, element, dataSource, opts, processData) {
1861
+ var Chart = function Chart(element, dataSource, options) {
1549
1862
  var elementId;
1550
1863
  if (typeof element === "string") {
1551
1864
  elementId = element;
@@ -1554,117 +1867,327 @@
1554
1867
  throw new Error("No element with id " + elementId);
1555
1868
  }
1556
1869
  }
1870
+ this.element = element;
1871
+ this.options = merge(Chartkick.options, options || {});
1872
+ this.dataSource = dataSource;
1873
+
1874
+ Chartkick.charts[element.id] = this;
1875
+
1876
+ fetchDataSource(this, dataSource);
1877
+
1878
+ if (this.options.refresh) {
1879
+ this.startRefresh();
1880
+ }
1881
+ };
1882
+
1883
+ Chart.prototype.getElement = function getElement () {
1884
+ return this.element;
1885
+ };
1886
+
1887
+ Chart.prototype.getDataSource = function getDataSource () {
1888
+ return this.dataSource;
1889
+ };
1890
+
1891
+ Chart.prototype.getData = function getData () {
1892
+ return this.data;
1893
+ };
1894
+
1895
+ Chart.prototype.getOptions = function getOptions () {
1896
+ return this.options;
1897
+ };
1898
+
1899
+ Chart.prototype.getChartObject = function getChartObject () {
1900
+ return this.chart;
1901
+ };
1902
+
1903
+ Chart.prototype.getAdapter = function getAdapter () {
1904
+ return this.adapter;
1905
+ };
1906
+
1907
+ Chart.prototype.updateData = function updateData (dataSource, options) {
1908
+ this.dataSource = dataSource;
1909
+ if (options) {
1910
+ this.__updateOptions(options);
1911
+ }
1912
+ fetchDataSource(this, dataSource);
1913
+ };
1914
+
1915
+ Chart.prototype.setOptions = function setOptions (options) {
1916
+ this.__updateOptions(options);
1917
+ this.redraw();
1918
+ };
1919
+
1920
+ Chart.prototype.redraw = function redraw () {
1921
+ fetchDataSource(this, this.rawData);
1922
+ };
1923
+
1924
+ Chart.prototype.refreshData = function refreshData () {
1925
+ if (typeof this.dataSource === "string") {
1926
+ // prevent browser from caching
1927
+ var sep = this.dataSource.indexOf("?") === -1 ? "?" : "&";
1928
+ var url = this.dataSource + sep + "_=" + (new Date()).getTime();
1929
+ fetchDataSource(this, url);
1930
+ }
1931
+ };
1557
1932
 
1558
- chart.element = element;
1559
- opts = merge(Chartkick.options, opts || {});
1560
- chart.options = opts;
1561
- chart.dataSource = dataSource;
1933
+ Chart.prototype.startRefresh = function startRefresh () {
1934
+ var this$1 = this;
1562
1935
 
1563
- if (!processData) {
1564
- processData = function (chart) {
1565
- return chart.rawData;
1936
+ var refresh = this.options.refresh;
1937
+
1938
+ if (!this.intervalId) {
1939
+ if (refresh) {
1940
+ this.intervalId = setInterval( function () {
1941
+ this$1.refreshData();
1942
+ }, refresh * 1000);
1943
+ } else {
1944
+ throw new Error("No refresh interval");
1566
1945
  }
1567
1946
  }
1947
+ };
1948
+
1949
+ Chart.prototype.stopRefresh = function stopRefresh () {
1950
+ if (this.intervalId) {
1951
+ clearInterval(this.intervalId);
1952
+ this.intervalId = null;
1953
+ }
1954
+ };
1955
+
1956
+ Chart.prototype.toImage = function toImage () {
1957
+ if (this.adapter === "chartjs") {
1958
+ return this.chart.toBase64Image();
1959
+ } else {
1960
+ return null;
1961
+ }
1962
+ };
1963
+
1964
+ Chart.prototype.destroy = function destroy () {
1965
+ if (this.__adapterObject) {
1966
+ this.__adapterObject.destroy(this);
1967
+ }
1968
+
1969
+ if (this.__enterEvent) {
1970
+ removeEvent(this.element, "mouseover", this.__enterEvent);
1971
+ }
1972
+
1973
+ if (this.__leaveEvent) {
1974
+ removeEvent(this.element, "mouseout", this.__leaveEvent);
1975
+ }
1976
+ };
1977
+
1978
+ Chart.prototype.__updateOptions = function __updateOptions (options) {
1979
+ var updateRefresh = options.refresh && options.refresh !== this.options.refresh;
1980
+ this.options = merge(Chartkick.options, options);
1981
+ if (updateRefresh) {
1982
+ this.stopRefresh();
1983
+ this.startRefresh();
1984
+ }
1985
+ };
1986
+
1987
+ Chart.prototype.__render = function __render () {
1988
+ this.data = this.__processData();
1989
+ renderChart(this.__chartName(), this);
1990
+ };
1991
+
1992
+ Chart.prototype.__config = function __config () {
1993
+ return config;
1994
+ };
1995
+
1996
+ var LineChart = (function (Chart) {
1997
+ function LineChart () {
1998
+ Chart.apply(this, arguments);
1999
+ }
2000
+
2001
+ if ( Chart ) LineChart.__proto__ = Chart;
2002
+ LineChart.prototype = Object.create( Chart && Chart.prototype );
2003
+ LineChart.prototype.constructor = LineChart;
2004
+
2005
+ LineChart.prototype.__processData = function __processData () {
2006
+ return processSeries(this);
2007
+ };
2008
+
2009
+ LineChart.prototype.__chartName = function __chartName () {
2010
+ return "LineChart";
2011
+ };
2012
+
2013
+ return LineChart;
2014
+ }(Chart));
2015
+
2016
+ var PieChart = (function (Chart) {
2017
+ function PieChart () {
2018
+ Chart.apply(this, arguments);
2019
+ }
1568
2020
 
1569
- // getters
1570
- chart.getElement = function () {
1571
- return element;
2021
+ if ( Chart ) PieChart.__proto__ = Chart;
2022
+ PieChart.prototype = Object.create( Chart && Chart.prototype );
2023
+ PieChart.prototype.constructor = PieChart;
2024
+
2025
+ PieChart.prototype.__processData = function __processData () {
2026
+ return processSimple(this);
1572
2027
  };
1573
- chart.getDataSource = function () {
1574
- return chart.dataSource;
2028
+
2029
+ PieChart.prototype.__chartName = function __chartName () {
2030
+ return "PieChart";
1575
2031
  };
1576
- chart.getData = function () {
1577
- return chart.data;
2032
+
2033
+ return PieChart;
2034
+ }(Chart));
2035
+
2036
+ var ColumnChart = (function (Chart) {
2037
+ function ColumnChart () {
2038
+ Chart.apply(this, arguments);
2039
+ }
2040
+
2041
+ if ( Chart ) ColumnChart.__proto__ = Chart;
2042
+ ColumnChart.prototype = Object.create( Chart && Chart.prototype );
2043
+ ColumnChart.prototype.constructor = ColumnChart;
2044
+
2045
+ ColumnChart.prototype.__processData = function __processData () {
2046
+ return processSeries(this, null, true);
1578
2047
  };
1579
- chart.getOptions = function () {
1580
- return chart.options;
2048
+
2049
+ ColumnChart.prototype.__chartName = function __chartName () {
2050
+ return "ColumnChart";
1581
2051
  };
1582
- chart.getChartObject = function () {
1583
- return chart.chart;
2052
+
2053
+ return ColumnChart;
2054
+ }(Chart));
2055
+
2056
+ var BarChart = (function (Chart) {
2057
+ function BarChart () {
2058
+ Chart.apply(this, arguments);
2059
+ }
2060
+
2061
+ if ( Chart ) BarChart.__proto__ = Chart;
2062
+ BarChart.prototype = Object.create( Chart && Chart.prototype );
2063
+ BarChart.prototype.constructor = BarChart;
2064
+
2065
+ BarChart.prototype.__processData = function __processData () {
2066
+ return processSeries(this, null, true);
1584
2067
  };
1585
- chart.getAdapter = function () {
1586
- return chart.adapter;
2068
+
2069
+ BarChart.prototype.__chartName = function __chartName () {
2070
+ return "BarChart";
1587
2071
  };
1588
2072
 
1589
- var callback = function () {
1590
- chart.data = processData(chart);
1591
- renderChart(chartType, chart);
2073
+ return BarChart;
2074
+ }(Chart));
2075
+
2076
+ var AreaChart = (function (Chart) {
2077
+ function AreaChart () {
2078
+ Chart.apply(this, arguments);
2079
+ }
2080
+
2081
+ if ( Chart ) AreaChart.__proto__ = Chart;
2082
+ AreaChart.prototype = Object.create( Chart && Chart.prototype );
2083
+ AreaChart.prototype.constructor = AreaChart;
2084
+
2085
+ AreaChart.prototype.__processData = function __processData () {
2086
+ return processSeries(this);
1592
2087
  };
1593
2088
 
1594
- // functions
1595
- chart.updateData = function (dataSource, options) {
1596
- chart.dataSource = dataSource;
1597
- if (options) {
1598
- chart.options = merge(Chartkick.options, options);
1599
- }
1600
- fetchDataSource(chart, callback, dataSource);
2089
+ AreaChart.prototype.__chartName = function __chartName () {
2090
+ return "AreaChart";
1601
2091
  };
1602
- chart.setOptions = function (options) {
1603
- chart.options = merge(Chartkick.options, options);
1604
- chart.redraw();
2092
+
2093
+ return AreaChart;
2094
+ }(Chart));
2095
+
2096
+ var GeoChart = (function (Chart) {
2097
+ function GeoChart () {
2098
+ Chart.apply(this, arguments);
2099
+ }
2100
+
2101
+ if ( Chart ) GeoChart.__proto__ = Chart;
2102
+ GeoChart.prototype = Object.create( Chart && Chart.prototype );
2103
+ GeoChart.prototype.constructor = GeoChart;
2104
+
2105
+ GeoChart.prototype.__processData = function __processData () {
2106
+ return processSimple(this);
1605
2107
  };
1606
- chart.redraw = function() {
1607
- fetchDataSource(chart, callback, chart.rawData);
2108
+
2109
+ GeoChart.prototype.__chartName = function __chartName () {
2110
+ return "GeoChart";
1608
2111
  };
1609
- chart.refreshData = function () {
1610
- if (typeof dataSource === "string") {
1611
- // prevent browser from caching
1612
- var sep = dataSource.indexOf("?") === -1 ? "?" : "&";
1613
- var url = dataSource + sep + "_=" + (new Date()).getTime();
1614
- fetchDataSource(chart, callback, url);
1615
- }
2112
+
2113
+ return GeoChart;
2114
+ }(Chart));
2115
+
2116
+ var ScatterChart = (function (Chart) {
2117
+ function ScatterChart () {
2118
+ Chart.apply(this, arguments);
2119
+ }
2120
+
2121
+ if ( Chart ) ScatterChart.__proto__ = Chart;
2122
+ ScatterChart.prototype = Object.create( Chart && Chart.prototype );
2123
+ ScatterChart.prototype.constructor = ScatterChart;
2124
+
2125
+ ScatterChart.prototype.__processData = function __processData () {
2126
+ return processSeries(this, "number");
1616
2127
  };
1617
- chart.stopRefresh = function () {
1618
- if (chart.intervalId) {
1619
- clearInterval(chart.intervalId);
1620
- }
2128
+
2129
+ ScatterChart.prototype.__chartName = function __chartName () {
2130
+ return "ScatterChart";
1621
2131
  };
1622
- chart.toImage = function () {
1623
- if (chart.adapter === "chartjs") {
1624
- return chart.chart.toBase64Image();
1625
- } else {
1626
- return null;
1627
- }
2132
+
2133
+ return ScatterChart;
2134
+ }(Chart));
2135
+
2136
+ var BubbleChart = (function (Chart) {
2137
+ function BubbleChart () {
2138
+ Chart.apply(this, arguments);
1628
2139
  }
1629
2140
 
1630
- Chartkick.charts[element.id] = chart;
2141
+ if ( Chart ) BubbleChart.__proto__ = Chart;
2142
+ BubbleChart.prototype = Object.create( Chart && Chart.prototype );
2143
+ BubbleChart.prototype.constructor = BubbleChart;
2144
+
2145
+ BubbleChart.prototype.__processData = function __processData () {
2146
+ return processSeries(this, "bubble");
2147
+ };
2148
+
2149
+ BubbleChart.prototype.__chartName = function __chartName () {
2150
+ return "BubbleChart";
2151
+ };
1631
2152
 
1632
- fetchDataSource(chart, callback, dataSource);
2153
+ return BubbleChart;
2154
+ }(Chart));
1633
2155
 
1634
- if (opts.refresh) {
1635
- chart.intervalId = setInterval( function () {
1636
- chart.refreshData();
1637
- }, opts.refresh * 1000);
2156
+ var Timeline = (function (Chart) {
2157
+ function Timeline () {
2158
+ Chart.apply(this, arguments);
1638
2159
  }
1639
- }
1640
2160
 
1641
- // define classes
2161
+ if ( Chart ) Timeline.__proto__ = Chart;
2162
+ Timeline.prototype = Object.create( Chart && Chart.prototype );
2163
+ Timeline.prototype.constructor = Timeline;
1642
2164
 
1643
- Chartkick = {
1644
- LineChart: function (element, dataSource, options) {
1645
- createChart("LineChart", this, element, dataSource, options, processLineData);
1646
- },
1647
- PieChart: function (element, dataSource, options) {
1648
- createChart("PieChart", this, element, dataSource, options, processSimple);
1649
- },
1650
- ColumnChart: function (element, dataSource, options) {
1651
- createChart("ColumnChart", this, element, dataSource, options, processColumnData);
1652
- },
1653
- BarChart: function (element, dataSource, options) {
1654
- createChart("BarChart", this, element, dataSource, options, processBarData);
1655
- },
1656
- AreaChart: function (element, dataSource, options) {
1657
- createChart("AreaChart", this, element, dataSource, options, processAreaData);
1658
- },
1659
- GeoChart: function (element, dataSource, options) {
1660
- createChart("GeoChart", this, element, dataSource, options, processSimple);
1661
- },
1662
- ScatterChart: function (element, dataSource, options) {
1663
- createChart("ScatterChart", this, element, dataSource, options, processScatterData);
1664
- },
1665
- Timeline: function (element, dataSource, options) {
1666
- createChart("Timeline", this, element, dataSource, options, processTime);
1667
- },
2165
+ Timeline.prototype.__processData = function __processData () {
2166
+ var i, data = this.rawData;
2167
+ for (i = 0; i < data.length; i++) {
2168
+ data[i][1] = toDate(data[i][1]);
2169
+ data[i][2] = toDate(data[i][2]);
2170
+ }
2171
+ return data;
2172
+ };
2173
+
2174
+ Timeline.prototype.__chartName = function __chartName () {
2175
+ return "Timeline";
2176
+ };
2177
+
2178
+ return Timeline;
2179
+ }(Chart));
2180
+
2181
+ var Chartkick = {
2182
+ LineChart: LineChart,
2183
+ PieChart: PieChart,
2184
+ ColumnChart: ColumnChart,
2185
+ BarChart: BarChart,
2186
+ AreaChart: AreaChart,
2187
+ GeoChart: GeoChart,
2188
+ ScatterChart: ScatterChart,
2189
+ BubbleChart: BubbleChart,
2190
+ Timeline: Timeline,
1668
2191
  charts: {},
1669
2192
  configure: function (options) {
1670
2193
  for (var key in options) {
@@ -1680,14 +2203,12 @@
1680
2203
  }
1681
2204
  }
1682
2205
  },
2206
+ config: config,
1683
2207
  options: {},
1684
2208
  adapters: adapters,
1685
- createChart: createChart
2209
+ addAdapter: addAdapter
1686
2210
  };
1687
2211
 
1688
- if (typeof module === "object" && typeof module.exports === "object") {
1689
- module.exports = Chartkick;
1690
- } else {
1691
- window.Chartkick = Chartkick;
1692
- }
1693
- }(window));
2212
+ return Chartkick;
2213
+
2214
+ })));