chartjs-ror 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -6,6 +6,8 @@ Simplifies using [Chart.js][] in Rails views.
6
6
  * Legends for your charts.
7
7
  * Renders charts on page load rather than DOMContentReady ([reason][browsersupport]).
8
8
  * Animates unless you have Modernizr and it doesn't detect canvas support ([reason][browsersupport]). You can manually override this.
9
+ * Optional alternative (better?) abscissa scale calculations.
10
+ * Utility method for filling in gaps in integer series.
9
11
 
10
12
  NOTE: this is Rails 3.0 only at the moment, so pre-asset pipeline. I plan to upgrade soon.
11
13
 
@@ -165,7 +167,7 @@ And in Ruby:
165
167
 
166
168
  You can put anything in the `options` hash that Chart.js recognises. It also supports these non-Chart.js settings:
167
169
 
168
- * `:css_class` - class of the enclosing `<figure/>` - default is `chart`.
170
+ * `:class` - class of the enclosing `<figure/>` - default is `chart`.
169
171
  * `:element_id` - id of the `<canvas/>` - default is `chart-n` where `n` is the 0-based index of the chart on the page.
170
172
  * `:width` - width of the canvas in px - default is `400`.
171
173
  * `:height` - height of the canvas in px - default is `400`.
@@ -214,6 +216,11 @@ Each item in the legend array is given two classes:
214
216
  This lets you style legends in general but override the styles for specific charts.
215
217
 
216
218
 
219
+ ### Scale calculations
220
+
221
+ The plugin implements its own abscissa scale calculations which I prefer to Chart.js's. You can opt-in to these calculations by passing `scaleOverride: true` in the `options` hash, without any of the other scale override keys (`scaleSteps`, `scaleStepWidth`, `scaleStartValue`).
222
+
223
+
217
224
  ## Inspiration
218
225
 
219
226
  * [Chart.js][] (obviously)
data/Rakefile CHANGED
@@ -1 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true
8
+ end
@@ -16,4 +16,7 @@ Gem::Specification.new do |gem|
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'activesupport', '>3'
21
+ gem.add_development_dependency 'rake'
19
22
  end
