sql-jarvis 2.0.1 → 2.0.2

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