rgviz-rails 0.67 → 0.68

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.markdown ADDED
@@ -0,0 +1,135 @@
1
+ rgviz-rails
2
+ ===========
3
+
4
+ this library makes it easy to implement a visualization data source so that you can easily chart or visualize your data from [activerecord](http://ar.rubyonrails.org/) models or from in-memory arrays. the library implements the [google visualization api wire protocol](http://code.google.com/apis/visualization/documentation/dev/implementing_data_source.html).
5
+
6
+ it also allows you to [render the visualizations in a view template](https://github.com/asterite/rgviz-rails/wiki/showing-a-visualization-in-a-view) in a very simple but powerful way.
7
+
8
+ this library is built on top of [rgviz](https://github.com/asterite/rgviz).
9
+
10
+ installation
11
+ ------------
12
+
13
+ gem install rgviz-rails
14
+
15
+ rails 3
16
+ -------
17
+
18
+ in your gemfile
19
+
20
+ gem 'rgviz'
21
+ gem 'rgviz-rails', :require => 'rgviz_rails'
22
+
23
+ rails 2.x
24
+ ---------
25
+
26
+ in your environment.rb
27
+
28
+ config.gem "rgviz"
29
+ config.gem "rgviz-rails", :lib => 'rgviz_rails'
30
+
31
+ usage
32
+ -----
33
+
34
+ to make a method in your controller be a visualization api endpoint:
35
+
36
+ class vizcontroller < applicationcontroller
37
+ def person
38
+ # person is an activerecord::base class
39
+ render :rgviz => person
40
+ end
41
+ end
42
+
43
+ so for example if <tt>person</tt> has <tt>name</tt> and <tt>age</tt>, pointing your browser to:
44
+
45
+ http://localhost:3000/viz/person?select name where age > 20 limit 5
46
+
47
+ would render the necessary javascript code that implements the google visualization api wire protocol.
48
+
49
+ associations
50
+ ------------
51
+
52
+ if you want to filter, order by or group by columns that are in a model's association you can use underscores. this is better understood with an example:
53
+
54
+ class person < activerecord::base
55
+ belongs_to :city
56
+ end
57
+
58
+ class city < activerecord::base
59
+ belongs_to :country
60
+ end
61
+
62
+ class country < activerecord::base
63
+ end
64
+
65
+ to select the name of the city each person belongs to:
66
+
67
+ select city_name
68
+
69
+ to select the name of the country of the city each person belongs to:
70
+
71
+ select city_country_name
72
+
73
+ a slightly more complex example:
74
+
75
+ select avg(age) where city_country_name = 'argentina' group by city_name
76
+
77
+ the library will make it in just one query, writing all the sql joins for you.
78
+
79
+ extra conditions
80
+ ----------------
81
+
82
+ sometimes you want to limit your results the query will work with. you can do it like this:
83
+
84
+ render :rgviz => person, :conditions => ['age > ?', 20]
85
+
86
+ or also:
87
+
88
+ render :rgviz => person, :conditions => 'age > 20'
89
+
90
+ preprocessing
91
+ -------------
92
+
93
+ if you need to tweak a result before returning it, just include a block:
94
+
95
+ render :rgviz => person do |table|
96
+ # modify the rgviz::table object
97
+ end
98
+
99
+ showing a visualization in a view
100
+ ---------------------------------
101
+
102
+ you can invoke the rgviz method in your views. [read more about this](https://github.com/asterite/rgviz-rails/wiki/showing-a-visualization-in-a-view).
103
+
104
+ you can always do it the [old way](http://code.google.com/apis/visualization/documentation/using_overview.html).
105
+
106
+ executing queries over in-memory arrays
107
+ ---------------------------------------
108
+
109
+ you can also apply a query over an array of arrays that contains your "records" to be queried.
110
+
111
+ types = [[:id, :number], [:name, :string], [:age, :number]]
112
+ records = [
113
+ [1, 'john', 23],
114
+ [2, 'pete', 36]
115
+ ]
116
+ executor = rgviz::memoryexecutor.new records, types
117
+
118
+ render :rgviz => executor
119
+
120
+ this is very useful if you need to present visualizations against data coming from a csv file.
121
+
122
+ current limitations
123
+ -------------------
124
+
125
+ * the *format* clause works, but formatting is as in ruby (like "%.2f" for numbers, "foo %s bar" for strings, and "%y-%m-%d" for dates, as specified by time#strftime)
126
+ * only supports mysql, postgresql and sqlite adapters
127
+ * these scalar functions are not supported for sqlite: *millisecond*, *quarter*
128
+ * these scalar functions are not supported for mysql: *millisecond*
129
+ * the function *toDate* doesn't accept a number as its argument
130
+ * the *tsv* output format is not supported
131
+
132
+ contributors
133
+ ------------
134
+
135
+ * [brad seefeld](https://github.com/bradseefeld)
@@ -2,6 +2,7 @@ module Rgviz
2
2
  class Executor
3
3
  attr_reader :model_class
4
4
  attr_reader :adapter
5
+ attr_reader :virtual_columns
5
6
 
6
7
  def initialize(model_class)
7
8
  @model_class = model_class
@@ -27,11 +28,13 @@ module Rgviz
27
28
 
28
29
  def execute(query, options = {})
29
30
  @query = query
30
- @query = RgvizRails::Parser.parse(@query, options) unless @query.kind_of?(Query)
31
+ @query = RgvizRails::Parser.parse(@query) unless @query.kind_of?(Query)
31
32
 
32
33
  @table = Table.new
33
34
  @extra_conditions = options[:conditions]
35
+ @virtual_columns = options[:virtual_columns]
34
36
 
37
+ process_virtual_columns
35
38
  process_pivot
36
39
  process_labels
37
40
  process_formats
@@ -46,6 +49,17 @@ module Rgviz
46
49
  @table
47
50
  end
48
51
 
52
+ def process_virtual_columns
53
+ return unless @virtual_columns
54
+
55
+ @virtual_columns.each do |key, value|
56
+ if value.is_a?(String) || value[:gql]
57
+ parser = RgvizRails::Parser.new(value.is_a?(String) ? value : value[:gql])
58
+ @virtual_columns[key] = {:gql => parser.parse_column}
59
+ end
60
+ end
61
+ end
62
+
49
63
  def process_labels
50
64
  return unless @query.labels.present?
51
65
 
@@ -319,6 +333,10 @@ module Rgviz
319
333
  def column_type(col)
320
334
  case col
321
335
  when IdColumn
336
+ if @virtual_columns && (vc = @virtual_columns[col.name])
337
+ return vc[:gql] ? column_type(vc[:gql]) : vc[:type]
338
+ end
339
+
322
340
  klass, rails_col, joins = Rgviz::find_rails_col @model_class, col.name
323
341
  raise "Unknown column #{col}" unless rails_col
324
342
  rails_column_type rails_col
@@ -440,6 +458,15 @@ module Rgviz
440
458
  end
441
459
 
442
460
  def visit_id_column(node)
461
+ if @executor.virtual_columns && (vc = @executor.virtual_columns[node.name])
462
+ if vc[:gql]
463
+ vc[:gql].accept self
464
+ else
465
+ @string += vc[:sql]
466
+ end
467
+ return
468
+ end
469
+
443
470
  klass, rails_col, joins = Rgviz::find_rails_col @executor.model_class, node.name
444
471
  raise "Unknown column '#{node.name}'" unless rails_col
445
472
  @string += ActiveRecord::Base.connection.quote_column_name(klass.table_name)
@@ -13,7 +13,7 @@ module Rgviz
13
13
  else
14
14
  model = hash[:rgviz]
15
15
  conditions = hash[:conditions]
16
- extensions = hash[:extensions]
16
+ virtual_columns = hash[:virtual_columns]
17
17
  query = params[:tq] || 'select *'
18
18
  tqx = params[:tqx] || ''
19
19
 
@@ -22,7 +22,7 @@ module Rgviz
22
22
  begin
23
23
  options = {}
24
24
  options[:conditions] = conditions if conditions
25
- options[:extensions] = extensions if extensions
25
+ options[:virtual_columns] = virtual_columns if virtual_columns
26
26
 
27
27
  table = if model.is_a?(Class) && model < ActiveRecord::Base
28
28
  Rgviz::Executor.new(model).execute query, options
@@ -1,7 +1,7 @@
1
1
  module RgvizRails
2
2
  class Parser < Rgviz::Parser
3
- def self.parse(string, options = {})
4
- new(string, options).parse
3
+ def self.parse(string)
4
+ new(string).parse
5
5
  end
6
6
 
7
7
  protected
@@ -20,14 +20,18 @@ module Rgviz
20
20
  events = options[:events] || {}
21
21
  html = options[:html] || {}
22
22
  hidden = options[:hidden]
23
- extensions = options[:extensions]
24
23
  conditions = options[:conditions]
24
+ virtual_columns = options[:virtual_columns]
25
25
  package = options[:package]
26
26
 
27
27
  rgviz_events, google_events = events.partition{|x| x[0].to_s.start_with? 'rgviz'}
28
28
  rgviz_events = rgviz_events.inject(Hash.new){|h, y| h[y[0]] = y[1]; h}
29
29
  rgviz_events = rgviz_events.with_indifferent_access
30
30
 
31
+ ajax = options.has_key?(:ajax) && options[:ajax]
32
+ load_package = !ajax && (!options.has_key?(:load_package) || options[:load_package])
33
+ load_google = !ajax && (!options.has_key?(:load_google) || options[:load_google])
34
+
31
35
  html_prefix = (options[:html_prefix] || 'html').to_s
32
36
  js_prefix = (options[:js_prefix] || 'js').to_s
33
37
  param_prefix = (options[:param_prefix] || 'param').to_s
@@ -87,7 +91,7 @@ module Rgviz
87
91
  url = url_for url unless custom_executor
88
92
 
89
93
  # Parse the query
90
- query = RgvizRails::Parser.parse query, :extensions => extensions
94
+ query = RgvizRails::Parser.parse query
91
95
 
92
96
  # And replace the html_ and javascript_ magic names
93
97
  query.accept visitor
@@ -104,7 +108,7 @@ module Rgviz
104
108
 
105
109
  # Output the google jsapi tag the first time
106
110
  @first_time ||= 1
107
- if @first_time == 1
111
+ if load_google && @first_time == 1
108
112
  out << "<script type=\"text/javascript\" src=\"http://www.google.com/jsapi\"></script>\n"
109
113
  end
110
114
  # Now the real script
@@ -150,7 +154,7 @@ module Rgviz
150
154
  @defined_rgviz_append = true
151
155
  end
152
156
 
153
- if !options.has_key?(:load_package) || options[:load_package]
157
+ if load_package
154
158
  # Load visualizations and the package, if not already loaded
155
159
  package ||= get_package(kind)
156
160
 
@@ -165,7 +169,7 @@ module Rgviz
165
169
 
166
170
  # Set the callback if the function doesn't have params and if the
167
171
  # user didn't request to hide the visualization
168
- if !hidden && params.empty?
172
+ if !ajax && !hidden && params.empty?
169
173
  out << "google.setOnLoadCallback(#{callback});\n"
170
174
  end
171
175
 
@@ -194,7 +198,7 @@ module Rgviz
194
198
  else
195
199
  executor_options = {}
196
200
  executor_options[:conditions] = conditions if conditions
197
- executor_options[:extensions] = extensions if extensions
201
+ executor_options[:virtual_columns] = virtual_columns if virtual_columns
198
202
 
199
203
  table = if url.is_a?(Class) and url < ActiveRecord::Base
200
204
  Rgviz::Executor.new(url).execute(query, executor_options)
@@ -216,7 +220,7 @@ module Rgviz
216
220
  out << "});\n"
217
221
  end
218
222
  out << "}\n"
219
-
223
+ out << "#{callback}()" if ajax
220
224
  out << "</script>\n"
221
225
 
222
226
  # Write the div
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgviz-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.67'
4
+ version: '0.68'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-05 00:00:00.000000000Z
12
+ date: 2012-07-23 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rgviz
16
- requirement: &70182476133340 !ruby/object:Gem::Requirement
16
+ requirement: &70314626649780 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: '0.43'
21
+ version: '0.46'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70182476133340
24
+ version_requirements: *70314626649780
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rails
27
- requirement: &70182476132920 !ruby/object:Gem::Requirement
27
+ requirement: &70314626649300 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,13 +32,13 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70182476132920
35
+ version_requirements: *70314626649300
36
36
  description:
37
37
  email: aborenszweig@manas.com.ar
38
38
  executables: []
39
39
  extensions: []
40
40
  extra_rdoc_files:
41
- - README.rdoc
41
+ - README.markdown
42
42
  files:
43
43
  - lib/rgviz_rails.rb
44
44
  - lib/rgviz_rails/executor.rb
@@ -51,7 +51,7 @@ files:
51
51
  - lib/rgviz_rails/adapters/sqlite_adapter.rb
52
52
  - lib/rgviz_rails/init.rb
53
53
  - rails/init.rb
54
- - README.rdoc
54
+ - README.markdown
55
55
  homepage: http://github.com/asterite/rgviz-rails
56
56
  licenses: []
57
57
  post_install_message:
data/README.rdoc DELETED
@@ -1,131 +0,0 @@
1
- == Rgviz-rails
2
-
3
- This library makes it easy to implement a Visualization data source so that you can easily chart or visualize your data from ActiveRecord[http://ar.rubyonrails.org/] models or from in-memory arrays. The library implements the {Google Visualization API wire protocol}[http://code.google.com/apis/visualization/documentation/dev/implementing_data_source.html].
4
-
5
- It also allows you to {render the visualizations in a view template}[https://github.com/asterite/rgviz-rails/wiki/Showing-a-visualization-in-a-view] in a very simple but powerful way.
6
-
7
- This library is built on top of rgviz[https://github.com/asterite/rgviz].
8
-
9
- === Installation
10
-
11
- gem install rgviz-rails
12
-
13
- === Rails 3
14
-
15
- In your Gemfile
16
-
17
- gem 'rgviz'
18
- gem 'rgviz-rails', :require => 'rgviz_rails'
19
-
20
- === Rails 2.x
21
-
22
- In your environment.rb
23
-
24
- config.gem "rgviz"
25
- config.gem "rgviz-rails", :lib => 'rgviz_rails'
26
-
27
- === Usage
28
-
29
- To make a method in your controller be a visualization API endpoint:
30
-
31
- class VizController < ApplicationController
32
-
33
- def person
34
- # Person is an ActiveRecord::Base class
35
- render :rgviz => Person
36
- end
37
-
38
- end
39
-
40
- So for example if +Person+ has +name+ and +age+, pointing your browser to:
41
-
42
- http://localhost:3000/viz/person?select name where age > 20 limit 5
43
-
44
- would render the necessary javascript code that implements the Google Visualization API wire protocol.
45
-
46
- === Extensions
47
-
48
- To enable the extensions defined by rgviz you need to specify it in the render method:
49
-
50
- render :rgviz => Person, :extensions => true
51
-
52
- === Associations
53
-
54
- If you want to filter, order by or group by columns that are in a model's association you can use underscores. This is better understood with an example:
55
-
56
- class Person < ActiveRecord::Base
57
- belongs_to :city
58
- end
59
-
60
- class City < ActiveRecord::Base
61
- belongs_to :country
62
- end
63
-
64
- class Country < ActiveRecord::Base
65
- end
66
-
67
- To select the name of the city each person belongs to:
68
-
69
- select city_name
70
-
71
- To select the name of the country of the city each person belongs to:
72
-
73
- select city_country_name
74
-
75
- A slightly more complex example:
76
-
77
- select avg(age) where city_country_name = 'Argentina' group by city_name
78
-
79
- The library will make it in just one query, writing all the SQL joins for you.
80
-
81
- === Extra conditions
82
-
83
- Sometimes you want to limit your results the query will work with. You can do it like this:
84
-
85
- render :rgviz => Person, :conditions => ['age > ?', 20]
86
-
87
- Or also:
88
-
89
- render :rgviz => Person, :conditions => 'age > 20'
90
-
91
- === Preprocessing
92
-
93
- If you need to tweak a result before returning it, just include a block:
94
-
95
- render :rgviz => Person do |table|
96
- # Modify the Rgviz::Table object
97
- end
98
-
99
- === Showing a visualization in a view
100
-
101
- You can invoke the rgviz method in your views. {Read more about this}[https://github.com/asterite/rgviz-rails/wiki/Showing-a-visualization-in-a-view].
102
-
103
- You can always do it the {old way}[http://code.google.com/apis/visualization/documentation/using_overview.html].
104
-
105
- === Executing queries over in-memory arrays
106
-
107
- You can also apply a query over an array of arrays that contains your "records" to be queried.
108
-
109
- types = [[:id, :number], [:name, :string], [:age, :number]]
110
- records = [
111
- [1, 'John', 23],
112
- [2, 'Pete', 36]
113
- ]
114
- executor = Rgviz::MemoryExecutor.new records, types
115
-
116
- render :rgviz => executor
117
-
118
- This is very useful if you need to present visualizations against data coming from a CSV file.
119
-
120
- === Current Limitations
121
-
122
- * The *format* clause works, but formatting is as in ruby (like "%.2f" for numbers, "foo %s bar" for strings, and "%Y-%m-%d" for dates, as specified by Time#strftime)
123
- * Only supports MySQL, PostgreSQL and SQLite adapters
124
- * These scalar functions are not supported for SQLite: *millisecond*, *quarter*
125
- * These scalar functions are not supported for MySQL: *millisecond*
126
- * The function *toDate* doesn't accept a number as its argument
127
- * The *tsv* output format is not supported
128
-
129
- === Contributors
130
-
131
- * {Brad Seefeld}[https://github.com/bradseefeld]