gchart 0.2.0 → 0.3.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.
- 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
|