chartkick 1.4.2 → 1.5.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: 30bd21c65fb97d053acf056e67d24b9982d77eed
4
- data.tar.gz: de5da367cefd5d077af3d2132b1ac948d7e8207c
3
+ metadata.gz: 80c67217ad8f9a74c889ccbf0688eb314c6b1617
4
+ data.tar.gz: ec4d8c578e879a41feb6de2eafe67aec3bc571d2
5
5
  SHA512:
6
- metadata.gz: 3a786415ad5316e7bc7237f67a0dc70407eaf9f96dcfa6ec9c99a78fbdcb036c848c1bb8363ce18ac109fc4cb9815f177b3f1758b7dac445c83ff207bbdcf62d
7
- data.tar.gz: 8173102a5c963174a9659ce964af53015489bad6674eb0ded65753b904c4164de8fe6db9403439cd68ae6e9c5a0acec52a01480e45f5712522b01c584a4069a4
6
+ metadata.gz: ea96ad5f348f87ff64815c74e80b5af3e5fbc83238dc2c06add9ceafcd87cad3bc0e37279d630d47724f18ccce22c4eac6c10e12ffedcfd481ac0b6182ec0d13
7
+ data.tar.gz: a1740a4e1e31db6bf346263b5cdba6883c5e52583bb28de7bdf7ef7db66e1ee5c15f282a94c5cca8efe2fea1b6aafcac9c619d55e9b85a76b12ee08b6cf65058
@@ -1,3 +1,8 @@
1
+ ## 1.5.0
2
+
3
+ - Added Chart.js adapter **beta**
4
+ - Fixed line height on timeline charts
5
+
1
6
  ## 1.4.2
2
7
 
3
8
  - Added `width` option
data/README.md CHANGED
@@ -156,7 +156,7 @@ You can pass options directly to the charting library with:
156
156
  <%= line_chart data, library: {backgroundColor: "#eee"} %>
157
157
  ```
158
158
 
159
- See the documentation for [Google Charts](https://developers.google.com/chart/interactive/docs/gallery) and [Highcharts](http://api.highcharts.com/highcharts) for more info.
159
+ 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.
160
160
 
161
161
  ### Global Options
162
162
 
@@ -230,12 +230,18 @@ For Google Charts, use:
230
230
  <%= javascript_include_tag "https://www.google.com/jsapi", "chartkick" %>
231
231
  ```
232
232
 
