chartkick 2.1.3 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of chartkick might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e8ed2c685106748108bd6e6e93cb468280b4b3d
4
- data.tar.gz: e34741a63fde19a62466eb7624555664f62d66a8
3
+ metadata.gz: 9e1f932c952cad32abefb5bdfe6d3920ede7a2a2
4
+ data.tar.gz: 89b2fe66eb366657306bb063f9937e30d4d6c380
5
5
  SHA512:
6
- metadata.gz: 8e613bf3f0291940255a08d8e4631b0dd218da32bdd9a57251ec41284a61a1fd76698621ca8bfa571a7a0d88397939d8af64bc96cb07c470c9e7cb57afc4555c
7
- data.tar.gz: 3f4a411acbfc6a4968621c701543f8f9e42c2ee978d996b36462bc675bf15d8f36139143c412e5020d653373b9cf6fb20b9cb6c454be552577c7c73d0f396010
6
+ metadata.gz: 2e3f98e5f9c0066f3d478b8097d7a8562ee0ca5ad0c9138561a8a4ac598019c66721b955f80742ffd66aa02dd6303cf80a04da426617348abe7913798adabb1d
7
+ data.tar.gz: cca4ae3d594a9e71f1a16d4d20b10d103a7c8455704bbe575bb7bfb2884dddf0b9ca591c092cf1b2768b03e7f2749337f2a7a2a5f8f90468f832b616745715e3
@@ -1,3 +1,11 @@
1
+ ## 2.2.0
2
+
3
+ - Updated Chartkick.js to 2.2.0
4
+ - Improved JavaScript API
5
+ - Added `download` option - *Chart.js only*
6
+ - Added `refresh` option
7
+ - Added `donut` option to pie chart
8
+
1
9
  ## 2.1.3
2
10
 
3
11
  - Updated Chartkick.js to 2.1.2 - fixes missing zero values for Chart.js
data/README.md CHANGED
@@ -146,13 +146,25 @@ Axis titles
146
146
  <%= line_chart data, xtitle: "Time", ytitle: "Population" %>
147
147
  ```
148
148
 
149
+ Donut chart
150
+
151
+ ```erb
152
+ <%= pie_chart data, donut: true %>
153
+ ```
154
+
155
+ Refresh data from a remote source every `n` seconds
156
+
157
+ ```erb
158
+ <%= line_chart url, refresh: 60 %>
159
+ ```
160
+
149
161
  You can pass options directly to the charting library with:
150
162
 
151
163
  ```erb
152
164
  <%= line_chart data, library: {backgroundColor: "#eee"} %>
153
165
  ```
154
166
 
155
- See the documentation for [Google Charts](https://developers.google.com/chart/interactive/docs/gallery), [Highcharts](http://api.highcharts.com/highcharts), and [Chart.js](http://www.chartjs.org/docs/) for more info.
167
+ See the documentation for [Chart.js](http://www.chartjs.org/docs/), [Google Charts](https://developers.google.com/chart/interactive/docs/gallery), and [Highcharts](http://api.highcharts.com/highcharts) for more info.
156
168
 
157
169
  ### Global Options
158
170
 
@@ -186,6 +198,24 @@ Then, in your layout:
186
198
 
187
199
  This is great for including all of your JavaScript at the bottom of the page.
188
200
 
201
+ ### Download Charts
202
+
203
+ *Chart.js only*
204
+
205
+ Give users the ability to download charts. It all happens in the browser - no server-side code needed.
206
+
207
+ ```erb
208
+ <%= line_chart data, download: true %>
209
+ ```
210
+
211
+ Set the filename
212
+
213
+ ```erb
214
+ <%= line_chart data, download: "boom" %>
215
+ ```
216
+
217
+ **Note:** Safari will open the image in a new window instead of downloading.
218
+
189
219
  ### Data
190
220
 
191
221
  Pass data as a Hash or Array
@@ -289,21 +319,47 @@ If more than one charting library is loaded, choose between them with:
289
319
  Access a chart with:
290
320
 
291
321
  ```javascript
