thm 0.1.8

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.
data/js/chartkick.js ADDED
@@ -0,0 +1,829 @@
1
+ /*
2
+ * Chartkick.js
3
+ * Create beautiful Javascript charts with minimal code
4
+ * https://github.com/ankane/chartkick.js
5
+ * v1.2.2
6
+ * MIT License
7
+ */
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
+
17
+ // helpers
18
+
19
+ function isArray(variable) {
20
+ return Object.prototype.toString.call(variable) === "[object Array]";
21
+ }
22
+
23
+ function isFunction(variable) {
24
+ return variable instanceof Function;
25
+ }
26
+
27
+ function isPlainObject(variable) {
28
+ return !isFunction(variable) && variable instanceof Object;
29
+ }
30
+
31
+ // https://github.com/madrobby/zepto/blob/master/src/zepto.js
32
+ function extend(target, source) {
33
+ var key;
34
+ for (key in source) {
35
+ if (isPlainObject(source[key]) || isArray(source[key])) {
36
+ if (isPlainObject(source[key]) && !isPlainObject(target[key])) {
37
+ target[key] = {};
38
+ }
39
+ if (isArray(source[key]) && !isArray(target[key])) {
40
+ target[key] = [];
41
+ }
42
+ extend(target[key], source[key]);
43
+ } else if (source[key] !== undefined) {
44
+ target[key] = source[key];
45
+ }
46
+ }
47
+ }
48
+
49
+ function merge(obj1, obj2) {
50
+ var target = {};
51
+ extend(target, obj1);
52
+ extend(target, obj2);
53
+ return target;
54
+ }
55
+
56
+ // https://github.com/Do/iso8601.js
57
+ ISO8601_PATTERN = /(\d\d\d\d)(\-)?(\d\d)(\-)?(\d\d)(T)?(\d\d)(:)?(\d\d)?(:)?(\d\d)?([\.,]\d+)?($|Z|([\+\-])(\d\d)(:)?(\d\d)?)/i;
58
+ DECIMAL_SEPARATOR = String(1.5).charAt(1);
59
+
60
+ function parseISO8601(input) {
61
+ var day, hour, matches, milliseconds, minutes, month, offset, result, seconds, type, year;
62
+ type = Object.prototype.toString.call(input);
63
+ if (type === '[object Date]') {
64
+ return input;
65
+ }
66
+ if (type !== '[object String]') {
67
+ return;
68
+ }
69
+ if (matches = input.match(ISO8601_PATTERN)) {
70
+ year = parseInt(matches[1], 10);
71
+ month = parseInt(matches[3], 10) - 1;
72
+ day = parseInt(matches[5], 10);
73
+ hour = parseInt(matches[7], 10);
74
+ minutes = matches[9] ? parseInt(matches[9], 10) : 0;
75
+ seconds = matches[11] ? parseInt(matches[11], 10) : 0;
76
+ milliseconds = matches[12] ? parseFloat(DECIMAL_SEPARATOR + matches[12].slice(1)) * 1000 : 0;
77
+ result = Date.UTC(year, month, day, hour, minutes, seconds, milliseconds);
78
+ if (matches[13] && matches[14]) {
79
+ offset = matches[15] * 60;
80
+ if (matches[17]) {
81
+ offset += parseInt(matches[17], 10);
82
+ }
83
+ offset *= matches[14] === '-' ? -1 : 1;
84
+ result -= offset * 60 * 1000;
85
+ }
86
+ return new Date(result);
87
+ }
88
+ }
89
+ // end iso8601.js
90
+
91
+ function negativeValues(series) {
92
+ var i, j, data;
93
+ for (i = 0; i < series.length; i++) {
94
+ data = series[i].data;
95
+ for (j = 0; j < data.length; j++) {
96
+ if (data[j][1] < 0) {
97
+ return true;
98
+ }
99
+ }
100
+ }
101
+ return false;
102
+ }
103
+
104
+ function jsOptionsFunc(defaultOptions, hideLegend, setMin, setMax, setStacked) {
105
+ return function (series, opts, chartOptions) {
106
+ var options = merge({}, defaultOptions);
107
+ options = merge(options, chartOptions || {});
108
+
109
+ // hide legend
110
+ // this is *not* an external option!
111
+ if (opts.hideLegend) {
112
+ hideLegend(options);
113
+ }
114
+
115
+ // min
116
+ if ("min" in opts) {
117
+ setMin(options, opts.min);
118
+ } else if (!negativeValues(series)) {
119
+ setMin(options, 0);
120
+ }
121
+
122
+ // max
123
+ if ("max" in opts) {
124
+ setMax(options, opts.max);
125
+ }
126
+
127
+ if (opts.stacked) {
128
+ setStacked(options);
129
+ }
130
+
131
+ if (opts.colors) {
132
+ options.colors = opts.colors;
133
+ }
134
+
135
+ // merge library last
136
+ options = merge(options, opts.library || {});
137
+
138
+ return options;
139
+ };
140
+ }
141
+
142
+ function setText(element, text) {
143
+ if (document.body.innerText) {
144
+ element.innerText = text;
145
+ } else {
146
+ element.textContent = text;
147
+ }
148
+ }
149
+
150
+ function chartError(element, message) {
151
+ setText(element, "Error Loading Chart: " + message);
152
+ element.style.color = "#ff0000";
153
+ }
154
+
155
+ function getJSON(element, url, success) {
156
+ var $ = window.jQuery || window.Zepto || window.$;
157
+ $.ajax({
158
+ dataType: "json",
159
+ url: url,
160
+ success: success,
161
+ error: function (jqXHR, textStatus, errorThrown) {
162
+ var message = (typeof errorThrown === "string") ? errorThrown : errorThrown.message;
163
+ chartError(element, message);
164
+ }
165
+ });
166
+ }
167
+
168
+ function errorCatcher(chart, callback) {
169
+ try {
170
+ callback(chart);
171
+ } catch (err) {
172
+ chartError(chart.element, err.message);
173
+ throw err;
174
+ }
175
+ }
176
+
177
+ function fetchDataSource(chart, callback) {
178
+ if (typeof chart.dataSource === "string") {
179
+ getJSON(chart.element, chart.dataSource, function (data, textStatus, jqXHR) {
180
+ chart.data = data;
181
+ errorCatcher(chart, callback);
182
+ });
183
+ } else {
184
+ chart.data = chart.dataSource;
185
+ errorCatcher(chart, callback);
186
+ }
187
+ }
188
+
189
+ // type conversions
190
+
191
+ function toStr(n) {
192
+ return "" + n;
193
+ }
194
+
195
+ function toFloat(n) {
196
+ return parseFloat(n);
197
+ }
198
+
199
+ function toDate(n) {
200
+ if (typeof n !== "object") {
201
+ if (typeof n === "number") {
202
+ n = new Date(n * 1000); // ms
203
+ } else { // str
204
+ // try our best to get the str into iso8601
205
+ // TODO be smarter about this
206
+ var str = n.replace(/ /, "T").replace(" ", "").replace("UTC", "Z");
207
+ n = parseISO8601(str) || new Date(n);
208
+ }
209
+ }
210
+ return n;
211
+ }
212
+
213
+ function toArr(n) {
214
+ if (!isArray(n)) {
215
+ var arr = [], i;
216
+ for (i in n) {
217
+ if (n.hasOwnProperty(i)) {
218
+ arr.push([i, n[i]]);
219
+ }
220
+ }
221
+ n = arr;
222
+ }
223
+ return n;
224
+ }
225
+
226
+ function sortByTime(a, b) {
227
+ return a[0].getTime() - b[0].getTime();
228
+ }
229
+
230
+ if ("Highcharts" in window) {
231
+ var HighchartsAdapter = new function () {
232
+ var Highcharts = window.Highcharts;
233
+
234
+ var defaultOptions = {
235
+ chart: {},
236
+ xAxis: {
237
+ labels: {
238
+ style: {
239
+ fontSize: "12px"
240
+ }
241
+ }
242
+ },
243
+ yAxis: {
244
+ title: {
245
+ text: null
246
+ },
247
+ labels: {
248
+ style: {
249
+ fontSize: "12px"
250
+ }
251
+ }
252
+ },
253
+ title: {
254
+ text: null
255
+ },
256
+ credits: {
257
+ enabled: false
258
+ },
259
+ legend: {
260
+ borderWidth: 0
261
+ },
262
+ tooltip: {
263
+ style: {
264
+ fontSize: "12px"
265
+ }
266
+ },
267
+ plotOptions: {
268
+ areaspline: {},
269
+ series: {
270
+ marker: {}
271
+ }
272
+ }
273
+ };
274
+
275
+ var hideLegend = function (options) {
276
+ options.legend.enabled = false;
277
+ };
278
+
279
+ var setMin = function (options, min) {
280
+ options.yAxis.min = min;
281
+ };
282
+
283
+ var setMax = function (options, max) {
284
+ options.yAxis.max = max;
285
+ };
286
+
287
+ var setStacked = function (options) {
288
+ options.plotOptions.series.stacking = "normal";
289
+ };
290
+
291
+ var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setMin, setMax, setStacked);
292
+
293
+ this.renderLineChart = function (chart, chartType) {
294
+ chartType = chartType || "spline";
295
+ var chartOptions = {};
296
+ if (chartType === "areaspline") {
297
+ chartOptions = {
298
+ plotOptions: {
299
+ areaspline: {
300
+ stacking: "normal"
301
+ },
302
+ series: {
303
+ marker: {
304
+ enabled: false
305
+ }
306
+ }
307
+ }
308
+ };
309
+ }
310
+ var options = jsOptions(chart.data, chart.options, chartOptions), data, i, j;
311
+ options.xAxis.type = chart.options.discrete ? "category" : "datetime";
312
+ options.chart.type = chartType;
313
+ options.chart.renderTo = chart.element.id;
314
+
315
+ var series = chart.data;
316
+ for (i = 0; i < series.length; i++) {
317
+ data = series[i].data;
318
+ if (!chart.options.discrete) {
319
+ for (j = 0; j < data.length; j++) {
320
+ data[j][0] = data[j][0].getTime();
321
+ }
322
+ }
323
+ series[i].marker = {symbol: "circle"};
324
+ }
325
+ options.series = series;
326
+ new Highcharts.Chart(options);
327
+ };
328
+
329
+ this.renderPieChart = function (chart) {
330
+ var chartOptions = {};
331
+ if (chart.options.colors) {
332
+ chartOptions.colors = chart.options.colors;
333
+ }
334
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
335
+ options.chart.renderTo = chart.element.id;
336
+ options.series = [{
337
+ type: "pie",
338
+ name: "Value",
339
+ data: chart.data
340
+ }];
341
+ new Highcharts.Chart(options);
342
+ };
343
+
344
+ this.renderColumnChart = function (chart, chartType) {
345
+ var chartType = chartType || "column";
346
+ var series = chart.data;
347
+ var options = jsOptions(series, chart.options), i, j, s, d, rows = [];
348
+ options.chart.type = chartType;
349
+ options.chart.renderTo = chart.element.id;
350
+
351
+ for (i = 0; i < series.length; i++) {
352
+ s = series[i];
353
+
354
+ for (j = 0; j < s.data.length; j++) {
355
+ d = s.data[j];
356
+ if (!rows[d[0]]) {
357
+ rows[d[0]] = new Array(series.length);
358
+ }
359
+ rows[d[0]][i] = d[1];
360
+ }
361
+ }
362
+
363
+ var categories = [];
364
+ for (i in rows) {
365
+ if (rows.hasOwnProperty(i)) {
366
+ categories.push(i);
367
+ }
368
+ }
369
+ options.xAxis.categories = categories;
370
+
371
+ var newSeries = [];
372
+ for (i = 0; i < series.length; i++) {
373
+ d = [];
374
+ for (j = 0; j < categories.length; j++) {
375
+ d.push(rows[categories[j]][i] || 0);
376
+ }
377
+
378
+ newSeries.push({
379
+ name: series[i].name,
380
+ data: d
381
+ });
382
+ }
383
+ options.series = newSeries;
384
+
385
+ new Highcharts.Chart(options);
386
+ };
387
+
388
+ var self = this;
389
+
390
+ this.renderBarChart = function (chart) {
391
+ self.renderColumnChart(chart, "bar");
392
+ };
393
+
394
+ this.renderAreaChart = function (chart) {
395
+ self.renderLineChart(chart, "areaspline");
396
+ };
397
+ };
398
+ adapters.push(HighchartsAdapter);
399
+ }
400
+ if (window.google && window.google.setOnLoadCallback) {
401
+ var GoogleChartsAdapter = new function () {
402
+ var google = window.google;
403
+
404
+ var loaded = {};
405
+ var callbacks = [];
406
+
407
+ var runCallbacks = function () {
408
+ var cb, call;
409
+ for (var i = 0; i < callbacks.length; i++) {
410
+ cb = callbacks[i];
411
+ call = google.visualization && ((cb.pack == "corechart" && google.visualization.LineChart) || (cb.pack == "timeline" && google.visualization.Timeline))
412
+ if (call) {
413
+ cb.callback();
414
+ callbacks.splice(i, 1);
415
+ i--;
416
+ }
417
+ }
418
+ };
419
+
420
+ var waitForLoaded = function (pack, callback) {
421
+ if (!callback) {
422
+ callback = pack;
423
+ pack = "corechart";
424
+ }
425
+
426
+ callbacks.push({pack: pack, callback: callback});
427
+
428
+ if (loaded[pack]) {
429
+ runCallbacks();
430
+ } else {
431
+ loaded[pack] = true;
432
+
433
+ // https://groups.google.com/forum/#!topic/google-visualization-api/fMKJcyA2yyI
434
+ var loadOptions = {
435
+ packages: [pack],
436
+ callback: runCallbacks
437
+ };
438
+ if (config.language) {
439
+ loadOptions.language = config.language;
440
+ }
441
+ google.load("visualization", "1", loadOptions);
442
+ }
443
+ };
444
+
445
+ // Set chart options
446
+ var defaultOptions = {
447
+ chartArea: {},
448
+ fontName: "'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",
449
+ pointSize: 6,
450
+ legend: {
451
+ textStyle: {
452
+ fontSize: 12,
453
+ color: "#444"
454
+ },
455
+ alignment: "center",
456
+ position: "right"
457
+ },
458
+ curveType: "function",
459
+ hAxis: {
460
+ textStyle: {
461
+ color: "#666",
462
+ fontSize: 12
463
+ },
464
+ gridlines: {
465
+ color: "transparent"
466
+ },
467
+ baselineColor: "#ccc",
468
+ viewWindow: {}
469
+ },
470
+ vAxis: {
471
+ textStyle: {
472
+ color: "#666",
473
+ fontSize: 12
474
+ },
475
+ baselineColor: "#ccc",
476
+ viewWindow: {}
477
+ },
478
+ tooltip: {
479
+ textStyle: {
480
+ color: "#666",
481
+ fontSize: 12
482
+ }
483
+ }
484
+ };
485
+
486
+ var hideLegend = function (options) {
487
+ options.legend.position = "none";
488
+ };
489
+
490
+ var setMin = function (options, min) {
491
+ options.vAxis.viewWindow.min = min;
492
+ };
493
+
494
+ var setMax = function (options, max) {
495
+ options.vAxis.viewWindow.max = max;
496
+ };
497
+
498
+ var setBarMin = function (options, min) {
499
+ options.hAxis.viewWindow.min = min;
500
+ };
501
+
502
+ var setBarMax = function (options, max) {
503
+ options.hAxis.viewWindow.max = max;
504
+ };
505
+
506
+ var setStacked = function (options) {
507
+ options.isStacked = true;
508
+ };
509
+
510
+ var jsOptions = jsOptionsFunc(defaultOptions, hideLegend, setMin, setMax, setStacked);
511
+
512
+ // cant use object as key
513
+ var createDataTable = function (series, columnType) {
514
+ var data = new google.visualization.DataTable();
515
+ data.addColumn(columnType, "");
516
+
517
+ var i, j, s, d, key, rows = [];
518
+ for (i = 0; i < series.length; i++) {
519
+ s = series[i];
520
+ data.addColumn("number", s.name);
521
+
522
+ for (j = 0; j < s.data.length; j++) {
523
+ d = s.data[j];
524
+ key = (columnType === "datetime") ? d[0].getTime() : d[0];
525
+ if (!rows[key]) {
526
+ rows[key] = new Array(series.length);
527
+ }
528
+ rows[key][i] = toFloat(d[1]);
529
+ }
530
+ }
531
+
532
+ var rows2 = [];
533
+ for (i in rows) {
534
+ if (rows.hasOwnProperty(i)) {
535
+ rows2.push([(columnType === "datetime") ? new Date(toFloat(i)) : i].concat(rows[i]));
536
+ }
537
+ }
538
+ if (columnType === "datetime") {
539
+ rows2.sort(sortByTime);
540
+ }
541
+ data.addRows(rows2);
542
+
543
+ return data;
544
+ };
545
+
546
+ var resize = function (callback) {
547
+ if (window.attachEvent) {
548
+ window.attachEvent("onresize", callback);
549
+ } else if (window.addEventListener) {
550
+ window.addEventListener("resize", callback, true);
551
+ }
552
+ callback();
553
+ };
554
+
555
+ this.renderLineChart = function (chart) {
556
+ waitForLoaded(function () {
557
+ var options = jsOptions(chart.data, chart.options);
558
+ var data = createDataTable(chart.data, chart.options.discrete ? "string" : "datetime");
559
+ chart.chart = new google.visualization.LineChart(chart.element);
560
+ resize(function () {
561
+ chart.chart.draw(data, options);
562
+ });
563
+ });
564
+ };
565
+
566
+ this.renderPieChart = function (chart) {
567
+ waitForLoaded(function () {
568
+ var chartOptions = {
569
+ chartArea: {
570
+ top: "10%",
571
+ height: "80%"
572
+ }
573
+ };
574
+ if (chart.options.colors) {
575
+ chartOptions.colors = chart.options.colors;
576
+ }
577
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
578
+
579
+ var data = new google.visualization.DataTable();
580
+ data.addColumn("string", "");
581
+ data.addColumn("number", "Value");
582
+ data.addRows(chart.data);
583
+
584
+ chart.chart = new google.visualization.PieChart(chart.element);
585
+ resize(function () {
586
+ chart.chart.draw(data, options);
587
+ });
588
+ });
589
+ };
590
+
591
+ this.renderColumnChart = function (chart) {
592
+ waitForLoaded(function () {
593
+ var options = jsOptions(chart.data, chart.options);
594
+ var data = createDataTable(chart.data, "string");
595
+ chart.chart = new google.visualization.ColumnChart(chart.element);
596
+ resize(function () {
597
+ chart.chart.draw(data, options);
598
+ });
599
+ });
600
+ };
601
+
602
+ this.renderBarChart = function (chart) {
603
+ waitForLoaded(function () {
604
+ var chartOptions = {
605
+ hAxis: {
606
+ gridlines: {
607
+ color: "#ccc"
608
+ }
609
+ }
610
+ };
611
+ var options = jsOptionsFunc(defaultOptions, hideLegend, setBarMin, setBarMax, setStacked)(chart.data, chart.options, chartOptions);
612
+ var data = createDataTable(chart.data, "string");
613
+ chart.chart = new google.visualization.BarChart(chart.element);
614
+ resize(function () {
615
+ chart.chart.draw(data, options);
616
+ });
617
+ });
618
+ };
619
+
620
+ this.renderAreaChart = function (chart) {
621
+ waitForLoaded(function () {
622
+ var chartOptions = {
623
+ isStacked: true,
624
+ pointSize: 0,
625
+ areaOpacity: 0.5
626
+ };
627
+ var options = jsOptions(chart.data, chart.options, chartOptions);
628
+ var data = createDataTable(chart.data, chart.options.discrete ? "string" : "datetime");
629
+ chart.chart = new google.visualization.AreaChart(chart.element);
630
+ resize(function () {
631
+ chart.chart.draw(data, options);
632
+ });
633
+ });
634
+ };
635
+
636
+ this.renderGeoChart = function (chart) {
637
+ waitForLoaded(function () {
638
+ var chartOptions = {
639
+ legend: "none",
640
+ colorAxis: {
641
+ colors: chart.options.colors || ["#f6c7b6", "#ce502d"]
642
+ }
643
+ };
644
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
645
+
646
+ var data = new google.visualization.DataTable();
647
+ data.addColumn("string", "");
648
+ data.addColumn("number", "Value");
649
+ data.addRows(chart.data);
650
+
651
+ chart.chart = new google.visualization.GeoChart(chart.element);
652
+ resize(function () {
653
+ chart.chart.draw(data, options);
654
+ });
655
+ });
656
+ };
657
+
658
+ this.renderTimeline = function (chart) {
659
+ waitForLoaded("timeline", function () {
660
+ var chartOptions = {
661
+ legend: "none"
662
+ };
663
+
664
+ if (chart.options.colors) {
665
+ chartOptions.colorAxis.colors = chart.options.colors;
666
+ }
667
+ var options = merge(merge(defaultOptions, chartOptions), chart.options.library || {});
668
+
669
+ var data = new google.visualization.DataTable();
670
+ data.addColumn({type: "string", id: "Name"});
671
+ data.addColumn({type: "date", id: "Start"});
672
+ data.addColumn({type: "date", id: "End"});
673
+ data.addRows(chart.data);
674
+
675
+ chart.chart = new google.visualization.Timeline(chart.element);
676
+
677
+ resize(function () {
678
+ chart.chart.draw(data, options);
679
+ });
680
+ });
681
+ };
682
+ };
683
+
684
+ adapters.push(GoogleChartsAdapter);
685
+ }
686
+
687
+ // TODO add adapter option
688
+ // TODO remove chartType if cross-browser way
689
+ // to get the name of the chart class
690
+ function renderChart(chartType, chart) {
691
+ var i, adapter, fnName;
692
+ fnName = "render" + chartType;
693
+
694
+ for (i = 0; i < adapters.length; i++) {
695
+ adapter = adapters[i];
696
+ if (isFunction(adapter[fnName])) {
697
+ return adapter[fnName](chart);
698
+ }
699
+ }
700
+ throw new Error("No adapter found");
701
+ }
702
+
703
+ // process data
704
+
705
+ function processSeries(series, opts, time) {
706
+ var i, j, data, r, key;
707
+
708
+ // see if one series or multiple
709
+ if (!isArray(series) || typeof series[0] !== "object" || isArray(series[0])) {
710
+ series = [{name: "Value", data: series}];
711
+ opts.hideLegend = true;
712
+ } else {
713
+ opts.hideLegend = false;
714
+ }
715
+ if (opts.discrete) {
716
+ time = false;
717
+ }
718
+
719
+ // right format
720
+ for (i = 0; i < series.length; i++) {
721
+ data = toArr(series[i].data);
722
+ r = [];
723
+ for (j = 0; j < data.length; j++) {
724
+ key = data[j][0];
725
+ key = time ? toDate(key) : toStr(key);
726
+ r.push([key, toFloat(data[j][1])]);
727
+ }
728
+ if (time) {
729
+ r.sort(sortByTime);
730
+ }
731
+ series[i].data = r;
732
+ }
733
+
734
+ return series;
735
+ }
736
+
737
+ function processSimple(data) {
738
+ var perfectData = toArr(data), i;
739
+ for (i = 0; i < perfectData.length; i++) {
740
+ perfectData[i] = [toStr(perfectData[i][0]), toFloat(perfectData[i][1])];
741
+ }
742
+ return perfectData;
743
+ }
744
+
745
+ function processTime(data)
746
+ {
747
+ var i;
748
+ for (i = 0; i < data.length; i++) {
749
+ data[i][1] = toDate(data[i][1]);
750
+ data[i][2] = toDate(data[i][2]);
751
+ }
752
+ return data;
753
+ }
754
+
755
+ function processLineData(chart) {
756
+ chart.data = processSeries(chart.data, chart.options, true);
757
+ renderChart("LineChart", chart);
758
+ }
759
+
760
+ function processColumnData(chart) {
761
+ chart.data = processSeries(chart.data, chart.options, false);
762
+ renderChart("ColumnChart", chart);
763
+ }
764
+
765
+ function processPieData(chart) {
766
+ chart.data = processSimple(chart.data);
767
+ renderChart("PieChart", chart);
768
+ }
769
+
770
+ function processBarData(chart) {
771
+ chart.data = processSeries(chart.data, chart.options, false);
772
+ renderChart("BarChart", chart);
773
+ }
774
+
775
+ function processAreaData(chart) {
776
+ chart.data = processSeries(chart.data, chart.options, true);
777
+ renderChart("AreaChart", chart);
778
+ }
779
+
780
+ function processGeoData(chart) {
781
+ chart.data = processSimple(chart.data);
782
+ renderChart("GeoChart", chart);
783
+ }
784
+
785
+ function processTimelineData(chart) {
786
+ chart.data = processTime(chart.data);
787
+ renderChart("Timeline", chart);
788
+ }
789
+
790
+ function setElement(chart, element, dataSource, opts, callback) {
791
+ if (typeof element === "string") {
792
+ element = document.getElementById(element);
793
+ }
794
+ chart.element = element;
795
+ chart.options = opts || {};
796
+ chart.dataSource = dataSource;
797
+ Chartkick.charts[element.id] = chart;
798
+ fetchDataSource(chart, callback);
799
+ }
800
+
801
+ // define classes
802
+
803
+ Chartkick = {
804
+ LineChart: function (element, dataSource, opts) {
805
+ setElement(this, element, dataSource, opts, processLineData);
806
+ },
807
+ PieChart: function (element, dataSource, opts) {
808
+ setElement(this, element, dataSource, opts, processPieData);
809
+ },
810
+ ColumnChart: function (element, dataSource, opts) {
811
+ setElement(this, element, dataSource, opts, processColumnData);
812
+ },
813
+ BarChart: function (element, dataSource, opts) {
814
+ setElement(this, element, dataSource, opts, processBarData);
815
+ },
816
+ AreaChart: function (element, dataSource, opts) {
817
+ setElement(this, element, dataSource, opts, processAreaData);
818
+ },
819
+ GeoChart: function (element, dataSource, opts) {
820
+ setElement(this, element, dataSource, opts, processGeoData);
821
+ },
822
+ Timeline: function (element, dataSource, opts) {
823
+ setElement(this, element, dataSource, opts, processTimelineData);
824
+ },
825
+ charts: {}
826
+ };
827
+
828
+ window.Chartkick = Chartkick;
829
+ }(window));