smart_chart 0.0.9 → 0.1.0

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.
@@ -121,7 +121,6 @@ Data can be passed to pie charts in a similar way. For more complex graphs depic
121
121
  :thickness => 1,
122
122
  :color => 'FF0099',
123
123
  :style => :dotted
124
- }
125
124
  }
126
125
  ]
127
126
 
@@ -133,6 +132,10 @@ Actual output is limited by Google's requirements. For example, while Google pro
133
132
 
134
133
  == To-do List
135
134
 
135
+ * validate height and width
136
+ * must be integers
137
+ * dimensions must be >= 1px
138
+
136
139
  * bar graphs
137
140
  * add chbh tests
138
141
  * style and orientation tests
@@ -197,5 +200,7 @@ Actual output is limited by Google's requirements. For example, while Google pro
197
200
  Other Google Charts APIs:
198
201
  http://groups.google.com/group/google-chart-api/web/useful-links-to-api-libraries
199
202
 
203
+ Seer:
204
+ http://www.idolhands.com/ruby-on-rails/gems-plugins-and-engines/graphing-for-ruby-on-rails-with-seer
200
205
 
201
206
  Copyright (c) 2009 Alex Reisner. See LICENSE for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.9
1
+ 0.1.0
@@ -133,7 +133,7 @@ module SmartChart
133
133
  # The number of data points represented along the x-axis.
134
134
  #
135
135
  def data_values_count
136
- data_values.map{ |set| set.size }.max
136
+ data_values.map{ |set| set.size }.max.to_i
137
137
  end
138
138
 
139
139
  ##
@@ -155,7 +155,7 @@ module SmartChart
155
155
  # start at 0 so the maximum allowed number is sample size minus one.
156
156
  #
157
157
  def x_axis_position(num)
158
- num.to_f * 100 / data_values_count.to_f
158
+ 100.0 * num / (data_values_count - 1)
159
159
  end
160
160
 
161
161
  ##
@@ -163,7 +163,7 @@ module SmartChart
163
163
  # of the axis is y_min to y_max.
164
164
  #
165
165
  def y_axis_position(num)
166
- 100.0 * (num.to_f - y_min.to_f) / (y_max - y_min).to_f
166
+ 100.0 * (num - y_min) / (y_max - y_min).to_f
167
167
  end
168
168
 
169
169
  ##
@@ -11,6 +11,21 @@ module SmartChart
11
11
  attr_accessor :labels
12
12
  end
13
13
  end
14
+
15
+ ##
16
+ # Determine a nice interval between labels based on the range of
17
+ # axis values.
18
+ #
19
+ def self.auto_label_interval(range)
20
+ return nil if range == 0
21
+ # position of decimal point
22
+ exp = Math.log10(range).floor
23
+ # first two non-zero digits
24
+ digits = (range.to_s + "00").sub(/^[\.0]*/, "")[0,2].to_i
25
+ # the digits are in either 10..55 or 56..99
26
+ # divide the base in half if they're in the lower half
27
+ 10**exp * (digits > 55 ? 1 : 0.5)
28
+ end
14
29
 
15
30
 
16
31
  private # ---------------------------------------------------------------
@@ -67,9 +82,13 @@ module SmartChart
67
82
  return nil unless show_axes?
68
83
  labels = []
69
84
  axis.values.each_with_index do |a,i|
70
- a[:labels].each do |pos,text|
71
- labels[i] ||= "#{i}:"
72
- labels[i] << "|" + text
85
+ if a[:labels][:positions] == :auto
86
+ labels[i] = "#{i}:|" + auto_labels(a).values.join("|")
87
+ else
88
+ a[:labels].each do |pos,text|
89
+ labels[i] ||= "#{i}:"
90
+ labels[i] << "|" + text.to_s
91
+ end
73
92
  end
74
93
  end
75
94
  labels.join('|')
@@ -82,17 +101,79 @@ module SmartChart
82
101
  return nil unless show_axes?
83
102
  labels = []
84
103
  axis.values.each_with_index do |a,i|
85
- a[:labels].each do |pos,text|
86
- # figure out whether are we on a vertical or horizontal axis
87
- dir = [:left, :right].include?(axis.keys[i]) ? "y" : "x"
88
- p = eval("#{dir}_axis_position(pos)")
89
- labels[i] ||= i.to_s
90
- labels[i] << "," + SmartChart.decimal_string(p)
104
+ if a[:labels][:positions] == :auto
105
+ l = auto_labels(a).keys
106
+ elsif [:left, :right].include?(axis.keys[i])
107
+ l = label_positions_by_values(a)
108
+ else
109
+ l = label_positions_by_data_points(a)
91
110
  end
111
+ labels << "#{i}," + l.join(',')
92
112
  end
93
113
  labels.join('|')
94
114
  end
95
115
 