292
- var chart = Chartkick.charts["chart-id"];
322
+ var chart = Chartkick.charts["chart-id"]
293
323
  ```
294
324
 
295
325
  Get the underlying chart object with:
296
326
 
297
327
  ```javascript
298
- chart.getChartObject();
328
+ chart.getChartObject()
299
329
  ```
300
330
 
301
331
  You can also use:
302
332
 
303
333
  ```javascript
304
- chart.getElement();
305
- chart.getData();
306
- chart.getOptions();
334
+ chart.getElement()
335
+ chart.getData()
336
+ chart.getOptions()
337
+ ```
338
+
339
+ Update the data with:
340
+
341
+ ```javascript
342
+ chart.updateData(newData)
343
+ ```
344
+
345
+ You can also specify new options:
346
+
347
+ ```javascript
348
+ chart.updateData(newData, newOptions)
349
+ ```
350
+
351
+ Refresh the data from a remote source:
352
+
353
+ ```javascript
354
+ chart.refreshData()
355
+ ```
356
+
357
+ Loop over charts with:
358
+
359
+ ```javascript
360
+ Chartkick.eachChart( function(chart) {
361
+ // do something
362
+ })
307
363
  ```
308
364
 
309
365
  ## No Ruby? No Problem
@@ -2,7 +2,7 @@
2
2
  * Chartkick.js
3
3
  * Create beautiful charts with one line of JavaScript
4
4
  * https://github.com/ankane/chartkick.js
5
- * v2.1.2
5
+ * v2.2.0
6
6
  * MIT License
7
7
  */
8
8
 
@@ -105,13 +105,12 @@
105
105
  }
106
106
 
107
107
  function jsOptionsFunc(defaultOptions, hideLegend, setMin, setMax, setStacked, setXtitle, setYtitle) {
108
- return function (series, opts, chartOptions) {
108
+ return function (chart, opts, chartOptions) {
109
+ var series = chart.data;
109
110
  var options = merge({}, defaultOptions);
110
111
  options = merge(options, chartOptions || {});
111
112
 
112
- // hide legend
113
- // this is *not* an external option!
114
- if (opts.hideLegend) {
113
+ if (chart.hideLegend) {
115
114
  hideLegend(options);
116
115
  }
117
116
 
@@ -204,18 +203,79 @@
204
203
  }
205
204
  }
206
205
 
207
- function fetchDataSource(chart, callback) {
208
- if (typeof chart.dataSource === "string") {
209
- getJSON(chart.element, chart.dataSource, function (data, textStatus, jqXHR) {
206
+ function fetchDataSource(chart, callback, dataSource) {
207
+ if (typeof dataSource === "string") {
208
+ getJSON(chart.element, dataSource, function (data, textStatus, jqXHR) {
210
209
  chart.data = data;
211
210
  errorCatcher(chart, callback);
212
211
  });
213
212
  } else {
214
- chart.data = chart.dataSource;
213
+ chart.data = dataSource;
215
214
  errorCatcher(chart, callback);
216
215
  }
217
216
  }
218
217
 
218
+ function addDownloadButton(chart) {
219
+ var element = chart.element;
220
+ var link = document.createElement("a");
221
+ link.download = chart.options.download === true ? "chart.png" : chart.options.download; // http://caniuse.com/download
222
+ link.style.position = "absolute";
223
+ link.style.top = "20px";
224
+ link.style.right = "20px";
225
+ link.style.zIndex = 1000;
226
+ link.style.lineHeight = "20px";
227
+ link.target = "_blank"; // for safari
228
+ var image = document.createElement("img");
229
+ image.alt = "Download";
230
+ image.style.border = "none";
231
+ // icon from font-awesome
232
+ // http://fa2png.io/
233
+ image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABCFBMVEUAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMywEsqxAAAAV3RSTlMAAQIDBggJCgsMDQ4PERQaHB0eISIjJCouLzE0OTo/QUJHSUpLTU5PUllhYmltcHh5foWLjI+SlaCio6atr7S1t7m6vsHHyM7R2tze5Obo7fHz9ff5+/1hlxK2AAAA30lEQVQYGUXBhVYCQQBA0TdYWAt2d3d3YWAHyur7/z9xgD16Lw0DW+XKx+1GgX+FRzM3HWQWrHl5N/oapW5RPe0PkBu+UYeICvozTWZVK23Ao04B79oJrOsJDOoxkZoQPWgX29pHpCZEk7rEvQYiNSFq1UMqvlCjJkRBS1R8hb00Vb/TajtBL7nTHE1X1vyMQF732dQhyF2o6SAwrzP06iUQzvwsArlnzcOdrgBhJyHa1QOgO9U1GsKuvjUTjavliZYQ8nNPapG6sap/3nrIdJ6bOWzmX/fy0XVpfzZP3S8OJT3g9EEiJwAAAABJRU5ErkJggg==";
234
+ link.appendChild(image);
235
+ element.style.position = "relative";
236
+
237
+ chart.downloadAttached = true;
238
+
239
+ // mouseenter
240
+ addEvent(element, "mouseover", function(e) {
241
+ var related = e.relatedTarget;
242
+ // check download option again to ensure it wasn't changed
243
+ if (!related || (related !== this && !childOf(this, related)) && chart.options.download) {
244
+ link.href = chart.toImage();
245
+ element.appendChild(link);
246
+ }
247
+ });
248
+
249
+ // mouseleave
250
+ addEvent(element, "mouseout", function(e) {
251
+ var related = e.relatedTarget;
252
+ if (!related || (related !== this && !childOf(this, related))) {
253
+ if (link.parentNode) {
254
+ link.parentNode.removeChild(link);
255
+ }
256
+ }
257
+ });
258
+ }
259
+
260
+ // http://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
261
+ function addEvent(elem, event, fn) {
262
+ if (elem.addEventListener) {
263
+ elem.addEventListener(event, fn, false);
264
+ } else {
265
+ elem.attachEvent("on" + event, function() {
266
+ // set the this pointer same as addEventListener when fn is called
267
+ return(fn.call(elem, window.event));
268
+ });
269
+ }
270
+ }
271
+
272
+ // https://gist.github.com/shawnbot/4166283
273
+ function childOf(p, c) {
274
+ if (p === c) return false;
275
+ while (c && c !== p) c = c.parentNode;
276
+ return c === p;
277
+ }
278
+
219
279
  // type conversions
220
280
 
221
281
  function toStr(n) {
@@ -361,8 +421,8 @@
361
421
  }
362
422
  };
363
423
  }
364
- var options = jsOptions(chart.data, chart.options, chartOptions), data, i, j;
365
- options.xAxis.type = chart.options.discrete ? "category" : "datetime";
424
+ var options = jsOptions(chart, chart.options, chartOptions), data, i, j;
425
+ options.xAxis.type = chart.discrete ? "category" : "datetime";
366
426
  if (!options.chart.type) {
367
427
  options.chart.type = chartType;
368
428
  }
@@ -371,7 +431,7 @@
371
431
  var series = chart.data;
372
432
  for (i = 0; i < series.length; i++) {
373
433
  data = series[i].data;
374
- if (!chart.options.discrete) {
434
+ if (!chart.discrete) {
375
435
  for (j = 0; j < data.length; j++) {
376
436
  data[j][0] = data[j][0].getTime();
377
437
  }
@@ -379,16 +439,16 @@
379
439
  series[i].marker = {symbol: "circle"};
380
440
  }
381
441
  options.series = series;
382
- new Highcharts.Chart(options);
442
+ chart.chart = new Highcharts.Chart(options);
383
443
  };
384
444
 
385
445
  this.renderScatterChart = function (chart) {
386
446
  var chartOptions = {};
387
- var options = jsOptions(chart.data, chart.options, chartOptions);
447
+ var options = jsOptions(chart, chart.options, chartOptions);
388
448
  options.chart.type = "scatter";
389
449
  options.chart.renderTo = chart.element.id;
390
450
  options.series = chart.data;
391
- new Highcharts.Chart(options);
451
+ chart.chart = new Highcharts.Chart(options);
392
452
  };
393
453
 
394
454
  this.renderPieChart = function (chart) {
@@ -396,6 +456,9 @@
396
456
  if (chart.options.colors) {
397
457
  chartOptions.colors = chart.options.colors;
398
458
  }
459
+ if (chart.options.donut) {
460
+ chartOptions.plotOptions = {pie: {innerSize: "50%"}};
461
+ }
399
462
  var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
400
463
  options.chart.renderTo = chart.element.id;
401
464
  options.series = [{
@@ -403,13 +466,13 @@
403
466
  name: chart.options.label || "Value",
404
467
  data: chart.data
405
468
  }];
406
- new Highcharts.Chart(options);
469
+ chart.chart = new Highcharts.Chart(options);
407
470
  };
408
471
 
409
472
  this.renderColumnChart = function (chart, chartType) {
410
473
  chartType = chartType || "column";
411
474
  var series = chart.data;
412
- var options = jsOptions(series, chart.options), i, j, s, d, rows = [];
475
+ var options = jsOptions(chart, chart.options), i, j, s, d, rows = [];
413
476
  options.chart.type = chartType;
414
477
  options.chart.renderTo = chart.element.id;
415
478
 
@@ -447,7 +510,7 @@
447
510
  }
448
511
  options.series = newSeries;
449
512
 
450
- new Highcharts.Chart(options);
513
+ chart.chart = new Highcharts.Chart(options);
451
514
  };
452
515
 
453
516
  var self = this;
@@ -652,8 +715,8 @@
652
715
 
653
716
  this.renderLineChart = function (chart) {
654
717
  waitForLoaded(function () {
655
- var options = jsOptions(chart.data, chart.options);
656
- var data = createDataTable(chart.data, chart.options.discrete ? "string" : "datetime");
718
+ var options = jsOptions(chart, chart.options);
719
+ var data = createDataTable(chart.data, chart.discrete ? "string" : "datetime");
657
720
  chart.chart = new google.visualization.LineChart(chart.element);
658
721
  resize(function () {
659
722
  chart.chart.draw(data, options);
@@ -672,6 +735,9 @@
672
735
  if (chart.options.colors) {
673
736
  chartOptions.colors = chart.options.colors;
674
737
  }
738
+ if (chart.options.donut) {
739
+ chartOptions.pieHole = 0.5;
740
+ }
675
741
  var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
676
742
 
677
743
  var data = new google.visualization.DataTable();
@@ -688,7 +754,7 @@
688
754
 
689
755
  this.renderColumnChart = function (chart) {
690
756
  waitForLoaded(function () {
691
- var options = jsOptions(chart.data, chart.options);
757
+ var options = jsOptions(chart, chart.options);
692
758
  var data = createDataTable(chart.data, "string");
693
759
  chart.chart = new google.visualization.ColumnChart(chart.element);
694
760
  resize(function () {
@@ -706,7 +772,7 @@
706
772
  }
707
773
  }
708
774
  };
709
- var options = jsOptionsFunc(defaultOptions, hideLegend, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart.data, chart.options, chartOptions);
775
+ var options = jsOptionsFunc(defaultOptions, hideLegend, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options, chartOptions);
710
776
  var data = createDataTable(chart.data, "string");
711
777
  chart.chart = new google.visualization.BarChart(chart.element);
712
778
  resize(function () {
@@ -722,8 +788,8 @@
722
788
  pointSize: 0,
723
789
  areaOpacity: 0.5
724
790
  };
725
- var options = jsOptions(chart.data, chart.options, chartOptions);
726
- var data = createDataTable(chart.data, chart.options.discrete ? "string" : "datetime");
791
+ var options = jsOptions(chart, chart.options, chartOptions);
792
+ var data = createDataTable(chart.data, chart.discrete ? "string" : "datetime");
727
793
  chart.chart = new google.visualization.AreaChart(chart.element);
728
794
  resize(function () {
729
795
  chart.chart.draw(data, options);
@@ -756,7 +822,7 @@
756
822
  this.renderScatterChart = function (chart) {
757
823
  waitForLoaded(function () {
758
824
  var chartOptions = {};
759
- var options = jsOptions(chart.data, chart.options, chartOptions);
825
+ var options = jsOptions(chart, chart.options, chartOptions);
760
826
  var data = createDataTable(chart.data, "number");
761
827
 
762
828
  chart.chart = new google.visualization.ScatterChart(chart.element);
@@ -803,7 +869,10 @@
803
869
 
804
870
  var baseOptions = {
805
871
  maintainAspectRatio: false,
806
- animation: false
872
+ animation: false,
873
+ tooltips: {
874
+ displayColors: false
875
+ }
807
876
  };
808
877
 
809
878
  var defaultOptions = {
@@ -835,10 +904,7 @@
835
904
  }
836
905
  ]
837
906
  },
838
- legend: {},
839
- tooltips: {
840
- displayColors: false
841
- }
907
+ legend: {}
842
908
  };
843
909
 
844
910
  // http://there4.io/2012/05/02/google-chart-color-list/
@@ -888,9 +954,13 @@
888
954
  };
889
955
 
890
956
  var drawChart = function(chart, type, data, options) {
891
- chart.element.innerHTML = "<canvas></canvas>";
892
- var ctx = chart.element.getElementsByTagName("CANVAS")[0];
957
+ if (chart.chart) {
958
+ chart.chart.destroy();
959
+ } else {
960
+ chart.element.innerHTML = "<canvas></canvas>";
961
+ }
893
962
 
963
+ var ctx = chart.element.getElementsByTagName("CANVAS")[0];
894
964
  chart.chart = new Chart(ctx, {
895
965
  type: type,
896
966
  data: data,
@@ -934,7 +1004,7 @@
934
1004
  var year = true;
935
1005
  var hour = true;
936
1006
  var minute = true;
937
- var detectType = (chartType === "line" || chartType === "area") && !chart.options.discrete;
1007
+ var detectType = (chartType === "line" || chartType === "area") && !chart.discrete;
938
1008
 
939
1009
  var series = chart.data;
940
1010
 
@@ -988,7 +1058,7 @@
988
1058
  labels.push(value);
989
1059
  for (j = 0; j < series.length; j++) {
990
1060
  // Chart.js doesn't like undefined
991
- rows2[j].push((typeof rows[i][j] === "undefined") ? null : rows[i][j]);
1061
+ rows2[j].push(rows[i][j] === undefined ? null : rows[i][j]);
992
1062
  }
993
1063
  }
994
1064
 
@@ -1085,17 +1155,21 @@
1085
1155
  chart.options.max = 1;
1086
1156
  }
1087
1157
 
1088
- var options = jsOptions(chart.data, merge(areaOptions, chart.options));
1158
+ var options = jsOptions(chart, merge(areaOptions, chart.options));
1089
1159
 
1090
1160
  var data = createDataTable(chart, options, chartType || "line");
1091
1161
 
1092
- options.scales.xAxes[0].type = chart.options.discrete ? "category" : "time";
1162
+ options.scales.xAxes[0].type = chart.discrete ? "category" : "time";
1093
1163
 
1094
1164
  drawChart(chart, "line", data, options);
1095
1165
  };
1096
1166
 
1097
1167
  this.renderPieChart = function (chart) {
1098
- var options = merge(baseOptions, chart.options.library || {});
1168
+ var options = merge({}, baseOptions);
1169
+ if (chart.options.donut) {
1170
+ options.cutoutPercentage = 50;
1171
+ }
1172
+ options = merge(options, chart.options.library || {});
1099
1173
 
1100
1174
  var labels = [];
1101
1175
  var values = [];
@@ -1121,9 +1195,9 @@
1121
1195
  this.renderColumnChart = function (chart, chartType) {
1122
1196
  var options;
1123
1197
  if (chartType === "bar") {
1124
- options = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart.data, chart.options);
1198
+ options = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setBarMin, setBarMax, setStacked, setXtitle, setYtitle)(chart, chart.options);
1125
1199
  } else {
1126
- options = jsOptions(chart.data, chart.options);
1200
+ options = jsOptions(chart, chart.options);
1127
1201
  }
1128
1202
  var data = createDataTable(chart, options, "column");
1129
1203
  setLabelSize(chart, data, options);
@@ -1141,7 +1215,7 @@
1141
1215
  };
1142
1216
 
1143
1217
  this.renderScatterChart = function (chart) {
1144
- var options = jsOptions(chart.data, chart.options);
1218
+ var options = jsOptions(chart, chart.options);
1145
1219
 
1146
1220
  var colors = chart.options.colors || defaultColors;
1147
1221
 
@@ -1180,9 +1254,16 @@
1180
1254
  }
1181
1255
  }
1182
1256
 
1257
+ function renderChart(chartType, chart) {
1258
+ callAdapter(chartType, chart);
1259
+ if (chart.options.download && !chart.downloadAttached && chart.adapter === "chartjs") {
1260
+ addDownloadButton(chart);
1261
+ }
1262
+ }
1263
+
1183
1264
  // TODO remove chartType if cross-browser way
1184
1265
  // to get the name of the chart class
1185
- function renderChart(chartType, chart) {
1266
+ function callAdapter(chartType, chart) {
1186
1267
  var i, adapter, fnName, adapterName;
1187
1268
  fnName = "render" + chartType;
1188
1269
  adapterName = chart.options.adapter;
@@ -1192,6 +1273,7 @@
1192
1273
  for (i = 0; i < adapters.length; i++) {
1193
1274
  adapter = adapters[i];
1194
1275
  if ((!adapterName || adapterName === adapter.name) && isFunction(adapter[fnName])) {
1276
+ chart.adapter = adapter.name;
1195
1277
  return adapter[fnName](chart);
1196
1278
  }
1197
1279
  }
@@ -1277,20 +1359,25 @@
1277
1359
  return false;
1278
1360
  }
1279
1361
 
1280
- function processSeries(series, opts, keyType) {
1362
+ function processSeries(chart, keyType) {
1281
1363
  var i;
1282
1364
 
1365
+ var opts = chart.options;
1366
+ var series = chart.data;
1367
+
1283
1368
  // see if one series or multiple
1284
1369
  if (!isArray(series) || typeof series[0] !== "object" || isArray(series[0])) {
1285
1370
  series = [{name: opts.label || "Value", data: series}];
1286
- opts.hideLegend = true;
1371
+ chart.hideLegend = true;
1287
1372
  } else {
1288
- opts.hideLegend = false;
1373
+ chart.hideLegend = false;
1289
1374
  }
1290
1375
  if ((opts.discrete === null || opts.discrete === undefined)) {
1291
- opts.discrete = detectDiscrete(series);
1376
+ chart.discrete = detectDiscrete(series);
1377
+ } else {
1378
+ chart.discrete = opts.discrete;
1292
1379
  }
1293
- if (opts.discrete) {
1380
+ if (chart.discrete) {
1294
1381
  keyType = "string";
1295
1382
  }
1296
1383
 
@@ -1321,12 +1408,12 @@
1321
1408
  }
1322
1409
 
1323
1410
  function processLineData(chart) {
1324
- chart.data = processSeries(chart.data, chart.options, "datetime");
1411
+ chart.data = processSeries(chart, "datetime");
1325
1412
  renderChart("LineChart", chart);
1326
1413
  }
1327
1414
 
1328
1415
  function processColumnData(chart) {
1329
- chart.data = processSeries(chart.data, chart.options, "string");
1416
+ chart.data = processSeries(chart, "string");
1330
1417
  renderChart("ColumnChart", chart);
1331
1418
  }
1332
1419
 
@@ -1336,12 +1423,12 @@
1336
1423
  }
1337
1424
 
1338
1425
  function processBarData(chart) {
1339
- chart.data = processSeries(chart.data, chart.options, "string");
1426
+ chart.data = processSeries(chart, "string");
1340
1427
  renderChart("BarChart", chart);
1341
1428
  }
1342
1429
 
1343
1430
  function processAreaData(chart) {
1344
- chart.data = processSeries(chart.data, chart.options, "datetime");
1431
+ chart.data = processSeries(chart, "datetime");
1345
1432
  renderChart("AreaChart", chart);
1346
1433
  }
1347
1434
 
@@ -1351,7 +1438,7 @@
1351
1438
  }
1352
1439
 
1353
1440
  function processScatterData(chart) {
1354
- chart.data = processSeries(chart.data, chart.options, "number");
1441
+ chart.data = processSeries(chart, "number");
1355
1442
  renderChart("ScatterChart", chart);
1356
1443
  }
1357
1444
 
@@ -1369,23 +1456,67 @@
1369
1456
  throw new Error("No element with id " + elementId);
1370
1457
  }
1371
1458
  }
1459
+
1372
1460
  chart.element = element;
1373
- chart.options = opts || {};
1461
+ opts = merge(Chartkick.options, opts || {});
1462
+ chart.options = opts;
1374
1463
  chart.dataSource = dataSource;
1464
+
1465
+ // getters
1375
1466
  chart.getElement = function () {
1376
1467
  return element;
1377
1468
  };
1469
+ chart.getDataSource = function () {
1470
+ return chart.dataSource;
1471
+ };
1378
1472
  chart.getData = function () {
1379
1473
  return chart.data;
1380
1474
  };
1381
1475
  chart.getOptions = function () {
1382
- return opts || {};
1476
+ return chart.options;
1383
1477
  };
1384
1478
  chart.getChartObject = function () {
1385
1479
  return chart.chart;
1386
1480
  };
1481
+
1482
+ // functions
1483
+ chart.updateData = function (dataSource, options) {
1484
+ chart.dataSource = dataSource;
1485
+ if (options) {
1486
+ chart.options = merge(Chartkick.options, options);
1487
+ }
1488
+ fetchDataSource(chart, callback, dataSource);
1489
+ };
1490
+ chart.refreshData = function () {
1491
+ if (typeof dataSource === "string") {
1492
+ // prevent browser from caching
1493
+ var sep = dataSource.indexOf("?") === -1 ? "?" : "&";
1494
+ var url = dataSource + sep + "_=" + (new Date()).getTime();
1495
+ fetchDataSource(chart, callback, url);
1496
+ }
1497
+ };
1498
+ chart.stopRefresh = function () {
1499
+ if (chart.intervalId) {
1500
+ clearInterval(chart.intervalId);
1501
+ }
1502
+ };
1503
+ chart.toImage = function () {
1504
+ if (chart.adapter === "chartjs") {
1505
+ return chart.chart.toBase64Image();
1506
+ } else {
1507
+ return null;
1508
+ }
1509
+ }
1510
+
1387
1511
  Chartkick.charts[element.id] = chart;
1388
- fetchDataSource(chart, callback);
1512
+
1513
+ fetchDataSource(chart, callback, dataSource);
1514
+
1515
+ if (opts.refresh) {
1516
+ chart.intervalId = setInterval( function () {
1517
+ chart.refreshData();
1518
+ }, opts.refresh * 1000);
1519
+ }
1389
1520
  }
1390
1521
 
1391
1522
  // define classes
@@ -1422,7 +1553,15 @@
1422
1553
  config[key] = options[key];
1423
1554
  }
1424
1555
  }
1425
- }
1556
+ },
1557
+ eachChart: function (callback) {
1558
+ for (var chartId in Chartkick.charts) {
1559
+ if (Chartkick.charts.hasOwnProperty(chartId)) {
1560
+ callback(Chartkick.charts[chartId]);
1561
+ }
1562
+ }
1563
+ },
1564
+ options: {}
1426
1565
  };
1427
1566
 
1428
1567
  if (typeof module === "object" && typeof module.exports === "object") {
@@ -1,3 +1,3 @@
1
1
  module Chartkick
2
- VERSION = "2.1.3"
2
+ VERSION = "2.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chartkick
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.3
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-29 00:00:00.000000000 Z
11
+ date: 2016-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler