ncri-seer 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/CONTRIBUTORS ADDED
@@ -0,0 +1,4 @@
1
+ Thanks go to the following individuals for their contributions:
2
+
3
+ Alexey Kuleshov (http://github.com/kulesa)
4
+ Harold Giménez (http://github.com/hgimenez)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Corey Ehmke / SEO Logic
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,51 @@
1
+ =Seer
2
+
3
+ Seer is a lightweight, semantically rich wrapper for the Google Visualization API. It allows you to easily create a visualization of data in a variety of formats, including area charts, bar charts, column charts, gauges, line charts, and pie charts.
4
+
5
+ ==Usage
6
+
7
+ Add the following to the head of the page that will display a chart, or add it to your layout file:
8
+
9
+ <%= Seer::init_visualization -%>
10
+
11
+ Gather the data you want to visualize in an instance variable in your controller, then use the visualize method to insert the appropriate chart in your view.
12
+
13
+ == Example
14
+
15
+ In your controller:
16
+
17
+ # @data must be an array, and each object in the array must respond to the data method specified
18
+ # in the visualize call (in this example, 'quantity')
19
+ @data = Widget.all
20
+
21
+ In your view:
22
+
23
+ <div id="chart"></div>
24
+
25
+ <%= Seer::visualize(
26
+ @widgets,
27
+ :as => :bar_chart,
28
+ :in_element => 'chart',
29
+ :series => {:series_label => 'name', :data_method => 'quantity'},
30
+ :chart_options => {
31
+ :height => 300,
32
+ :width => 200 * @widgets.size,
33
+ :is_3_d => false,
34
+ :legend => 'none',
35
+ :colors => ["#990000"],
36
+ :title => "Widget Quantities",
37
+ :title_x => 'Quantity',
38
+ :title_y => 'Widgets'
39
+ }
40
+ )
41
+ -%>
42
+
43
+ == More information
44
+
45
+ For examples of additional chart types, refer to the documentation for each of the individual chart objects, or see the blog post announcing Seer: {Simple, Semantic Graphing for Ruby on Rails with Seer}[http://www.idolhands.com/ruby-on-rails/gems-plugins-and-engines/graphing-for-ruby-on-rails-with-seer]
46
+
47
+ A {sample project}[http://github.com/Bantik/seer_sample] that demonstrates each of the chart types is available on GitHub.
48
+
49
+ Seer is developed and maintained by {Corey Ehmke}[http://www.idolhands.com/] at {SEO Logic}[http://www.seologic.com/].
50
+
51
+ Copyright (c) 2010 Corey Ehmke / SEO Logic, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,64 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "seer"
8
+ gem.summary = %Q{Seer is a lightweight, semantically rich wrapper for the Google Visualization API.}
9
+ gem.description = %Q{ Seer is a lightweight, semantically rich wrapper for the Google Visualization API. It allows you to easily create a visualization of data in a variety of formats, including area charts, bar charts, column charts, gauges, line charts, and pie charts.}
10
+ gem.email = "corey@seologic.com"
11
+ gem.homepage = "http://github.com/Bantik/seer"
12
+ gem.authors = ["Corey Ehmke / SEO Logic"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.files = [
15
+ "CONTRIBUTORS",
16
+ "init.rb",
17
+ "lib/seer.rb",
18
+ "lib/seer/area_chart.rb",
19
+ "lib/seer/bar_chart.rb",
20
+ "lib/seer/chart.rb",
21
+ "lib/seer/column_chart.rb",
22
+ "lib/seer/gauge.rb",
23
+ "lib/seer/line_chart.rb",
24
+ "lib/seer/pie_chart.rb",
25
+ "lib/seer/visualization_helper.rb",
26
+ "LICENSE",
27
+ "Rakefile",
28
+ "README.rdoc",
29
+ "rails/init.rb",
30
+ "spec/spec.opts",
31
+ "spec/spec_helper.rb",
32
+ "spec/seer_spec.rb"
33
+ ]
34
+ end
35
+ Jeweler::GemcutterTasks.new
36
+ rescue LoadError
37
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
38
+ end
39
+
40
+ require 'spec/rake/spectask'
41
+ Spec::Rake::SpecTask.new(:spec) do |spec|
42
+ spec.libs << 'lib' << 'spec'
43
+ spec.spec_files = FileList['spec/**/*_spec.rb']
44
+ end
45
+
46
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
47
+ spec.libs << 'lib' << 'spec'
48
+ spec.pattern = 'spec/**/*_spec.rb'
49
+ spec.rcov = true
50
+ end
51
+
52
+ task :spec => :check_dependencies
53
+
54
+ task :default => :spec
55
+
56
+ require 'rake/rdoctask'
57
+ Rake::RDocTask.new do |rdoc|
58
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
59
+
60
+ rdoc.rdoc_dir = 'rdoc'
61
+ rdoc.title = "seer #{version}"
62
+ rdoc.rdoc_files.include('README*')
63
+ rdoc.rdoc_files.include('lib/**/*.rb')
64
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'seer'
data/lib/seer.rb ADDED
@@ -0,0 +1,59 @@
1
+ module Seer
2
+
3
+ require 'seer/chart'
4
+ require 'seer/area_chart'
5
+ require 'seer/bar_chart'
6
+ require 'seer/column_chart'
7
+ require 'seer/gauge'
8
+ require 'seer/line_chart'
9
+ require 'seer/pie_chart'
10
+
11
+ VISUALIZERS = [:area_chart, :bar_chart, :column_chart, :gauge, :line_chart, :pie_chart]
12
+
13
+ def self.valid_hex_number?(val) #:nodoc:
14
+ return false unless val.is_a?(String) && ! val.empty?
15
+ ! (val =~ /^\#([0-9]|[a-f]|[A-F])+$/).nil? && val.length == 7
16
+ end
17
+
18
+ def self.log(message) #:nodoc:
19
+ RAILS_DEFAULT_LOGGER.info(message)
20
+ end
21
+
22
+ def self.init_visualization
23
+ %{<script type="text/javascript" src="http://www.google.com/jsapi">
24
+ </script><script type="text/javascript">var Seer = \{ chartsCount: 0, charts: [], chartsData: [] \}</script> }
25
+ end
26
+
27
+ def self.visualize(data, args={})
28
+ raise ArgumentError, "Seer: Invalid visualizer: #{args[:as]}" unless args[:as] && VISUALIZERS.include?(args[:as])
29
+ raise ArgumentError, "Seer: No data provided!" unless data && ! data.empty?
30
+ self.send(args[:as], data, args)
31
+ end
32
+
33
+ private
34
+
35
+ def self.area_chart(data, args)
36
+ AreaChart.render(data, args)
37
+ end
38
+
39
+ def self.bar_chart(data, args)
40
+ BarChart.render(data, args)
41
+ end
42
+
43
+ def self.column_chart(data, args)
44
+ ColumnChart.render(data, args)
45
+ end
46
+
47
+ def self.gauge(data, args)
48
+ Gauge.render(data, args)
49
+ end
50
+
51
+ def self.line_chart(data, args)
52
+ LineChart.render(data, args)
53
+ end
54
+
55
+ def self.pie_chart(data, args)
56
+ PieChart.render(data, args)
57
+ end
58
+
59
+ end
@@ -0,0 +1,142 @@
1
+ module Seer
2
+
3
+ # =USAGE
4
+ #
5
+ # In your controller:
6
+ #
7
+ # @data = Widgets.all # Must be an array, and must respond
8
+ # # to the data method specified below (in this example, 'quantity')
9
+ #
10
+ # @series = @data.map{|w| w.widget_stats} # An array of arrays
11
+ #
12
+ # In your view:
13
+ #
14
+ # <div id="chart"></div>
15
+ #
16
+ # <%= Seer::visualize(
17
+ # @data,
18
+ # :as => :area_chart,
19
+ # :in_element => 'chart',
20
+ # :series => {
21
+ # :series_label => 'name',
22
+ # :data_label => 'date',
23
+ # :data_method => 'quantity',
24
+ # :data_series => @series
25
+ # },
26
+ # :chart_options => {
27
+ # :height => 300,
28
+ # :width => 300,
29
+ # :axis_font_size => 11,
30
+ # :colors => ['#7e7587','#990000','#009900'],
31
+ # :title => "Widget Quantities",
32
+ # :point_size => 5
33
+ # }
34
+ # )
35
+ # -%>
36
+ #
37
+ # For details on the chart options, see the Google API docs at
38
+ # http://code.google.com/apis/visualization/documentation/gallery/areachart.html
39
+ #
40
+ class AreaChart
41
+
42
+ include Seer::Chart
43
+
44
+ # Graph options
45
+ attr_accessor :axis_color, :axis_background_color, :axis_font_size, :background_color, :border_color, :data_table, :enable_tooltip, :focus_border_color, :height, :is_stacked, :legend, :legend_background_color, :legend_font_size, :legend_text_color, :line_size, :log_scale, :max, :min, :point_size, :reverse_axis, :show_categories, :title, :title_x, :title_y, :title_color, :title_font_size, :tooltip_font_size, :tooltip_height, :number, :tooltip_width, :width, :on_select
46
+
47
+ # Graph data
48
+ attr_accessor :series_label, :data_label, :data, :data_method, :data_series
49
+
50
+ def initialize(args={}) #:nodoc:
51
+
52
+ # Standard options
53
+ args.each{ |method,arg| self.send("#{method}=",arg) if self.respond_to?(method) }
54
+
55
+ # Chart options
56
+ args[:chart_options].each{ |method, arg| self.send("#{method}=",arg) if self.respond_to?(method) }
57
+
58
+ # Handle defaults
59
+ @colors ||= args[:chart_options][:colors] || DEFAULT_COLORS
60
+ @legend ||= args[:chart_options][:legend] || DEFAULT_LEGEND_LOCATION
61
+ @height ||= args[:chart_options][:height] || DEFAULT_HEIGHT
62
+ @width ||= args[:chart_options][:width] || DEFAULT_WIDTH
63
+
64
+ @data_table = []
65
+
66
+ end
67
+
68
+ def data_columns #:nodoc:
69
+ _data_columns = " Seer.chartsData[chartIndex].addRows(#{data_rows.size});\r"
70
+ _data_columns << " Seer.chartsData[chartIndex].addColumn('string', 'Date');\r"
71
+ data.each do |datum|
72
+ _data_columns << " Seer.chartsData[chartIndex].addColumn('number', '#{datum.send(series_label)}');\r"
73
+ end
74
+ _data_columns
75
+ end
76
+
77
+ def data_table #:nodoc:
78
+ _rows = data_rows
79
+ _rows.each_with_index do |r,i|
80
+ @data_table << " Seer.chartsData[chartIndex].setCell(#{i}, 0,'#{r}');\r"
81
+ end
82
+ data_series.each_with_index do |column,i|
83
+ column.each_with_index do |c,j|
84
+ @data_table << " Seer.chartsData[chartIndex].setCell(#{j},#{i+1},#{c.send(data_method)});\r"
85
+ end
86
+ end
87
+ @data_table
88
+ end
89
+
90
+ def data_rows
91
+ data_series.inject([]) do |rows, element|
92
+ rows |= element.map { |e| e.send(data_label) }
93
+ end
94
+ end
95
+
96
+ def nonstring_options #:nodoc:
97
+ [ :axis_font_size, :colors, :enable_tooltip, :height, :is_stacked, :legend_font_size, :line_size, :log_scale, :max, :min, :point_size, :reverse_axis, :show_categories, :title_font_size, :tooltip_font_size, :tooltip_height, :tooltip_width, :width]
98
+ end
99
+
100
+ def string_options #:nodoc:
101
+ [ :axis_color, :axis_background_color, :background_color, :border_color, :focus_border_color, :legend, :legend_background_color, :legend_text_color, :title, :title_x, :title_y, :title_color ]
102
+ end
103
+
104
+ def to_js #:nodoc:
105
+
106
+ %{
107
+ <script type="text/javascript">
108
+ google.load('visualization', '1', {'packages':['areachart']});
109
+ google.setOnLoadCallback(drawChart);
110
+ function drawChart() {
111
+ var chartIndex = Seer.chartsCount;
112
+ Seer.chartsData[chartIndex] = new google.visualization.DataTable();
113
+ #{data_columns}
114
+ #{data_table.to_s}
115
+ var options = {};
116
+ #{options}
117
+ var container = document.getElementById('#{self.chart_element}');
118
+ Seer.charts[chartIndex] = new google.visualization.AreaChart(container);
119
+ Seer.charts[chartIndex].draw(Seer.chartsData[chartIndex], options);
120
+ #{ @on_select ? "\ngoogle.visualization.events.addListener(Seer.charts[chartIndex], 'select', " + @on_select + ");" : ''}
121
+ Seer.chartsCount += 1;
122
+ }
123
+ </script>
124
+ }
125
+ end
126
+
127
+ def self.render(data, args) #:nodoc:
128
+ graph = Seer::AreaChart.new(
129
+ :data => data,
130
+ :series_label => args[:series][:series_label],
131
+ :data_series => args[:series][:data_series],
132
+ :data_label => args[:series][:data_label],
133
+ :data_method => args[:series][:data_method],
134
+ :chart_options => args[:chart_options],
135
+ :chart_element => args[:in_element] || 'chart'
136
+ )
137
+ graph.to_js
138
+ end
139
+
140
+ end
141
+
142
+ end
@@ -0,0 +1,127 @@
1
+ module Seer
2
+
3
+ # =USAGE
4
+ #
5
+ # In your controller:
6
+ #
7
+ # @data = Widgets.all # Must be an array, and must respond
8
+ # # to the data method specified below (in this example, 'quantity')
9
+ #
10
+ # In your view:
11
+ #
12
+ # <div id="chart"></div>
13
+ #
14
+ # <%= Seer::visualize(
15
+ # @widgets,
16
+ # :as => :bar_chart,
17
+ # :in_element => 'chart',
18
+ # :series => {:series_label => 'name', :data_method => 'quantity'},
19
+ # :chart_options => {
20
+ # :height => 300,
21
+ # :width => 200 * @widgets.size,
22
+ # :is_3_d => false,
23
+ # :legend => 'none',
24
+ # :colors => ["#990000"],
25
+ # :title => "Widget Quantities",
26
+ # :title_x => 'Quantity',
27
+ # :title_y => 'Widgets'
28
+ # }
29
+ # )
30
+ # -%>
31
+ #
32
+ # Colors are treated differently for 2d and 3d graphs. If you set is_3_d to true, set the
33
+ # graph colors like this:
34
+ #
35
+ # :colors => "[{color:'#990000', darker:'#660000'}]",
36
+ #
37
+ # For details on the chart options, see the Google API docs at
38
+ # http://code.google.com/apis/visualization/documentation/gallery/barchart.html
39
+ #
40
+ class BarChart
41
+
42
+ include Seer::Chart
43
+
44
+ # Chart options accessors
45
+ attr_accessor :axis_color, :axis_background_color, :axis_font_size, :background_color, :border_color, :data_table, :enable_tooltip, :focus_border_color, :height, :is_3_d, :is_stacked, :legend, :legend_background_color, :legend_font_size, :legend_text_color, :log_scale, :max, :min, :reverse_axis, :show_categories, :title, :title_x, :title_y, :title_color, :title_font_size, :tooltip_font_size, :tooltip_height, :tooltip_width, :width, :on_select, :on_select
46
+
47
+ # Graph data
48
+ attr_accessor :data, :data_method, :label_method
49
+
50
+ def initialize(args={}) #:nodoc:
51
+
52
+ # Standard options
53
+ args.each{ |method,arg| self.send("#{method}=",arg) if self.respond_to?(method) }
54
+
55
+ # Chart options
56
+ args[:chart_options].each{ |method, arg| self.send("#{method}=",arg) if self.respond_to?(method) }
57
+
58
+ # Handle defaults
59
+ @colors ||= args[:chart_options][:colors] || DEFAULT_COLORS
60
+ @legend ||= args[:chart_options][:legend] || DEFAULT_LEGEND_LOCATION
61
+ @height ||= args[:chart_options][:height] || DEFAULT_HEIGHT
62
+ @width ||= args[:chart_options][:width] || DEFAULT_WIDTH
63
+ @is_3_d ||= args[:chart_options][:is_3_d]
64
+
65
+ @data_table = []
66
+
67
+ end
68
+
69
+ def data_table #:nodoc:
70
+ data.each_with_index do |datum, column|
71
+ @data_table << [
72
+ " Seer.chartsData[chartIndex].setValue(#{column}, 0,'#{datum.send(label_method)}');\r",
73
+ " Seer.chartsData[chartIndex].setValue(#{column}, 1, #{datum.send(data_method)});\r"
74
+ ]
75
+ end
76
+ @data_table
77
+ end
78
+
79
+ def is_3_d #:nodoc:
80
+ @is_3_d.blank? ? false : @is_3_d
81
+ end
82
+
83
+ def nonstring_options #:nodoc:
84
+ [:axis_font_size, :colors, :enable_tooltip, :is_3_d, :is_stacked, :legend_font_size, :log_scale, :max, :min, :reverse_axis, :show_categories, :title_font_size, :tooltip_font_size, :tooltip_width]
85
+ end
86
+
87
+ def string_options #:nodoc:
88
+ [:axis_color, :axis_background_color, :background_color, :border_color, :focus_border_color, :height, :legend, :legend_background_color, :legend_text_color, :title, :title_x, :title_y, :title_color, :width]
89
+ end
90
+
91
+ def to_js #:nodoc:
92
+
93
+ %{
94
+ <script type="text/javascript">
95
+ google.load('visualization', '1', {'packages':['barchart']});
96
+ google.setOnLoadCallback(drawChart);
97
+ function drawChart() {
98
+ var chartIndex = Seer.chartsCount;
99
+ Seer.chartsData[chartIndex] = new google.visualization.DataTable();
100
+ #{data_columns}
101
+ #{data_table.to_s}
102
+ var options = {};
103
+ #{options}
104
+ var container = document.getElementById('#{self.chart_element}');
105
+ Seer.charts[chartIndex] = new google.visualization.BarChart(container);
106
+ Seer.charts[chartIndex].draw(Seer.chartsData[chartIndex], options);
107
+ #{ @on_select ? "\ngoogle.visualization.events.addListener(Seer.charts[chartIndex], 'select', " + @on_select + ");" : ''}
108
+ Seer.chartsCount += 1;
109
+ }
110
+ </script>
111
+ }
112
+ end
113
+
114
+ def self.render(data, args) #:nodoc:
115
+ graph = Seer::BarChart.new(
116
+ :label_method => args[:series][:series_label],
117
+ :data_method => args[:series][:data_method],
118
+ :chart_options => args[:chart_options],
119
+ :chart_element => args[:in_element] || 'chart',
120
+ :data => data
121
+ )
122
+ graph.to_js
123
+ end
124
+
125
+ end
126
+
127
+ end