JamieFlournoy-g_viz 0.3.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/.gitignore +4 -0
- data/CHANGELOG +3 -0
- data/JamieFlournoy-g_viz.gemspec +58 -0
- data/Manifest +13 -0
- data/README.markdown +113 -0
- data/Rakefile +24 -0
- data/VERSION +2 -0
- data/lib/g_viz/data.rb +101 -0
- data/lib/g_viz/g_viz.rb +50 -0
- data/lib/g_viz/json_google.rb +11 -0
- data/lib/g_viz/templates/data_tables.erb +43 -0
- data/lib/g_viz.rb +5 -0
- data/spec/g_viz/fixtures/annotated_timeline.rb +44 -0
- data/spec/g_viz/g_viz_spec.rb +83 -0
- data/spec/g_viz/templates/rendered_annotated_timeline.html +41 -0
- data/spec/test_helper.rb +10 -0
- metadata +72 -0
data/.gitignore
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{JamieFlournoy-g_viz}
|
8
|
+
s.version = "0.3.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Gary Tsang"]
|
12
|
+
s.date = %q{2009-11-25}
|
13
|
+
s.description = %q{A Ruby client for the Google Visualization API.}
|
14
|
+
s.email = %q{gary.tsang@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.markdown"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"CHANGELOG",
|
21
|
+
"JamieFlournoy-g_viz.gemspec",
|
22
|
+
"Manifest",
|
23
|
+
"README.markdown",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/g_viz.rb",
|
27
|
+
"lib/g_viz/data.rb",
|
28
|
+
"lib/g_viz/g_viz.rb",
|
29
|
+
"lib/g_viz/json_google.rb",
|
30
|
+
"lib/g_viz/templates/data_tables.erb",
|
31
|
+
"spec/g_viz/fixtures/annotated_timeline.rb",
|
32
|
+
"spec/g_viz/g_viz_spec.rb",
|
33
|
+
"spec/g_viz/templates/rendered_annotated_timeline.html",
|
34
|
+
"spec/test_helper.rb"
|
35
|
+
]
|
36
|
+
s.homepage = %q{http://github.com/JamieFlournoy/g_viz}
|
37
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
38
|
+
s.require_paths = ["lib"]
|
39
|
+
s.rubyforge_project = %q{none}
|
40
|
+
s.rubygems_version = %q{1.3.5}
|
41
|
+
s.summary = %q{Google Visualization API Ruby Client}
|
42
|
+
s.test_files = [
|
43
|
+
"spec/g_viz/fixtures/annotated_timeline.rb",
|
44
|
+
"spec/g_viz/g_viz_spec.rb",
|
45
|
+
"spec/test_helper.rb"
|
46
|
+
]
|
47
|
+
|
48
|
+
if s.respond_to? :specification_version then
|
49
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
50
|
+
s.specification_version = 3
|
51
|
+
|
52
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
53
|
+
else
|
54
|
+
end
|
55
|
+
else
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
data/Manifest
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
CHANGELOG
|
2
|
+
lib/g_viz/data.rb
|
3
|
+
lib/g_viz/g_viz.rb
|
4
|
+
lib/g_viz/json_google.rb
|
5
|
+
lib/g_viz/templates/data_tables.erb
|
6
|
+
lib/g_viz.rb
|
7
|
+
Manifest
|
8
|
+
Rakefile
|
9
|
+
README.markdown
|
10
|
+
spec/g_viz/fixtures/annotated_timeline.rb
|
11
|
+
spec/g_viz/g_viz_spec.rb
|
12
|
+
spec/g_viz/templates/rendered_annotated_timeline.html
|
13
|
+
spec/test_helper.rb
|
data/README.markdown
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# GViz
|
2
|
+
|
3
|
+
GViz is a simple Ruby wrapper for the Google Visualization API
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
### Definitions
|
8
|
+
<dl>
|
9
|
+
<dt>chart_type</dt>
|
10
|
+
<dd>Google Visualization Chart Constructor</dd>
|
11
|
+
<dt>data</dt>
|
12
|
+
<dd>An array of objects that responds to [](key) i.e. and array of Hashes</dd>
|
13
|
+
<dt>mapping</dt>
|
14
|
+
<dd>An array of key, description pairs that we are using as data points for our chart</dd>
|
15
|
+
</dl>
|
16
|
+
|
17
|
+
GViz::Base keeps track of charts that need to be rendered.
|
18
|
+
|
19
|
+
chart = GViz::Base.new
|
20
|
+
dom_id = chart.add_graph(chart_type, data, mapping, config_options)
|
21
|
+
chart.output
|
22
|
+
|
23
|
+
You can add multiple visualizations
|
24
|
+
|
25
|
+
chart = GViz::Base.new
|
26
|
+
dom_id1 = chart.add_graph(chart_type, data, mapping, config_options)
|
27
|
+
dom_id2 = chart.add_graph(chart_type, data, mapping, config_options)
|
28
|
+
chart.output
|
29
|
+
|
30
|
+
You can use dynamic adders
|
31
|
+
|
32
|
+
#chart_type for dynamic adders are lowercased and underscored
|
33
|
+
chart = GViz::Base.new
|
34
|
+
dom_id1 = chart.add_chart_type(data, mapping, config_options)
|
35
|
+
chart.output
|
36
|
+
|
37
|
+
## Examples
|
38
|
+
### AnnotatedTimeLine
|
39
|
+
|
40
|
+
mapping = [[:date, 'Date'],[:sold_pencils, 'Solid Pencils'], [:title1, 'title1'], [:text1, 'text1'],
|
41
|
+
[:sold_pens, 'Sold Pens'], [:title2, 'title2'], [:text2, 'text2']]
|
42
|
+
|
43
|
+
data = [
|
44
|
+
{:date => "2008-02-01", :sold_pencils => 30000, :sold_pens => 40645},
|
45
|
+
{:date => Date.parse("2008-02-02"), :sold_pencils => 14045, :sold_pens => 20374},
|
46
|
+
{:date => Date.parse("2008-02-03"), :sold_pencils => 55022, :sold_pens => 50766},
|
47
|
+
{:date => Date.parse("2008-02-04"), :sold_pencils => 75284, :sold_pens => 14334, :title2 => 'Out of Stock',:text2 => 'Ran out of stock on pens at 4pm'},
|
48
|
+
{:date => Date.parse("2008-02-05"), :sold_pencils => 41476, :sold_pens => 66467, :title1 => 'Bought Pens',:text2 => 'Bought 200k pens'},
|
49
|
+
{:date => Date.parse("2008-02-06"), :sold_pencils => 33322, :sold_pens => 39463, :title1 => 'Bought Pens',:text2 => 'Bought 200k pens'}
|
50
|
+
]
|
51
|
+
|
52
|
+
g = GViz::Base.new
|
53
|
+
chart_id = g.add_annotated_time_line(data, mapping)
|
54
|
+
puts g.output
|
55
|
+
puts "<div id='#{chart_id}'></div>"
|
56
|
+
|
57
|
+
Outputs
|
58
|
+
|
59
|
+
<script type='text/javascript' src='http://www.google.com/jsapi'></script>
|
60
|
+
<script type='text/javascript'>
|
61
|
+
google.load('visualization', '1', {'packages':['annotatedtimeline']});
|
62
|
+
google.setOnLoadCallback(drawChart);
|
63
|
+
function drawChart() {
|
64
|
+
var data_0 = new google.visualization.DataTable();
|
65
|
+
data_0.addColumn('date', 'Date')
|
66
|
+
data_0.addColumn('number', 'Solid Pencils')
|
67
|
+
data_0.addColumn('string', 'title1')
|
68
|
+
data_0.addColumn('number', 'Sold Pens')
|
69
|
+
data_0.addColumn('string', 'title2')
|
70
|
+
data_0.addColumn('string', 'text2')
|
71
|
+
data_0.addRows(6)
|
72
|
+
data_0.setValue(0, 0, new Date(2008, 1, 1))
|
73
|
+
data_0.setValue(0, 1, 30000)
|
74
|
+
data_0.setValue(0, 2, '')
|
75
|
+
data_0.setValue(0, 3, 40645)
|
76
|
+
data_0.setValue(0, 4, '')
|
77
|
+
data_0.setValue(0, 5, '')
|
78
|
+
data_0.setValue(1, 0, new Date(2008, 1, 2))
|
79
|
+
data_0.setValue(1, 1, 14045)
|
80
|
+
data_0.setValue(1, 2, '')
|
81
|
+
data_0.setValue(1, 3, 20374)
|
82
|
+
data_0.setValue(1, 4, '')
|
83
|
+
data_0.setValue(1, 5, '')
|
84
|
+
data_0.setValue(2, 0, new Date(2008, 1, 3))
|
85
|
+
data_0.setValue(2, 1, 55022)
|
86
|
+
data_0.setValue(2, 2, '')
|
87
|
+
data_0.setValue(2, 3, 50766)
|
88
|
+
data_0.setValue(2, 4, '')
|
89
|
+
data_0.setValue(2, 5, '')
|
90
|
+
data_0.setValue(3, 0, new Date(2008, 1, 4))
|
91
|
+
data_0.setValue(3, 1, 75284)
|
92
|
+
data_0.setValue(3, 2, '')
|
93
|
+
data_0.setValue(3, 3, 14334)
|
94
|
+
data_0.setValue(3, 4, 'Out of Stock')
|
95
|
+
data_0.setValue(3, 5, 'Ran out of stock on pens at 4pm')
|
96
|
+
data_0.setValue(4, 0, new Date(2008, 1, 5))
|
97
|
+
data_0.setValue(4, 1, 41476)
|
98
|
+
data_0.setValue(4, 2, 'Bought Pens')
|
99
|
+
data_0.setValue(4, 3, 66467)
|
100
|
+
data_0.setValue(4, 4, '')
|
101
|
+
data_0.setValue(4, 5, 'Bought 200k pens')
|
102
|
+
data_0.setValue(5, 0, new Date(2008, 1, 6))
|
103
|
+
data_0.setValue(5, 1, 33322)
|
104
|
+
data_0.setValue(5, 2, 'Bought Pens')
|
105
|
+
data_0.setValue(5, 3, 39463)
|
106
|
+
data_0.setValue(5, 4, '')
|
107
|
+
data_0.setValue(5, 5, 'Bought 200k pens')
|
108
|
+
var chart_data_0 = new google.visualization.AnnotatedTimeline(document.getElementById('annotatedtimeline0'));
|
109
|
+
chart_data_0.draw(data_0, {});
|
110
|
+
}
|
111
|
+
</script>
|
112
|
+
<div id='annotatedtimeline0'></div>
|
113
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gemspec|
|
7
|
+
gemspec.name = "JamieFlournoy-g_viz"
|
8
|
+
gemspec.summary = "Google Visualization API Ruby Client"
|
9
|
+
gemspec.email = "gary.tsang@gmail.com"
|
10
|
+
gemspec.homepage = "http://github.com/JamieFlournoy/g_viz"
|
11
|
+
gemspec.description = "A Ruby client for the Google Visualization API."
|
12
|
+
gemspec.authors = ["Gary Tsang"]
|
13
|
+
gemspec.rubyforge_project = "none"
|
14
|
+
end
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Run all tests"
|
20
|
+
Spec::Rake::SpecTask.new do |t|
|
21
|
+
t.libs = [File.join(File.dirname(__FILE__), 'lib', 'g_viz')]
|
22
|
+
t.fail_on_error = false
|
23
|
+
t.spec_files = FileList['spec/*.rb']
|
24
|
+
end
|
data/VERSION
ADDED
data/lib/g_viz/data.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
module GViz
|
2
|
+
class Data
|
3
|
+
|
4
|
+
def initialize(data, map)
|
5
|
+
@map = map
|
6
|
+
@data = data
|
7
|
+
@data_type = {}
|
8
|
+
import_data_types
|
9
|
+
end
|
10
|
+
|
11
|
+
def import_data_types
|
12
|
+
found_data_types = Set.new
|
13
|
+
@data.each do |x|
|
14
|
+
break if found_data_types.size == @map.size
|
15
|
+
@map.each do |k, v|
|
16
|
+
next if found_data_types.member?(k)
|
17
|
+
if x[k]
|
18
|
+
@data_type[k] = self.class.google_data_type(x[k])
|
19
|
+
found_data_types.add([k,v])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
# if there is no data that responds to a mapped value, remove that mapping
|
24
|
+
@map -= (@map - found_data_types.to_a)
|
25
|
+
end
|
26
|
+
|
27
|
+
def columns
|
28
|
+
data = @map.map do |k, v|
|
29
|
+
[@data_type[k], k]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def size
|
34
|
+
@data.size
|
35
|
+
end
|
36
|
+
|
37
|
+
def rows_hash(prune = false)
|
38
|
+
@data.map do |value|
|
39
|
+
@map.inject({}) do |maps, (k, v)|
|
40
|
+
maps[k] = self.class.ruby_to_js(@data_type[k], value[k], prune)
|
41
|
+
maps
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_json
|
47
|
+
@json ||= begin
|
48
|
+
{
|
49
|
+
:columns => columns.inject({}){|hash, (k,v)| hash[v] = k; hash},
|
50
|
+
:data => rows_hash
|
51
|
+
}.to_json
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def data_name
|
56
|
+
"data_#{@data.object_id}"
|
57
|
+
end
|
58
|
+
|
59
|
+
class << self
|
60
|
+
def google_data_type(value)
|
61
|
+
if value.is_a?(Numeric)
|
62
|
+
data_type = 'number'
|
63
|
+
elsif value.is_a?(Date)
|
64
|
+
data_type = 'date'
|
65
|
+
elsif value.is_a?(DateTime) || value.is_a?(Time)
|
66
|
+
data_type = 'datetime'
|
67
|
+
elsif value.respond_to?(:to_s)
|
68
|
+
if !value.match(/[^0-9.]/)
|
69
|
+
data_type = 'number'
|
70
|
+
else
|
71
|
+
if (a = Date._parse(value)).size >= 3
|
72
|
+
if a.size >= 5
|
73
|
+
data_type = 'datetime'
|
74
|
+
else
|
75
|
+
data_type = 'date'
|
76
|
+
end
|
77
|
+
else
|
78
|
+
data_type = 'string'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
data_type
|
83
|
+
end
|
84
|
+
|
85
|
+
def ruby_to_js(type, value, prune = false)
|
86
|
+
return nil if value.nil? && prune
|
87
|
+
return "" if value == "" || value.nil?
|
88
|
+
if type == 'string'
|
89
|
+
value = "#{value}"
|
90
|
+
elsif type == 'date'
|
91
|
+
value = Date.parse(value.to_s)
|
92
|
+
elsif type == 'datetime'
|
93
|
+
value = DateTime.parse(value.to_s)
|
94
|
+
elsif type == 'number'
|
95
|
+
value = value.to_s.match(/\./) ? value.to_f : value.to_i
|
96
|
+
end
|
97
|
+
return value
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/g_viz/g_viz.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'data')
|
2
|
+
require File.join(File.dirname(__FILE__), 'json_google')
|
3
|
+
|
4
|
+
module GViz
|
5
|
+
class Base
|
6
|
+
|
7
|
+
def initialize(config = {})
|
8
|
+
@viz_package_names = Set.new
|
9
|
+
@config = config
|
10
|
+
@namespace = @config[:namespace] || ""
|
11
|
+
@datas = {}
|
12
|
+
@visualizations = []
|
13
|
+
@template_name = File.join(File.dirname(__FILE__), 'templates', 'data_tables.erb')
|
14
|
+
end
|
15
|
+
|
16
|
+
def output
|
17
|
+
b = binding
|
18
|
+
rhtml = ERB.new(IO.read(@template_name), 0, "-")
|
19
|
+
@output = rhtml.result(b)
|
20
|
+
return @output
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_data(data, mapping)
|
24
|
+
@datas[data.object_id] = GViz::Data.new(data, mapping)
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_graph(type, dom_id, data, columns, options= {}, extra_options = {})
|
28
|
+
@viz_package_names.add(type)
|
29
|
+
new_viz = draw_visualization(type, dom_id, data, columns, options, extra_options)
|
30
|
+
@visualizations << new_viz
|
31
|
+
end
|
32
|
+
|
33
|
+
def draw_visualization(type, dom_id, data, columns, options = {}, extra_options = {})
|
34
|
+
viz_string = <<-STRING
|
35
|
+
var chart_#{data.object_id} = new google.visualization.#{type}(document.getElementById('#{dom_id}'));
|
36
|
+
chart_#{data.object_id}.draw(createDataTable(#{@datas[data.object_id].data_name}, #{columns.to_json}, #{extra_options[:first_column_title] == true ? 'true' : 'false' }), #{options.to_json});
|
37
|
+
STRING
|
38
|
+
end
|
39
|
+
|
40
|
+
def method_missing(name, *args)
|
41
|
+
if name.to_s.match(/add_/)
|
42
|
+
type = name.to_s.gsub(/add_/){""}.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
43
|
+
return add_graph(type, *args)
|
44
|
+
else
|
45
|
+
raise NoMethodError.new("Undefined method #{name} for #{self.inspect}")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<script type='text/javascript' src='http://www.google.com/jsapi<%= @api_key %>'></script>
|
2
|
+
<script type='text/javascript'>
|
3
|
+
// <![CDATA[
|
4
|
+
google.load('visualization', '1', {'packages':[<%= @viz_package_names.map{|p|"'" + p.downcase + "'"}.join(',') -%>]});
|
5
|
+
google.setOnLoadCallback(drawChart<%= @namespace %>);
|
6
|
+
|
7
|
+
|
8
|
+
function createDataTable(data_pkg, _columns, first_column_title){
|
9
|
+
if(typeof(first_column_title) == undefined) first_column_title = false;
|
10
|
+
var dataTable = new google.visualization.DataTable();
|
11
|
+
var data_columns = data_pkg['columns'];
|
12
|
+
for(var j = 0; j < _columns.length; ++j){
|
13
|
+
if(j == 0 && first_column_title){
|
14
|
+
dataTable.addColumn('string', _columns[j]);
|
15
|
+
}else if(data_columns[_columns[j]] != undefined){
|
16
|
+
dataTable.addColumn(data_columns[_columns[j]], _columns[j]);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
data = data_pkg['data']
|
20
|
+
dataTable.addRows(data.length);
|
21
|
+
for(var i = 0; i < data.length; ++i){
|
22
|
+
for(var j = 0; j < _columns.length; ++j){
|
23
|
+
if(data[i][_columns[j]] != undefined){
|
24
|
+
if(j == 0 && first_column_title){
|
25
|
+
dataTable.setValue(i, j, String(data[i][_columns[j]]));
|
26
|
+
}else{
|
27
|
+
dataTable.setValue(i, j, data[i][_columns[j]]);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
return dataTable;
|
33
|
+
}
|
34
|
+
|
35
|
+
<%- @datas.each do |k, data| -%>
|
36
|
+
var <%= data.data_name %> = <%= data.to_json %>;
|
37
|
+
<%- end -%>
|
38
|
+
|
39
|
+
function drawChart<%= @namespace %>() {
|
40
|
+
<%= @visualizations %>
|
41
|
+
}
|
42
|
+
// ]]>
|
43
|
+
</script>
|
data/lib/g_viz.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#http://code.google.com/apis/visualization/documentation/gallery/annotatedtimeline.html
|
2
|
+
# data.addColumn('date', 'Date');
|
3
|
+
# data.addColumn('number', 'Sold Pencils');
|
4
|
+
# data.addColumn('string', 'title1');
|
5
|
+
# data.addColumn('string', 'text1');
|
6
|
+
# data.addColumn('number', 'Sold Pens');
|
7
|
+
# data.addColumn('string', 'title2');
|
8
|
+
# data.addColumn('string', 'text2');
|
9
|
+
# data.addRows(6);
|
10
|
+
# data.setValue(0, 0, new Date(2008, 1 ,1));
|
11
|
+
# data.setValue(0, 1, 30000);
|
12
|
+
# data.setValue(0, 4, 40645);
|
13
|
+
# data.setValue(1, 0, new Date(2008, 1 ,2));
|
14
|
+
# data.setValue(1, 1, 14045);
|
15
|
+
# data.setValue(1, 4, 20374);
|
16
|
+
# data.setValue(2, 0, new Date(2008, 1 ,3));
|
17
|
+
# data.setValue(2, 1, 55022);
|
18
|
+
# data.setValue(2, 4, 50766);
|
19
|
+
# data.setValue(3, 0, new Date(2008, 1 ,4));
|
20
|
+
# data.setValue(3, 1, 75284);
|
21
|
+
# data.setValue(3, 4, 14334);
|
22
|
+
# data.setValue(3, 5, 'Out of Stock');
|
23
|
+
# data.setValue(3, 6, 'Ran out of stock on pens at 4pm');
|
24
|
+
# data.setValue(4, 0, new Date(2008, 1 ,5));
|
25
|
+
# data.setValue(4, 1, 41476);
|
26
|
+
# data.setValue(4, 2, 'Bought Pens');
|
27
|
+
# data.setValue(4, 3, 'Bought 200k pens');
|
28
|
+
# data.setValue(4, 4, 66467);
|
29
|
+
# data.setValue(5, 0, new Date(2008, 1 ,6));
|
30
|
+
# data.setValue(5, 1, 33322);
|
31
|
+
# data.setValue(5, 4, 39463);
|
32
|
+
mapping = [[:date, 'Date'],[:sold_pencils, 'Solid Pencils'], [:title1, 'title1'], [:text1, 'text1'],
|
33
|
+
[:sold_pens, 'Sold Pens'], [:title2, 'title2'], [:text2, 'text2']]
|
34
|
+
|
35
|
+
data = [
|
36
|
+
{:date => "2008-01-01", :sold_pencils => 30000, :sold_pens => 40645},
|
37
|
+
{:date => Date.parse("2008-01-02"), :sold_pencils => 14045, :sold_pens => 20374},
|
38
|
+
{:date => Date.parse("2008-01-03"), :sold_pencils => 55022, :sold_pens => 50766},
|
39
|
+
{:date => Date.parse("2008-01-04"), :sold_pencils => 75284, :sold_pens => 14334, :title2 => 'Out of Stock',:text2 => 'Ran out of stock on pens at 4pm'},
|
40
|
+
{:date => Date.parse("2008-01-05"), :sold_pencils => 41476, :sold_pens => 66467, :title1 => 'Bought Pens',:text2 => 'Bought 200k pens'},
|
41
|
+
{:date => Date.parse("2008-01-06"), :sold_pencils => 33322, :sold_pens => 39463, :title1 => 'Bought Pens',:text2 => 'Bought 200k pens'}
|
42
|
+
]
|
43
|
+
|
44
|
+
@test_data = [data, mapping]
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
2
|
+
|
3
|
+
describe GViz do
|
4
|
+
describe 'api' do
|
5
|
+
describe 'examples' do
|
6
|
+
|
7
|
+
describe 'annotated timeline' do
|
8
|
+
@mapping = [[:date, 'Date'],[:sold_pencils, 'Sold Pencils'], [:title1, 'title1'], [:text1, 'text1'],
|
9
|
+
[:sold_pens, 'Sold Pens'], [:title2, 'title2'], [:text2, 'text2']]
|
10
|
+
|
11
|
+
@data = [
|
12
|
+
{:date => "2008-02-01", :sold_pencils => 30000, :sold_pens => 40645},
|
13
|
+
{:date => Date.parse("2008-02-02"), :sold_pencils => 14045, :sold_pens => 20374},
|
14
|
+
{:date => Date.parse("2008-02-03"), :sold_pencils => 55022, :sold_pens => 50766},
|
15
|
+
{:date => Date.parse("2008-02-04"), :sold_pencils => 75284, :sold_pens => 14334, :title2 => 'Out of Stock', :text2 => 'Ran out of stock on pens at 4pm'},
|
16
|
+
{:date => Date.parse("2008-02-05"), :sold_pencils => 41476, :sold_pens => 66467, :title1 => 'Bought Pens', :text1 => 'Bought 200k pens'},
|
17
|
+
{:date => Date.parse("2008-02-06"), :sold_pencils => 33322, :sold_pens => 39463}
|
18
|
+
]
|
19
|
+
g = GViz::Base.new
|
20
|
+
g.add_data(@data, @mapping)
|
21
|
+
g.add_graph('AnnotatedTimeLine', 'chart_id', @data, [:date, :sold_pencils, :tilte1, :text1, :sold_pens, :title2, :text2], {:displayAnnotations => true})
|
22
|
+
output = g.output
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'implementation details - class methods' do
|
29
|
+
describe 'google_data_type' do
|
30
|
+
it "should classify ruby data types to google visualization data types" do
|
31
|
+
GViz::Data.google_data_type(Time.now).should == 'datetime'
|
32
|
+
GViz::Data.google_data_type(Date.new).should == 'date'
|
33
|
+
GViz::Data.google_data_type("June 23 1982").should == 'date'
|
34
|
+
GViz::Data.google_data_type("June 23 1982 12:23").should == 'datetime'
|
35
|
+
GViz::Data.google_data_type("12312412").should == 'number'
|
36
|
+
GViz::Data.google_data_type("12312412.1234").should == 'number'
|
37
|
+
GViz::Data.google_data_type(1234123).should == 'number'
|
38
|
+
GViz::Data.google_data_type(1234123.1234).should == 'number'
|
39
|
+
GViz::Data.google_data_type("a123124123").should == 'string'
|
40
|
+
# should this really happen? documenting it because i need to think if this is ok.
|
41
|
+
GViz::Data.google_data_type("a12312412").should == 'date'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'ruby_to_js' do
|
46
|
+
it "should return the js string representation of that data " do
|
47
|
+
GViz::Data.ruby_to_js('numeric', 12341234).should == 12341234
|
48
|
+
GViz::Data.ruby_to_js('string', 12341234).should == "12341234"
|
49
|
+
GViz::Data.ruby_to_js('date', "June 23 1982").should == Date.parse('June 23 1982')
|
50
|
+
GViz::Data.ruby_to_js('date', Date.parse("June 23 1982")).should == Date.parse('June 23 1982')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'implmentation details - instances methods' do
|
56
|
+
before(:all) do
|
57
|
+
@games = [{:name => "Gary", :games_won => "2", :birthday => "2008-02-01"},
|
58
|
+
{:name => "John", :games_won => "4", :birthday => Date.parse("2009-01-01 11:11")},
|
59
|
+
{:name => "A", :games_won => "2", :birthday => "Jun 14 1982"}]
|
60
|
+
|
61
|
+
@rows = [["'Gary'", "2", "new Date(2008, 1, 1)"],
|
62
|
+
["'John'", "4", "new Date(2009, 0, 1)"],
|
63
|
+
["'A'", "2", "new Date(1982, 5, 14)"]]
|
64
|
+
|
65
|
+
@gviz = GViz::Data.new(@games, [[:name, "Name"], [:games_won, "Games Won"], [:birthday, 'Birthday']])
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'columns' do
|
69
|
+
it 'should return google data types and labels' do
|
70
|
+
@gviz.columns.should == [['string', :name], ['number', :games_won], ['date', :birthday]]
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# describe 'rows' do
|
77
|
+
# it 'should return data rows' do
|
78
|
+
# @gviz.rows.should == @rows
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<script type='text/javascript' src='http://www.google.com/jsapi'></script>
|
2
|
+
<script type='text/javascript'>
|
3
|
+
google.load('visualization', '1', {'packages':['annotatedtimeline']});
|
4
|
+
google.setOnLoadCallback(drawChart);
|
5
|
+
function drawChart() {
|
6
|
+
var data = new google.visualization.DataTable();
|
7
|
+
data.addColumn('date', 'Date');
|
8
|
+
data.addColumn('number', 'Sold Pencils');
|
9
|
+
data.addColumn('string', 'title1');
|
10
|
+
data.addColumn('string', 'text1');
|
11
|
+
data.addColumn('number', 'Sold Pens');
|
12
|
+
data.addColumn('string', 'title2');
|
13
|
+
data.addColumn('string', 'text2');
|
14
|
+
data.addRows(6);
|
15
|
+
data.setValue(0, 0, new Date(2008, 1 ,1));
|
16
|
+
data.setValue(0, 1, 30000);
|
17
|
+
data.setValue(0, 4, 40645);
|
18
|
+
data.setValue(1, 0, new Date(2008, 1 ,2));
|
19
|
+
data.setValue(1, 1, 14045);
|
20
|
+
data.setValue(1, 4, 20374);
|
21
|
+
data.setValue(2, 0, new Date(2008, 1 ,3));
|
22
|
+
data.setValue(2, 1, 55022);
|
23
|
+
data.setValue(2, 4, 50766);
|
24
|
+
data.setValue(3, 0, new Date(2008, 1 ,4));
|
25
|
+
data.setValue(3, 1, 75284);
|
26
|
+
data.setValue(3, 4, 14334);
|
27
|
+
data.setValue(3, 5, 'Out of Stock');
|
28
|
+
data.setValue(3, 6, 'Ran out of stock on pens at 4pm');
|
29
|
+
data.setValue(4, 0, new Date(2008, 1 ,5));
|
30
|
+
data.setValue(4, 1, 41476);
|
31
|
+
data.setValue(4, 2, 'Bought Pens');
|
32
|
+
data.setValue(4, 3, 'Bought 200k pens');
|
33
|
+
data.setValue(4, 4, 66467);
|
34
|
+
data.setValue(5, 0, new Date(2008, 1 ,6));
|
35
|
+
data.setValue(5, 1, 33322);
|
36
|
+
data.setValue(5, 4, 39463);
|
37
|
+
|
38
|
+
var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
|
39
|
+
chart.draw(data, {displayAnnotations: true});
|
40
|
+
}
|
41
|
+
</script>
|
data/spec/test_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'g_viz')
|
3
|
+
|
4
|
+
class TestHelper
|
5
|
+
def self.template(name)
|
6
|
+
f = File.open(File.join(File.dirname(__FILE__), 'g_viz', 'templates', "#{name}.html"))
|
7
|
+
d = f.readlines(nil)
|
8
|
+
return d[0].to_s
|
9
|
+
end
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: JamieFlournoy-g_viz
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gary Tsang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-25 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A Ruby client for the Google Visualization API.
|
17
|
+
email: gary.tsang@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.markdown
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- CHANGELOG
|
27
|
+
- JamieFlournoy-g_viz.gemspec
|
28
|
+
- Manifest
|
29
|
+
- README.markdown
|
30
|
+
- Rakefile
|
31
|
+
- VERSION
|
32
|
+
- lib/g_viz.rb
|
33
|
+
- lib/g_viz/data.rb
|
34
|
+
- lib/g_viz/g_viz.rb
|
35
|
+
- lib/g_viz/json_google.rb
|
36
|
+
- lib/g_viz/templates/data_tables.erb
|
37
|
+
- spec/g_viz/fixtures/annotated_timeline.rb
|
38
|
+
- spec/g_viz/g_viz_spec.rb
|
39
|
+
- spec/g_viz/templates/rendered_annotated_timeline.html
|
40
|
+
- spec/test_helper.rb
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/JamieFlournoy/g_viz
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options:
|
47
|
+
- --charset=UTF-8
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
version:
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project: none
|
65
|
+
rubygems_version: 1.3.5
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: Google Visualization API Ruby Client
|
69
|
+
test_files:
|
70
|
+
- spec/g_viz/fixtures/annotated_timeline.rb
|
71
|
+
- spec/g_viz/g_viz_spec.rb
|
72
|
+
- spec/test_helper.rb
|