gchart 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +7 -0
- data/Manifest.txt +19 -1
- data/README.txt +3 -3
- data/Rakefile +11 -0
- data/lib/gchart.rb +30 -142
- data/lib/gchart/bar.rb +37 -0
- data/lib/gchart/base.rb +120 -0
- data/lib/gchart/line.rb +7 -0
- data/lib/gchart/pie.rb +11 -0
- data/lib/gchart/pie_3d.rb +7 -0
- data/lib/gchart/scatter.rb +7 -0
- data/lib/gchart/venn.rb +7 -0
- data/lib/gchart/xy_line.rb +7 -0
- data/lib/version.rb +2 -2
- data/spec/gchart/bar_spec.rb +24 -0
- data/spec/gchart/base_spec.rb +150 -0
- data/spec/gchart/line_spec.rb +7 -0
- data/spec/gchart/pie_3d_spec.rb +7 -0
- data/spec/gchart/pie_spec.rb +7 -0
- data/spec/gchart/scatter_spec.rb +7 -0
- data/spec/gchart/venn_spec.rb +7 -0
- data/spec/gchart/xy_line_spec.rb +7 -0
- data/spec/gchart_spec.rb +39 -0
- data/spec/helper.rb +11 -0
- data/spec/spec.opts +0 -0
- metadata +26 -8
- data/test/test_gchart.rb +0 -114
data/CHANGELOG.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 0.3.0 (2007-12-24)
|
2
|
+
|
3
|
+
* Breaking change: labels --> legend
|
4
|
+
* Switched to RSpec, added skeletal specs for all types
|
5
|
+
* Extensive refactoring, pulled chart types into GChart::Base subclasses
|
6
|
+
* (bug) Errors in the static helpers should report a reasonable file and line
|
7
|
+
|
1
8
|
== 0.2.0 (2007-12-12)
|
2
9
|
|
3
10
|
* Support for basic :labels
|
data/Manifest.txt
CHANGED
@@ -3,5 +3,23 @@ Manifest.txt
|
|
3
3
|
README.txt
|
4
4
|
Rakefile
|
5
5
|
lib/gchart.rb
|
6
|
+
lib/gchart/bar.rb
|
7
|
+
lib/gchart/base.rb
|
8
|
+
lib/gchart/line.rb
|
9
|
+
lib/gchart/pie.rb
|
10
|
+
lib/gchart/pie_3d.rb
|
11
|
+
lib/gchart/scatter.rb
|
12
|
+
lib/gchart/venn.rb
|
13
|
+
lib/gchart/xy_line.rb
|
6
14
|
lib/version.rb
|
7
|
-
|
15
|
+
spec/gchart/bar_spec.rb
|
16
|
+
spec/gchart/base_spec.rb
|
17
|
+
spec/gchart/line_spec.rb
|
18
|
+
spec/gchart/pie_3d_spec.rb
|
19
|
+
spec/gchart/pie_spec.rb
|
20
|
+
spec/gchart/scatter_spec.rb
|
21
|
+
spec/gchart/venn_spec.rb
|
22
|
+
spec/gchart/xy_line_spec.rb
|
23
|
+
spec/gchart_spec.rb
|
24
|
+
spec/helper.rb
|
25
|
+
spec/spec.opts
|
data/README.txt
CHANGED
@@ -8,7 +8,7 @@ a friendly Ruby interface. It can generate the URL for a given chart
|
|
8
8
|
|
9
9
|
== PROBLEMS/TODO
|
10
10
|
|
11
|
-
* Add support
|
11
|
+
* Add support fills (area or background), grid lines, shape markers, range markers
|
12
12
|
* Support shorthand colors and color names
|
13
13
|
* Make venn data specification friendlier
|
14
14
|
|
@@ -38,8 +38,8 @@ query parameters using the :extras key, e.g.,
|
|
38
38
|
# chart title
|
39
39
|
g = GChart.line(:title => "Awesomeness over Time", :data => [0, 10, 100])
|
40
40
|
|
41
|
-
# data set
|
42
|
-
g = GChart.line(:data => [[1, 2], [3, 4]], :
|
41
|
+
# data set legend
|
42
|
+
g = GChart.line(:data => [[1, 2], [3, 4]], :legend => ["Monkeys", "Ferrets"])
|
43
43
|
|
44
44
|
# data set colors
|
45
45
|
g = GChart.line(:data => [[0, 10, 100], [100, 10, 0]], :colors => ["ff0000", "0000ff"])
|
data/Rakefile
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
require "hoe"
|
3
|
+
require "spec/rake/spectask"
|
4
|
+
|
3
5
|
require "./lib/version.rb"
|
4
6
|
|
5
7
|
hoe = Hoe.new("gchart", GChart::VERSION) do |p|
|
@@ -11,3 +13,12 @@ hoe = Hoe.new("gchart", GChart::VERSION) do |p|
|
|
11
13
|
p.url = "http://gchart.rubyforge.org"
|
12
14
|
p.changes = p.paragraphs_of("CHANGELOG.txt", 0..1).join("\n\n")
|
13
15
|
end
|
16
|
+
|
17
|
+
desc "Run all specs"
|
18
|
+
Spec::Rake::SpecTask.new do |t|
|
19
|
+
t.spec_files = FileList["spec/**/*_spec.rb"]
|
20
|
+
t.spec_opts = ["--options", "spec/spec.opts"]
|
21
|
+
end
|
22
|
+
|
23
|
+
Rake::Task[:default].prerequisites.clear
|
24
|
+
task :default => :spec
|
data/lib/gchart.rb
CHANGED
@@ -1,157 +1,45 @@
|
|
1
|
-
require File.dirname(__FILE__) + "/version"
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/version")
|
2
2
|
|
3
|
-
|
4
|
-
require "
|
3
|
+
%w(base bar line pie pie_3d scatter venn xy_line).each do |type|
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + "/gchart/#{type}")
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
+
module GChart
|
7
8
|
URL = "http://chart.apis.google.com/chart"
|
8
|
-
TYPES = %w(line linexy bar pie pie3d venn scatter).collect { |t| t.to_sym }
|
9
9
|
CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.".split("")
|
10
10
|
PAIRS = CHARS.collect { |first| CHARS.collect { |second| first + second } }.flatten
|
11
11
|
|
12
12
|
class << self
|
13
|
-
|
14
|
-
|
15
|
-
PAIRS[number.to_i]
|
16
|
-
end
|
13
|
+
# Convenience constructor for GChart::Line.
|
14
|
+
def line(*args, &block); Line.new(*args, &block) end
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
def #{type}(options={}, &block)
|
21
|
-
new(options.merge(:type => #{type.inspect}, &block))
|
22
|
-
end
|
23
|
-
END
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# Array of chart data
|
28
|
-
attr_accessor :data
|
29
|
-
|
30
|
-
# Hash of additional query params
|
31
|
-
attr_accessor :extras
|
32
|
-
|
33
|
-
# Width (in pixels)
|
34
|
-
attr_accessor :width
|
35
|
-
|
36
|
-
# Height (in pixels)
|
37
|
-
attr_accessor :height
|
38
|
-
|
39
|
-
# Orientation. Applies to bar charts
|
40
|
-
attr_accessor :horizontal
|
41
|
-
|
42
|
-
# Grouping. Applies to bar charts
|
43
|
-
attr_accessor :grouped
|
44
|
-
|
45
|
-
# Overall chart title
|
46
|
-
attr_accessor :title
|
47
|
-
|
48
|
-
# Array of RRGGBB colors, one per data set
|
49
|
-
attr_accessor :colors
|
50
|
-
|
51
|
-
# Array of data set labels
|
52
|
-
attr_accessor :labels
|
53
|
-
|
54
|
-
attr_accessor :max
|
55
|
-
|
56
|
-
# The chart type
|
57
|
-
attr_reader :type
|
58
|
-
|
59
|
-
alias_method :horizontal?, :horizontal
|
60
|
-
alias_method :grouped?, :grouped
|
61
|
-
|
62
|
-
def initialize(options={}, &block)
|
63
|
-
@type = :line
|
64
|
-
@data = []
|
65
|
-
@extras = {}
|
66
|
-
@width = 300
|
67
|
-
@height = 200
|
68
|
-
@horizontal = false
|
69
|
-
@grouped = false
|
16
|
+
# Convenience constructor for GChart::XYLine.
|
17
|
+
def xyline(*args, &block); XYLine.new(*args, &block) end
|
70
18
|
|
71
|
-
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
# Sets the chart type. Raises +ArgumentError+ if +type+ isn't in +TYPES+.
|
76
|
-
def type=(type)
|
77
|
-
unless TYPES.include?(type)
|
78
|
-
raise ArgumentError, %Q(Invalid type #{type.inspect}. Valid types: #{TYPES.inspect}.)
|
79
|
-
end
|
19
|
+
# Convenience constructor for GChart::Bar.
|
20
|
+
def bar(*args, &block); Bar.new(*args, &block) end
|
80
21
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
# Returns the chart's size as "WIDTHxHEIGHT".
|
85
|
-
def size
|
86
|
-
"#{width}x#{height}"
|
87
|
-
end
|
88
|
-
|
89
|
-
# Sets the chart's size as "WIDTHxHEIGHT".
|
90
|
-
def size=(size)
|
91
|
-
self.width, self.height = size.split("x").collect { |n| Integer(n) }
|
92
|
-
end
|
93
|
-
|
94
|
-
# Returns the chart's URL.
|
95
|
-
def to_url
|
96
|
-
query = google_query_params.collect { |k, v| "#{k}=#{URI.escape(v)}" }.join("&")
|
97
|
-
"#{URL}?#{query}"
|
98
|
-
end
|
99
|
-
|
100
|
-
# Returns the chart's generated PNG as a blob.
|
101
|
-
def fetch
|
102
|
-
open(to_url) { |data| data.read }
|
103
|
-
end
|
104
|
-
|
105
|
-
# Writes the chart's generated PNG to a file. If +io_or_file+ quacks like an IO,
|
106
|
-
# +write+ will be called on it instead.
|
107
|
-
def write(io_or_file="chart.png")
|
108
|
-
return io_or_file.write(fetch) if io_or_file.respond_to?(:write)
|
109
|
-
open(io_or_file, "w+") { |f| f.write(fetch) }
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
|
-
|
114
|
-
def google_query_params
|
115
|
-
params = { "cht" => google_chart_type, "chd" => google_data, "chs" => size }
|
116
|
-
params["chtt"] = title.tr("\n", "|").gsub(/\s+/, "+") if title
|
117
|
-
params["chco"] = colors.join(",") if colors
|
22
|
+
# Convenience constructor for GChart::Pie.
|
23
|
+
def pie(*args, &block); Pie.new(*args, &block) end
|
118
24
|
|
119
|
-
|
120
|
-
|
121
|
-
params[param] = labels.join("|")
|
122
|
-
end
|
25
|
+
# Convenience constructor for GChart::Pie3D.
|
26
|
+
def pie3d(*args, &block); Pie3D.new(*args, &block) end
|
123
27
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
def google_chart_type
|
128
|
-
case type
|
129
|
-
when :line
|
130
|
-
"lc"
|
131
|
-
when :linexy
|
132
|
-
"lxy"
|
133
|
-
when :bar
|
134
|
-
"b" + (horizontal? ? "h" : "v") + (grouped? ? "g" : "s")
|
135
|
-
when :pie
|
136
|
-
"p"
|
137
|
-
when :pie3d
|
138
|
-
"p3"
|
139
|
-
when :venn
|
140
|
-
"v"
|
141
|
-
when :scatter
|
142
|
-
"s"
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def google_data
|
147
|
-
raw = data && data.first.is_a?(Array) ? data : [data]
|
148
|
-
max = self.max || raw.collect { |s| s.max }.max
|
28
|
+
# Convenience constructor for GChart::Venn.
|
29
|
+
def venn(*args, &block); Venn.new(*args, &block) end
|
149
30
|
|
150
|
-
|
151
|
-
|
152
|
-
set.collect { |n| GChart.encode_extended(n * (PAIRS.size - 1) / max) }.join
|
153
|
-
end
|
31
|
+
# Convenience constructor for GChart::Scatter.
|
32
|
+
def scatter(*args, &block); Scatter.new(*args, &block) end
|
154
33
|
|
155
|
-
|
156
|
-
|
34
|
+
# Encode +n+ as a string. +n+ is normalized based on +max+.
|
35
|
+
# +encoding+ can currently only be :extended.
|
36
|
+
def encode(encoding, n, max)
|
37
|
+
unless encoding == :extended
|
38
|
+
raise ArgumentError, "unsupported encoding: #{encoding.inspect}"
|
39
|
+
end
|
40
|
+
|
41
|
+
return "__" if n.nil?
|
42
|
+
PAIRS[(n * (PAIRS.size - 1) / max).to_i]
|
43
|
+
end
|
44
|
+
end
|
157
45
|
end
|
data/lib/gchart/bar.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module GChart
|
2
|
+
class Bar < GChart::Base
|
3
|
+
ORIENTATIONS = [:horizontal, :vertical]
|
4
|
+
|
5
|
+
attr_accessor :grouped
|
6
|
+
alias_method :grouped?, :grouped
|
7
|
+
|
8
|
+
attr_reader :orientation
|
9
|
+
|
10
|
+
def initialize(*args, &block)
|
11
|
+
@grouped = false
|
12
|
+
@orientation = :horizontal
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def orientation=(orientation)
|
17
|
+
unless ORIENTATIONS.include?(orientation)
|
18
|
+
raise ArgumentError, "Invalid orientation: #{orientation.inspect}. " +
|
19
|
+
"Valid orientations: #{ORIENTATIONS.inspect}"
|
20
|
+
end
|
21
|
+
|
22
|
+
@orientation = orientation
|
23
|
+
end
|
24
|
+
|
25
|
+
def horizontal?
|
26
|
+
@orientation == :horizontal
|
27
|
+
end
|
28
|
+
|
29
|
+
def vertical?
|
30
|
+
@orientation == :vertical
|
31
|
+
end
|
32
|
+
|
33
|
+
def render_chart_type #:nodoc:
|
34
|
+
"b#{@orientation.to_s[0..0]}#{grouped? ? "g" : "s"}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/gchart/base.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require "open-uri"
|
2
|
+
require "uri"
|
3
|
+
|
4
|
+
module GChart
|
5
|
+
class Base
|
6
|
+
# Array of chart data. See subclasses for specific usage.
|
7
|
+
attr_accessor :data
|
8
|
+
|
9
|
+
# Hash of additional HTTP query params.
|
10
|
+
attr_accessor :extras
|
11
|
+
|
12
|
+
# Chart title.
|
13
|
+
attr_accessor :title
|
14
|
+
|
15
|
+
# Array of rrggbb colors, one per data set.
|
16
|
+
attr_accessor :colors
|
17
|
+
|
18
|
+
# Array of legend text, one per data set.
|
19
|
+
attr_accessor :legend
|
20
|
+
|
21
|
+
# Max data value for quantization.
|
22
|
+
attr_accessor :max
|
23
|
+
|
24
|
+
# Chart width, in pixels.
|
25
|
+
attr_reader :width
|
26
|
+
|
27
|
+
# Chart height, in pixels.
|
28
|
+
attr_reader :height
|
29
|
+
|
30
|
+
def initialize(options={}, &block)
|
31
|
+
@data = []
|
32
|
+
@extras = {}
|
33
|
+
@width = 300
|
34
|
+
@height = 200
|
35
|
+
|
36
|
+
options.each { |k, v| send("#{k}=", v) }
|
37
|
+
yield(self) if block_given?
|
38
|
+
end
|
39
|
+
|
40
|
+
# Sets the chart's width, in pixels. Raises +ArgumentError+ if +width+ is less than 1.
|
41
|
+
def width=(width)
|
42
|
+
raise ArgumentError, "Invalid width: #{width.inspect}" if width.nil? || width < 1
|
43
|
+
@width = width
|
44
|
+
end
|
45
|
+
|
46
|
+
# Sets the chart's height, in pixels. Raises +ArgumentError+ if +height+ is less than 1.
|
47
|
+
def height=(height)
|
48
|
+
raise ArgumentError, "Invalid height: #{height.inspect}" if height.nil? || height < 1
|
49
|
+
@height = height
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the chart's size as "WIDTHxHEIGHT".
|
53
|
+
def size
|
54
|
+
"#{width}x#{height}"
|
55
|
+
end
|
56
|
+
|
57
|
+
# Sets the chart's size as "WIDTHxHEIGHT".
|
58
|
+
def size=(size)
|
59
|
+
self.width, self.height = size.split("x").collect { |n| Integer(n) }
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the chart's URL.
|
63
|
+
def to_url
|
64
|
+
query = query_params.collect { |k, v| "#{k}=#{URI.escape(v)}" }.join("&")
|
65
|
+
"#{GChart::URL}?#{query}"
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns the chart's generated PNG as a blob.
|
69
|
+
def fetch
|
70
|
+
open(to_url) { |io| io.read }
|
71
|
+
end
|
72
|
+
|
73
|
+
# Writes the chart's generated PNG to a file. If +io_or_file+ quacks like an IO,
|
74
|
+
# calls +write+ on it instead.
|
75
|
+
def write(io_or_file="chart.png")
|
76
|
+
return io_or_file.write(fetch) if io_or_file.respond_to?(:write)
|
77
|
+
open(io_or_file, "w+") { |io| io.write(fetch) }
|
78
|
+
end
|
79
|
+
|
80
|
+
protected
|
81
|
+
|
82
|
+
def query_params #:nodoc:
|
83
|
+
params = { "cht" => render_chart_type, "chs" => size }
|
84
|
+
|
85
|
+
render_data(params)
|
86
|
+
render_title(params)
|
87
|
+
render_colors(params)
|
88
|
+
render_legend(params)
|
89
|
+
|
90
|
+
params.merge(extras)
|
91
|
+
end
|
92
|
+
|
93
|
+
def render_chart_type #:nodoc:
|
94
|
+
raise NotImplementedError, "override in subclasses"
|
95
|
+
end
|
96
|
+
|
97
|
+
def render_data(params) #:nodoc:
|
98
|
+
raw = data && data.first.is_a?(Array) ? data : [data]
|
99
|
+
max = self.max || raw.collect { |s| s.max }.max
|
100
|
+
|
101
|
+
sets = raw.collect do |set|
|
102
|
+
set.collect { |n| GChart.encode(:extended, n, max) }.join
|
103
|
+
end
|
104
|
+
|
105
|
+
params["chd"] = "e:#{sets.join(",")}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def render_title(params) #:nodoc:
|
109
|
+
params["chtt"] = title.tr("\n", "|").gsub(/\s+/, "+") if title
|
110
|
+
end
|
111
|
+
|
112
|
+
def render_colors(params) #:nodoc:
|
113
|
+
params["chco"] = colors.join(",") if colors
|
114
|
+
end
|
115
|
+
|
116
|
+
def render_legend(params) #:nodoc:
|
117
|
+
params["chdl"] = legend.join("|") if legend
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/lib/gchart/line.rb
ADDED
data/lib/gchart/pie.rb
ADDED
data/lib/gchart/venn.rb
ADDED
data/lib/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.
|
1
|
+
module GChart
|
2
|
+
VERSION = "0.3.0"
|
3
3
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
2
|
+
|
3
|
+
describe GChart::Bar do
|
4
|
+
before(:each) do
|
5
|
+
@chart = GChart::Bar.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "is ungrouped by default" do
|
9
|
+
@chart.grouped.should == false
|
10
|
+
@chart.should_not be_grouped
|
11
|
+
end
|
12
|
+
|
13
|
+
it "is horizontal by default" do
|
14
|
+
@chart.orientation.should == :horizontal
|
15
|
+
@chart.should be_horizontal
|
16
|
+
@chart.should_not be_vertical
|
17
|
+
end
|
18
|
+
|
19
|
+
it "renders the correct chart type" do
|
20
|
+
GChart::Bar.new.render_chart_type.should == "bhs"
|
21
|
+
GChart::Bar.new(:grouped => true).render_chart_type.should == "bhg"
|
22
|
+
GChart::Bar.new(:orientation => :vertical).render_chart_type.should == "bvs"
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require "tmpdir"
|
2
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
3
|
+
|
4
|
+
describe GChart::Base do
|
5
|
+
it "can be initialized with a hash" do
|
6
|
+
GChart::Base.new(:title => "foo").title.should == "foo"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "complains about being initialized with unknown attributes" do
|
10
|
+
lambda { GChart::Base.new(:monkey => :chimchim) }.should raise_error(NoMethodError)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can be initialized with a block" do
|
14
|
+
chart = GChart::Base.new do |c|
|
15
|
+
c.title = "foo"
|
16
|
+
end
|
17
|
+
|
18
|
+
chart.title.should == "foo"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe GChart::Base, "#data" do
|
23
|
+
it "is an empty array by default" do
|
24
|
+
GChart::Base.new.data.should == []
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe GChart::Base, "#size" do
|
29
|
+
before(:each) { @chart = GChart::Base.new }
|
30
|
+
|
31
|
+
it "can be accessed as width and height" do
|
32
|
+
@chart.width.should_not be_zero
|
33
|
+
@chart.height.should_not be_zero
|
34
|
+
end
|
35
|
+
|
36
|
+
it "can be accessed as a combined size" do
|
37
|
+
@chart.size.should == "#{@chart.width}x#{@chart.height}"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "can be specified as a combined size" do
|
41
|
+
@chart.size = "11x13"
|
42
|
+
@chart.width.should == 11
|
43
|
+
@chart.height.should == 13
|
44
|
+
end
|
45
|
+
|
46
|
+
it "has a reasonable default value" do
|
47
|
+
@chart.size.should == "300x200"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "complains about negative numbers" do
|
51
|
+
lambda { @chart.size = "-15x13" }.should raise_error(ArgumentError)
|
52
|
+
lambda { @chart.width = -1 }.should raise_error(ArgumentError)
|
53
|
+
lambda { @chart.height= -1 }.should raise_error(ArgumentError)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe GChart::Base, "#render_chart_type" do
|
58
|
+
it "raises; subclasses must implement" do
|
59
|
+
lambda { GChart::Base.new.render_chart_type }.should raise_error(NotImplementedError)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe GChart::Base, "#query_params" do
|
64
|
+
before(:each) do
|
65
|
+
@chart = GChart::Base.new
|
66
|
+
@chart.stub!(:render_chart_type).and_return("TEST")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "contains the chart's type" do
|
70
|
+
@chart.query_params["cht"].should == "TEST"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "contains the chart's data" do
|
74
|
+
@chart.data = [[1, 2, 3], [3, 2, 1]]
|
75
|
+
@chart.query_params["chd"].should == "e:VVqq..,..qqVV"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "contains the chart's size" do
|
79
|
+
@chart.query_params["chs"].should == "300x200"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "contains the chart's title" do
|
83
|
+
@chart.title = "foo"
|
84
|
+
@chart.query_params["chtt"].should == "foo"
|
85
|
+
end
|
86
|
+
|
87
|
+
it "escapes the chart's title" do
|
88
|
+
@chart.title = "foo bar"
|
89
|
+
@chart.query_params["chtt"].should == "foo+bar"
|
90
|
+
|
91
|
+
@chart.title = "foo\nbar"
|
92
|
+
@chart.query_params["chtt"].should == "foo|bar"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "contains the chart's colors" do
|
96
|
+
@chart.colors = ["cccccc", "eeeeee"]
|
97
|
+
@chart.query_params["chco"].should == "cccccc,eeeeee"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe GChart::Base, "#to_url" do
|
102
|
+
before(:each) do
|
103
|
+
@chart = GChart::Base.new
|
104
|
+
@chart.stub!(:render_chart_type).and_return("TEST")
|
105
|
+
end
|
106
|
+
|
107
|
+
it "generates a URL that points at Google" do
|
108
|
+
@chart.to_url.should =~ %r(http://chart.apis.google.com/chart)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe GChart::Base, "#fetch" do
|
113
|
+
# THIS EXPECTATION HITS THE CLOUD! Comment it out for a faster cycle. :)
|
114
|
+
it "fetches a blob from Google" do
|
115
|
+
blob = GChart.line(:data => [1, 2]).fetch
|
116
|
+
blob.should_not be_nil
|
117
|
+
blob.should =~ /PNG/
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe GChart::Base, "#write" do
|
122
|
+
before(:each) do
|
123
|
+
@chart = GChart::Base.new
|
124
|
+
@chart.stub!(:fetch).and_return("PAYLOAD")
|
125
|
+
end
|
126
|
+
|
127
|
+
it "writes to chart.png by default" do
|
128
|
+
Dir.chdir(Dir.tmpdir) do
|
129
|
+
@chart.write
|
130
|
+
File.file?("chart.png").should == true
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it "writes to a specified file" do
|
135
|
+
Dir.chdir(Dir.tmpdir) do
|
136
|
+
@chart.write("foo.png")
|
137
|
+
File.file?("foo.png").should == true
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it "writes to anything that quacks like IO" do
|
142
|
+
result = ""
|
143
|
+
|
144
|
+
StringIO.open(result, "w+") do |io|
|
145
|
+
@chart.write(io)
|
146
|
+
end
|
147
|
+
|
148
|
+
result.should == "PAYLOAD"
|
149
|
+
end
|
150
|
+
end
|
data/spec/gchart_spec.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/helper")
|
2
|
+
|
3
|
+
describe GChart do
|
4
|
+
it "supplies a version" do
|
5
|
+
GChart::VERSION.should_not be_nil
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe GChart, ".encode" do
|
10
|
+
it "only supports the extended encoding" do
|
11
|
+
lambda { GChart.encode(:simple, 4, 10) }.should raise_error(ArgumentError)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "implements the extended encoding" do
|
15
|
+
expected = {
|
16
|
+
0 => "AA", 25 => "AZ", 26 => "Aa", 51 => "Az", 52 => "A0", 61 => "A9", 62 => "A-", 63 => "A.",
|
17
|
+
64 => "BA", 89 => "BZ", 90 => "Ba", 115 => "Bz", 116 => "B0", 125 => "B9", 126 => "B-", 127 => "B.",
|
18
|
+
4032 => ".A", 4057 => ".Z", 4058 => ".a", 4083 => ".z", 4084 => ".0", 4093 => ".9", 4094 => ".-", 4095 => ".."
|
19
|
+
}
|
20
|
+
|
21
|
+
expected.each do |original, encoded|
|
22
|
+
GChart.encode(:extended, original, 4095).should == encoded
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "encodes nil correctly" do
|
27
|
+
GChart.encode(:extended, nil, 1).should == "__"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe GChart, ".line" do
|
32
|
+
it "can render a basic line URL" do
|
33
|
+
expected = { "cht" => "lc", "chs" => "300x200", "chd" => "e:AAAo..", "chtt" => "test" }
|
34
|
+
chart = GChart.line(:title => "test", :data => [1, 100, 10000])
|
35
|
+
|
36
|
+
chart.query_params.should == expected
|
37
|
+
chart.to_url.should == "http://chart.apis.google.com/chart?chs=300x200&cht=lc&chtt=test&chd=e:AAAo.."
|
38
|
+
end
|
39
|
+
end
|
data/spec/helper.rb
ADDED
data/spec/spec.opts
ADDED
File without changes
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gchart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
platform:
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Barnette
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2007-12-
|
12
|
+
date: 2007-12-24 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 1.3.0
|
23
23
|
version:
|
24
|
-
description: "== PROBLEMS/TODO * Add support
|
24
|
+
description: "== PROBLEMS/TODO * Add support fills (area or background), grid lines, shape markers, range markers * Support shorthand colors and color names * Make venn data specification friendlier There are lots of missing features. Until they're implemented, you can directly specify query parameters using the :extras key, e.g., # provides a legend for each data set g = GChart.line(:data => [[1, 2], [3, 4]], :extras => { \"chdl\" => [\"First\", \"Second\"] })"
|
25
25
|
email: jbarnette@rubyforge.org
|
26
26
|
executables: []
|
27
27
|
|
@@ -37,8 +37,26 @@ files:
|
|
37
37
|
- README.txt
|
38
38
|
- Rakefile
|
39
39
|
- lib/gchart.rb
|
40
|
+
- lib/gchart/bar.rb
|
41
|
+
- lib/gchart/base.rb
|
42
|
+
- lib/gchart/line.rb
|
43
|
+
- lib/gchart/pie.rb
|
44
|
+
- lib/gchart/pie_3d.rb
|
45
|
+
- lib/gchart/scatter.rb
|
46
|
+
- lib/gchart/venn.rb
|
47
|
+
- lib/gchart/xy_line.rb
|
40
48
|
- lib/version.rb
|
41
|
-
-
|
49
|
+
- spec/gchart/bar_spec.rb
|
50
|
+
- spec/gchart/base_spec.rb
|
51
|
+
- spec/gchart/line_spec.rb
|
52
|
+
- spec/gchart/pie_3d_spec.rb
|
53
|
+
- spec/gchart/pie_spec.rb
|
54
|
+
- spec/gchart/scatter_spec.rb
|
55
|
+
- spec/gchart/venn_spec.rb
|
56
|
+
- spec/gchart/xy_line_spec.rb
|
57
|
+
- spec/gchart_spec.rb
|
58
|
+
- spec/helper.rb
|
59
|
+
- spec/spec.opts
|
42
60
|
has_rdoc: true
|
43
61
|
homepage: http://gchart.rubyforge.org
|
44
62
|
post_install_message:
|
@@ -62,9 +80,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
80
|
requirements: []
|
63
81
|
|
64
82
|
rubyforge_project: gchart
|
65
|
-
rubygems_version: 0.
|
83
|
+
rubygems_version: 1.0.1
|
66
84
|
signing_key:
|
67
85
|
specification_version: 2
|
68
86
|
summary: GChart uses the Google Chart API to create pretty pictures.
|
69
|
-
test_files:
|
70
|
-
|
87
|
+
test_files: []
|
88
|
+
|
data/test/test_gchart.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
require "test/unit"
|
2
|
-
require "gchart"
|
3
|
-
|
4
|
-
class GChart
|
5
|
-
public :google_query_params, :google_chart_type, :google_data
|
6
|
-
end
|
7
|
-
|
8
|
-
class TestGChart < Test::Unit::TestCase
|
9
|
-
def test_supplies_a_version
|
10
|
-
assert_not_nil(GChart::VERSION)
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_allows_hash_initialization
|
14
|
-
assert_equal(:line, GChart.new(:type => :line).type)
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_complains_about_unknown_options
|
18
|
-
assert_raise(NoMethodError) { GChart.new(:monkey => :chimchim) }
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_allows_block_initialization
|
22
|
-
c = GChart.new do |chart|
|
23
|
-
chart.type = :line
|
24
|
-
end
|
25
|
-
|
26
|
-
assert_equal(:line, c.type)
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_allows_all_valid_chart_types
|
30
|
-
GChart::TYPES.each do |type|
|
31
|
-
assert_nothing_raised(ArgumentError) { GChart.new(:type => type) }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_complains_about_invalid_chart_types
|
36
|
-
assert_raise(ArgumentError) { GChart.new(:type => :monkey) }
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_allows_size_to_be_specified_combined
|
40
|
-
c = GChart.new(:size => "13x14")
|
41
|
-
assert_equal(13, c.width)
|
42
|
-
assert_equal(14, c.height)
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_defaults
|
46
|
-
c = GChart.new
|
47
|
-
assert_equal(:line, c.type)
|
48
|
-
assert_equal([], c.data)
|
49
|
-
assert_equal(300, c.width)
|
50
|
-
assert_equal(200, c.height)
|
51
|
-
assert(!c.horizontal?)
|
52
|
-
assert(!c.grouped?)
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_google_chart_types
|
56
|
-
assert_equal("lc", GChart.new(:type => :line).google_chart_type)
|
57
|
-
assert_equal("lxy", GChart.new(:type => :linexy).google_chart_type)
|
58
|
-
|
59
|
-
assert_equal("bhg", GChart.new(:type => :bar, :horizontal => true, :grouped => true).google_chart_type)
|
60
|
-
assert_equal("bhs", GChart.new(:type => :bar, :horizontal => true, :grouped => false).google_chart_type)
|
61
|
-
assert_equal("bvs", GChart.new(:type => :bar, :horizontal => false, :grouped => false).google_chart_type)
|
62
|
-
|
63
|
-
assert_equal("p", GChart.new(:type => :pie).google_chart_type)
|
64
|
-
assert_equal("v", GChart.new(:type => :venn).google_chart_type)
|
65
|
-
assert_equal("s", GChart.new(:type => :scatter).google_chart_type)
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_google_extended_notation
|
69
|
-
expected = {
|
70
|
-
0 => "AA", 25 => "AZ", 26 => "Aa", 51 => "Az", 52 => "A0", 61 => "A9", 62 => "A-", 63 => "A.",
|
71
|
-
64 => "BA", 89 => "BZ", 90 => "Ba", 115 => "Bz", 116 => "B0", 125 => "B9", 126 => "B-", 127 => "B.",
|
72
|
-
4032 => ".A", 4057 => ".Z", 4058 => ".a", 4083 => ".z", 4084 => ".0", 4093 => ".9", 4094 => ".-", 4095 => ".."
|
73
|
-
}
|
74
|
-
|
75
|
-
expected.each do |original, encoded|
|
76
|
-
assert_equal(encoded, GChart.encode_extended(original))
|
77
|
-
end
|
78
|
-
|
79
|
-
assert_equal("__", GChart.encode_extended(nil))
|
80
|
-
end
|
81
|
-
|
82
|
-
def test_allows_extra_query_params
|
83
|
-
c = GChart.new(:extras => { :foo => :bar })
|
84
|
-
assert(c.google_query_params.include?(:foo))
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_supports_title
|
88
|
-
chart = GChart.new
|
89
|
-
|
90
|
-
assert_nil(chart.google_query_params["chtt"])
|
91
|
-
|
92
|
-
chart.title = "foo"
|
93
|
-
assert_equal("foo", chart.google_query_params["chtt"])
|
94
|
-
|
95
|
-
chart.title = "a space"
|
96
|
-
assert_equal("a+space", chart.google_query_params["chtt"])
|
97
|
-
|
98
|
-
chart.title = "a\nnewline"
|
99
|
-
assert_equal("a|newline", chart.google_query_params["chtt"])
|
100
|
-
end
|
101
|
-
|
102
|
-
def test_supports_colors
|
103
|
-
chart = GChart.new(:colors => ["cccccc", "eeeeee"])
|
104
|
-
assert_equal(chart.google_query_params["chco"], "cccccc,eeeeee")
|
105
|
-
end
|
106
|
-
|
107
|
-
def test_generates_correct_query_params_and_url_for_simple_example
|
108
|
-
expected = { "cht" => "lc", "chs" => "300x200", "chd" => "e:AAAo..", "chtt" => "test" }
|
109
|
-
|
110
|
-
chart = GChart.new(:title => "test", :data => [1, 100, 10000])
|
111
|
-
assert_equal(expected, chart.google_query_params)
|
112
|
-
assert_equal("http://chart.apis.google.com/chart?chs=300x200&cht=lc&chtt=test&chd=e:AAAo..", chart.to_url)
|
113
|
-
end
|
114
|
-
end
|