chartkick 1.2.2 → 1.2.3
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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +25 -13
- data/app/assets/javascripts/chartkick.js +423 -354
- data/lib/chartkick/helper.rb +4 -0
- data/lib/chartkick/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3d82466b6703318eaead4b787e2029ed81b6419
|
4
|
+
data.tar.gz: 6a94782f3c4fbfd27171e03e89e1288e97221287
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b14d7a3cd54eb4d67af1efa3776c7f9c5bf6c07c8d8d22aff8294312236095b1ab5de4850c330d938aae2f0b21108c31aacad0da73a0248b190da79fbf637884
|
7
|
+
data.tar.gz: ce3df7336aa518bc1c3859c7e113607bd851779c5efc23b483f1154fdc2913d207ab0fffc6ed86b82f9743a1d656f4034bba4e67520769c2bff06d851c006684
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -19,19 +19,19 @@ Line chart
|
|
19
19
|
Pie chart
|
20
20
|
|
21
21
|
```erb
|
22
|
-
<%= pie_chart Goal.group(
|
22
|
+
<%= pie_chart Goal.group(:name).count %>
|
23
23
|
```
|
24
24
|
|
25
25
|
Column chart
|
26
26
|
|
27
27
|
```erb
|
28
|
-
<%= column_chart Task.group_by_hour_of_day(:created_at).count %>
|
28
|
+
<%= column_chart Task.group_by_hour_of_day(:created_at, format: "%l %P").count %>
|
29
29
|
```
|
30
30
|
|
31
31
|
Bar chart
|
32
32
|
|
33
33
|
```erb
|
34
|
-
<%= bar_chart Shirt.group(
|
34
|
+
<%= bar_chart Shirt.group(:size).sum(:price) %>
|
35
35
|
```
|
36
36
|
|
37
37
|
Area chart
|
@@ -40,11 +40,17 @@ Area chart
|
|
40
40
|
<%= area_chart Visit.group_by_minute(:created_at).maximum(:load_time) %>
|
41
41
|
```
|
42
42
|
|
43
|
+
Geo chart
|
44
|
+
|
45
|
+
```erb
|
46
|
+
<%= geo_chart Medal.group(:country).count %>
|
47
|
+
```
|
48
|
+
|
43
49
|
Multiple series (except pie chart)
|
44
50
|
|
45
51
|
```erb
|
46
52
|
<%= line_chart @goals.map{|goal|
|
47
|
-
{:
|
53
|
+
{name: goal.name, data: goal.feats.group_by_week(:created_at).count}
|
48
54
|
} %>
|
49
55
|
```
|
50
56
|
|
@@ -61,43 +67,49 @@ And in your controller, pass the data as JSON.
|
|
61
67
|
```ruby
|
62
68
|
class ChartsController < ApplicationController
|
63
69
|
def completed_tasks
|
64
|
-
render :
|
70
|
+
render json: Task.group_by_day(:completed_at).count
|
65
71
|
end
|
66
72
|
end
|
67
73
|
```
|
68
74
|
|
69
|
-
**Note:** This feature requires jQuery at the moment.
|
75
|
+
**Note:** This feature requires [jQuery](http://jquery.com/) or [Zepto](http://zeptojs.com/) at the moment.
|
70
76
|
|
71
77
|
### Options
|
72
78
|
|
73
79
|
Id and height
|
74
80
|
|
75
81
|
```erb
|
76
|
-
<%= line_chart data, :
|
82
|
+
<%= line_chart data, id: "users-chart", height: "500px" %>
|
77
83
|
```
|
78
84
|
|
79
85
|
Min and max values (except pie chart)
|
80
86
|
|
81
87
|
```erb
|
82
|
-
<%= line_chart data, :
|
88
|
+
<%= line_chart data, min: 1000, max: 5000 %>
|
83
89
|
```
|
84
90
|
|
85
91
|
Stacked columns or bars
|
86
92
|
|
87
93
|
```erb
|
88
|
-
<%= column_chart data, :
|
94
|
+
<%= column_chart data, stacked: true %>
|
95
|
+
```
|
96
|
+
|
97
|
+
Discrete axis
|
98
|
+
|
99
|
+
```erb
|
100
|
+
<%= line_chart data, discrete: true %>
|
89
101
|
```
|
90
102
|
|
91
103
|
You can pass options directly to the charting library with:
|
92
104
|
|
93
105
|
```erb
|
94
|
-
<%= line_chart data, :
|
106
|
+
<%= line_chart data, library: {backgroundColor: "#eee"} %>
|
95
107
|
```
|
96
108
|
|
97
109
|
You can also pass a content_for option, which will put the javascript in a content block. This is great for including all of your javascript at the bottom of the page.
|
98
110
|
|
99
111
|
```erb
|
100
|
-
<%= line_chart data, :
|
112
|
+
<%= line_chart data, content_for: :charts_js %>
|
101
113
|
```
|
102
114
|
Then, in your layout:
|
103
115
|
|
@@ -125,8 +137,8 @@ For multiple series, use the format
|
|
125
137
|
|
126
138
|
```erb
|
127
139
|
<%= line_chart [
|
128
|
-
{:
|
129
|
-
{:
|
140
|
+
{name: "Series A", data: series_a},
|
141
|
+
{name: "Series B", data: series_b}
|
130
142
|
] %>
|
131
143
|
```
|
132
144
|
|
@@ -2,21 +2,18 @@
|
|
2
2
|
* Chartkick.js
|
3
3
|
* Create beautiful Javascript charts with minimal code
|
4
4
|
* https://github.com/ankane/chartkick.js
|
5
|
-
* v1.
|
5
|
+
* v1.2.1
|
6
6
|
* MIT License
|
7
7
|
*/
|
8
8
|
|
9
9
|
/*jslint browser: true, indent: 2, plusplus: true, vars: true */
|
10
|
-
/*global google, Highcharts, $*/
|
11
10
|
|
12
|
-
(function () {
|
11
|
+
(function (window) {
|
13
12
|
'use strict';
|
14
13
|
|
15
|
-
var Chartkick, ISO8601_PATTERN, DECIMAL_SEPARATOR,
|
16
|
-
setMin, setMax, setStacked, jsOptions, loaded, waitForLoaded, setBarMin, setBarMax, createDataTable, resize;
|
14
|
+
var Chartkick, ISO8601_PATTERN, DECIMAL_SEPARATOR, adapters = [];
|
17
15
|
|
18
|
-
|
19
|
-
var renderLineChart, renderPieChart, renderColumnChart, renderBarChart, renderAreaChart;
|
16
|
+
var $ = window.jQuery || window.Zepto || window.$;
|
20
17
|
|
21
18
|
// helpers
|
22
19
|
|
@@ -153,7 +150,7 @@
|
|
153
150
|
}
|
154
151
|
|
155
152
|
function getJSON(element, url, success) {
|
156
|
-
|
153
|
+
$.ajax({
|
157
154
|
dataType: "json",
|
158
155
|
url: url,
|
159
156
|
success: success,
|
@@ -164,22 +161,24 @@
|
|
164
161
|
});
|
165
162
|
}
|
166
163
|
|
167
|
-
function errorCatcher(
|
164
|
+
function errorCatcher(chart, callback) {
|
168
165
|
try {
|
169
|
-
callback(
|
166
|
+
callback(chart);
|
170
167
|
} catch (err) {
|
171
|
-
chartError(element, err.message);
|
168
|
+
chartError(chart.element, err.message);
|
172
169
|
throw err;
|
173
170
|
}
|
174
171
|
}
|
175
172
|
|
176
|
-
function fetchDataSource(
|
177
|
-
if (typeof dataSource === "string") {
|
178
|
-
getJSON(element, dataSource, function (data, textStatus, jqXHR) {
|
179
|
-
|
173
|
+
function fetchDataSource(chart, callback) {
|
174
|
+
if (typeof chart.dataSource === "string") {
|
175
|
+
getJSON(chart.element, chart.dataSource, function (data, textStatus, jqXHR) {
|
176
|
+
chart.data = data;
|
177
|
+
errorCatcher(chart, callback);
|
180
178
|
});
|
181
179
|
} else {
|
182
|
-
|
180
|
+
chart.data = chart.dataSource;
|
181
|
+
errorCatcher(chart, callback);
|
183
182
|
}
|
184
183
|
}
|
185
184
|
|
@@ -225,371 +224,416 @@
|
|
225
224
|
}
|
226
225
|
|
227
226
|
if ("Highcharts" in window) {
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
227
|
+
var HighchartsAdapter = new function () {
|
228
|
+
var Highcharts = window.Highcharts;
|
229
|
+
|
230
|
+
var defaultOptions = {
|
231
|
+
chart: {},
|
232
|
+
xAxis: {
|
233
|
+
labels: {
|
234
|
+
style: {
|
235
|
+
fontSize: "12px"
|
236
|
+
}
|
235
237
|
}
|
236
|
-
}
|
237
|
-
|
238
|
-
|
238
|
+
},
|
239
|
+
yAxis: {
|
240
|
+
title: {
|
241
|
+
text: null
|
242
|
+
},
|
243
|
+
labels: {
|
244
|
+
style: {
|
245
|
+
fontSize: "12px"
|
246
|
+
}
|
247
|
+
}
|
248
|
+
},
|
239
249
|
title: {
|
240
250
|
text: null
|
241
251
|
},
|
242
|
-
|
252
|
+
credits: {
|
253
|
+
enabled: false
|
254
|
+
},
|
255
|
+
legend: {
|
256
|
+
borderWidth: 0
|
257
|
+
},
|
258
|
+
tooltip: {
|
243
259
|
style: {
|
244
260
|
fontSize: "12px"
|
245
261
|
}
|
262
|
+
},
|
263
|
+
plotOptions: {
|
264
|
+
areaspline: {},
|
265
|
+
series: {
|
266
|
+
marker: {}
|
267
|
+
}
|
246
268
|
}
|
247
|
-
}
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
269
|
+
};
|
270
|
+
|
271
|
+
var hideLegend = function (options) {
|
272
|
+
options.legend.enabled = false;
|
273
|
+
};
|
274
|
+
|
275
|
+
var setMin = function (options, min) {
|
276
|
+
options.yAxis.min = min;
|
277
|
+
};
|
278
|
+
|
279
|
+
var setMax = function (options, max) {
|
280
|
+
options.yAxis.max = max;
|
281
|
+
};
|
282
|
+
|
283
|
+
var setStacked = function (options) {
|
284
|
+
options.plotOptions.series.stacking = "normal";
|
285
|
+
};
|
286
|
+
|
287
|
+
var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setMin, setMax, setStacked);
|
288
|
+
|
289
|
+
this.renderLineChart = function (chart, chartType) {
|
290
|
+
chartType = chartType || "spline";
|
291
|
+
var chartOptions = {};
|
292
|
+
if (chartType === "areaspline") {
|
293
|
+
chartOptions = {
|
294
|
+
plotOptions: {
|
295
|
+
areaspline: {
|
296
|
+
stacking: "normal"
|
297
|
+
},
|
298
|
+
series: {
|
299
|
+
marker: {
|
300
|
+
enabled: false
|
301
|
+
}
|
302
|
+
}
|
303
|
+
}
|
304
|
+
};
|
260
305
|
}
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
306
|
+
var options = jsOptions(chart.data, chart.options, chartOptions), data, i, j;
|
307
|
+
options.xAxis.type = chart.options.discrete ? "category" : "datetime";
|
308
|
+
options.chart.type = chartType;
|
309
|
+
options.chart.renderTo = chart.element.id;
|
310
|
+
|
311
|
+
var series = chart.data;
|
312
|
+
for (i = 0; i < series.length; i++) {
|
313
|
+
data = series[i].data;
|
314
|
+
if (!chart.options.discrete) {
|
315
|
+
for (j = 0; j < data.length; j++) {
|
316
|
+
data[j][0] = data[j][0].getTime();
|
317
|
+
}
|
318
|
+
}
|
319
|
+
series[i].marker = {symbol: "circle"};
|
266
320
|
}
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
},
|
297
|
-
series: {
|
298
|
-
marker: {
|
299
|
-
enabled: false
|
300
|
-
}
|
321
|
+
options.series = series;
|
322
|
+
new Highcharts.Chart(options);
|
323
|
+
};
|
324
|
+
|
325
|
+
this.renderPieChart = function (chart) {
|
326
|
+
var options = merge(defaultOptions, chart.options.library || {});
|
327
|
+
options.chart.renderTo = chart.element.id;
|
328
|
+
options.series = [{
|
329
|
+
type: "pie",
|
330
|
+
name: "Value",
|
331
|
+
data: chart.data
|
332
|
+
}];
|
333
|
+
new Highcharts.Chart(options);
|
334
|
+
};
|
335
|
+
|
336
|
+
this.renderColumnChart = function (chart, chartType) {
|
337
|
+
var chartType = chartType || "column";
|
338
|
+
var series = chart.data;
|
339
|
+
var options = jsOptions(series, chart.options), i, j, s, d, rows = [];
|
340
|
+
options.chart.type = chartType;
|
341
|
+
options.chart.renderTo = chart.element.id;
|
342
|
+
|
343
|
+
for (i = 0; i < series.length; i++) {
|
344
|
+
s = series[i];
|
345
|
+
|
346
|
+
for (j = 0; j < s.data.length; j++) {
|
347
|
+
d = s.data[j];
|
348
|
+
if (!rows[d[0]]) {
|
349
|
+
rows[d[0]] = new Array(series.length);
|
301
350
|
}
|
351
|
+
rows[d[0]][i] = d[1];
|
302
352
|
}
|
303
|
-
};
|
304
|
-
}
|
305
|
-
var options = jsOptions(series, opts, chartOptions), data, i, j;
|
306
|
-
options.xAxis.type = "datetime";
|
307
|
-
options.chart.type = chartType;
|
308
|
-
options.chart.renderTo = element.id;
|
309
|
-
|
310
|
-
for (i = 0; i < series.length; i++) {
|
311
|
-
data = series[i].data;
|
312
|
-
for (j = 0; j < data.length; j++) {
|
313
|
-
data[j][0] = data[j][0].getTime();
|
314
353
|
}
|
315
|
-
series[i].marker = {symbol: "circle"};
|
316
|
-
}
|
317
|
-
options.series = series;
|
318
|
-
new Highcharts.Chart(options);
|
319
|
-
};
|
320
|
-
|
321
|
-
renderPieChart = function (element, series, opts) {
|
322
|
-
var options = merge(defaultOptions, opts.library || {});
|
323
|
-
options.chart.renderTo = element.id;
|
324
|
-
options.series = [{
|
325
|
-
type: "pie",
|
326
|
-
name: "Value",
|
327
|
-
data: series
|
328
|
-
}];
|
329
|
-
new Highcharts.Chart(options);
|
330
|
-
};
|
331
|
-
|
332
|
-
renderColumnChart = function (element, series, opts, chartType) {
|
333
|
-
chartType = chartType || "column";
|
334
|
-
var options = jsOptions(series, opts), i, j, s, d, rows = [];
|
335
|
-
options.chart.type = chartType;
|
336
|
-
options.chart.renderTo = element.id;
|
337
354
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
d = s.data[j];
|
343
|
-
if (!rows[d[0]]) {
|
344
|
-
rows[d[0]] = new Array(series.length);
|
355
|
+
var categories = [];
|
356
|
+
for (i in rows) {
|
357
|
+
if (rows.hasOwnProperty(i)) {
|
358
|
+
categories.push(i);
|
345
359
|
}
|
346
|
-
rows[d[0]][i] = d[1];
|
347
360
|
}
|
348
|
-
|
361
|
+
options.xAxis.categories = categories;
|
349
362
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
categories.
|
354
|
-
|
355
|
-
|
356
|
-
options.xAxis.categories = categories;
|
363
|
+
var newSeries = [];
|
364
|
+
for (i = 0; i < series.length; i++) {
|
365
|
+
d = [];
|
366
|
+
for (j = 0; j < categories.length; j++) {
|
367
|
+
d.push(rows[categories[j]][i] || 0);
|
368
|
+
}
|
357
369
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
d.push(rows[categories[j]][i] || 0);
|
370
|
+
newSeries.push({
|
371
|
+
name: series[i].name,
|
372
|
+
data: d
|
373
|
+
});
|
363
374
|
}
|
375
|
+
options.series = newSeries;
|
364
376
|
|
365
|
-
|
366
|
-
|
367
|
-
data: d
|
368
|
-
});
|
369
|
-
}
|
370
|
-
options.series = newSeries;
|
377
|
+
new Highcharts.Chart(options);
|
378
|
+
};
|
371
379
|
|
372
|
-
|
373
|
-
};
|
380
|
+
var self = this;
|
374
381
|
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
renderAreaChart = function (element, series, opts) {
|
380
|
-
renderLineChart(element, series, opts, "areaspline");
|
381
|
-
};
|
382
|
-
} else if ("google" in window) { // Google charts
|
383
|
-
// load from google
|
384
|
-
loaded = false;
|
385
|
-
google.setOnLoadCallback(function () {
|
386
|
-
loaded = true;
|
387
|
-
});
|
388
|
-
var loadOptions = {"packages": ["corechart"]};
|
389
|
-
var config = window.Chartkick || {};
|
390
|
-
if (config.language) {
|
391
|
-
loadOptions.language = config.language;
|
392
|
-
}
|
393
|
-
google.load("visualization", "1.0", loadOptions);
|
382
|
+
this.renderBarChart = function (chart) {
|
383
|
+
self.renderColumnChart(chart, "bar");
|
384
|
+
};
|
394
385
|
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
callback();
|
399
|
-
}
|
386
|
+
this.renderAreaChart = function (chart) {
|
387
|
+
self.renderLineChart(chart, "areaspline");
|
388
|
+
};
|
400
389
|
};
|
390
|
+
adapters.push(HighchartsAdapter);
|
391
|
+
}
|
392
|
+
if ("google" in window) {
|
393
|
+
var GoogleChartsAdapter = new function () {
|
394
|
+
var google = window.google;
|
395
|
+
|
396
|
+
// load from google
|
397
|
+
var loaded = false;
|
398
|
+
google.setOnLoadCallback(function () {
|
399
|
+
loaded = true;
|
400
|
+
});
|
401
|
+
google.load("visualization", "1.0", {"packages": ["corechart"]});
|
401
402
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
},
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
403
|
+
var waitForLoaded = function (callback) {
|
404
|
+
google.setOnLoadCallback(callback); // always do this to prevent race conditions (watch out for other issues due to this)
|
405
|
+
if (loaded) {
|
406
|
+
callback();
|
407
|
+
}
|
408
|
+
};
|
409
|
+
|
410
|
+
// Set chart options
|
411
|
+
var defaultOptions = {
|
412
|
+
chartArea: {},
|
413
|
+
fontName: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",
|
414
|
+
pointSize: 6,
|
415
|
+
legend: {
|
416
|
+
textStyle: {
|
417
|
+
fontSize: 12,
|
418
|
+
color: "#444"
|
419
|
+
},
|
420
|
+
alignment: "center",
|
421
|
+
position: "right"
|
420
422
|
},
|
421
|
-
|
422
|
-
|
423
|
+
curveType: "function",
|
424
|
+
hAxis: {
|
425
|
+
textStyle: {
|
426
|
+
color: "#666",
|
427
|
+
fontSize: 12
|
428
|
+
},
|
429
|
+
gridlines: {
|
430
|
+
color: "transparent"
|
431
|
+
},
|
432
|
+
baselineColor: "#ccc",
|
433
|
+
viewWindow: {}
|
423
434
|
},
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
435
|
+
vAxis: {
|
436
|
+
textStyle: {
|
437
|
+
color: "#666",
|
438
|
+
fontSize: 12
|
439
|
+
},
|
440
|
+
baselineColor: "#ccc",
|
441
|
+
viewWindow: {}
|
431
442
|
},
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
color: "#666",
|
438
|
-
fontSize: 12
|
443
|
+
tooltip: {
|
444
|
+
textStyle: {
|
445
|
+
color: "#666",
|
446
|
+
fontSize: 12
|
447
|
+
}
|
439
448
|
}
|
440
|
-
}
|
441
|
-
};
|
449
|
+
};
|
442
450
|
|
443
|
-
|
444
|
-
|
445
|
-
|
451
|
+
var hideLegend = function (options) {
|
452
|
+
options.legend.position = "none";
|
453
|
+
};
|
446
454
|
|
447
|
-
|
448
|
-
|
449
|
-
|
455
|
+
var setMin = function (options, min) {
|
456
|
+
options.vAxis.viewWindow.min = min;
|
457
|
+
};
|
450
458
|
|
451
|
-
|
452
|
-
|
453
|
-
|
459
|
+
var setMax = function (options, max) {
|
460
|
+
options.vAxis.viewWindow.max = max;
|
461
|
+
};
|
454
462
|
|
455
|
-
|
456
|
-
|
457
|
-
|
463
|
+
var setBarMin = function (options, min) {
|
464
|
+
options.hAxis.viewWindow.min = min;
|
465
|
+
};
|
458
466
|
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
setStacked = function (options) {
|
464
|
-
options.isStacked = true;
|
465
|
-
};
|
466
|
-
|
467
|
-
jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setMin, setMax, setStacked);
|
467
|
+
var setBarMax = function (options, max) {
|
468
|
+
options.hAxis.viewWindow.max = max;
|
469
|
+
};
|
468
470
|
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
data.addColumn(columnType, "");
|
471
|
+
var setStacked = function (options) {
|
472
|
+
options.isStacked = true;
|
473
|
+
};
|
473
474
|
|
474
|
-
var
|
475
|
-
for (i = 0; i < series.length; i++) {
|
476
|
-
s = series[i];
|
477
|
-
data.addColumn("number", s.name);
|
475
|
+
var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setMin, setMax, setStacked);
|
478
476
|
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
477
|
+
// cant use object as key
|
478
|
+
var createDataTable = function (series, columnType) {
|
479
|
+
var data = new google.visualization.DataTable();
|
480
|
+
data.addColumn(columnType, "");
|
481
|
+
|
482
|
+
var i, j, s, d, key, rows = [];
|
483
|
+
for (i = 0; i < series.length; i++) {
|
484
|
+
s = series[i];
|
485
|
+
data.addColumn("number", s.name);
|
486
|
+
|
487
|
+
for (j = 0; j < s.data.length; j++) {
|
488
|
+
d = s.data[j];
|
489
|
+
key = (columnType === "datetime") ? d[0].getTime() : d[0];
|
490
|
+
if (!rows[key]) {
|
491
|
+
rows[key] = new Array(series.length);
|
492
|
+
}
|
493
|
+
rows[key][i] = toFloat(d[1]);
|
484
494
|
}
|
485
|
-
rows[key][i] = toFloat(d[1]);
|
486
495
|
}
|
487
|
-
}
|
488
496
|
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
497
|
+
var rows2 = [];
|
498
|
+
for (i in rows) {
|
499
|
+
if (rows.hasOwnProperty(i)) {
|
500
|
+
rows2.push([(columnType === "datetime") ? new Date(toFloat(i)) : i].concat(rows[i]));
|
501
|
+
}
|
493
502
|
}
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
data.addRows(rows2);
|
499
|
-
|
500
|
-
return data;
|
501
|
-
};
|
503
|
+
if (columnType === "datetime") {
|
504
|
+
rows2.sort(sortByTime);
|
505
|
+
}
|
506
|
+
data.addRows(rows2);
|
502
507
|
|
503
|
-
|
504
|
-
|
505
|
-
window.attachEvent("onresize", callback);
|
506
|
-
} else if (window.addEventListener) {
|
507
|
-
window.addEventListener("resize", callback, true);
|
508
|
-
}
|
509
|
-
callback();
|
510
|
-
};
|
508
|
+
return data;
|
509
|
+
};
|
511
510
|
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
511
|
+
var resize = function (callback) {
|
512
|
+
if (window.attachEvent) {
|
513
|
+
window.attachEvent("onresize", callback);
|
514
|
+
} else if (window.addEventListener) {
|
515
|
+
window.addEventListener("resize", callback, true);
|
516
|
+
}
|
517
|
+
callback();
|
518
|
+
};
|
519
|
+
|
520
|
+
this.renderLineChart = function (chart) {
|
521
|
+
waitForLoaded(function () {
|
522
|
+
var options = jsOptions(chart.data, chart.options);
|
523
|
+
var data = createDataTable(chart.data, chart.options.discrete ? "string" : "datetime");
|
524
|
+
chart.chart = new google.visualization.LineChart(chart.element);
|
525
|
+
resize(function () {
|
526
|
+
chart.chart.draw(data, options);
|
527
|
+
});
|
519
528
|
});
|
520
|
-
}
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
}
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
529
|
+
};
|
530
|
+
|
531
|
+
this.renderPieChart = function (chart) {
|
532
|
+
waitForLoaded(function () {
|
533
|
+
var chartOptions = {
|
534
|
+
chartArea: {
|
535
|
+
top: "10%",
|
536
|
+
height: "80%"
|
537
|
+
}
|
538
|
+
};
|
539
|
+
var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
|
540
|
+
|
541
|
+
var data = new google.visualization.DataTable();
|
542
|
+
data.addColumn("string", "");
|
543
|
+
data.addColumn("number", "Value");
|
544
|
+
data.addRows(chart.data);
|
545
|
+
|
546
|
+
chart.chart = new google.visualization.PieChart(chart.element);
|
547
|
+
resize(function () {
|
548
|
+
chart.chart.draw(data, options);
|
549
|
+
});
|
541
550
|
});
|
542
|
-
}
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
551
|
+
};
|
552
|
+
|
553
|
+
this.renderColumnChart = function (chart) {
|
554
|
+
waitForLoaded(function () {
|
555
|
+
var options = jsOptions(chart.data, chart.options);
|
556
|
+
var data = createDataTable(chart.data, "string");
|
557
|
+
chart.chart = new google.visualization.ColumnChart(chart.element);
|
558
|
+
resize(function () {
|
559
|
+
chart.chart.draw(data, options);
|
560
|
+
});
|
552
561
|
});
|
553
|
-
}
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
+
};
|
563
|
+
|
564
|
+
this.renderBarChart = function (chart) {
|
565
|
+
waitForLoaded(function () {
|
566
|
+
var chartOptions = {
|
567
|
+
hAxis: {
|
568
|
+
gridlines: {
|
569
|
+
color: "#ccc"
|
570
|
+
}
|
562
571
|
}
|
563
|
-
}
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
572
|
+
};
|
573
|
+
var options = jsOptionsFunc(defaultOptions, hideLegend, setBarMin, setBarMax, setStacked)(chart.data, chart.options, chartOptions);
|
574
|
+
var data = createDataTable(chart.data, "string");
|
575
|
+
chart.chart = new google.visualization.BarChart(chart.element);
|
576
|
+
resize(function () {
|
577
|
+
chart.chart.draw(data, options);
|
578
|
+
});
|
570
579
|
});
|
571
|
-
}
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
580
|
+
};
|
581
|
+
|
582
|
+
this.renderAreaChart = function (chart) {
|
583
|
+
waitForLoaded(function () {
|
584
|
+
var chartOptions = {
|
585
|
+
isStacked: true,
|
586
|
+
pointSize: 0,
|
587
|
+
areaOpacity: 0.5
|
588
|
+
};
|
589
|
+
var options = jsOptions(chart.data, chart.options, chartOptions);
|
590
|
+
var data = createDataTable(chart.data, chart.options.discrete ? "string" : "datetime");
|
591
|
+
chart.chart = new google.visualization.AreaChart(chart.element);
|
592
|
+
resize(function () {
|
593
|
+
chart.chart.draw(data, options);
|
594
|
+
});
|
586
595
|
});
|
587
|
-
}
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
596
|
+
};
|
597
|
+
|
598
|
+
this.renderGeoChart = function (chart) {
|
599
|
+
waitForLoaded(function () {
|
600
|
+
var chartOptions = {
|
601
|
+
legend: "none",
|
602
|
+
colorAxis: {
|
603
|
+
colors: ["#f6c7b6", "#ce502d"]
|
604
|
+
}
|
605
|
+
};
|
606
|
+
var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
|
607
|
+
|
608
|
+
var data = new google.visualization.DataTable();
|
609
|
+
data.addColumn("string", "");
|
610
|
+
data.addColumn("number", "Value");
|
611
|
+
data.addRows(chart.data);
|
612
|
+
|
613
|
+
chart.chart = new google.visualization.GeoChart(chart.element);
|
614
|
+
resize(function () {
|
615
|
+
chart.chart.draw(data, options);
|
616
|
+
});
|
617
|
+
});
|
618
|
+
};
|
592
619
|
};
|
620
|
+
adapters.push(GoogleChartsAdapter);
|
621
|
+
}
|
622
|
+
|
623
|
+
// TODO add adapter option
|
624
|
+
// TODO remove chartType if cross-browser way
|
625
|
+
// to get the name of the chart class
|
626
|
+
function renderChart(chartType, chart) {
|
627
|
+
var i, adapter, fnName;
|
628
|
+
fnName = "render" + chartType + "Chart";
|
629
|
+
|
630
|
+
for (i = 0; i < adapters.length; i++) {
|
631
|
+
adapter = adapters[i];
|
632
|
+
if (isFunction(adapter[fnName])) {
|
633
|
+
return adapter[fnName](chart);
|
634
|
+
}
|
635
|
+
}
|
636
|
+
throw new Error("No adapter found");
|
593
637
|
}
|
594
638
|
|
595
639
|
// process data
|
@@ -604,6 +648,9 @@
|
|
604
648
|
} else {
|
605
649
|
opts.hideLegend = false;
|
606
650
|
}
|
651
|
+
if (opts.discrete) {
|
652
|
+
time = false;
|
653
|
+
}
|
607
654
|
|
608
655
|
// right format
|
609
656
|
for (i = 0; i < series.length; i++) {
|
@@ -623,56 +670,78 @@
|
|
623
670
|
return series;
|
624
671
|
}
|
625
672
|
|
626
|
-
function
|
627
|
-
renderLineChart(element, processSeries(data, opts, true), opts);
|
628
|
-
}
|
629
|
-
|
630
|
-
function processColumnData(element, data, opts) {
|
631
|
-
renderColumnChart(element, processSeries(data, opts, false), opts);
|
632
|
-
}
|
633
|
-
|
634
|
-
function processPieData(element, data, opts) {
|
673
|
+
function processSimple(data) {
|
635
674
|
var perfectData = toArr(data), i;
|
636
675
|
for (i = 0; i < perfectData.length; i++) {
|
637
676
|
perfectData[i] = [toStr(perfectData[i][0]), toFloat(perfectData[i][1])];
|
638
677
|
}
|
639
|
-
|
678
|
+
return perfectData;
|
679
|
+
}
|
680
|
+
|
681
|
+
function processLineData(chart) {
|
682
|
+
chart.data = processSeries(chart.data, chart.options, true);
|
683
|
+
renderChart("Line", chart);
|
684
|
+
}
|
685
|
+
|
686
|
+
function processColumnData(chart) {
|
687
|
+
chart.data = processSeries(chart.data, chart.options, false);
|
688
|
+
renderChart("Column", chart);
|
640
689
|
}
|
641
690
|
|
642
|
-
function
|
643
|
-
|
691
|
+
function processPieData(chart) {
|
692
|
+
chart.data = processSimple(chart.data);
|
693
|
+
renderChart("Pie", chart);
|
644
694
|
}
|
645
695
|
|
646
|
-
function
|
647
|
-
|
696
|
+
function processBarData(chart) {
|
697
|
+
chart.data = processSeries(chart.data, chart.options, false);
|
698
|
+
renderChart("Bar", chart);
|
648
699
|
}
|
649
700
|
|
650
|
-
function
|
701
|
+
function processAreaData(chart) {
|
702
|
+
chart.data = processSeries(chart.data, chart.options, true);
|
703
|
+
renderChart("Area", chart);
|
704
|
+
}
|
705
|
+
|
706
|
+
function processGeoData(chart) {
|
707
|
+
chart.data = processSimple(chart.data);
|
708
|
+
renderChart("Geo", chart);
|
709
|
+
}
|
710
|
+
|
711
|
+
function setElement(chart, element, dataSource, opts, callback) {
|
651
712
|
if (typeof element === "string") {
|
652
713
|
element = document.getElementById(element);
|
653
714
|
}
|
654
|
-
|
715
|
+
chart.element = element;
|
716
|
+
chart.options = opts || {};
|
717
|
+
chart.dataSource = dataSource;
|
718
|
+
Chartkick.charts[element.id] = chart;
|
719
|
+
fetchDataSource(chart, callback);
|
655
720
|
}
|
656
721
|
|
657
722
|
// define classes
|
658
723
|
|
659
724
|
Chartkick = {
|
660
725
|
LineChart: function (element, dataSource, opts) {
|
661
|
-
setElement(element, dataSource, opts, processLineData);
|
726
|
+
setElement(this, element, dataSource, opts, processLineData);
|
662
727
|
},
|
663
728
|
PieChart: function (element, dataSource, opts) {
|
664
|
-
setElement(element, dataSource, opts, processPieData);
|
729
|
+
setElement(this, element, dataSource, opts, processPieData);
|
665
730
|
},
|
666
731
|
ColumnChart: function (element, dataSource, opts) {
|
667
|
-
setElement(element, dataSource, opts, processColumnData);
|
732
|
+
setElement(this, element, dataSource, opts, processColumnData);
|
668
733
|
},
|
669
734
|
BarChart: function (element, dataSource, opts) {
|
670
|
-
setElement(element, dataSource, opts, processBarData);
|
735
|
+
setElement(this, element, dataSource, opts, processBarData);
|
671
736
|
},
|
672
737
|
AreaChart: function (element, dataSource, opts) {
|
673
|
-
setElement(element, dataSource, opts, processAreaData);
|
674
|
-
}
|
738
|
+
setElement(this, element, dataSource, opts, processAreaData);
|
739
|
+
},
|
740
|
+
GeoChart: function (element, dataSource, opts) {
|
741
|
+
setElement(this, element, dataSource, opts, processGeoData);
|
742
|
+
},
|
743
|
+
charts: {}
|
675
744
|
};
|
676
745
|
|
677
746
|
window.Chartkick = Chartkick;
|
678
|
-
}());
|
747
|
+
}(window));
|
data/lib/chartkick/helper.rb
CHANGED
@@ -24,6 +24,10 @@ module Chartkick
|
|
24
24
|
chartkick_chart "AreaChart", data_source, options
|
25
25
|
end
|
26
26
|
|
27
|
+
def geo_chart(data_source, options = {})
|
28
|
+
chartkick_chart "GeoChart", data_source, options
|
29
|
+
end
|
30
|
+
|
27
31
|
private
|
28
32
|
|
29
33
|
def chartkick_chart(klass, data_source, options, &block)
|
data/lib/chartkick/version.rb
CHANGED
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: 1.2.
|
4
|
+
version: 1.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -95,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
95
|
version: '0'
|
96
96
|
requirements: []
|
97
97
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.2.
|
98
|
+
rubygems_version: 2.2.2
|
99
99
|
signing_key:
|
100
100
|
specification_version: 4
|
101
101
|
summary: Create beautiful Javascript charts with one line of Ruby
|