116
+ ##
117
+ # Automatically generate numeric labels based on the given min and max.
118
+ #
119
+ def auto_labels(axis)
120
+ options = axis[:labels]
121
+ min = options[:min]
122
+ max = options[:max]
123
+ range = max - min
124
+ int = options[:interval] ||
125
+ SmartChart::Axes.auto_label_interval(range)
126
+ labels = {}
127
+ labels[0] = min unless options[:omit_first]
128
+ labels[100] = max unless options[:omit_last]
129
+
130
+ # advance cursor to first label position (min + int/2)
131
+ l = first_auto_label_position(min, int)
132
+
133
+ # add labels until within int/2 of max
134
+ until l > (max - int / 2.0)
135
+ pos = 100.0 * (l - min) / range
136
+ labels[pos] = l
137
+ l += int
138
+ end
139
+
140
+ # format if required
141
+ if options[:format]
142
+ labels.each{ |p,l| labels[p] = options[:format].call(l) }
143
+ end
144
+
145
+ labels
146
+ end
147
+
148
+ ##
149
+ # Find the first "round number" above the given minimum.
150
+ #
151
+ def first_auto_label_position(min, int)
152
+ i = int
153
+ i += int while i < min + int / 2.0
154
+ i
155
+ end
156
+
157
+ ##
158
+ # Generate label position values, interpreting given label positions
159
+ # as data point indices.
160
+ #
161
+ def label_positions_by_data_points(axis)
162
+ axis[:labels].map do |pos,text|
163
+ SmartChart.decimal_string(x_axis_position(pos))
164
+ end
165
+ end
166
+
167
+ ##
168
+ # Generate label position values, interpreting given label positions
169
+ # as data point values.
170
+ #
171
+ def label_positions_by_values(axis)
172
+ axis[:labels].map do |pos,text|
173
+ SmartChart.decimal_string(y_axis_position(pos))
174
+ end
175
+ end
176
+
96
177
  ##
97
178
  # Translate an alignment name into a URL parameter value.
98
179
  #
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{smart_chart}
8
- s.version = "0.0.9"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Alex Reisner"]
12
- s.date = %q{2009-12-14}
12
+ s.date = %q{2010-04-07}
13
13
  s.description = %q{Easily create charts and graphs for the web (uses Google Charts).}
14
14
  s.email = %q{alex@alexreisner.com}
15
15
  s.extra_rdoc_files = [
@@ -51,7 +51,7 @@ Gem::Specification.new do |s|
51
51
  s.homepage = %q{http://github.com/alexreisner/smart_chart}
52
52
  s.rdoc_options = ["--charset=UTF-8"]
53
53
  s.require_paths = ["lib"]
54
- s.rubygems_version = %q{1.3.5}
54
+ s.rubygems_version = %q{1.3.6}
55
55
  s.summary = %q{Easily create charts and graphs for the web (uses Google Charts).}
56
56
  s.test_files = [
57
57
  "test/smart_charts_test.rb",
@@ -149,6 +149,33 @@ class SmartChartTest < Test::Unit::TestCase
149
149
  assert_equal "1,999999,12,-1,lt,888888|2,666666,,,l,", c.send(:chxs)
150
150
  end
151
151
 
152
+ def test_auto_label_interval
153
+ {
154
+ 755 => 100,
155
+ 23 => 5,
156
+ 1 => 0.5,
157
+ 0.99 => 0.1,
158
+ 0.456 => 0.05
159
+ }.each do |range,int|
160
+ assert_equal int, SmartChart::Axes.auto_label_interval(range),
161
+ "Axis label interval should be #{int} when range is #{range}"
162
+ end
163
+ end
164
+
165
+ def test_x_axis_label_position
166
+ c = line_graph(
167
+ :data => [{:values => [1,2,3,9,25,18,4,67,108,43,62]}], # data points
168
+ :axis => {
169
+ :x => {
170
+ :labels => {
171
+ 10 => "last"
172
+ }
173
+ }
174
+ }
175
+ )
176
+ assert_equal "0,100", c.send(:chxp)
177
+ end
178
+
152
179
 
153
180
  # --- pie -----------------------------------------------------------------
154
181
 
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_chart
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Alex Reisner
@@ -9,7 +14,7 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-12-14 00:00:00 -05:00
17
+ date: 2010-04-07 00:00:00 -04:00
13
18
  default_executable:
14
19
  dependencies: []
15
20
 
@@ -66,18 +71,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
66
71
  requirements:
67
72
  - - ">="
68
73
  - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
69
76
  version: "0"
70
- version:
71
77
  required_rubygems_version: !ruby/object:Gem::Requirement
72
78
  requirements:
73
79
  - - ">="
74
80
  - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
75
83
  version: "0"
76
- version:
77
84
  requirements: []
78
85
 
79
86
  rubyforge_project:
80
- rubygems_version: 1.3.5
87
+ rubygems_version: 1.3.6
81
88
  signing_key:
82
89
  specification_version: 3
83
90
  summary: Easily create charts and graphs for the web (uses Google Charts).