@@ -0,0 +1,130 @@
1
+ require 'active_support'
2
+
3
+ module Chartjs
4
+ module AxisHelpers
5
+
6
+ # Returns an ordered copy of data with "missing" keys mapped to 0 values.
7
+ #
8
+ # data - a Hash of Integer keys mapped to to Integer values.
9
+ #
10
+ # Returns an OrderedHash whose Integer keys run from 0 to data's maximum key
11
+ # and whose values are the corresponding values in data or 0.
12
+ def series(data)
13
+ return {} if data.nil? || data.empty?
14
+ (0..data.keys.max).reduce(ActiveSupport::OrderedHash.new) { |hash,k| hash[k] = data[k] || 0; hash }
15
+ end
16
+
17
+ # Calculates the number of steps and the step width for ordinate axis labels.
18
+ # The ordinate axis is assumed to start at 0.
19
+ #
20
+ # data - an Array of Numerics.
21
+ #
22
+ # Returns a Hash with:
23
+ # :scaleSteps - the number of steps (always <= 10)
24
+ # :scaleStepWidth - the value jump between steps
25
+ # :scaleStartValue - 0
26
+ def ordinate_scale(data)
27
+ scale_max = calculate_scale_max data.max
28
+ normalised_scale_max = normalise scale_max
29
+
30
+ # normalised_scale_max number_steps step_width
31
+ # 0 0 0
32
+ # 0.5 5 1
33
+ # 1 5 2
34
+ # 1.5 5 3
35
+ # 2 4 5
36
+ # 2.5 5 5
37
+ # 3 6 5
38
+ # 3.5 7 5
39
+ # 4 8 5
40
+ # 4.5 9 5
41
+ # 5 10 5
42
+ # 5.5 6 10
43
+ # 6 6 10
44
+ # 6.5 7 10
45
+ # 7 7 10
46
+ # 7.5 8 10
47
+ # 8 8 10
48
+ # 8.5 9 10
49
+ # 9 9 10
50
+ # 9.5 10 10
51
+ if normalised_scale_max.zero?
52
+ number_steps = 0
53
+ step_width = 0
54
+ elsif normalised_scale_max < 2
55
+ number_steps = 5
56
+ step_width = scale_max / number_steps
57
+ elsif normalised_scale_max < 5.5
58
+ step_width = 5 * 10**(order_of_magnitude(scale_max) - 1)
59
+ number_steps = scale_max / step_width.to_f
60
+ else
61
+ step_width = 10**(order_of_magnitude(scale_max))
62
+ number_steps = scale_max / step_width.to_f
63
+ end
64
+
65
+ {scaleSteps: number_steps.ceil, scaleStepWidth: step_width, scaleStartValue: 0}
66
+ end
67
+
68
+ # Rounds up value to the next "increment", where an increment is half
69
+ # the order of magnitude value.
70
+ #
71
+ # value - a Numeric.
72
+ #
73
+ # Examples
74
+ #
75
+ # input output
76
+ # 12 15
77
+ # 15 15
78
+ # 16 20
79
+ # 1432 1500
80
+ # 7654 8000
81
+ #
82
+ # Returns an Integer.
83
+ def calculate_scale_max(value)
84
+ normalised = normalise value
85
+ quotient, modulus = normalised.divmod 1
86
+ next_increment = if modulus.zero?
87
+ quotient
88
+ elsif modulus <= 0.5
89
+ quotient + 0.5
90
+ else
91
+ quotient + 1
92
+ end
93
+ (next_increment * 10**(order_of_magnitude(value))).to_i
94
+ end
95
+
96
+ # Normalises the value to between 0 inclusive and 10.
97
+ #
98
+ # value - a Numeric.
99
+ #
100
+ # Returns a Float or 0 if value is nil or zero..
101
+ def normalise(value)
102
+ return 0 if value.nil? || value.zero?
103
+ value.to_f / 10**(order_of_magnitude(value))
104
+ end
105
+
106
+ # Calculates the order of magnitude of value.
107
+ #
108
+ # value - a Numeric.
109
+ #
110
+ # Examples
111
+ #
112
+ # order_of_magnitude(3)
113
+ # # => 1
114
+ #
115
+ # order_of_magnitude(13)
116
+ # # => 1
117
+ #
118
+ # order_of_magnitude(153)
119
+ # # => 2
120
+ #
121
+ # Returns a Integer or 0 if value is nil or zero.
122
+ def order_of_magnitude(value)
123
+ return 0 if value.nil? || value.zero?
124
+ magnitude = Math.log10 value
125
+ order_of_magnitude = magnitude.floor
126
+ order_of_magnitude.zero? ? 1 : order_of_magnitude
127
+ end
128
+
129
+ end
130
+ end
@@ -56,6 +56,11 @@ module Chartjs
56
56
  ''
57
57
  end
58
58
 
59
+ # Alternative scale calculations.
60
+ if options[:scaleOverride] && !options.has_key?(:scaleSteps)
61
+ options.merge! ordinate_scale(combined_data(datasets))
62
+ end
63
+
59
64
  script = javascript_tag do
60
65
  <<-END.html_safe
