chartkick 1.4.1 → 1.4.2
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 +9 -0
- data/README.md +17 -11
- data/app/assets/javascripts/chartkick.js +451 -434
- data/chartkick.gemspec +2 -2
- data/lib/chartkick/engine.rb +6 -2
- data/lib/chartkick/helper.rb +2 -1
- data/lib/chartkick/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30bd21c65fb97d053acf056e67d24b9982d77eed
|
4
|
+
data.tar.gz: de5da367cefd5d077af3d2132b1ac948d7e8207c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a786415ad5316e7bc7237f67a0dc70407eaf9f96dcfa6ec9c99a78fbdcb036c848c1bb8363ce18ac109fc4cb9815f177b3f1758b7dac445c83ff207bbdcf62d
|
7
|
+
data.tar.gz: 8173102a5c963174a9659ce964af53015489bad6674eb0ded65753b904c4164de8fe6db9403439cd68ae6e9c5a0acec52a01480e45f5712522b01c584a4069a4
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 1.4.2
|
2
|
+
|
3
|
+
- Added `width` option
|
4
|
+
- Added `label` option
|
5
|
+
- Added support for `stacked: false` for area charts
|
6
|
+
- Lazy load adapters
|
7
|
+
- Better tooltip for dates for Google Charts
|
8
|
+
- Fixed asset precompilation issue with Rails 5
|
9
|
+
|
1
10
|
## 1.4.1
|
2
11
|
|
3
12
|
- Fixed regression with `min: nil`
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Chartkick
|
2
2
|
|
3
|
-
Create beautiful
|
3
|
+
Create beautiful JavaScript charts with one line of Ruby. No more fighting with charting libraries!
|
4
4
|
|
5
5
|
[See it in action](http://ankane.github.io/chartkick/)
|
6
6
|
|
@@ -67,7 +67,7 @@ Timeline
|
|
67
67
|
Multiple series
|
68
68
|
|
69
69
|
```erb
|
70
|
-
<%= line_chart @goals.map{|goal|
|
70
|
+
<%= line_chart @goals.map { |goal|
|
71
71
|
{name: goal.name, data: goal.feats.group_by_week(:created_at).count}
|
72
72
|
} %>
|
73
73
|
```
|
@@ -106,10 +106,10 @@ render json: Task.group(:goal_id).group_by_day(:completed_at).count.chart_json
|
|
106
106
|
|
107
107
|
### Options
|
108
108
|
|
109
|
-
Id and height
|
109
|
+
Id, width, and height
|
110
110
|
|
111
111
|
```erb
|
112
|
-
<%= line_chart data, id: "users-chart", height: "500px" %>
|
112
|
+
<%= line_chart data, id: "users-chart", width: "800px", height: "500px" %>
|
113
113
|
```
|
114
114
|
|
115
115
|
Min and max values
|
@@ -138,6 +138,12 @@ Discrete axis
|
|
138
138
|
<%= line_chart data, discrete: true %>
|
139
139
|
```
|
140
140
|
|
141
|
+
Label (for single series)
|
142
|
+
|
143
|
+
```erb
|
144
|
+
<%= line_chart data, label: "Value" %>
|
145
|
+
```
|
146
|
+
|
141
147
|
Axis titles
|
142
148
|
|
143
149
|
```erb
|
@@ -169,7 +175,7 @@ Customize the html
|
|
169
175
|
Chartkick.options[:html] = '<div id="%{id}" style="height: %{height};">Loading...</div>'
|
170
176
|
```
|
171
177
|
|
172
|
-
You capture the
|
178
|
+
You capture the JavaScript in a content block with:
|
173
179
|
|
174
180
|
```ruby
|
175
181
|
Chartkick.options[:content_for] = :charts_js
|
@@ -182,7 +188,7 @@ Then, in your layout:
|
|
182
188
|
<%= yield_content :charts_js %> <%# Padrino %>
|
183
189
|
```
|
184
190
|
|
185
|
-
This is great for including all of your
|
191
|
+
This is great for including all of your JavaScript at the bottom of the page.
|
186
192
|
|
187
193
|
### Data
|
188
194
|
|
@@ -216,12 +222,12 @@ Add this line to your application's Gemfile:
|
|
216
222
|
gem "chartkick"
|
217
223
|
```
|
218
224
|
|
219
|
-
And add the
|
225
|
+
And add the JavaScript files to your views. These files must be included **before** the helper methods, unless using the `:content_for` option.
|
220
226
|
|
221
227
|
For Google Charts, use:
|
222
228
|
|
223
229
|
```erb
|
224
|
-
<%= javascript_include_tag "
|
230
|
+
<%= javascript_include_tag "https://www.google.com/jsapi", "chartkick" %>
|
225
231
|
```
|
226
232
|
|
227
233
|
If you prefer Highcharts, use:
|
@@ -241,7 +247,7 @@ You must include `chartkick.js` manually. [Download it here](https://raw.github
|
|
241
247
|
For Rails 2.3, you must use a script tag for Google Charts due to [this bug](https://rails.lighthouseapp.com/projects/8994/tickets/1664-javascript_include_tag-shouldnt-append-a-js-onto-external-urls).
|
242
248
|
|
243
249
|
```html
|
244
|
-
<script src="
|
250
|
+
<script src="https://www.google.com/jsapi"></script>
|
245
251
|
```
|
246
252
|
|
247
253
|
### For Sinatra
|
@@ -249,7 +255,7 @@ For Rails 2.3, you must use a script tag for Google Charts due to [this bug](htt
|
|
249
255
|
You must include `chartkick.js` manually. [Download it here](https://raw.github.com/ankane/chartkick/master/app/assets/javascripts/chartkick.js)
|
250
256
|
|
251
257
|
```html
|
252
|
-
<script src="
|
258
|
+
<script src="https://www.google.com/jsapi"></script>
|
253
259
|
<script src="chartkick.js"></script>
|
254
260
|
```
|
255
261
|
|
@@ -273,7 +279,7 @@ To specify a language for Google Charts, add:
|
|
273
279
|
</script>
|
274
280
|
```
|
275
281
|
|
276
|
-
**before** the
|
282
|
+
**before** the JavaScript files.
|
277
283
|
|
278
284
|
## No Ruby? No Problem
|
279
285
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
/*
|
2
2
|
* Chartkick.js
|
3
|
-
* Create beautiful
|
3
|
+
* Create beautiful JavaScript charts with minimal code
|
4
4
|
* https://github.com/ankane/chartkick.js
|
5
|
-
* v1.4.
|
5
|
+
* v1.4.2
|
6
6
|
* MIT License
|
7
7
|
*/
|
8
8
|
|
@@ -13,6 +13,7 @@
|
|
13
13
|
|
14
14
|
var config = window.Chartkick || {};
|
15
15
|
var Chartkick, ISO8601_PATTERN, DECIMAL_SEPARATOR, adapters = [];
|
16
|
+
var adapters = [];
|
16
17
|
|
17
18
|
// helpers
|
18
19
|
|
@@ -124,8 +125,8 @@
|
|
124
125
|
setMax(options, opts.max);
|
125
126
|
}
|
126
127
|
|
127
|
-
if (opts
|
128
|
-
setStacked(options);
|
128
|
+
if ("stacked" in opts) {
|
129
|
+
setStacked(options, opts.stacked);
|
129
130
|
}
|
130
131
|
|
131
132
|
if (opts.colors) {
|
@@ -235,518 +236,526 @@
|
|
235
236
|
return a[0].getTime() - b[0].getTime();
|
236
237
|
}
|
237
238
|
|
238
|
-
|
239
|
-
|
240
|
-
var
|
239
|
+
function loadAdapters() {
|
240
|
+
if (!HighchartsAdapter && "Highcharts" in window) {
|
241
|
+
var HighchartsAdapter = new function () {
|
242
|
+
var Highcharts = window.Highcharts;
|
241
243
|
|
242
|
-
|
244
|
+
this.name = "highcharts";
|
243
245
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
246
|
+
var defaultOptions = {
|
247
|
+
chart: {},
|
248
|
+
xAxis: {
|
249
|
+
title: {
|
250
|
+
text: null
|
251
|
+
},
|
252
|
+
labels: {
|
253
|
+
style: {
|
254
|
+
fontSize: "12px"
|
255
|
+
}
|
256
|
+
}
|
249
257
|
},
|
250
|
-
|
251
|
-
|
252
|
-
|
258
|
+
yAxis: {
|
259
|
+
title: {
|
260
|
+
text: null
|
261
|
+
},
|
262
|
+
labels: {
|
263
|
+
style: {
|
264
|
+
fontSize: "12px"
|
265
|
+
}
|
253
266
|
}
|
254
|
-
}
|
255
|
-
},
|
256
|
-
yAxis: {
|
267
|
+
},
|
257
268
|
title: {
|
258
269
|
text: null
|
259
270
|
},
|
260
|
-
|
271
|
+
credits: {
|
272
|
+
enabled: false
|
273
|
+
},
|
274
|
+
legend: {
|
275
|
+
borderWidth: 0
|
276
|
+
},
|
277
|
+
tooltip: {
|
261
278
|
style: {
|
262
279
|
fontSize: "12px"
|
263
280
|
}
|
281
|
+
},
|
282
|
+
plotOptions: {
|
283
|
+
areaspline: {},
|
284
|
+
series: {
|
285
|
+
marker: {}
|
286
|
+
}
|
264
287
|
}
|
265
|
-
}
|
266
|
-
title: {
|
267
|
-
text: null
|
268
|
-
},
|
269
|
-
credits: {
|
270
|
-
enabled: false
|
271
|
-
},
|
272
|
-
legend: {
|
273
|
-
borderWidth: 0
|
274
|
-
},
|
275
|
-
tooltip: {
|
276
|
-
style: {
|
277
|
-
fontSize: "12px"
|
278
|
-
}
|
279
|
-
},
|
280
|
-
plotOptions: {
|
281
|
-
areaspline: {},
|
282
|
-
series: {
|
283
|
-
marker: {}
|
284
|
-
}
|
285
|
-
}
|
286
|
-
};
|
288
|
+
};
|
287
289
|
|
288
|
-
|
289
|
-
|
290
|
-
|
290
|
+
var hideLegend = function (options) {
|
291
|
+
options.legend.enabled = false;
|
292
|
+
};
|
291
293
|
|
292
|
-
|
293
|
-
|
294
|
-
|
294
|
+
var setMin = function (options, min) {
|
295
|
+
options.yAxis.min = min;
|
296
|
+
};
|
295
297
|
|
296
|
-
|
297
|
-
|
298
|
-
|
298
|
+
var setMax = function (options, max) {
|
299
|
+
options.yAxis.max = max;
|
300
|
+
};
|
299
301
|
|
300
|
-
|
301
|
-
|
302
|
-
|
302
|
+
var setStacked = function (options, stacked) {
|
303
|
+
options.plotOptions.series.stacking = stacked ? "normal" : null;
|
304
|
+
};
|
303
305
|
|
304
|
-
|
305
|
-
|
306
|
-
|
306
|
+
var setXtitle = function (options, title) {
|
307
|
+
options.xAxis.title.text = title;
|
308
|
+
};
|
307
309
|
|
308
|
-
|
309
|
-
|
310
|
-
|
310
|
+
var setYtitle = function (options, title) {
|
311
|
+
options.yAxis.title.text = title;
|
312
|
+
};
|
313
|
+
|
314
|
+
var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setMin, setMax, setStacked, setXtitle, setYtitle);
|
311
315
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
enabled: false
|
316
|
+
this.renderLineChart = function (chart, chartType) {
|
317
|
+
chartType = chartType || "spline";
|
318
|
+
var chartOptions = {};
|
319
|
+
if (chartType === "areaspline") {
|
320
|
+
chartOptions = {
|
321
|
+
plotOptions: {
|
322
|
+
areaspline: {
|
323
|
+
stacking: "normal"
|
324
|
+
},
|
325
|
+
series: {
|
326
|
+
marker: {
|
327
|
+
enabled: false
|
328
|
+
}
|
326
329
|
}
|
327
330
|
}
|
331
|
+
};
|
332
|
+
}
|
333
|
+
var options = jsOptions(chart.data, chart.options, chartOptions), data, i, j;
|
334
|
+
options.xAxis.type = chart.options.discrete ? "category" : "datetime";
|
335
|
+
options.chart.type = chartType;
|
336
|
+
options.chart.renderTo = chart.element.id;
|
337
|
+
|
338
|
+
var series = chart.data;
|
339
|
+
for (i = 0; i < series.length; i++) {
|
340
|
+
data = series[i].data;
|
341
|
+
if (!chart.options.discrete) {
|
342
|
+
for (j = 0; j < data.length; j++) {
|
343
|
+
data[j][0] = data[j][0].getTime();
|
344
|
+
}
|
328
345
|
}
|
329
|
-
|
330
|
-
}
|
331
|
-
var options = jsOptions(chart.data, chart.options, chartOptions), data, i, j;
|
332
|
-
options.xAxis.type = chart.options.discrete ? "category" : "datetime";
|
333
|
-
options.chart.type = chartType;
|
334
|
-
options.chart.renderTo = chart.element.id;
|
335
|
-
|
336
|
-
var series = chart.data;
|
337
|
-
for (i = 0; i < series.length; i++) {
|
338
|
-
data = series[i].data;
|
339
|
-
if (!chart.options.discrete) {
|
340
|
-
for (j = 0; j < data.length; j++) {
|
341
|
-
data[j][0] = data[j][0].getTime();
|
342
|
-
}
|
346
|
+
series[i].marker = {symbol: "circle"};
|
343
347
|
}
|
344
|
-
series
|
345
|
-
|
346
|
-
|
347
|
-
new Highcharts.Chart(options);
|
348
|
-
};
|
349
|
-
|
350
|
-
this.renderScatterChart = function (chart) {
|
351
|
-
var chartOptions = {};
|
352
|
-
var options = jsOptions(chart.data, chart.options, chartOptions);
|
353
|
-
options.chart.type = 'scatter';
|
354
|
-
options.chart.renderTo = chart.element.id;
|
355
|
-
options.series = chart.data;
|
356
|
-
new Highcharts.Chart(options);
|
357
|
-
};
|
358
|
-
|
359
|
-
this.renderPieChart = function (chart) {
|
360
|
-
var chartOptions = {};
|
361
|
-
if (chart.options.colors) {
|
362
|
-
chartOptions.colors = chart.options.colors;
|
363
|
-
}
|
364
|
-
var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
|
365
|
-
options.chart.renderTo = chart.element.id;
|
366
|
-
options.series = [{
|
367
|
-
type: "pie",
|
368
|
-
name: "Value",
|
369
|
-
data: chart.data
|
370
|
-
}];
|
371
|
-
new Highcharts.Chart(options);
|
372
|
-
};
|
373
|
-
|
374
|
-
this.renderColumnChart = function (chart, chartType) {
|
375
|
-
var chartType = chartType || "column";
|
376
|
-
var series = chart.data;
|
377
|
-
var options = jsOptions(series, chart.options), i, j, s, d, rows = [];
|
378
|
-
options.chart.type = chartType;
|
379
|
-
options.chart.renderTo = chart.element.id;
|
348
|
+
options.series = series;
|
349
|
+
new Highcharts.Chart(options);
|
350
|
+
};
|
380
351
|
|
381
|
-
|
382
|
-
|
352
|
+
this.renderScatterChart = function (chart) {
|
353
|
+
var chartOptions = {};
|
354
|
+
var options = jsOptions(chart.data, chart.options, chartOptions);
|
355
|
+
options.chart.type = 'scatter';
|
356
|
+
options.chart.renderTo = chart.element.id;
|
357
|
+
options.series = chart.data;
|
358
|
+
new Highcharts.Chart(options);
|
359
|
+
};
|
383
360
|
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
361
|
+
this.renderPieChart = function (chart) {
|
362
|
+
var chartOptions = {};
|
363
|
+
if (chart.options.colors) {
|
364
|
+
chartOptions.colors = chart.options.colors;
|
365
|
+
}
|
366
|
+
var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
|
367
|
+
options.chart.renderTo = chart.element.id;
|
368
|
+
options.series = [{
|
369
|
+
type: "pie",
|
370
|
+
name: chart.options.label || "Value",
|
371
|
+
data: chart.data
|
372
|
+
}];
|
373
|
+
new Highcharts.Chart(options);
|
374
|
+
};
|
375
|
+
|
376
|
+
this.renderColumnChart = function (chart, chartType) {
|
377
|
+
var chartType = chartType || "column";
|
378
|
+
var series = chart.data;
|
379
|
+
var options = jsOptions(series, chart.options), i, j, s, d, rows = [];
|
380
|
+
options.chart.type = chartType;
|
381
|
+
options.chart.renderTo = chart.element.id;
|
382
|
+
|
383
|
+
for (i = 0; i < series.length; i++) {
|
384
|
+
s = series[i];
|
385
|
+
|
386
|
+
for (j = 0; j < s.data.length; j++) {
|
387
|
+
d = s.data[j];
|
388
|
+
if (!rows[d[0]]) {
|
389
|
+
rows[d[0]] = new Array(series.length);
|
390
|
+
}
|
391
|
+
rows[d[0]][i] = d[1];
|
388
392
|
}
|
389
|
-
rows[d[0]][i] = d[1];
|
390
393
|
}
|
391
|
-
}
|
392
394
|
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
395
|
+
var categories = [];
|
396
|
+
for (i in rows) {
|
397
|
+
if (rows.hasOwnProperty(i)) {
|
398
|
+
categories.push(i);
|
399
|
+
}
|
397
400
|
}
|
398
|
-
|
399
|
-
options.xAxis.categories = categories;
|
401
|
+
options.xAxis.categories = categories;
|
400
402
|
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
403
|
+
var newSeries = [];
|
404
|
+
for (i = 0; i < series.length; i++) {
|
405
|
+
d = [];
|
406
|
+
for (j = 0; j < categories.length; j++) {
|
407
|
+
d.push(rows[categories[j]][i] || 0);
|
408
|
+
}
|
407
409
|
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
410
|
+
newSeries.push({
|
411
|
+
name: series[i].name,
|
412
|
+
data: d
|
413
|
+
});
|
414
|
+
}
|
415
|
+
options.series = newSeries;
|
414
416
|
|
415
|
-
|
416
|
-
|
417
|
+
new Highcharts.Chart(options);
|
418
|
+
};
|
417
419
|
|
418
|
-
|
420
|
+
var self = this;
|
419
421
|
|
420
|
-
|
421
|
-
|
422
|
-
|
422
|
+
this.renderBarChart = function (chart) {
|
423
|
+
self.renderColumnChart(chart, "bar");
|
424
|
+
};
|
423
425
|
|
424
|
-
|
425
|
-
|
426
|
+
this.renderAreaChart = function (chart) {
|
427
|
+
self.renderLineChart(chart, "areaspline");
|
428
|
+
};
|
426
429
|
};
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
430
|
+
adapters.push(HighchartsAdapter);
|
431
|
+
}
|
432
|
+
if (!GoogleChartsAdapter && window.google && window.google.setOnLoadCallback) {
|
433
|
+
var GoogleChartsAdapter = new function () {
|
434
|
+
var google = window.google;
|
435
|
+
|
436
|
+
this.name = "google";
|
437
|
+
|
438
|
+
var loaded = {};
|
439
|
+
var callbacks = [];
|
440
|
+
|
441
|
+
var runCallbacks = function () {
|
442
|
+
var cb, call;
|
443
|
+
for (var i = 0; i < callbacks.length; i++) {
|
444
|
+
cb = callbacks[i];
|
445
|
+
call = google.visualization && ((cb.pack === "corechart" && google.visualization.LineChart) || (cb.pack === "timeline" && google.visualization.Timeline))
|
446
|
+
if (call) {
|
447
|
+
cb.callback();
|
448
|
+
callbacks.splice(i, 1);
|
449
|
+
i--;
|
450
|
+
}
|
448
451
|
}
|
449
|
-
}
|
450
|
-
};
|
452
|
+
};
|
451
453
|
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
454
|
+
var waitForLoaded = function (pack, callback) {
|
455
|
+
if (!callback) {
|
456
|
+
callback = pack;
|
457
|
+
pack = "corechart";
|
458
|
+
}
|
457
459
|
|
458
|
-
|
460
|
+
callbacks.push({pack: pack, callback: callback});
|
459
461
|
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
462
|
+
if (loaded[pack]) {
|
463
|
+
runCallbacks();
|
464
|
+
} else {
|
465
|
+
loaded[pack] = true;
|
464
466
|
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
467
|
+
// https://groups.google.com/forum/#!topic/google-visualization-api/fMKJcyA2yyI
|
468
|
+
var loadOptions = {
|
469
|
+
packages: [pack],
|
470
|
+
callback: runCallbacks
|
471
|
+
};
|
472
|
+
if (config.language) {
|
473
|
+
loadOptions.language = config.language;
|
474
|
+
}
|
475
|
+
google.load("visualization", "1", loadOptions);
|
472
476
|
}
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
477
|
+
};
|
478
|
+
|
479
|
+
// Set chart options
|
480
|
+
var defaultOptions = {
|
481
|
+
chartArea: {},
|
482
|
+
fontName: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",
|
483
|
+
pointSize: 6,
|
484
|
+
legend: {
|
485
|
+
textStyle: {
|
486
|
+
fontSize: 12,
|
487
|
+
color: "#444"
|
488
|
+
},
|
489
|
+
alignment: "center",
|
490
|
+
position: "right"
|
486
491
|
},
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
492
|
+
curveType: "function",
|
493
|
+
hAxis: {
|
494
|
+
textStyle: {
|
495
|
+
color: "#666",
|
496
|
+
fontSize: 12
|
497
|
+
},
|
498
|
+
titleTextStyle: {},
|
499
|
+
gridlines: {
|
500
|
+
color: "transparent"
|
501
|
+
},
|
502
|
+
baselineColor: "#ccc",
|
503
|
+
viewWindow: {}
|
495
504
|
},
|
496
|
-
|
497
|
-
|
498
|
-
|
505
|
+
vAxis: {
|
506
|
+
textStyle: {
|
507
|
+
color: "#666",
|
508
|
+
fontSize: 12
|
509
|
+
},
|
510
|
+
titleTextStyle: {},
|
511
|
+
baselineColor: "#ccc",
|
512
|
+
viewWindow: {}
|
499
513
|
},
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
color: "#666",
|
506
|
-
fontSize: 12
|
507
|
-
},
|
508
|
-
titleTextStyle: {},
|
509
|
-
baselineColor: "#ccc",
|
510
|
-
viewWindow: {}
|
511
|
-
},
|
512
|
-
tooltip: {
|
513
|
-
textStyle: {
|
514
|
-
color: "#666",
|
515
|
-
fontSize: 12
|
514
|
+
tooltip: {
|
515
|
+
textStyle: {
|
516
|
+
color: "#666",
|
517
|
+
fontSize: 12
|
518
|
+
}
|
516
519
|
}
|
517
|
-
}
|
518
|
-
};
|
520
|
+
};
|
519
521
|
|
520
|
-
|
521
|
-
|
522
|
-
|
522
|
+
var hideLegend = function (options) {
|
523
|
+
options.legend.position = "none";
|
524
|
+
};
|
523
525
|
|
524
|
-
|
525
|
-
|
526
|
-
|
526
|
+
var setMin = function (options, min) {
|
527
|
+
options.vAxis.viewWindow.min = min;
|
528
|
+
};
|
527
529
|
|
528
|
-
|
529
|
-
|
530
|
-
|
530
|
+
var setMax = function (options, max) {
|
531
|
+
options.vAxis.viewWindow.max = max;
|
532
|
+
};
|
531
533
|
|
532
|
-
|
533
|
-
|
534
|
-
|
534
|
+
var setBarMin = function (options, min) {
|
535
|
+
options.hAxis.viewWindow.min = min;
|
536
|
+
};
|
535
537
|
|
536
|
-
|
537
|
-
|
538
|
-
|
538
|
+
var setBarMax = function (options, max) {
|
539
|
+
options.hAxis.viewWindow.max = max;
|
540
|
+
};
|
539
541
|
|
540
|
-
|
541
|
-
|
542
|
-
|
542
|
+
var setStacked = function (options, stacked) {
|
543
|
+
options.isStacked = !!stacked;
|
544
|
+
};
|
543
545
|
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
var setYtitle = function (options, title) {
|
550
|
-
options.vAxis.title = title;
|
551
|
-
options.vAxis.titleTextStyle.italic = false;
|
552
|
-
};
|
546
|
+
var setXtitle = function (options, title) {
|
547
|
+
options.hAxis.title = title;
|
548
|
+
options.hAxis.titleTextStyle.italic = false;
|
549
|
+
}
|
553
550
|
|
554
|
-
|
551
|
+
var setYtitle = function (options, title) {
|
552
|
+
options.vAxis.title = title;
|
553
|
+
options.vAxis.titleTextStyle.italic = false;
|
554
|
+
};
|
555
555
|
|
556
|
-
|
557
|
-
var createDataTable = function (series, columnType) {
|
558
|
-
var data = new google.visualization.DataTable();
|
559
|
-
data.addColumn(columnType, "");
|
556
|
+
var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setMin, setMax, setStacked, setXtitle, setYtitle);
|
560
557
|
|
561
|
-
|
562
|
-
|
563
|
-
s =
|
564
|
-
|
558
|
+
// cant use object as key
|
559
|
+
var createDataTable = function (series, columnType) {
|
560
|
+
var i, j, s, d, key, rows = [];
|
561
|
+
for (i = 0; i < series.length; i++) {
|
562
|
+
s = series[i];
|
565
563
|
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
564
|
+
for (j = 0; j < s.data.length; j++) {
|
565
|
+
d = s.data[j];
|
566
|
+
key = (columnType === "datetime") ? d[0].getTime() : d[0];
|
567
|
+
if (!rows[key]) {
|
568
|
+
rows[key] = new Array(series.length);
|
569
|
+
}
|
570
|
+
rows[key][i] = toFloat(d[1]);
|
571
571
|
}
|
572
|
-
rows[key][i] = toFloat(d[1]);
|
573
572
|
}
|
574
|
-
}
|
575
573
|
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
if (
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
574
|
+
var rows2 = [];
|
575
|
+
var day = true;
|
576
|
+
var value;
|
577
|
+
for (i in rows) {
|
578
|
+
if (rows.hasOwnProperty(i)) {
|
579
|
+
if (columnType === "datetime") {
|
580
|
+
value = new Date(toFloat(i));
|
581
|
+
day = day && isDay(value);
|
582
|
+
} else if (columnType === "number") {
|
583
|
+
value = toFloat(i);
|
584
|
+
} else {
|
585
|
+
value = i;
|
586
|
+
}
|
587
|
+
rows2.push([value].concat(rows[i]));
|
586
588
|
}
|
587
|
-
rows2.push([value].concat(rows[i]));
|
588
589
|
}
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
}
|
593
|
-
data.addRows(rows2);
|
590
|
+
if (columnType === "datetime") {
|
591
|
+
rows2.sort(sortByTime);
|
592
|
+
}
|
594
593
|
|
595
|
-
|
596
|
-
|
594
|
+
// create datatable
|
595
|
+
var data = new google.visualization.DataTable();
|
596
|
+
columnType = columnType === "datetime" && day ? "date" : columnType;
|
597
|
+
data.addColumn(columnType, "");
|
598
|
+
for (i = 0; i < series.length; i++) {
|
599
|
+
data.addColumn("number", series[i].name);
|
600
|
+
}
|
601
|
+
data.addRows(rows2);
|
597
602
|
|
598
|
-
|
599
|
-
|
600
|
-
window.attachEvent("onresize", callback);
|
601
|
-
} else if (window.addEventListener) {
|
602
|
-
window.addEventListener("resize", callback, true);
|
603
|
-
}
|
604
|
-
callback();
|
605
|
-
};
|
603
|
+
return data;
|
604
|
+
};
|
606
605
|
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
606
|
+
var resize = function (callback) {
|
607
|
+
if (window.attachEvent) {
|
608
|
+
window.attachEvent("onresize", callback);
|
609
|
+
} else if (window.addEventListener) {
|
610
|
+
window.addEventListener("resize", callback, true);
|
611
|
+
}
|
612
|
+
callback();
|
613
|
+
};
|
614
|
+
|
615
|
+
this.renderLineChart = function (chart) {
|
616
|
+
waitForLoaded(function () {
|
617
|
+
var options = jsOptions(chart.data, chart.options);
|
618
|
+
var data = createDataTable(chart.data, chart.options.discrete ? "string" : "datetime");
|
619
|
+
chart.chart = new google.visualization.LineChart(chart.element);
|
620
|
+
resize(function () {
|
621
|
+
chart.chart.draw(data, options);
|
622
|
+
});
|
614
623
|
});
|
615
|
-
}
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
+
};
|
625
|
+
|
626
|
+
this.renderPieChart = function (chart) {
|
627
|
+
waitForLoaded(function () {
|
628
|
+
var chartOptions = {
|
629
|
+
chartArea: {
|
630
|
+
top: "10%",
|
631
|
+
height: "80%"
|
632
|
+
}
|
633
|
+
};
|
634
|
+
if (chart.options.colors) {
|
635
|
+
chartOptions.colors = chart.options.colors;
|
624
636
|
}
|
625
|
-
|
626
|
-
if (chart.options.colors) {
|
627
|
-
chartOptions.colors = chart.options.colors;
|
628
|
-
}
|
629
|
-
var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
|
637
|
+
var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
|
630
638
|
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
639
|
+
var data = new google.visualization.DataTable();
|
640
|
+
data.addColumn("string", "");
|
641
|
+
data.addColumn("number", "Value");
|
642
|
+
data.addRows(chart.data);
|
635
643
|
|
636
|
-
|
637
|
-
|
638
|
-
|
644
|
+
chart.chart = new google.visualization.PieChart(chart.element);
|
645
|
+
resize(function () {
|
646
|
+
chart.chart.draw(data, options);
|
647
|
+
});
|
639
648
|
});
|
640
|
-
}
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
649
|
+
};
|
650
|
+
|
651
|
+
this.renderColumnChart = function (chart) {
|
652
|
+
waitForLoaded(function () {
|
653
|
+
var options = jsOptions(chart.data, chart.options);
|
654
|
+
var data = createDataTable(chart.data, "string");
|
655
|
+
chart.chart = new google.visualization.ColumnChart(chart.element);
|
656
|
+
resize(function () {
|
657
|
+
chart.chart.draw(data, options);
|
658
|
+
});
|
650
659
|
});
|
651
|
-
}
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
+
};
|
661
|
+
|
662
|
+
this.renderBarChart = function (chart) {
|
663
|
+
waitForLoaded(function () {
|
664
|
+
var chartOptions = {
|
665
|
+
hAxis: {
|
666
|
+
gridlines: {
|
667
|
+
color: "#ccc"
|
668
|
+
}
|
660
669
|
}
|
661
|
-
}
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
670
|
+
};
|
671
|
+
var options = jsOptionsFunc(defaultOptions, hideLegend, setBarMin, setBarMax, setStacked)(chart.data, chart.options, chartOptions);
|
672
|
+
var data = createDataTable(chart.data, "string");
|
673
|
+
chart.chart = new google.visualization.BarChart(chart.element);
|
674
|
+
resize(function () {
|
675
|
+
chart.chart.draw(data, options);
|
676
|
+
});
|
668
677
|
});
|
669
|
-
}
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
678
|
+
};
|
679
|
+
|
680
|
+
this.renderAreaChart = function (chart) {
|
681
|
+
waitForLoaded(function () {
|
682
|
+
var chartOptions = {
|
683
|
+
isStacked: true,
|
684
|
+
pointSize: 0,
|
685
|
+
areaOpacity: 0.5
|
686
|
+
};
|
687
|
+
var options = jsOptions(chart.data, chart.options, chartOptions);
|
688
|
+
var data = createDataTable(chart.data, chart.options.discrete ? "string" : "datetime");
|
689
|
+
chart.chart = new google.visualization.AreaChart(chart.element);
|
690
|
+
resize(function () {
|
691
|
+
chart.chart.draw(data, options);
|
692
|
+
});
|
684
693
|
});
|
685
|
-
}
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
}
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
694
|
+
};
|
695
|
+
|
696
|
+
this.renderGeoChart = function (chart) {
|
697
|
+
waitForLoaded(function () {
|
698
|
+
var chartOptions = {
|
699
|
+
legend: "none",
|
700
|
+
colorAxis: {
|
701
|
+
colors: chart.options.colors || ["#f6c7b6", "#ce502d"]
|
702
|
+
}
|
703
|
+
};
|
704
|
+
var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
|
705
|
+
|
706
|
+
var data = new google.visualization.DataTable();
|
707
|
+
data.addColumn("string", "");
|
708
|
+
data.addColumn("number", chart.options.label || "Value");
|
709
|
+
data.addRows(chart.data);
|
710
|
+
|
711
|
+
chart.chart = new google.visualization.GeoChart(chart.element);
|
712
|
+
resize(function () {
|
713
|
+
chart.chart.draw(data, options);
|
714
|
+
});
|
706
715
|
});
|
707
|
-
}
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
716
|
+
};
|
717
|
+
|
718
|
+
this.renderScatterChart = function (chart) {
|
719
|
+
waitForLoaded(function () {
|
720
|
+
var chartOptions = {};
|
721
|
+
var options = jsOptions(chart.data, chart.options, chartOptions);
|
722
|
+
var data = createDataTable(chart.data, "number");
|
723
|
+
|
724
|
+
chart.chart = new google.visualization.ScatterChart(chart.element);
|
725
|
+
resize(function () {
|
726
|
+
chart.chart.draw(data, options);
|
727
|
+
});
|
719
728
|
});
|
720
|
-
}
|
721
|
-
};
|
729
|
+
};
|
722
730
|
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
731
|
+
this.renderTimeline = function (chart) {
|
732
|
+
waitForLoaded("timeline", function () {
|
733
|
+
var chartOptions = {
|
734
|
+
legend: "none"
|
735
|
+
};
|
728
736
|
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
737
|
+
if (chart.options.colors) {
|
738
|
+
chartOptions.colors = chart.options.colors;
|
739
|
+
}
|
740
|
+
var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
|
733
741
|
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
742
|
+
var data = new google.visualization.DataTable();
|
743
|
+
data.addColumn({type: "string", id: "Name"});
|
744
|
+
data.addColumn({type: "date", id: "Start"});
|
745
|
+
data.addColumn({type: "date", id: "End"});
|
746
|
+
data.addRows(chart.data);
|
739
747
|
|
740
|
-
|
748
|
+
chart.chart = new google.visualization.Timeline(chart.element);
|
741
749
|
|
742
|
-
|
743
|
-
|
750
|
+
resize(function () {
|
751
|
+
chart.chart.draw(data, options);
|
752
|
+
});
|
744
753
|
});
|
745
|
-
}
|
754
|
+
};
|
746
755
|
};
|
747
|
-
};
|
748
756
|
|
749
|
-
|
757
|
+
adapters.push(GoogleChartsAdapter);
|
758
|
+
}
|
750
759
|
}
|
751
760
|
|
752
761
|
// TODO remove chartType if cross-browser way
|
@@ -756,6 +765,10 @@
|
|
756
765
|
fnName = "render" + chartType;
|
757
766
|
adapterName = chart.options.adapter;
|
758
767
|
|
768
|
+
if (adapters.length == 0) {
|
769
|
+
loadAdapters();
|
770
|
+
}
|
771
|
+
|
759
772
|
for (i = 0; i < adapters.length; i++) {
|
760
773
|
adapter = adapters[i];
|
761
774
|
if ((!adapterName || adapterName === adapter.name) && isFunction(adapter[fnName])) {
|
@@ -790,12 +803,16 @@
|
|
790
803
|
return r;
|
791
804
|
};
|
792
805
|
|
806
|
+
function isDay(d) {
|
807
|
+
return d.getMilliseconds() + d.getSeconds() + d.getMinutes() + d.getHours() === 0;
|
808
|
+
}
|
809
|
+
|
793
810
|
function processSeries(series, opts, keyType) {
|
794
811
|
var i;
|
795
812
|
|
796
813
|
// see if one series or multiple
|
797
814
|
if (!isArray(series) || typeof series[0] !== "object" || isArray(series[0])) {
|
798
|
-
series = [{name: "Value", data: series}];
|
815
|
+
series = [{name: opts.label || "Value", data: series}];
|
799
816
|
opts.hideLegend = true;
|
800
817
|
} else {
|
801
818
|
opts.hideLegend = false;
|
data/chartkick.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Chartkick::VERSION
|
9
9
|
spec.authors = ["Andrew Kane"]
|
10
10
|
spec.email = ["acekane1@gmail.com"]
|
11
|
-
spec.description = "Create beautiful
|
12
|
-
spec.summary = "Create beautiful
|
11
|
+
spec.description = "Create beautiful JavaScript charts with one line of Ruby"
|
12
|
+
spec.summary = "Create beautiful JavaScript charts with one line of Ruby"
|
13
13
|
spec.homepage = "http://chartkick.com"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/lib/chartkick/engine.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
module Chartkick
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
initializer "precompile", group: :all do |app|
|
4
|
-
|
5
|
-
|
4
|
+
if Rails::VERSION::MAJOR >= 5
|
5
|
+
app.config.assets.precompile << "chartkick.js"
|
6
|
+
else
|
7
|
+
# use a proc instead of a string
|
8
|
+
app.config.assets.precompile << proc { |path| path == "chartkick.js" }
|
9
|
+
end
|
6
10
|
end
|
7
11
|
|
8
12
|
initializer "helper" do
|
data/lib/chartkick/helper.rb
CHANGED
@@ -42,10 +42,11 @@ module Chartkick
|
|
42
42
|
options = chartkick_deep_merge(Chartkick.options, options)
|
43
43
|
element_id = options.delete(:id) || "chart-#{@chartkick_chart_id += 1}"
|
44
44
|
height = options.delete(:height) || "300px"
|
45
|
+
width = options.delete(:width) || "100%"
|
45
46
|
# content_for: nil must override default
|
46
47
|
content_for = options.key?(:content_for) ? options.delete(:content_for) : Chartkick.content_for
|
47
48
|
|
48
|
-
html = (options.delete(:html) || %(<div id="%{id}" style="height: %{height}; text-align: center; color: #999; line-height: %{height}; font-size: 14px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif;">Loading...</div>)) % {id: ERB::Util.html_escape(element_id), height: ERB::Util.html_escape(height)}
|
49
|
+
html = (options.delete(:html) || %(<div id="%{id}" style="height: %{height}; width: %{width}; text-align: center; color: #999; line-height: %{height}; font-size: 14px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif;">Loading...</div>)) % {id: ERB::Util.html_escape(element_id), height: ERB::Util.html_escape(height), width: ERB::Util.html_escape(width)}
|
49
50
|
|
50
51
|
js = <<JS
|
51
52
|
<script type="text/javascript">
|
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.4.
|
4
|
+
version: 1.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
description: Create beautiful
|
55
|
+
description: Create beautiful JavaScript charts with one line of Ruby
|
56
56
|
email:
|
57
57
|
- acekane1@gmail.com
|
58
58
|
executables: []
|
@@ -95,10 +95,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
95
|
version: '0'
|
96
96
|
requirements: []
|
97
97
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.
|
98
|
+
rubygems_version: 2.5.2
|
99
99
|
signing_key:
|
100
100
|
specification_version: 4
|
101
|
-
summary: Create beautiful
|
101
|
+
summary: Create beautiful JavaScript charts with one line of Ruby
|
102
102
|
test_files:
|
103
103
|
- test/chartkick_test.rb
|
104
104
|
- test/test_helper.rb
|