chartjs-ror 1.0.0 → 1.0.1

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/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