texel-gchart 0.5.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 +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
|
+
|