texel-gchart 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +43 -0
- data/Manifest.txt +31 -0
- data/README.txt +81 -0
- data/Rakefile +31 -0
- data/lib/gchart.rb +62 -0
- data/lib/gchart/bar.rb +60 -0
- data/lib/gchart/base.rb +133 -0
- data/lib/gchart/line.rb +7 -0
- data/lib/gchart/map.rb +71 -0
- data/lib/gchart/meter.rb +29 -0
- data/lib/gchart/pie.rb +21 -0
- data/lib/gchart/pie_3d.rb +7 -0
- data/lib/gchart/scatter.rb +7 -0
- data/lib/gchart/sparkline.rb +15 -0
- data/lib/gchart/venn.rb +7 -0
- data/lib/gchart/xy_line.rb +7 -0
- data/lib/version.rb +3 -0
- data/spec/gchart/bar_spec.rb +80 -0
- data/spec/gchart/base_spec.rb +156 -0
- data/spec/gchart/line_spec.rb +7 -0
- data/spec/gchart/map_spec.rb +56 -0
- data/spec/gchart/meter_spec.rb +48 -0
- data/spec/gchart/pie_3d_spec.rb +7 -0
- data/spec/gchart/pie_spec.rb +29 -0
- data/spec/gchart/scatter_spec.rb +7 -0
- data/spec/gchart/sparkline_spec.rb +12 -0
- data/spec/gchart/venn_spec.rb +7 -0
- data/spec/gchart/xy_line_spec.rb +7 -0
- data/spec/gchart_spec.rb +69 -0
- data/spec/helper.rb +11 -0
- data/spec/spec.opts +7 -0
- metadata +94 -0
data/CHANGELOG.txt
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
== 0.5.0 (2008-04-17)
|
2
|
+
|
3
|
+
* Support for Map charts
|
4
|
+
* Support for Sparkline charts
|
5
|
+
* Initial support for Google-o-meter
|
6
|
+
|
7
|
+
== UNRELEASED
|
8
|
+
|
9
|
+
* Freeze GChart::VERSION.
|
10
|
+
|
11
|
+
== 0.4.2 (2008-01-09)
|
12
|
+
|
13
|
+
* Encoding a flatlined chart doesn't asplode [Jack Danger Canty]
|
14
|
+
|
15
|
+
== 0.4.1 (2008-01-02)
|
16
|
+
|
17
|
+
* (bug #16756 fixed) Example in the README is incorrect
|
18
|
+
|
19
|
+
== 0.4.0 (2007-12-28)
|
20
|
+
|
21
|
+
* New committer, Abhay Kumar
|
22
|
+
* Implement all three encodings. Fix extended encoding calculation.
|
23
|
+
* Support bar thickness/spacing for bar charts
|
24
|
+
* (bug #16565 fixed) GChart now tells you when your chart is too big.
|
25
|
+
* Pushed some bar chart params logic down where it belongs
|
26
|
+
* Enforce pie chart spec: pie charts only take one set of data
|
27
|
+
|
28
|
+
== 0.3.0 (2007-12-24)
|
29
|
+
|
30
|
+
* Breaking change: labels --> legend
|
31
|
+
* Switched to RSpec, added skeletal specs for all types
|
32
|
+
* Extensive refactoring, pulled chart types into GChart::Base subclasses
|
33
|
+
* (bug) Errors in the static helpers should report a reasonable file and line
|
34
|
+
|
35
|
+
== 0.2.0 (2007-12-12)
|
36
|
+
|
37
|
+
* Support for basic :labels
|
38
|
+
* Support for pie3d
|
39
|
+
* Minor doc cleanups
|
40
|
+
|
41
|
+
== 0.1.0 (2007-12-10)
|
42
|
+
|
43
|
+
* Birthday!
|
data/Manifest.txt
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
CHANGELOG.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
lib/gchart.rb
|
6
|
+
lib/gchart/bar.rb
|
7
|
+
lib/gchart/base.rb
|
8
|
+
lib/gchart/line.rb
|
9
|
+
lib/gchart/map.rb
|
10
|
+
lib/gchart/meter.rb
|
11
|
+
lib/gchart/pie.rb
|
12
|
+
lib/gchart/pie_3d.rb
|
13
|
+
lib/gchart/scatter.rb
|
14
|
+
lib/gchart/sparkline.rb
|
15
|
+
lib/gchart/venn.rb
|
16
|
+
lib/gchart/xy_line.rb
|
17
|
+
lib/version.rb
|
18
|
+
spec/gchart/bar_spec.rb
|
19
|
+
spec/gchart/base_spec.rb
|
20
|
+
spec/gchart/line_spec.rb
|
21
|
+
spec/gchart/map_spec.rb
|
22
|
+
spec/gchart/meter_spec.rb
|
23
|
+
spec/gchart/pie_3d_spec.rb
|
24
|
+
spec/gchart/pie_spec.rb
|
25
|
+
spec/gchart/scatter_spec.rb
|
26
|
+
spec/gchart/sparkline_spec.rb
|
27
|
+
spec/gchart/venn_spec.rb
|
28
|
+
spec/gchart/xy_line_spec.rb
|
29
|
+
spec/gchart_spec.rb
|
30
|
+
spec/helper.rb
|
31
|
+
spec/spec.opts
|
data/README.txt
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
= GChart
|
2
|
+
|
3
|
+
== DESCRIPTION
|
4
|
+
|
5
|
+
GChart exposes the Google Chart API (http://code.google.com/apis/chart) via
|
6
|
+
a friendly Ruby interface. It can generate the URL for a given chart
|
7
|
+
(for webpage use), or download the generated PNG (for offline use).
|
8
|
+
|
9
|
+
== PROBLEMS/TODO
|
10
|
+
|
11
|
+
* Add support fills (area or background), grid lines, shape markers, range markers
|
12
|
+
* Support shorthand colors and color names
|
13
|
+
* Make venn data specification friendlier
|
14
|
+
|
15
|
+
There are lots of missing features. Until they're implemented, you can directly specify
|
16
|
+
query parameters using the :extras key, e.g.,
|
17
|
+
|
18
|
+
# provides a legend for each data set
|
19
|
+
g = GChart.line(:data => [[1, 2], [3, 4]], :extras => { "chdl" => "First|Second"})
|
20
|
+
|
21
|
+
== SYNOPSIS
|
22
|
+
|
23
|
+
# line chart
|
24
|
+
g = GChart.line(:data => [0, 10, 100])
|
25
|
+
|
26
|
+
# bar chart
|
27
|
+
g = GChart.bar(:data => [100, 1000, 10000])
|
28
|
+
|
29
|
+
# pie chart (pie3d for a fancier look)
|
30
|
+
g = GChart.pie(:data => [33, 33, 34])
|
31
|
+
|
32
|
+
# venn diagram (asize, bsize, csize, ab%, bc%, ca%, abc%)
|
33
|
+
g = GChart.venn(:data => [100, 80, 60, 30, 30, 30, 10])
|
34
|
+
|
35
|
+
# scatter plot (x coords, y coords [, sizes])
|
36
|
+
g = GChart.scatter(:data => [[1, 2, 3, 4, 5], [5, 4, 3, 2, 1], [1, 2, 3, 4, 5]])
|
37
|
+
|
38
|
+
# map chart
|
39
|
+
g = GChart.map(:area => 'usa', :data => {'NY'=>1,'VA'=>3,'CA'=>2})
|
40
|
+
|
41
|
+
# meter
|
42
|
+
g = GChart.meter(:data => 70, :label => "70%")
|
43
|
+
|
44
|
+
# chart title
|
45
|
+
g = GChart.line(:title => "Awesomeness over Time", :data => [0, 10, 100])
|
46
|
+
|
47
|
+
# data set legend
|
48
|
+
g = GChart.line(:data => [[1, 2], [3, 4]], :legend => ["Monkeys", "Ferrets"])
|
49
|
+
|
50
|
+
# data set colors
|
51
|
+
g = GChart.line(:data => [[0, 10, 100], [100, 10, 0]], :colors => ["ff0000", "0000ff"])
|
52
|
+
|
53
|
+
g.to_url # generate the chart's URL, or
|
54
|
+
g.fetch # get the bytes, or
|
55
|
+
g.write("foo.png") # write to a file (defaults to "chart.png")
|
56
|
+
g.write(stream) # write to anything that quacks like IO
|
57
|
+
|
58
|
+
== LICENSE
|
59
|
+
|
60
|
+
(The MIT License)
|
61
|
+
|
62
|
+
Copyright 2007-2008 John Barnette (jbarnette@rubyforge.org)
|
63
|
+
|
64
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
65
|
+
a copy of this software and associated documentation files (the
|
66
|
+
'Software'), to deal in the Software without restriction, including
|
67
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
68
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
69
|
+
permit persons to whom the Software is furnished to do so, subject to
|
70
|
+
the following conditions:
|
71
|
+
|
72
|
+
The above copyright notice and this permission notice shall be
|
73
|
+
included in all copies or substantial portions of the Software.
|
74
|
+
|
75
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
76
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
77
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
78
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
79
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
80
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
81
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "hoe"
|
3
|
+
require "spec/rake/spectask"
|
4
|
+
|
5
|
+
require "./lib/version.rb"
|
6
|
+
|
7
|
+
hoe = Hoe.new("gchart", GChart::VERSION) do |p|
|
8
|
+
p.rubyforge_name = "gchart"
|
9
|
+
p.author = "John Barnette"
|
10
|
+
p.email = "jbarnette@rubyforge.org"
|
11
|
+
p.summary = "GChart uses the Google Chart API to create pretty pictures."
|
12
|
+
p.description = p.paragraphs_of("README.txt", 2..5).join("\n\n")
|
13
|
+
p.url = "http://gchart.rubyforge.org"
|
14
|
+
p.changes = p.paragraphs_of("CHANGELOG.txt", 0..1).join("\n\n")
|
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
|
+
desc "Run all specs and get coverage statistics"
|
24
|
+
Spec::Rake::SpecTask.new('spec:rcov') do |t|
|
25
|
+
t.spec_files = FileList["spec/**/*_spec.rb"]
|
26
|
+
t.rcov = true
|
27
|
+
t.spec_opts = ["--options", "spec/spec.opts"]
|
28
|
+
end
|
29
|
+
|
30
|
+
Rake::Task[:default].prerequisites.clear
|
31
|
+
task :default => :spec
|
data/lib/gchart.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/version")
|
2
|
+
|
3
|
+
%w(base bar line map meter pie pie_3d scatter sparkline venn xy_line).each do |type|
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + "/gchart/#{type}")
|
5
|
+
end
|
6
|
+
|
7
|
+
module GChart
|
8
|
+
URL = "http://chart.apis.google.com/chart"
|
9
|
+
SIMPLE_CHARS = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a
|
10
|
+
EXTENDED_CHARS = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + %w[- .]
|
11
|
+
EXTENDED_PAIRS = EXTENDED_CHARS.collect { |first| EXTENDED_CHARS.collect { |second| first + second } }.flatten
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# Convenience constructor for GChart::Line.
|
15
|
+
def line(*args, &block); Line.new(*args, &block) end
|
16
|
+
|
17
|
+
# Convenience constructor for GChart::XYLine.
|
18
|
+
def xyline(*args, &block); XYLine.new(*args, &block) end
|
19
|
+
|
20
|
+
# Convenience constructor for GChart::Bar.
|
21
|
+
def bar(*args, &block); Bar.new(*args, &block) end
|
22
|
+
|
23
|
+
# Convenience constructor for GChart::Map.
|
24
|
+
def map(*args, &block); Map.new(*args, &block) end
|
25
|
+
|
26
|
+
# Convenience constructor for GChart::Meter.
|
27
|
+
def meter(*args, &block); Meter.new(*args, &block) end
|
28
|
+
|
29
|
+
# Convenience constructor for GChart::Pie.
|
30
|
+
def pie(*args, &block); Pie.new(*args, &block) end
|
31
|
+
|
32
|
+
# Convenience constructor for GChart::Pie3D.
|
33
|
+
def pie3d(*args, &block); Pie3D.new(*args, &block) end
|
34
|
+
|
35
|
+
# Convenience constructor for GChart::Line.
|
36
|
+
def sparkline(*args, &block); Sparkline.new(*args, &block) end
|
37
|
+
|
38
|
+
# Convenience constructor for GChart::Venn.
|
39
|
+
def venn(*args, &block); Venn.new(*args, &block) end
|
40
|
+
|
41
|
+
# Convenience constructor for GChart::Scatter.
|
42
|
+
def scatter(*args, &block); Scatter.new(*args, &block) end
|
43
|
+
|
44
|
+
# Encode +n+ as a string. +n+ is normalized based on +max+.
|
45
|
+
# +encoding+ can currently only be :extended.
|
46
|
+
def encode(encoding, n, max)
|
47
|
+
case encoding
|
48
|
+
when :simple
|
49
|
+
return "_" if n.nil?
|
50
|
+
SIMPLE_CHARS[((n/max.to_f) * (SIMPLE_CHARS.size - 1)).round]
|
51
|
+
when :text
|
52
|
+
return "-1" if n.nil?
|
53
|
+
((((n/max.to_f) * 1000.0).round)/10.0).to_s
|
54
|
+
when :extended
|
55
|
+
return "__" if n.nil?
|
56
|
+
EXTENDED_PAIRS[max.zero? ? 0 : ((n/max.to_f) * (EXTENDED_PAIRS.size - 1)).round]
|
57
|
+
else
|
58
|
+
raise ArgumentError, "unsupported encoding: #{encoding.inspect}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/gchart/bar.rb
ADDED
@@ -0,0 +1,60 @@
|
|
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
|
+
attr_reader :thickness
|
11
|
+
attr_reader :spacing
|
12
|
+
|
13
|
+
def initialize(*args, &block)
|
14
|
+
@grouped = false
|
15
|
+
@orientation = :horizontal
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def orientation=(orientation)
|
20
|
+
unless ORIENTATIONS.include?(orientation)
|
21
|
+
raise ArgumentError, "Invalid orientation: #{orientation.inspect}. " +
|
22
|
+
"Valid orientations: #{ORIENTATIONS.inspect}"
|
23
|
+
end
|
24
|
+
|
25
|
+
@orientation = orientation
|
26
|
+
end
|
27
|
+
|
28
|
+
def horizontal?
|
29
|
+
@orientation == :horizontal
|
30
|
+
end
|
31
|
+
|
32
|
+
def vertical?
|
33
|
+
@orientation == :vertical
|
34
|
+
end
|
35
|
+
|
36
|
+
def thickness=(thickness)
|
37
|
+
raise ArgumentError, "Invalid thickness: #{thickness.inspect}" if thickness.nil? || thickness < 1
|
38
|
+
@thickness = thickness
|
39
|
+
end
|
40
|
+
|
41
|
+
def spacing=(spacing)
|
42
|
+
raise ArgumentError, "Invalid spacing: #{spacing.inspect}" if spacing.nil? || spacing < 1
|
43
|
+
@spacing = spacing
|
44
|
+
end
|
45
|
+
|
46
|
+
# overrides GChart::Base#query_params
|
47
|
+
def query_params(params={}) #:nodoc:
|
48
|
+
values = []
|
49
|
+
values << thickness if thickness
|
50
|
+
values << spacing if thickness && spacing
|
51
|
+
|
52
|
+
params["chbh"] = values.join(",") unless values.empty?
|
53
|
+
super(params)
|
54
|
+
end
|
55
|
+
|
56
|
+
def render_chart_type #:nodoc:
|
57
|
+
"b#{@orientation.to_s[0..0]}#{grouped? ? "g" : "s"}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/gchart/base.rb
ADDED
@@ -0,0 +1,133 @@
|
|
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+
|
41
|
+
# if +width+ is less than 1 or greater than 1,000.
|
42
|
+
def width=(width)
|
43
|
+
if width.nil? || width < 1 || width > 1_000
|
44
|
+
raise ArgumentError, "Invalid width: #{width.inspect}"
|
45
|
+
end
|
46
|
+
|
47
|
+
@width = width
|
48
|
+
end
|
49
|
+
|
50
|
+
# Sets the chart's height, in pixels. Raises +ArgumentError+
|
51
|
+
# if +height+ is less than 1 or greater than 1,000.
|
52
|
+
def height=(height)
|
53
|
+
if height.nil? || height < 1 || height > 1_000
|
54
|
+
raise ArgumentError, "Invalid height: #{height.inspect}"
|
55
|
+
end
|
56
|
+
|
57
|
+
@height = height
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the chart's size as "WIDTHxHEIGHT".
|
61
|
+
def size
|
62
|
+
"#{width}x#{height}"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Sets the chart's size as "WIDTHxHEIGHT". Raises +ArgumentError+
|
66
|
+
# if +width+ * +height+ is greater than 300,000 pixels.
|
67
|
+
def size=(size)
|
68
|
+
self.width, self.height = size.split("x").collect { |n| Integer(n) }
|
69
|
+
|
70
|
+
if (width * height) > 300_000
|
71
|
+
raise ArgumentError, "Invalid size: #{size.inspect} yields a graph with more than 300,000 pixels"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the chart's URL.
|
76
|
+
def to_url
|
77
|
+
query = query_params.collect { |k, v| "#{k}=#{URI.escape(v)}" }.join("&")
|
78
|
+
"#{GChart::URL}?#{query}"
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns the chart's generated PNG as a blob.
|
82
|
+
def fetch
|
83
|
+
open(to_url) { |io| io.read }
|
84
|
+
end
|
85
|
+
|
86
|
+
# Writes the chart's generated PNG to a file. If +io_or_file+ quacks like an IO,
|
87
|
+
# calls +write+ on it instead.
|
88
|
+
def write(io_or_file="chart.png")
|
89
|
+
return io_or_file.write(fetch) if io_or_file.respond_to?(:write)
|
90
|
+
open(io_or_file, "w+") { |io| io.write(fetch) }
|
91
|
+
end
|
92
|
+
|
93
|
+
protected
|
94
|
+
|
95
|
+
def query_params(raw_params={}) #:nodoc:
|
96
|
+
params = raw_params.merge("cht" => render_chart_type, "chs" => size)
|
97
|
+
|
98
|
+
render_data(params)
|
99
|
+
render_title(params)
|
100
|
+
render_colors(params)
|
101
|
+
render_legend(params)
|
102
|
+
|
103
|
+
params.merge(extras)
|
104
|
+
end
|
105
|
+
|
106
|
+
def render_chart_type #:nodoc:
|
107
|
+
raise NotImplementedError, "override in subclasses"
|
108
|
+
end
|
109
|
+
|
110
|
+
def render_data(params) #:nodoc:
|
111
|
+
raw = data && data.first.is_a?(Array) ? data : [data]
|
112
|
+
max = self.max || raw.collect { |s| s.max }.max
|
113
|
+
|
114
|
+
sets = raw.collect do |set|
|
115
|
+
set.collect { |n| GChart.encode(:extended, n, max) }.join
|
116
|
+
end
|
117
|
+
|
118
|
+
params["chd"] = "e:#{sets.join(",")}"
|
119
|
+
end
|
120
|
+
|
121
|
+
def render_title(params) #:nodoc:
|
122
|
+
params["chtt"] = title.tr("\n ", "|+") if title
|
123
|
+
end
|
124
|
+
|
125
|
+
def render_colors(params) #:nodoc:
|
126
|
+
params["chco"] = colors.join(",") if colors
|
127
|
+
end
|
128
|
+
|
129
|
+
def render_legend(params) #:nodoc:
|
130
|
+
params["chdl"] = legend.join("|") if legend
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/lib/gchart/line.rb
ADDED
data/lib/gchart/map.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
module GChart
|
2
|
+
class Map < GChart::Base
|
3
|
+
AREAS = %w[africa asia europe middle_east south_america usa world]
|
4
|
+
attr_accessor :area
|
5
|
+
attr_accessor :area_codes
|
6
|
+
attr_accessor :background
|
7
|
+
|
8
|
+
def initialize(*args, &block)
|
9
|
+
super(*args, &block)
|
10
|
+
# Set some sane defaults so that the only requirement is data
|
11
|
+
@area = 'world' #default
|
12
|
+
@background = 'dfdfff' #make it look like water
|
13
|
+
@colors = ['ffffff','f8fcf8','006c00']
|
14
|
+
#Set the maximum size for maps (this is a better default because
|
15
|
+
# it is also the proper aspect ratio)
|
16
|
+
@width = '440'
|
17
|
+
@height = '220'
|
18
|
+
end
|
19
|
+
|
20
|
+
# Map data can be in the form {"VA'=>5,'NY'=>1} or [['VA',5],['NY',1]]
|
21
|
+
# Raises +ArgumentError+ if data does not fit these forms.
|
22
|
+
def data=(data)
|
23
|
+
if data.is_a?(Array) && data.any?{ |pair| pair.size != 2 }
|
24
|
+
raise ArgumentError, "Data array must contain [area],[value] pairs"
|
25
|
+
end
|
26
|
+
# 'unzip' the data into separate arrays
|
27
|
+
area_data, values = data.to_a.transpose
|
28
|
+
|
29
|
+
# Reject malformed area codes
|
30
|
+
if area_data.any?{ |code| code !~ /^\w\w$/}
|
31
|
+
raise ArgumentError, "Area data must have exactly two characters"
|
32
|
+
end
|
33
|
+
@area_codes = area_data.join.upcase
|
34
|
+
super(values)
|
35
|
+
end
|
36
|
+
|
37
|
+
def render_chart_type #:nodoc:
|
38
|
+
"t"
|
39
|
+
end
|
40
|
+
|
41
|
+
def area=(area)
|
42
|
+
raise ArgumentError unless AREAS.include? area
|
43
|
+
@area = area
|
44
|
+
end
|
45
|
+
|
46
|
+
# overrides GChart::Base#query_params
|
47
|
+
def query_params(params={}) #:nodoc:
|
48
|
+
params["chtm"] = area unless area.empty?
|
49
|
+
params["chld"] = area_codes if area_codes
|
50
|
+
params["chf"] = "bg,s,#{@background}" if @background
|
51
|
+
super(params)
|
52
|
+
end
|
53
|
+
|
54
|
+
# overrides GChart::Base#render_data
|
55
|
+
def render_data(params)
|
56
|
+
super(params)
|
57
|
+
# Maps require at least one data point. Add a "missing value".
|
58
|
+
# It may be better to refactor the base class.
|
59
|
+
params["chd"] << '__' if params["chd"] =~ /e:$/
|
60
|
+
end
|
61
|
+
|
62
|
+
def render_title(params) #:nodoc:
|
63
|
+
nil #N/A for map
|
64
|
+
end
|
65
|
+
|
66
|
+
def render_legend(params) #:nodoc:
|
67
|
+
nil #N/A for map
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
data/lib/gchart/meter.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module GChart
|
2
|
+
class Meter < GChart::Base
|
3
|
+
attr_accessor :label
|
4
|
+
|
5
|
+
def render_chart_type #:nodoc:
|
6
|
+
"gom"
|
7
|
+
end
|
8
|
+
|
9
|
+
# The data for a meter is a single data point expressed as a percent
|
10
|
+
def render_data(params)
|
11
|
+
value = data.is_a?(Array) ? data.flatten.first : data
|
12
|
+
params["chd"] = "t:#{value.to_f}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def label=(string)
|
16
|
+
return if string.nil?
|
17
|
+
if (string.is_a?(Array) && string.size > 1) or string.include?("|")
|
18
|
+
raise ArgumentError, "Meter can only have one label"
|
19
|
+
end
|
20
|
+
@label = string.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
# Commandeer render_legend to render the label
|
24
|
+
def render_legend(params)
|
25
|
+
self.label = legend if self.label.nil? # Can use legend instead of label
|
26
|
+
params["chl"] = label if label
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/gchart/pie.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module GChart
|
2
|
+
class Pie < GChart::Base
|
3
|
+
# A single array of chart data. Raises +ArgumentError+
|
4
|
+
# if more than one data set is provided.
|
5
|
+
def data=(data)
|
6
|
+
if data.is_a?(Array) and data.first.is_a?(Array) and data.size > 1
|
7
|
+
raise ArgumentError, "Pie charts only have one data set"
|
8
|
+
end
|
9
|
+
|
10
|
+
super(data)
|
11
|
+
end
|
12
|
+
|
13
|
+
def render_chart_type #:nodoc:
|
14
|
+
"p"
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_legend(params) #:nodoc:
|
18
|
+
params["chl"] = legend.join("|") if legend
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module GChart
|
2
|
+
class Sparkline < GChart::Base
|
3
|
+
# Sparklines are essentially the same as line charts, but without
|
4
|
+
# axis lines. Because they are often placed within text, the default
|
5
|
+
# size should be smaller.
|
6
|
+
def initialize(*args, &block)
|
7
|
+
super(*args, &block)
|
8
|
+
@width = "60"
|
9
|
+
@height = "20"
|
10
|
+
end
|
11
|
+
def render_chart_type #:nodoc:
|
12
|
+
"ls"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/gchart/venn.rb
ADDED
data/lib/version.rb
ADDED
@@ -0,0 +1,80 @@
|
|
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
|
25
|
+
|
26
|
+
describe GChart::Bar, "#orientation" do
|
27
|
+
before(:each) { @chart = GChart::Bar.new }
|
28
|
+
|
29
|
+
it "complains if orientation is invalid" do
|
30
|
+
lambda { @chart.orientation = :monkey }.should raise_error(ArgumentError)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe GChart::Bar, "#thickness" do
|
35
|
+
before(:each) { @chart = GChart::Bar.new }
|
36
|
+
|
37
|
+
it "can be specified" do
|
38
|
+
@chart.thickness = 10
|
39
|
+
@chart.thickness.should == 10
|
40
|
+
end
|
41
|
+
|
42
|
+
it "complains about negative numbers" do
|
43
|
+
lambda { @chart.thickness = -1 }.should raise_error(ArgumentError)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe GChart::Bar, "#spacing" do
|
48
|
+
before(:each) { @chart = GChart::Bar.new }
|
49
|
+
|
50
|
+
it "can be specified" do
|
51
|
+
@chart.spacing = 2
|
52
|
+
@chart.spacing.should == 2
|
53
|
+
end
|
54
|
+
|
55
|
+
it "complains about negative numbers" do
|
56
|
+
lambda { @chart.spacing = -1 }.should raise_error(ArgumentError)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe GChart::Bar, "#query_params" do
|
61
|
+
before(:each) { @chart = GChart::Bar.new }
|
62
|
+
|
63
|
+
it "contains the chart's type" do
|
64
|
+
@chart.query_params["cht"].should =~ /b(h|v)(g|s)/
|
65
|
+
end
|
66
|
+
|
67
|
+
it "contains the chart's bar height" do
|
68
|
+
@chart.thickness = 10
|
69
|
+
@chart.query_params.keys.include?("chbh").should be_true
|
70
|
+
@chart.query_params["chbh"].should == "10"
|
71
|
+
@chart.spacing = 2
|
72
|
+
@chart.query_params.keys.include?("chbh").should be_true
|
73
|
+
@chart.query_params["chbh"].should == "10,2"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "it does not contain a bar height without a thickness" do
|
77
|
+
@chart.spacing = 2
|
78
|
+
@chart.query_params.keys.include?("chbh").should be_false
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,156 @@
|
|
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
|
+
|
56
|
+
it "complains about sizes that are out of bounds (300,000 pixel graph limit, 1000 pixel side limit)" do
|
57
|
+
lambda { @chart.size = "491x611" }.should raise_error(ArgumentError)
|
58
|
+
lambda { @chart.size = "1001x300" }.should raise_error(ArgumentError)
|
59
|
+
lambda { @chart.size = "300x1001" }.should raise_error(ArgumentError)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe GChart::Base, "#render_chart_type" do
|
64
|
+
it "raises; subclasses must implement" do
|
65
|
+
lambda { GChart::Base.new.render_chart_type }.should raise_error(NotImplementedError)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe GChart::Base, "#query_params" do
|
70
|
+
before(:each) do
|
71
|
+
@chart = GChart::Base.new
|
72
|
+
@chart.stub!(:render_chart_type).and_return("TEST")
|
73
|
+
end
|
74
|
+
|
75
|
+
it "contains the chart's type" do
|
76
|
+
@chart.query_params["cht"].should == "TEST"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "contains the chart's data" do
|
80
|
+
@chart.data = [[1, 2, 3], [3, 2, 1]]
|
81
|
+
@chart.query_params["chd"].should == "e:VVqq..,..qqVV"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "contains the chart's size" do
|
85
|
+
@chart.query_params["chs"].should == "300x200"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "contains the chart's title" do
|
89
|
+
@chart.title = "foo"
|
90
|
+
@chart.query_params["chtt"].should == "foo"
|
91
|
+
end
|
92
|
+
|
93
|
+
it "escapes the chart's title" do
|
94
|
+
@chart.title = "foo bar"
|
95
|
+
@chart.query_params["chtt"].should == "foo+bar"
|
96
|
+
|
97
|
+
@chart.title = "foo\nbar"
|
98
|
+
@chart.query_params["chtt"].should == "foo|bar"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "contains the chart's colors" do
|
102
|
+
@chart.colors = ["cccccc", "eeeeee"]
|
103
|
+
@chart.query_params["chco"].should == "cccccc,eeeeee"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe GChart::Base, "#to_url" do
|
108
|
+
before(:each) do
|
109
|
+
@chart = GChart::Base.new
|
110
|
+
@chart.stub!(:render_chart_type).and_return("TEST")
|
111
|
+
end
|
112
|
+
|
113
|
+
it "generates a URL that points at Google" do
|
114
|
+
@chart.to_url.should =~ %r(http://chart.apis.google.com/chart)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe GChart::Base, "#fetch" do
|
119
|
+
# THIS EXPECTATION HITS THE CLOUD! Comment it out for a faster cycle. :)
|
120
|
+
it "fetches a blob from Google" do
|
121
|
+
blob = GChart.line(:data => [1, 2]).fetch
|
122
|
+
blob.should_not be_nil
|
123
|
+
blob.should =~ /PNG/
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe GChart::Base, "#write" do
|
128
|
+
before(:each) do
|
129
|
+
@chart = GChart::Base.new
|
130
|
+
@chart.stub!(:fetch).and_return("PAYLOAD")
|
131
|
+
end
|
132
|
+
|
133
|
+
it "writes to chart.png by default" do
|
134
|
+
Dir.chdir(Dir.tmpdir) do
|
135
|
+
@chart.write
|
136
|
+
File.file?("chart.png").should == true
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
it "writes to a specified file" do
|
141
|
+
Dir.chdir(Dir.tmpdir) do
|
142
|
+
@chart.write("foo.png")
|
143
|
+
File.file?("foo.png").should == true
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it "writes to anything that quacks like IO" do
|
148
|
+
result = ""
|
149
|
+
|
150
|
+
StringIO.open(result, "w+") do |io|
|
151
|
+
@chart.write(io)
|
152
|
+
end
|
153
|
+
|
154
|
+
result.should == "PAYLOAD"
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
2
|
+
|
3
|
+
describe GChart::Map do
|
4
|
+
before(:each) { @chart = GChart::Map.new }
|
5
|
+
|
6
|
+
it "initializes to a default area of 'world'" do
|
7
|
+
@chart.area.should == 'world'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "defaults to maximum size of 440x220" do
|
11
|
+
@chart.size.should == '440x220'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "renders the correct chart type" do
|
15
|
+
@chart.render_chart_type.should == "t"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe GChart::Map, "#query_params" do
|
20
|
+
before(:each) { @chart = GChart::Map.new }
|
21
|
+
|
22
|
+
it "contains the chart's type" do
|
23
|
+
@chart.query_params["cht"].should == "t"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "contains the map's area" do
|
27
|
+
@chart.area = "usa"
|
28
|
+
@chart.query_params.keys.include?("chtm").should be_true
|
29
|
+
@chart.query_params["chtm"].should == "usa"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "defaults to a blank map" do
|
33
|
+
@chart.query_params["chd"].should =~ /^[es]:__?/
|
34
|
+
end
|
35
|
+
|
36
|
+
it "checks for a valid area" do
|
37
|
+
lambda { @chart.area = 'usa' }.should_not raise_error(ArgumentError)
|
38
|
+
lambda { @chart.area = 'mars' }.should raise_error(ArgumentError)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "makes sure the areas have one value" do
|
42
|
+
@chart.data = [['NY',1],['VA',2],['WY',3]]
|
43
|
+
@chart.area_codes.length.should == @chart.data.size * 2
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe GChart::Map, "#data" do
|
48
|
+
it "accepts data as a hash or pair of arrays" do
|
49
|
+
lambda { GChart::Map.new(:data => {"VA"=>5}) }.should_not raise_error(ArgumentError)
|
50
|
+
lambda { GChart::Map.new(:data => {"VA"=>5, "NY"=>1}) }.should_not raise_error(ArgumentError)
|
51
|
+
lambda { GChart::Map.new(:data => [["VA",5],["NY",1]]) }.should_not raise_error(ArgumentError)
|
52
|
+
lambda { GChart::Map.new(:data => [["VA","NY"],[5,1]]) }.should raise_error(ArgumentError)
|
53
|
+
lambda { GChart::Map.new(:data => [1, 2, 3]) }.should raise_error(ArgumentError)
|
54
|
+
lambda { GChart::Map.new(:data => [[1, 2, 3]]) }.should raise_error(ArgumentError)
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
2
|
+
|
3
|
+
describe GChart::Meter do
|
4
|
+
it "renders the correct chart type" do
|
5
|
+
GChart::Meter.new.render_chart_type.should == "gom"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe GChart::Meter, "#query_params" do
|
10
|
+
before(:each) do
|
11
|
+
@meter = GChart::Meter.new
|
12
|
+
@meter.data = 50
|
13
|
+
end
|
14
|
+
it "encodes the data correctly" do
|
15
|
+
for data in [70, 70.0, "70", "70.0", "70%"] do
|
16
|
+
@meter.data = data
|
17
|
+
@meter.query_params["chd"].should == "t:70.0"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
it "allows a label" do
|
21
|
+
@meter.label = "Label"
|
22
|
+
@meter.query_params.keys.include?("chl").should be_true
|
23
|
+
@meter.query_params["chl"].should == "Label"
|
24
|
+
end
|
25
|
+
it "allows a legend" do
|
26
|
+
@meter.legend = "Legend"
|
27
|
+
@meter.query_params.keys.include?("chl").should be_true
|
28
|
+
@meter.query_params["chl"].should == "Legend"
|
29
|
+
end
|
30
|
+
it "makes label take precedence over legend" do
|
31
|
+
@meter.legend = "Legend"
|
32
|
+
@meter.label = "Label"
|
33
|
+
@meter.query_params.keys.include?("chl").should be_true
|
34
|
+
@meter.query_params["chl"].should == "Label"
|
35
|
+
end
|
36
|
+
it "complains about more than one label" do
|
37
|
+
lambda { @meter.label = "set1" }.should_not raise_error(ArgumentError)
|
38
|
+
lambda { @meter.label = ["set1"] }.should_not raise_error(ArgumentError)
|
39
|
+
lambda { @meter.label = "set1|set2" }.should raise_error(ArgumentError)
|
40
|
+
lambda { @meter.label = ['set1','set2'] }.should raise_error(ArgumentError)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe GChart::Map, "#render_data" do
|
45
|
+
it "allows only one data point" do
|
46
|
+
lambda { @meter.data = "set1" }.should_not raise_error(ArgumentError)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
2
|
+
|
3
|
+
describe GChart::Pie do
|
4
|
+
it "renders the correct chart type" do
|
5
|
+
GChart::Pie.new.render_chart_type.should == "p"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe GChart::Pie, "#query_params" do
|
10
|
+
before(:each) { @chart = GChart::Pie.new }
|
11
|
+
|
12
|
+
it "contains the chart's type" do
|
13
|
+
@chart.query_params["cht"].should == "p"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "contains the chart's legend" do
|
17
|
+
@chart.legend = ["foo"]
|
18
|
+
@chart.query_params.keys.include?("chl").should be_true
|
19
|
+
@chart.query_params["chl"].should == "foo"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe GChart::Pie, "#data" do
|
24
|
+
it "complains if you provide more than one set of data" do
|
25
|
+
lambda { GChart::Pie.new(:data => [1, 2, 3]) }.should_not raise_error(ArgumentError)
|
26
|
+
lambda { GChart::Pie.new(:data => [[1, 2, 3]]) }.should_not raise_error(ArgumentError)
|
27
|
+
lambda { GChart::Pie.new(:data => [[1, 2, 3], [3, 2, 1]]) }.should raise_error(ArgumentError)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
2
|
+
|
3
|
+
describe GChart::Sparkline do
|
4
|
+
it "renders the correct chart type" do
|
5
|
+
GChart::Sparkline.new.render_chart_type.should == "ls"
|
6
|
+
end
|
7
|
+
|
8
|
+
it "defaults to 60x20" do
|
9
|
+
GChart::Sparkline.new.size.should == "60x20"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
data/spec/gchart_spec.rb
ADDED
@@ -0,0 +1,69 @@
|
|
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 "supports the simple, text, and extended encoding" do
|
11
|
+
lambda { GChart.encode(:simple, 4, 10) }.should_not raise_error(ArgumentError)
|
12
|
+
lambda { GChart.encode(:text, 4, 10) }.should_not raise_error(ArgumentError)
|
13
|
+
lambda { GChart.encode(:extended, 4, 10) }.should_not raise_error(ArgumentError)
|
14
|
+
lambda { GChart.encode(:monkey, 4, 10) }.should raise_error(ArgumentError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "implements the simple encoding" do
|
18
|
+
expected = {
|
19
|
+
0 => "A", 19 => "T", 27 => "b", 53 => "1", 61 => "9",
|
20
|
+
12 => "M", 39 => "n", 57 => "5", 45 => "t", 51 => "z"
|
21
|
+
}
|
22
|
+
|
23
|
+
expected.each do |original, encoded|
|
24
|
+
GChart.encode(:simple, original, 61).should == encoded
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "implements the text encoding" do
|
29
|
+
expected = {
|
30
|
+
0 => "0.0", 10 => "10.0", 58 => "58.0", 95 => "95.0", 30 => "30.0", 8 => "8.0", 63 => "63.0", 100 => "100.0"
|
31
|
+
}
|
32
|
+
|
33
|
+
expected.each do |original, encoded|
|
34
|
+
GChart.encode(:text, original, 100).should == encoded
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "implements the extended encoding" do
|
39
|
+
expected = {
|
40
|
+
0 => "AA", 25 => "AZ", 26 => "Aa", 51 => "Az", 52 => "A0", 61 => "A9", 62 => "A-", 63 => "A.",
|
41
|
+
64 => "BA", 89 => "BZ", 90 => "Ba", 115 => "Bz", 116 => "B0", 125 => "B9", 126 => "B-", 127 => "B.",
|
42
|
+
4032 => ".A", 4057 => ".Z", 4058 => ".a", 4083 => ".z", 4084 => ".0", 4093 => ".9", 4094 => ".-", 4095 => ".."
|
43
|
+
}
|
44
|
+
|
45
|
+
expected.each do |original, encoded|
|
46
|
+
GChart.encode(:extended, original, 4095).should == encoded
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it "encodes nil correctly" do
|
51
|
+
GChart.encode(:simple, nil, 1).should == "_"
|
52
|
+
GChart.encode(:text, nil, 1).should == "-1"
|
53
|
+
GChart.encode(:extended, nil, 1).should == "__"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "encodes 0 with a max of 0 correctly" do
|
57
|
+
GChart.encode(:extended, 0, 0).should == "AA"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe GChart, ".line" do
|
62
|
+
it "can render a basic line URL" do
|
63
|
+
expected = { "cht" => "lc", "chs" => "300x200", "chd" => "e:AAAp..", "chtt" => "test" }
|
64
|
+
chart = GChart.line(:title => "test", :data => [1, 100, 10000])
|
65
|
+
|
66
|
+
chart.query_params.should == expected
|
67
|
+
chart.to_url.should == "http://chart.apis.google.com/chart?chs=300x200&cht=lc&chtt=test&chd=e:AAAp.."
|
68
|
+
end
|
69
|
+
end
|
data/spec/helper.rb
ADDED
data/spec/spec.opts
ADDED
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: texel-gchart
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Barnette
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-06-03 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.5.3
|
23
|
+
version:
|
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
|
+
email: jbarnette@rubyforge.org
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- CHANGELOG.txt
|
32
|
+
- Manifest.txt
|
33
|
+
- README.txt
|
34
|
+
files:
|
35
|
+
- CHANGELOG.txt
|
36
|
+
- Manifest.txt
|
37
|
+
- README.txt
|
38
|
+
- Rakefile
|
39
|
+
- lib/gchart.rb
|
40
|
+
- lib/gchart/bar.rb
|
41
|
+
- lib/gchart/base.rb
|
42
|
+
- lib/gchart/line.rb
|
43
|
+
- lib/gchart/map.rb
|
44
|
+
- lib/gchart/meter.rb
|
45
|
+
- lib/gchart/pie.rb
|
46
|
+
- lib/gchart/pie_3d.rb
|
47
|
+
- lib/gchart/scatter.rb
|
48
|
+
- lib/gchart/sparkline.rb
|
49
|
+
- lib/gchart/venn.rb
|
50
|
+
- lib/gchart/xy_line.rb
|
51
|
+
- lib/version.rb
|
52
|
+
- spec/gchart/bar_spec.rb
|
53
|
+
- spec/gchart/base_spec.rb
|
54
|
+
- spec/gchart/line_spec.rb
|
55
|
+
- spec/gchart/map_spec.rb
|
56
|
+
- spec/gchart/meter_spec.rb
|
57
|
+
- spec/gchart/pie_3d_spec.rb
|
58
|
+
- spec/gchart/pie_spec.rb
|
59
|
+
- spec/gchart/scatter_spec.rb
|
60
|
+
- spec/gchart/sparkline_spec.rb
|
61
|
+
- spec/gchart/venn_spec.rb
|
62
|
+
- spec/gchart/xy_line_spec.rb
|
63
|
+
- spec/gchart_spec.rb
|
64
|
+
- spec/helper.rb
|
65
|
+
- spec/spec.opts
|
66
|
+
has_rdoc: true
|
67
|
+
homepage: http://gchart.rubyforge.org
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options:
|
70
|
+
- --main
|
71
|
+
- README.txt
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
version:
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project: gchart
|
89
|
+
rubygems_version: 1.0.1
|
90
|
+
signing_key:
|
91
|
+
specification_version: 2
|
92
|
+
summary: GChart uses the Google Chart API to create pretty pictures.
|
93
|
+
test_files: []
|
94
|
+
|