233
- If you prefer Highcharts, use:
233
+ If you prefer Highcharts (works with 2.1+), [download it](http://www.highcharts.com/download) and use:
234
234
 
235
235
  ```erb
236
236
  <%= javascript_include_tag "path/to/highcharts.js", "chartkick" %>
237
237
  ```
238
238
 
239
+ If you prefer Chart.js (works with 2.0+, in beta), [download the bundle](http://www.chartjs.org/docs/#getting-started-download-chart-js) and use:
240
+
241
+ ```erb
242
+ <%= javascript_include_tag "path/to/Chart.bundle.js", "chartkick" %>
243
+ ```
244
+
239
245
  ### For Rails 3.1+
240
246
 
241
247
  `chartkick.js` runs as a Rails engine - no need to install it.
@@ -263,8 +269,6 @@ You must include `chartkick.js` manually. [Download it here](https://raw.github
263
269
 
264
270
  You must include `chartkick.js` manually. [Download it here](https://raw.github.com/ankane/chartkick/master/app/assets/javascripts/chartkick.js)
265
271
 
266
- In addition, you must specify `http` or `https` if you use Google Charts, since Padrino tries to append `.js` to protocol relative urls.
267
-
268
272
  ```erb
269
273
  <%= javascript_include_tag "https://www.google.com/jsapi", "chartkick" %>
270
274
  ```
@@ -2,7 +2,7 @@
2
2
  * Chartkick.js
3
3
  * Create beautiful JavaScript charts with minimal code
4
4
  * https://github.com/ankane/chartkick.js
5
- * v1.4.2
5
+ * v1.5.0
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 DATE_PATTERN = /^(\d\d\d\d)(\-)?(\d\d)(\-)?(\d\d)$/i;
16
17
  var adapters = [];
17
18
 
18
19
  // helpers
@@ -206,9 +207,15 @@
206
207
  }
207
208
 
208
209
  function toDate(n) {
210
+ var matches, year, month, day;
209
211
  if (typeof n !== "object") {
210
212
  if (typeof n === "number") {
211
213
  n = new Date(n * 1000); // ms
214
+ } else if (config.smarterDates && (matches = n.match(DATE_PATTERN))) {
215
+ year = parseInt(matches[1], 10);
216
+ month = parseInt(matches[3], 10) - 1;
217
+ day = parseInt(matches[5], 10);
218
+ return new Date(year, month, day);
212
219
  } else { // str
213
220
  // try our best to get the str into iso8601
214
221
  // TODO be smarter about this
@@ -745,6 +752,7 @@
745
752
  data.addColumn({type: "date", id: "End"});
746
753
  data.addRows(chart.data);
747
754
 
755
+ chart.element.style.lineHeight = "normal";
748
756
  chart.chart = new google.visualization.Timeline(chart.element);
749
757
 
750
758
  resize(function () {
@@ -756,6 +764,257 @@
756
764
 
757
765
  adapters.push(GoogleChartsAdapter);
758
766
  }
767
+ if (!ChartjsAdapter && "Chart" in window) {
768
+ var ChartjsAdapter = new function () {
769
+ var Chart = window.Chart;
770
+
771
+ this.name = "chartjs";
772
+
773
+ var baseOptions = {
774
+ maintainAspectRatio: false,
775
+ animation: false
776
+ };
777
+
778
+ var defaultOptions = {
779
+ scales: {
780
+ yAxes: [
781
+ {
782
+ ticks: {
783
+ maxTicksLimit: 4
784
+ },
785
+ scaleLabel: {
786
+ fontSize: 16,
787
+ // fontStyle: "bold",
788
+ fontColor: "#333"
789
+ }
790
+ }
791
+ ],
792
+ xAxes: [
793
+ {
794
+ gridLines: {
795
+ drawOnChartArea: false
796
+ },
797
+ scaleLabel: {
798
+ fontSize: 16,
799
+ // fontStyle: "bold",
800
+ fontColor: "#333"
801
+ },
802
+ time: {}
803
+ }
804
+ ]
805
+ },
806
+ legend: {}
807
+ };
808
+
809
+ // http://there4.io/2012/05/02/google-chart-color-list/
810
+ var defaultColors = [
811
+ "#3366CC", "#DC3912", "#FF9900", "#109618", "#990099", "#3B3EAC", "#0099C6",
812
+ "#DD4477", "#66AA00", "#B82E2E", "#316395", "#994499", "#22AA99", "#AAAA11",
813
+ "#6633CC", "#E67300", "#8B0707", "#329262", "#5574A6", "#3B3EAC"
814
+ ];
815
+
816
+ var hideLegend = function (options) {
817
+ options.legend.display = false;
818
+ };
819
+
820
+ var setMin = function (options, min) {
821
+ if (min !== null) {
822
+ options.scales.yAxes[0].ticks.min = min;
823
+ }
824
+ };
825
+
826
+ var setMax = function (options, max) {
827
+ options.scales.yAxes[0].ticks.max = max;
828
+ };
829
+
830
+ var setStacked = function (options, stacked) {
831
+ options.scales.xAxes[0].stacked = !!stacked;
832
+ options.scales.yAxes[0].stacked = !!stacked;
833
+ };
834
+
835
+ var setXtitle = function (options, title) {
836
+ options.scales.xAxes[0].scaleLabel.display = true;
837
+ options.scales.xAxes[0].scaleLabel.labelString = title;
838
+ };
839
+
840
+ var setYtitle = function (options, title) {
841
+ options.scales.yAxes[0].scaleLabel.display = true;
842
+ options.scales.yAxes[0].scaleLabel.labelString = title;
843
+ };
844
+
845
+ var drawChart = function(chart, type, data, options) {
846
+ chart.element.innerHTML = "<canvas></canvas>";
847
+ var ctx = chart.element.getElementsByTagName("CANVAS")[0];
848
+
849
+ chart.chart = new Chart(ctx, {
850
+ type: type,
851
+ data: data,
852
+ options: options
853
+ });
854
+ };
855
+
856
+ // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
857
+ var addOpacity = function(hex, opacity) {
858
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
859
+ return result ? "rgba(" + parseInt(result[1], 16) + ", " + parseInt(result[2], 16) + ", " + parseInt(result[3], 16) + ", " + opacity + ")" : hex;
860
+ };
861
+
862
+ var jsOptions = jsOptionsFunc(merge(baseOptions, defaultOptions), hideLegend, setMin, setMax, setStacked, setXtitle, setYtitle);
863
+
864
+ var createDataTable = function (chart, options, chartType) {
865
+ var datasets = [];
866
+ var labels = [];
867
+
868
+ var colors = chart.options.colors || defaultColors;
869
+
870
+ var day = true;
871
+ var week = true;
872
+ var dayOfWeek;
873
+ var month = true;
874
+ var year = true;
875
+ var detectType = (chartType === "line" || chartType === "area") && !chart.options.discrete;
876
+
877
+ var series = chart.data;
878
+
879
+ var i, j, s, d, key, rows = [];
880
+ for (i = 0; i < series.length; i++) {
881
+ s = series[i];
882
+
883
+ for (j = 0; j < s.data.length; j++) {
884
+ d = s.data[j];
885
+ key = detectType ? d[0].getTime() : d[0];
886
+ if (!rows[key]) {
887
+ rows[key] = new Array(series.length);
888
+ }
889
+ rows[key][i] = toFloat(d[1]);
890
+ }
891
+ }
892
+
893
+ var rows2 = [];
894
+ for (var j = 0; j < series.length; j++) {
895
+ rows2.push([]);
896
+ }
897
+
898
+ var day = true;
899
+ var value;
900
+ for (i in rows) {
901
+ if (rows.hasOwnProperty(i)) {
902
+ if (detectType) {
903
+ value = new Date(toFloat(i));
904
+ // TODO make this efficient
905
+ day = day && isDay(value);
906
+ if (!dayOfWeek) {
907
+ dayOfWeek = value.getDay();
908
+ }
909
+ week = week && isWeek(value, dayOfWeek);
910
+ month = month && isMonth(value);
911
+ year = year && isYear(value);
912
+ } else {
913
+ value = i;
914
+ }
915
+ labels.push(value);
916
+ for (var j = 0; j < series.length; j++) {
917
+ rows2[j].push(rows[i][j])
918
+ }
919
+ }
920
+ }
921
+
922
+ for (var i = 0; i < series.length; i++) {
923
+ var s = series[i];
924
+
925
+ var backgroundColor = chartType !== "line" ? addOpacity(colors[i], 0.5) : colors[i];
926
+
927
+ var dataset = {
928
+ label: s.name,
929
+ data: rows2[i],
930
+ fill: chartType === "area",
931
+ borderColor: colors[i],
932
+ backgroundColor: backgroundColor,
933
+ pointBackgroundColor: colors[i],
934
+ borderWidth: 2
935
+ };
936
+
937
+ datasets.push(dataset);
938
+ }
939
+
940
+ if (detectType) {
941
+ if (year) {
942
+ options.scales.xAxes[0].time.unit = "year";
943
+ options.scales.xAxes[0].time.tooltipFormat = "ll";
944
+ } else if (month) {
945
+ options.scales.xAxes[0].time.unit = "month";
946
+ options.scales.xAxes[0].time.tooltipFormat = "ll";
947
+ } else if (week) {
948
+ options.scales.xAxes[0].time.unit = "week";
949
+ options.scales.xAxes[0].time.tooltipFormat = "ll";
950
+ } else if (day) {
951
+ options.scales.xAxes[0].time.unit = "day";
952
+ options.scales.xAxes[0].time.tooltipFormat = "ll";
953
+ }
954
+ }
955
+
956
+ var data = {
957
+ labels: labels,
958
+ datasets: datasets
959
+ };
960
+
961
+ return data;
962
+ };
963
+
964
+ this.renderLineChart = function (chart, chartType) {
965
+ var areaOptions = {};
966
+ if (chartType === "area") {
967
+ // TODO fix area stacked
968
+ // areaOptions.stacked = true;
969
+ }
970
+ var options = jsOptions(chart.data, merge(areaOptions, chart.options));
971
+
972
+ var data = createDataTable(chart, options, chartType || "line");
973
+
974
+ options.scales.xAxes[0].type = chart.options.discrete ? "category" : "time";
975
+
976
+ drawChart(chart, "line", data, options);
977
+ }
978
+
979
+ this.renderPieChart = function (chart) {
980
+ var options = merge(baseOptions, chart.options.library || {});
981
+
982
+ var labels = [];
983
+ var values = [];
984
+ for (var i = 0; i < chart.data.length; i++) {
985
+ var point = chart.data[i];
986
+ labels.push(point[0]);
987
+ values.push(point[1]);
988
+ }
989
+
990
+ var data = {
991
+ labels: labels,
992
+ datasets: [
993
+ {
994
+ data: values,
995
+ backgroundColor: chart.options.colors || defaultColors
996
+ }
997
+ ]
998
+ };
999
+
1000
+ drawChart(chart, "pie", data, options);
1001
+ }
1002
+
1003
+ this.renderColumnChart = function (chart) {
1004
+ var options = jsOptions(chart.data, chart.options);
1005
+ var data = createDataTable(chart, {}, "column");
1006
+ drawChart(chart, "bar", data, options);
1007
+ }
1008
+
1009
+ var self = this;
1010
+
1011
+ this.renderAreaChart = function (chart) {
1012
+ self.renderLineChart(chart, "area");
1013
+ };
1014
+ }
1015
+
1016
+ adapters.push(ChartjsAdapter);
1017
+ }
759
1018
  }
760
1019
 
761
1020
  // TODO remove chartType if cross-browser way
@@ -807,6 +1066,35 @@
807
1066
  return d.getMilliseconds() + d.getSeconds() + d.getMinutes() + d.getHours() === 0;
808
1067
  }
809
1068
 
1069
+ function isWeek(d, dayOfWeek) {
1070
+ return isDay(d) && d.getDay() === dayOfWeek;
1071
+ }
1072
+
1073
+ function isMonth(d) {
1074
+ return isDay(d) && d.getDate() === 1;
1075
+ }
1076
+
1077
+ function isYear(d) {
1078
+ return isMonth(d) && d.getMonth() === 0;
1079
+ }
1080
+
1081
+ function isDate(obj) {
1082
+ return !isNaN(toDate(obj)) && toStr(obj).length >= 6;
1083
+ }
1084
+
1085
+ function detectDiscrete(series) {
1086
+ var i, j, data;
1087
+ for (i = 0; i < series.length; i++) {
1088
+ data = toArr(series[i].data);
1089
+ for (j = 0; j < data.length; j++) {
1090
+ if (!isDate(data[j][0])) {
1091
+ return true;
1092
+ }
1093
+ }
1094
+ }
1095
+ return false;
1096
+ }
1097
+
810
1098
  function processSeries(series, opts, keyType) {
811
1099
  var i;
812
1100
 
@@ -817,6 +1105,9 @@
817
1105
  } else {
818
1106
  opts.hideLegend = false;
819
1107
  }
1108
+ if (config.smarterDiscrete && (opts.discrete === null || opts.discrete === undefined)) {
1109
+ opts.discrete = detectDiscrete(series);
1110
+ }
820
1111
  if (opts.discrete) {
821
1112
  keyType = "string";
822
1113
  }
@@ -1,7 +1,7 @@
1
1
  module Chartkick
2
2
  class Engine < ::Rails::Engine
3
3
  initializer "precompile", group: :all do |app|
4
- if Rails::VERSION::MAJOR >= 5
4
+ if Gem::Version.new(Sprockets::VERSION) >= Gem::Version.new("4.0.0.beta1")
5
5
  app.config.assets.precompile << "chartkick.js"
6
6
  else
7
7
  # use a proc instead of a string
@@ -1,3 +1,3 @@
1
1
  module Chartkick
2
- VERSION = "1.4.2"
2
+ VERSION = "1.5.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: 1.4.2
4
+ version: 1.5.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-02-29 00:00:00.000000000 Z
11
+ date: 2016-05-02 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.5.2
98
+ rubygems_version: 2.6.1
99
99
  signing_key:
100
100
  specification_version: 4
101
101
  summary: Create beautiful JavaScript charts with one line of Ruby