61
66
  var initChart = function() {
@@ -87,5 +92,9 @@ module Chartjs
87
92
  end
88
93
  end
89
94
 
95
+ def combined_data(datasets)
96
+ datasets.map { |d| d[:data] || d[:value] }.flatten
97
+ end
98
+
90
99
  end
91
100
  end
@@ -1,9 +1,11 @@
1
1
  require 'chartjs/chart_helpers'
2
+ require 'chartjs/axis_helpers'
2
3
 
3
4
  module Chartjs
4
5
  class Railtie < Rails::Railtie
5
6
  initializer 'chartjs.chart_helpers' do
6
7
  ActionView::Base.send :include, Chartjs::ChartHelpers
8
+ ActionView::Base.send :include, Chartjs::AxisHelpers
7
9
  end
8
10
  end
9
11
  end
@@ -1,3 +1,3 @@
1
1
  module Chartjs
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -0,0 +1,64 @@
1
+ require 'minitest/autorun'
2
+ require 'chartjs/axis_helpers'
3
+
4
+ class AxisHelpersTest < MiniTest::Unit::TestCase
5
+
6
+ def setup
7
+ @subject = Object.new
8
+ @subject.extend Chartjs::AxisHelpers
9
+ end
10
+
11
+ def test_series_empty_data
12
+ data = {}
13
+ result = @subject.series data
14
+ assert_equal 0, result.length
15
+ end
16
+
17
+ def test_series
18
+ data = { 2 => 42 }
19
+ result = @subject.series data
20
+ assert_equal 3, result.length
21
+ assert_equal({0 => 0, 1 => 0, 2 => 42}, result)
22
+ end
23
+
24
+ def test_calculate_scale_max
25
+ {
26
+ 0 => 0,
27
+ 3 => 5,
28
+ 5 => 5,
29
+ 6 => 10,
30
+ 9 => 10,
31
+ 10 => 10,
32
+ 12 => 15,
33
+ 16 => 20,
34
+ 60 => 60,
35
+ 65 => 65,
36
+ 601 => 650,
37
+ 1430 => 1500,
38
+ 7654 => 8000,
39
+ }.each do |input, expected_output|
40
+ assert_equal expected_output, @subject.calculate_scale_max(input)
41
+ end
42
+ end
43
+
44
+ def test_ordinate_scale
45
+ data = []
46
+ assert_equal({scaleSteps: 0, scaleStepWidth: 0, scaleStartValue: 0}, @subject.ordinate_scale(data))
47
+
48
+ data = [ 12 ]
49
+ assert_equal({scaleSteps: 5, scaleStepWidth: 3, scaleStartValue: 0}, @subject.ordinate_scale(data))
50
+
51
+ data = [ 33 ]
52
+ assert_equal({scaleSteps: 7, scaleStepWidth: 5, scaleStartValue: 0}, @subject.ordinate_scale(data))
53
+
54
+ data = [ 601 ]
55
+ assert_equal({scaleSteps: 7, scaleStepWidth: 100, scaleStartValue: 0}, @subject.ordinate_scale(data))
56
+
57
+ data = [ 999 ]
58
+ assert_equal({scaleSteps: 5, scaleStepWidth: 200, scaleStartValue: 0}, @subject.ordinate_scale(data))
59
+
60
+ data = [ 13001 ]
61
+ assert_equal({scaleSteps: 5, scaleStepWidth: 3000, scaleStartValue: 0}, @subject.ordinate_scale(data))
62
+ end
63
+
64
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chartjs-ror
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,40 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-06 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-06-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>'
20
+ - !ruby/object:Gem::Version
21
+ version: '3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>'
28
+ - !ruby/object:Gem::Version
29
+ version: '3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
14
46
  description: Simplifies using Chart.js in Rails
15
47
  email:
16
48
  - boss@airbladesoftware.com
@@ -26,9 +58,11 @@ files:
26
58
  - chartjs-ror.gemspec
27
59
  - lib/chartjs-ror.rb
28
60
  - lib/chartjs.rb
61
+ - lib/chartjs/axis_helpers.rb
29
62
  - lib/chartjs/chart_helpers.rb
30
63
  - lib/chartjs/railtie.rb
31
64
  - lib/chartjs/version.rb
65
+ - test/axis_helpers_test.rb
32
66
  homepage: https://github.com/airblade/chartjs-ror
33
67
  licenses: []
34
68
  post_install_message:
@@ -53,4 +87,5 @@ rubygems_version: 1.8.23
53
87
  signing_key:
54
88
  specification_version: 3
55
89
  summary: Simplifies using Chart.js in Rails
56
- test_files: []
90
+ test_files:
91
+ - test/axis_helpers_test.rb