gruff 0.2.6 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/Manifest.txt +33 -13
- data/Rakefile +18 -210
- data/assets/city_scene/background/0000.png +0 -0
- data/assets/city_scene/background/0600.png +0 -0
- data/assets/city_scene/background/2000.png +0 -0
- data/assets/city_scene/clouds/cloudy.png +0 -0
- data/assets/city_scene/clouds/partly_cloudy.png +0 -0
- data/assets/city_scene/clouds/stormy.png +0 -0
- data/assets/city_scene/grass/default.png +0 -0
- data/assets/city_scene/haze/true.png +0 -0
- data/assets/city_scene/number_sample/1.png +0 -0
- data/assets/city_scene/number_sample/2.png +0 -0
- data/assets/city_scene/number_sample/default.png +0 -0
- data/assets/city_scene/sky/0000.png +0 -0
- data/assets/city_scene/sky/0200.png +0 -0
- data/assets/city_scene/sky/0400.png +0 -0
- data/assets/city_scene/sky/0600.png +0 -0
- data/assets/city_scene/sky/0800.png +0 -0
- data/assets/city_scene/sky/1000.png +0 -0
- data/assets/city_scene/sky/1200.png +0 -0
- data/assets/city_scene/sky/1400.png +0 -0
- data/assets/city_scene/sky/1500.png +0 -0
- data/assets/city_scene/sky/1700.png +0 -0
- data/assets/city_scene/sky/2000.png +0 -0
- data/assets/pc306715.jpg +0 -0
- data/lib/gruff/base.rb +50 -13
- data/lib/gruff/mini/pie.rb +6 -2
- data/lib/gruff/mini/side_bar.rb +5 -6
- data/lib/gruff/pie.rb +12 -3
- data/lib/gruff/side_bar.rb +48 -42
- data/lib/gruff/side_stacked_bar.rb +1 -0
- data/test/test_bar.rb +13 -1
- data/test/test_mini_side_bar.rb +28 -2
- data/test/test_side_bar.rb +12 -0
- metadata +35 -11
data/CHANGELOG
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
|
3
|
+
== 0.2.7
|
4
|
+
|
5
|
+
* Regenerated Manifest.txt
|
6
|
+
* Added scene sample to package
|
7
|
+
* Added mini side_bar (EXPERIMENTAL)
|
8
|
+
* Added @zero_degree option to Gruff::Pie so first slice can start somewhere other than 3 o'clock
|
9
|
+
* Increased size of numbers in Gruff::Mini::Pie
|
10
|
+
* Added legend_box_size accessor
|
11
|
+
|
3
12
|
== 0.2.6
|
4
13
|
|
5
14
|
* Fixed missing side_bar.rb in Manifest.txt
|
data/Manifest.txt
CHANGED
@@ -1,9 +1,31 @@
|
|
1
1
|
CHANGELOG
|
2
|
-
|
2
|
+
Manifest.txt
|
3
3
|
MIT-LICENSE
|
4
4
|
Rakefile
|
5
|
-
|
6
|
-
|
5
|
+
README.txt
|
6
|
+
assets/pc306715.jpg
|
7
|
+
assets/city_scene/background/0000.png
|
8
|
+
assets/city_scene/background/0600.png
|
9
|
+
assets/city_scene/background/2000.png
|
10
|
+
assets/city_scene/clouds/cloudy.png
|
11
|
+
assets/city_scene/clouds/partly_cloudy.png
|
12
|
+
assets/city_scene/clouds/stormy.png
|
13
|
+
assets/city_scene/grass/default.png
|
14
|
+
assets/city_scene/haze/true.png
|
15
|
+
assets/city_scene/number_sample/1.png
|
16
|
+
assets/city_scene/number_sample/2.png
|
17
|
+
assets/city_scene/number_sample/default.png
|
18
|
+
assets/city_scene/sky/0000.png
|
19
|
+
assets/city_scene/sky/0200.png
|
20
|
+
assets/city_scene/sky/0400.png
|
21
|
+
assets/city_scene/sky/0600.png
|
22
|
+
assets/city_scene/sky/0800.png
|
23
|
+
assets/city_scene/sky/1000.png
|
24
|
+
assets/city_scene/sky/1200.png
|
25
|
+
assets/city_scene/sky/1400.png
|
26
|
+
assets/city_scene/sky/1500.png
|
27
|
+
assets/city_scene/sky/1700.png
|
28
|
+
assets/city_scene/sky/2000.png
|
7
29
|
lib/gruff.rb
|
8
30
|
lib/gruff/area.rb
|
9
31
|
lib/gruff/bar.rb
|
@@ -15,31 +37,29 @@ lib/gruff/net.rb
|
|
15
37
|
lib/gruff/photo_bar.rb
|
16
38
|
lib/gruff/pie.rb
|
17
39
|
lib/gruff/scene.rb
|
40
|
+
lib/gruff/side_bar.rb
|
18
41
|
lib/gruff/side_stacked_bar.rb
|
19
42
|
lib/gruff/spider.rb
|
20
43
|
lib/gruff/stacked_bar.rb
|
21
|
-
lib/gruff/side_bar.rb
|
22
|
-
|
23
44
|
lib/gruff/mini/bar.rb
|
45
|
+
lib/gruff/mini/legend.rb
|
24
46
|
lib/gruff/mini/pie.rb
|
25
47
|
lib/gruff/mini/side_bar.rb
|
26
|
-
|
27
|
-
|
48
|
+
test/gruff_test_case.rb
|
49
|
+
test/output
|
28
50
|
test/test_area.rb
|
29
51
|
test/test_bar.rb
|
30
52
|
test/test_base.rb
|
31
|
-
test/gruff_test_case.rb
|
32
53
|
test/test_legend.rb
|
33
54
|
test/test_line.rb
|
55
|
+
test/test_mini_bar.rb
|
56
|
+
test/test_mini_pie.rb
|
57
|
+
test/test_mini_side_bar.rb
|
34
58
|
test/test_net.rb
|
35
|
-
test/output
|
36
59
|
test/test_photo.rb
|
37
60
|
test/test_pie.rb
|
38
61
|
test/test_scene.rb
|
62
|
+
test/test_side_bar.rb
|
39
63
|
test/test_sidestacked_bar.rb
|
40
64
|
test/test_spider.rb
|
41
65
|
test/test_stacked_bar.rb
|
42
|
-
|
43
|
-
test/test_mini_bar.rb
|
44
|
-
test/test_mini_pie.rb
|
45
|
-
test/test_mini_side_bar.rb
|
data/Rakefile
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require 'rubygems'
|
3
2
|
require 'hoe'
|
4
3
|
$:.unshift(File.dirname(__FILE__) + "/lib")
|
@@ -12,216 +11,25 @@ Hoe.new('Gruff', Gruff::VERSION) do |p|
|
|
12
11
|
p.summary = "Beautiful graphs for one or multiple datasets."
|
13
12
|
p.url = "http://nubyonrails.com/pages/gruff"
|
14
13
|
p.clean_globs = ['test/output/*.png']
|
14
|
+
end
|
15
15
|
|
16
|
-
|
16
|
+
desc "Simple test on packaged files to make sure they are all there"
|
17
|
+
task :verify => :package do
|
18
|
+
# An error message will be displayed if files are missing
|
19
|
+
if system %(ruby -e "require 'pkg/gruff-#{Gruff::VERSION}/lib/gruff'")
|
20
|
+
puts "\nThe library files are present"
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
24
|
+
##
|
25
|
+
# Catch unmatched tasks and run them as a unit test.
|
26
|
+
#
|
27
|
+
# Makes it possible to do
|
28
|
+
#
|
29
|
+
# rake pie
|
30
|
+
#
|
31
|
+
# To run the +test/test_pie+ file.
|
19
32
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# require 'rake/packagetask'
|
24
|
-
# require 'rake/gempackagetask'
|
25
|
-
# require 'rake/contrib/rubyforgepublisher'
|
26
|
-
#
|
27
|
-
# $:.unshift(File.dirname(__FILE__) + "/lib")
|
28
|
-
# require 'gruff'
|
29
|
-
#
|
30
|
-
# PKG_NAME = 'gruff'
|
31
|
-
# PKG_VERSION = Gruff::VERSION
|
32
|
-
# PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
33
|
-
#
|
34
|
-
# RELEASE_NAME = "REL #{PKG_VERSION}"
|
35
|
-
#
|
36
|
-
# RUBY_FORGE_PROJECT = "gruff"
|
37
|
-
# RUBY_FORGE_USER = "topfunky"
|
38
|
-
#
|
39
|
-
# desc "Default Task"
|
40
|
-
# task :default => [ :clean, :test ]
|
41
|
-
#
|
42
|
-
# desc "Clean images generated by tests"
|
43
|
-
# task :clean do
|
44
|
-
# rm FileList['test/output/*.png']
|
45
|
-
# rm_rf 'pkg'
|
46
|
-
# rm_rf 'doc'
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# desc "Copy documentation to topfunky.com"
|
50
|
-
# task :rdoc_deploy => [:rdoc] do
|
51
|
-
# dirs = %w{doc}
|
52
|
-
# onserver = "topfunky@topfunky.com:/home/topfunky/topfunky.com/clients/rails/gruff"
|
53
|
-
# dirs.each do | dir|
|
54
|
-
# `rsync -avz -e ssh "#{`pwd`.chomp}/#{dir}" "#{onserver}" --exclude ".svn"`
|
55
|
-
# end
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
# # Run the unit tests
|
59
|
-
# Rake::TestTask.new { |t|
|
60
|
-
# t.libs << "test"
|
61
|
-
# t.pattern = 'test/*_test.rb'
|
62
|
-
# t.verbose = true
|
63
|
-
# }
|
64
|
-
#
|
65
|
-
# # Genereate the RDoc documentation
|
66
|
-
# Rake::RDocTask.new { |rdoc|
|
67
|
-
# rdoc.rdoc_dir = 'doc'
|
68
|
-
# rdoc.title = "Gruff -- Beautiful graphs"
|
69
|
-
# # rdoc.options << '--line-numbers --inline-source --main README --accessor adv_attr_accessor=M'
|
70
|
-
# rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
71
|
-
# rdoc.rdoc_files.include('README', 'CHANGELOG')
|
72
|
-
# rdoc.rdoc_files.include('lib/gruff.rb')
|
73
|
-
# rdoc.rdoc_files.include('lib/gruff/*.rb')
|
74
|
-
# }
|
75
|
-
#
|
76
|
-
#
|
77
|
-
# # Create compressed packages
|
78
|
-
# spec = Gem::Specification.new do |s|
|
79
|
-
# s.platform = Gem::Platform::RUBY
|
80
|
-
# s.name = PKG_NAME
|
81
|
-
# s.summary = "Beautiful graphs for one or multiple datasets."
|
82
|
-
# s.description = %q{Make colorful graphs for use on websites or documents.}
|
83
|
-
# s.version = PKG_VERSION
|
84
|
-
#
|
85
|
-
# s.author = "Geoffrey Grosenbach"
|
86
|
-
# s.email = "boss@topfunky.com"
|
87
|
-
# s.rubyforge_project = RUBY_FORGE_PROJECT
|
88
|
-
# s.homepage = "http://www.topfunky.com"
|
89
|
-
#
|
90
|
-
# s.has_rdoc = true
|
91
|
-
# s.requirements << 'none'
|
92
|
-
# s.require_path = 'lib'
|
93
|
-
# s.autorequire = 'gruff'
|
94
|
-
#
|
95
|
-
# s.files = [ "Rakefile", "README", "CHANGELOG", "MIT-LICENSE" ]
|
96
|
-
# s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
97
|
-
# s.files = s.files + Dir.glob( "assets/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
98
|
-
# s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "\.svn" ) || item.include?("\.png") }
|
99
|
-
# end
|
100
|
-
#
|
101
|
-
# Rake::GemPackageTask.new(spec) do |p|
|
102
|
-
# p.gem_spec = spec
|
103
|
-
# p.need_tar = true
|
104
|
-
# p.need_zip = true
|
105
|
-
# end
|
106
|
-
#
|
107
|
-
# desc "Publish the API documentation"
|
108
|
-
# task :pgem => [:package] do
|
109
|
-
# Rake::SshFilePublisher.new("boss@topfunky.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
|
110
|
-
# end
|
111
|
-
#
|
112
|
-
# desc "Publish the release files to RubyForge."
|
113
|
-
# task :release => [:package] do
|
114
|
-
# files = ["gem", "tgz", "zip"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
|
115
|
-
#
|
116
|
-
# if RUBY_FORGE_PROJECT then
|
117
|
-
# require 'net/http'
|
118
|
-
# require 'open-uri'
|
119
|
-
#
|
120
|
-
# project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
|
121
|
-
# project_data = open(project_uri) { |data| data.read }
|
122
|
-
# group_id = project_data[/[?&]group_id=(\d+)/, 1]
|
123
|
-
# raise "Couldn't get group id" unless group_id
|
124
|
-
#
|
125
|
-
# # This echos password to shell which is a bit sucky
|
126
|
-
# if ENV["RUBY_FORGE_PASSWORD"]
|
127
|
-
# password = ENV["RUBY_FORGE_PASSWORD"]
|
128
|
-
# else
|
129
|
-
# print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
|
130
|
-
# password = STDIN.gets.chomp
|
131
|
-
# end
|
132
|
-
#
|
133
|
-
# login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
|
134
|
-
# data = [
|
135
|
-
# "login=1",
|
136
|
-
# "form_loginname=#{RUBY_FORGE_USER}",
|
137
|
-
# "form_pw=#{password}"
|
138
|
-
# ].join("&")
|
139
|
-
# http.post("/account/login.php", data)
|
140
|
-
# end
|
141
|
-
#
|
142
|
-
# cookie = login_response["set-cookie"]
|
143
|
-
# raise "Login failed" unless cookie
|
144
|
-
# headers = { "Cookie" => cookie }
|
145
|
-
#
|
146
|
-
# release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
|
147
|
-
# release_data = open(release_uri, headers) { |data| data.read }
|
148
|
-
# package_id = release_data[/[?&]package_id=(\d+)/, 1]
|
149
|
-
# raise "Couldn't get package id" unless package_id
|
150
|
-
#
|
151
|
-
# first_file = true
|
152
|
-
# release_id = ""
|
153
|
-
#
|
154
|
-
# files.each do |filename|
|
155
|
-
# basename = File.basename(filename)
|
156
|
-
# file_ext = File.extname(filename)
|
157
|
-
# file_data = File.open(filename, "rb") { |file| file.read }
|
158
|
-
#
|
159
|
-
# puts "Releasing #{basename}..."
|
160
|
-
#
|
161
|
-
# release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
|
162
|
-
# release_date = Time.now.strftime("%Y-%m-%d %H:%M")
|
163
|
-
# type_map = {
|
164
|
-
# ".zip" => "3000",
|
165
|
-
# ".tgz" => "3110",
|
166
|
-
# ".gz" => "3110",
|
167
|
-
# ".gem" => "1400"
|
168
|
-
# }; type_map.default = "9999"
|
169
|
-
# type = type_map[file_ext]
|
170
|
-
# boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
|
171
|
-
#
|
172
|
-
# query_hash = if first_file then
|
173
|
-
# {
|
174
|
-
# "group_id" => group_id,
|
175
|
-
# "package_id" => package_id,
|
176
|
-
# "release_name" => RELEASE_NAME,
|
177
|
-
# "release_date" => release_date,
|
178
|
-
# "type_id" => type,
|
179
|
-
# "processor_id" => "8000", # Any
|
180
|
-
# "release_notes" => "",
|
181
|
-
# "release_changes" => "",
|
182
|
-
# "preformatted" => "1",
|
183
|
-
# "submit" => "1"
|
184
|
-
# }
|
185
|
-
# else
|
186
|
-
# {
|
187
|
-
# "group_id" => group_id,
|
188
|
-
# "release_id" => release_id,
|
189
|
-
# "package_id" => package_id,
|
190
|
-
# "step2" => "1",
|
191
|
-
# "type_id" => type,
|
192
|
-
# "processor_id" => "8000", # Any
|
193
|
-
# "submit" => "Add This File"
|
194
|
-
# }
|
195
|
-
# end
|
196
|
-
#
|
197
|
-
# query = "?" + query_hash.map do |(name, value)|
|
198
|
-
# [name, URI.encode(value)].join("=")
|
199
|
-
# end.join("&")
|
200
|
-
#
|
201
|
-
# data = [
|
202
|
-
# "--" + boundary,
|
203
|
-
# "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
|
204
|
-
# "Content-Type: application/octet-stream",
|
205
|
-
# "Content-Transfer-Encoding: binary",
|
206
|
-
# "", file_data, ""
|
207
|
-
# ].join("\x0D\x0A")
|
208
|
-
#
|
209
|
-
# release_headers = headers.merge(
|
210
|
-
# "Content-Type" => "multipart/form-data; boundary=#{boundary}"
|
211
|
-
# )
|
212
|
-
#
|
213
|
-
# target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
|
214
|
-
# http.post(target + query, data, release_headers)
|
215
|
-
# end
|
216
|
-
#
|
217
|
-
# if first_file then
|
218
|
-
# release_id = release_response.body[/release_id=(\d+)/, 1]
|
219
|
-
# raise("Couldn't get release id") unless release_id
|
220
|
-
# end
|
221
|
-
#
|
222
|
-
# first_file = false
|
223
|
-
# end
|
224
|
-
# end
|
225
|
-
# end
|
226
|
-
#
|
227
|
-
#
|
33
|
+
rule '' do |t|
|
34
|
+
system "ruby test/test_#{t.name}.rb"
|
35
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/assets/pc306715.jpg
ADDED
Binary file
|
data/lib/gruff/base.rb
CHANGED
@@ -20,7 +20,7 @@ require File.dirname(__FILE__) + '/deprecated'
|
|
20
20
|
|
21
21
|
module Gruff
|
22
22
|
|
23
|
-
VERSION = '0.2.
|
23
|
+
VERSION = '0.2.7'
|
24
24
|
|
25
25
|
class Base
|
26
26
|
|
@@ -124,6 +124,12 @@ module Gruff
|
|
124
124
|
# Experimental
|
125
125
|
attr_accessor :stacked
|
126
126
|
|
127
|
+
|
128
|
+
# Optionally set the size of the colored box by each item in the legend. Default is 20.0
|
129
|
+
#
|
130
|
+
# Will be scaled down if graph is smaller than 800px wide.
|
131
|
+
attr_accessor :legend_box_size
|
132
|
+
|
127
133
|
|
128
134
|
# If one numerical argument is given, the graph is drawn at 4/3 ratio according to the given width (800 results in 800x600, 400 gives 400x300, etc.).
|
129
135
|
#
|
@@ -141,6 +147,21 @@ module Gruff
|
|
141
147
|
@rows = target_width.to_f * 0.75
|
142
148
|
end
|
143
149
|
|
150
|
+
initialize_ivars
|
151
|
+
|
152
|
+
reset_themes
|
153
|
+
theme_keynote
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
# Set instance variables for this object.
|
158
|
+
#
|
159
|
+
# Subclasses can override this, call super, then set values separately.
|
160
|
+
#
|
161
|
+
# This makes it possible to set defaults in a subclass but still allow
|
162
|
+
# developers to change this values in their program.
|
163
|
+
|
164
|
+
def initialize_ivars
|
144
165
|
# Internal for calculations
|
145
166
|
@raw_columns = 800.0
|
146
167
|
@raw_rows = 800.0 * (@rows/@columns)
|
@@ -162,6 +183,8 @@ module Gruff
|
|
162
183
|
@marker_font_size = 21.0
|
163
184
|
@legend_font_size = 20.0
|
164
185
|
@title_font_size = 36.0
|
186
|
+
|
187
|
+
@legend_box_size = 20.0
|
165
188
|
|
166
189
|
@no_data_message = "No Data"
|
167
190
|
|
@@ -177,9 +200,6 @@ module Gruff
|
|
177
200
|
@y_axis_increment = nil
|
178
201
|
@stacked = nil
|
179
202
|
@norm_data = nil
|
180
|
-
|
181
|
-
reset_themes()
|
182
|
-
theme_keynote()
|
183
203
|
end
|
184
204
|
|
185
205
|
def font=(font_path)
|
@@ -380,7 +400,7 @@ protected
|
|
380
400
|
# Subclasses should start by calling super() for this method.
|
381
401
|
def draw
|
382
402
|
make_stacked if @stacked
|
383
|
-
setup_drawing
|
403
|
+
setup_drawing
|
384
404
|
|
385
405
|
debug {
|
386
406
|
# Outer margin
|
@@ -391,10 +411,13 @@ protected
|
|
391
411
|
}
|
392
412
|
end
|
393
413
|
|
394
|
-
|
395
|
-
#
|
396
|
-
#
|
397
|
-
#
|
414
|
+
##
|
415
|
+
# Calculates size of drawable area and draws the decorations.
|
416
|
+
#
|
417
|
+
# * line markers
|
418
|
+
# * legend
|
419
|
+
# * title
|
420
|
+
|
398
421
|
def setup_drawing
|
399
422
|
# Maybe should be done in one of the following functions for more granularity.
|
400
423
|
unless @has_data
|
@@ -439,6 +462,9 @@ protected
|
|
439
462
|
@spread = @spread > 0 ? @spread : 1
|
440
463
|
end
|
441
464
|
|
465
|
+
##
|
466
|
+
# Calculates size of drawable area, general font dimensions, etc.
|
467
|
+
|
442
468
|
def setup_graph_measurements
|
443
469
|
@marker_caps_height = calculate_caps_height(@marker_font_size)
|
444
470
|
@title_caps_height = calculate_caps_height(@title_font_size)
|
@@ -449,10 +475,19 @@ protected
|
|
449
475
|
@graph_right_margin,
|
450
476
|
@graph_bottom_margin) = [LEFT_MARGIN, RIGHT_MARGIN, BOTTOM_MARGIN]
|
451
477
|
else
|
478
|
+
longest_left_label_width = 0
|
479
|
+
if @has_left_labels
|
480
|
+
longest_left_label_width = calculate_width(@marker_font_size,
|
481
|
+
labels.values.inject('') { |value, memo| (value.to_s.length > memo.to_s.length) ? value : memo }) * 1.25
|
482
|
+
else
|
483
|
+
longest_left_label_width = calculate_width(@marker_font_size,
|
484
|
+
label(@maximum_value.to_f))
|
485
|
+
end
|
486
|
+
|
452
487
|
# Shift graph if left line numbers are hidden
|
453
|
-
line_number_width = @hide_line_numbers ?
|
488
|
+
line_number_width = @hide_line_numbers && !@has_left_labels ?
|
454
489
|
0.0 :
|
455
|
-
(
|
490
|
+
(longest_left_label_width + LABEL_MARGIN * 2)
|
456
491
|
|
457
492
|
@graph_left = LEFT_MARGIN +
|
458
493
|
line_number_width +
|
@@ -607,8 +642,7 @@ protected
|
|
607
642
|
|
608
643
|
@legend_labels = @data.collect {|item| item[DATA_LABEL_INDEX] }
|
609
644
|
|
610
|
-
legend_square_width =
|
611
|
-
legend_square_margin = 4
|
645
|
+
legend_square_width = @legend_box_size # small square with color of this item
|
612
646
|
|
613
647
|
# May fix legend drawing problem at small sizes
|
614
648
|
@d.font = @font if @font
|
@@ -886,6 +920,9 @@ private
|
|
886
920
|
end
|
887
921
|
end
|
888
922
|
|
923
|
+
##
|
924
|
+
# Return a formatted string representing a number value that should be printed as a label.
|
925
|
+
|
889
926
|
def label(value)
|
890
927
|
if (@spread.to_f % @marker_count.to_f == 0) || !@y_axis_increment.nil?
|
891
928
|
return value.to_i.to_s
|
data/lib/gruff/mini/pie.rb
CHANGED
@@ -9,14 +9,18 @@ module Gruff
|
|
9
9
|
|
10
10
|
include Gruff::Mini::Legend
|
11
11
|
|
12
|
-
def
|
12
|
+
def initialize_ivars
|
13
|
+
super
|
14
|
+
|
13
15
|
@hide_legend = true
|
14
16
|
@hide_title = true
|
15
17
|
@hide_line_numbers = true
|
16
18
|
|
17
|
-
@marker_font_size =
|
19
|
+
@marker_font_size = 60.0
|
18
20
|
@legend_font_size = 60.0
|
21
|
+
end
|
19
22
|
|
23
|
+
def draw
|
20
24
|
expand_canvas_for_vertical_legend
|
21
25
|
|
22
26
|
super
|
data/lib/gruff/mini/side_bar.rb
CHANGED
@@ -5,18 +5,17 @@
|
|
5
5
|
module Gruff
|
6
6
|
module Mini
|
7
7
|
|
8
|
-
class SideBar < Gruff::
|
8
|
+
class SideBar < Gruff::SideBar
|
9
9
|
|
10
|
-
def
|
10
|
+
def initialize_ivars
|
11
|
+
super
|
11
12
|
@hide_legend = true
|
12
13
|
@hide_title = true
|
13
14
|
@hide_line_numbers = true
|
14
|
-
|
15
|
+
|
15
16
|
@marker_font_size = 40.0
|
16
|
-
super
|
17
|
-
|
18
17
|
end
|
19
|
-
|
18
|
+
|
20
19
|
end
|
21
20
|
|
22
21
|
end
|
data/lib/gruff/pie.rb
CHANGED
@@ -5,6 +5,15 @@ class Gruff::Pie < Gruff::Base
|
|
5
5
|
|
6
6
|
TEXT_OFFSET_PERCENTAGE = 0.15
|
7
7
|
|
8
|
+
# Can be used to make the pie start cutting slices at the top (-90.0)
|
9
|
+
# or at another angle. Default is 0.0, which starts at 3 o'clock.
|
10
|
+
attr_accessor :zero_degree
|
11
|
+
|
12
|
+
def initialize_ivars
|
13
|
+
super
|
14
|
+
@zero_degree = 0.0
|
15
|
+
end
|
16
|
+
|
8
17
|
def draw
|
9
18
|
@hide_line_markers = true
|
10
19
|
|
@@ -18,7 +27,7 @@ class Gruff::Pie < Gruff::Base
|
|
18
27
|
center_x = @graph_left + (@graph_width / 2.0)
|
19
28
|
center_y = @graph_top + (@graph_height / 2.0) - 10 # Move graph up a bit
|
20
29
|
total_sum = sums_for_pie()
|
21
|
-
prev_degrees =
|
30
|
+
prev_degrees = @zero_degree
|
22
31
|
|
23
32
|
# Use full data since we can easily calculate percentages
|
24
33
|
@data.sort{ |a, b| a[DATA_VALUES_INDEX][0] <=> b[DATA_VALUES_INDEX][0] }.each do |data_row|
|
@@ -61,11 +70,11 @@ private
|
|
61
70
|
# labels on the left and right.
|
62
71
|
def draw_label(center_x, center_y, angle, radius, amount)
|
63
72
|
# TODO Don't use so many hard-coded numbers
|
64
|
-
r_offset =
|
73
|
+
r_offset = 20.0 # The distance out from the center of the pie to get point
|
65
74
|
x_offset = center_x # + 15.0 # The label points need to be tweaked slightly
|
66
75
|
y_offset = center_y # This one doesn't though
|
67
76
|
radius_offset = (radius + r_offset)
|
68
|
-
ellipse_factor = radius_offset * 0.
|
77
|
+
ellipse_factor = radius_offset * 0.15
|
69
78
|
x = x_offset + ((radius_offset + ellipse_factor) * Math.cos(angle.deg2rad))
|
70
79
|
y = y_offset + (radius_offset * Math.sin(angle.deg2rad))
|
71
80
|
|
data/lib/gruff/side_bar.rb
CHANGED
@@ -14,6 +14,8 @@ class Gruff::SideBar < Gruff::Base
|
|
14
14
|
|
15
15
|
return if @hide_line_markers
|
16
16
|
|
17
|
+
@d = @d.stroke_antialias false
|
18
|
+
|
17
19
|
# Draw horizontal line markers and annotate with numbers
|
18
20
|
@d = @d.stroke(@marker_color)
|
19
21
|
@d = @d.stroke_width 1
|
@@ -23,38 +25,41 @@ class Gruff::SideBar < Gruff::Base
|
|
23
25
|
increment = significant(@maximum_value.to_f / number_of_lines)
|
24
26
|
(0..number_of_lines).each do |index|
|
25
27
|
|
26
|
-
line_diff
|
27
|
-
x
|
28
|
-
@d
|
29
|
-
|
30
|
-
diff = index - number_of_lines
|
28
|
+
line_diff = (@graph_right - @graph_left) / number_of_lines
|
29
|
+
x = @graph_right - (line_diff * index) - 1
|
30
|
+
@d = @d.line(x, @graph_bottom, x, @graph_top)
|
31
|
+
diff = index - number_of_lines
|
31
32
|
marker_label = diff.abs * increment
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
unless @hide_line_numbers
|
35
|
+
@d.fill = @marker_color
|
36
|
+
@d.font = @font if @font
|
37
|
+
@d.stroke = 'transparent'
|
38
|
+
@d.pointsize = scale_fontsize(@marker_font_size)
|
39
|
+
# @d.gravity = NorthGravity
|
40
|
+
@d = @d.annotate_scaled( @base_image,
|
41
|
+
100, 20,
|
42
|
+
x - (@marker_font_size/1.5), @graph_bottom + 40,
|
43
|
+
marker_label.to_s, @scale)
|
44
|
+
end # unless
|
45
|
+
@d = @d.stroke_antialias true
|
43
46
|
end
|
44
47
|
end
|
45
48
|
|
46
|
-
|
49
|
+
##
|
50
|
+
# Draw on the Y axis instead of the X
|
51
|
+
|
47
52
|
def draw_label(y_offset, index)
|
48
53
|
if !@labels[index].nil? && @labels_seen[index].nil?
|
49
|
-
@d.fill
|
50
|
-
@d.font
|
51
|
-
@d.stroke
|
52
|
-
@d.font_weight
|
53
|
-
@d.pointsize
|
54
|
-
@d.gravity
|
55
|
-
@d
|
54
|
+
@d.fill = @marker_color
|
55
|
+
@d.font = @font if @font
|
56
|
+
@d.stroke = 'transparent'
|
57
|
+
@d.font_weight = NormalWeight
|
58
|
+
@d.pointsize = scale_fontsize(@marker_font_size)
|
59
|
+
@d.gravity = EastGravity
|
60
|
+
@d = @d.annotate_scaled(@base_image,
|
56
61
|
1, 1,
|
57
|
-
|
62
|
+
-@graph_left + LABEL_MARGIN * 2.0, y_offset,
|
58
63
|
@labels[index], @scale)
|
59
64
|
@labels_seen[index] = 1
|
60
65
|
end
|
@@ -72,34 +77,35 @@ class Gruff::SideBar < Gruff::Base
|
|
72
77
|
spacing_factor = 0.9
|
73
78
|
|
74
79
|
@bar_width = @graph_height / @column_count.to_f
|
75
|
-
@d
|
76
|
-
height
|
77
|
-
length
|
80
|
+
@d = @d.stroke_opacity 0.0
|
81
|
+
height = Array.new(@column_count, 0)
|
82
|
+
length = Array.new(@column_count, @graph_left)
|
78
83
|
|
79
84
|
@norm_data.each_with_index do |data_row, row_index|
|
80
85
|
@d = @d.fill data_row[DATA_COLOR_INDEX]
|
81
86
|
|
82
87
|
data_row[1].each_with_index do |data_point, point_index|
|
83
88
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
89
|
+
# Using the original calcs from the stacked bar chart
|
90
|
+
# to get the difference between
|
91
|
+
# part of the bart chart we wish to stack.
|
92
|
+
temp1 = @graph_left + (@graph_width -
|
93
|
+
data_point * @graph_width -
|
94
|
+
height[point_index]) + 1
|
95
|
+
temp2 = @graph_left + @graph_width - height[point_index] - 1
|
96
|
+
difference = temp2 - temp1
|
97
|
+
|
98
|
+
left_x = length[point_index] #+ 1
|
99
|
+
left_y = @graph_top + (@bar_width * point_index)
|
100
|
+
right_x = left_x + difference
|
101
|
+
right_y = left_y + @bar_width * spacing_factor
|
102
|
+
length[point_index] += difference
|
97
103
|
height[point_index] += (data_point * @graph_width - 2)
|
98
104
|
|
99
|
-
@d
|
105
|
+
@d = @d.rectangle(left_x, left_y, right_x, right_y)
|
100
106
|
|
101
107
|
# Calculate center based on bar_width and current row
|
102
|
-
label_center
|
108
|
+
label_center = @graph_top + (@bar_width * point_index) + (@bar_width * spacing_factor / 2.0)
|
103
109
|
draw_label(label_center, point_index)
|
104
110
|
end
|
105
111
|
|
data/test/test_bar.rb
CHANGED
@@ -112,6 +112,18 @@ class TestGruffBar < GruffTestCase
|
|
112
112
|
g.write("test/output/bar_set_marker.png")
|
113
113
|
end
|
114
114
|
|
115
|
+
def test_set_legend_box_size
|
116
|
+
g = setup_basic_graph(400)
|
117
|
+
g.title = "Set Legend Box Size"
|
118
|
+
g.legend_box_size = 10.0
|
119
|
+
g.write("test/output/bar_set_legend_box_size_sm.png")
|
120
|
+
|
121
|
+
g = setup_basic_graph(400)
|
122
|
+
g.title = "Set Legend Box Size"
|
123
|
+
g.legend_box_size = 50.0
|
124
|
+
g.write("test/output/bar_set_legend_box_size_lg.png")
|
125
|
+
end
|
126
|
+
|
115
127
|
def test_x_y_labels
|
116
128
|
g = setup_basic_graph(400)
|
117
129
|
g.title = "X Y Labels"
|
@@ -122,7 +134,7 @@ class TestGruffBar < GruffTestCase
|
|
122
134
|
|
123
135
|
def test_fireball
|
124
136
|
g = Gruff::Bar.new
|
125
|
-
g.
|
137
|
+
g.title = "Daring Fireball-type Accumulation Graph"
|
126
138
|
g.hide_line_numbers = true
|
127
139
|
|
128
140
|
running_totals = []
|
data/test/test_mini_side_bar.rb
CHANGED
@@ -1,11 +1,37 @@
|
|
1
1
|
|
2
2
|
require File.dirname(__FILE__) + "/gruff_test_case"
|
3
3
|
|
4
|
-
class
|
4
|
+
class TestMiniSideBar < GruffTestCase
|
5
5
|
|
6
|
-
def
|
6
|
+
def test_one_color
|
7
|
+
# Use a single data set
|
8
|
+
@datasets = [
|
9
|
+
[:Jimmy, [25, 36, 86, 39]]
|
10
|
+
]
|
11
|
+
@labels = {
|
12
|
+
0 => 'Auto',
|
13
|
+
1 => 'Entertainment',
|
14
|
+
2 => 'Food',
|
15
|
+
3 => 'Bus'
|
16
|
+
}
|
17
|
+
|
7
18
|
g = setup_basic_graph(Gruff::Mini::SideBar, 200)
|
8
19
|
write_test_file g, 'mini_side_bar.png'
|
9
20
|
end
|
10
21
|
|
22
|
+
def test_multi_color
|
23
|
+
# @datasets = [
|
24
|
+
# [:Jimmy, [25, 36, 86, 39]]
|
25
|
+
# ]
|
26
|
+
# @labels = {
|
27
|
+
# 0 => 'Auto',
|
28
|
+
# 1 => 'Entertainment',
|
29
|
+
# 2 => 'Food',
|
30
|
+
# 3 => 'Bus'
|
31
|
+
# }
|
32
|
+
|
33
|
+
g = setup_basic_graph(Gruff::Mini::SideBar, 200)
|
34
|
+
write_test_file g, 'mini_side_bar_multi_color.png'
|
35
|
+
end
|
36
|
+
|
11
37
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: gruff
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.2.
|
7
|
-
date: 2006-
|
6
|
+
version: 0.2.7
|
7
|
+
date: 2006-11-03 00:00:00 -08:00
|
8
8
|
summary: Beautiful graphs for one or multiple datasets.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -31,10 +31,33 @@ authors:
|
|
31
31
|
- Geoffrey Grosenbach
|
32
32
|
files:
|
33
33
|
- CHANGELOG
|
34
|
-
-
|
34
|
+
- Manifest.txt
|
35
35
|
- MIT-LICENSE
|
36
36
|
- Rakefile
|
37
|
-
-
|
37
|
+
- README.txt
|
38
|
+
- assets/pc306715.jpg
|
39
|
+
- assets/city_scene/background/0000.png
|
40
|
+
- assets/city_scene/background/0600.png
|
41
|
+
- assets/city_scene/background/2000.png
|
42
|
+
- assets/city_scene/clouds/cloudy.png
|
43
|
+
- assets/city_scene/clouds/partly_cloudy.png
|
44
|
+
- assets/city_scene/clouds/stormy.png
|
45
|
+
- assets/city_scene/grass/default.png
|
46
|
+
- assets/city_scene/haze/true.png
|
47
|
+
- assets/city_scene/number_sample/1.png
|
48
|
+
- assets/city_scene/number_sample/2.png
|
49
|
+
- assets/city_scene/number_sample/default.png
|
50
|
+
- assets/city_scene/sky/0000.png
|
51
|
+
- assets/city_scene/sky/0200.png
|
52
|
+
- assets/city_scene/sky/0400.png
|
53
|
+
- assets/city_scene/sky/0600.png
|
54
|
+
- assets/city_scene/sky/0800.png
|
55
|
+
- assets/city_scene/sky/1000.png
|
56
|
+
- assets/city_scene/sky/1200.png
|
57
|
+
- assets/city_scene/sky/1400.png
|
58
|
+
- assets/city_scene/sky/1500.png
|
59
|
+
- assets/city_scene/sky/1700.png
|
60
|
+
- assets/city_scene/sky/2000.png
|
38
61
|
- lib/gruff.rb
|
39
62
|
- lib/gruff/area.rb
|
40
63
|
- lib/gruff/bar.rb
|
@@ -46,31 +69,32 @@ files:
|
|
46
69
|
- lib/gruff/photo_bar.rb
|
47
70
|
- lib/gruff/pie.rb
|
48
71
|
- lib/gruff/scene.rb
|
72
|
+
- lib/gruff/side_bar.rb
|
49
73
|
- lib/gruff/side_stacked_bar.rb
|
50
74
|
- lib/gruff/spider.rb
|
51
75
|
- lib/gruff/stacked_bar.rb
|
52
|
-
- lib/gruff/side_bar.rb
|
53
76
|
- lib/gruff/mini/bar.rb
|
77
|
+
- lib/gruff/mini/legend.rb
|
54
78
|
- lib/gruff/mini/pie.rb
|
55
79
|
- lib/gruff/mini/side_bar.rb
|
56
|
-
-
|
80
|
+
- test/gruff_test_case.rb
|
81
|
+
- test/output
|
57
82
|
- test/test_area.rb
|
58
83
|
- test/test_bar.rb
|
59
84
|
- test/test_base.rb
|
60
|
-
- test/gruff_test_case.rb
|
61
85
|
- test/test_legend.rb
|
62
86
|
- test/test_line.rb
|
87
|
+
- test/test_mini_bar.rb
|
88
|
+
- test/test_mini_pie.rb
|
89
|
+
- test/test_mini_side_bar.rb
|
63
90
|
- test/test_net.rb
|
64
|
-
- test/output
|
65
91
|
- test/test_photo.rb
|
66
92
|
- test/test_pie.rb
|
67
93
|
- test/test_scene.rb
|
94
|
+
- test/test_side_bar.rb
|
68
95
|
- test/test_sidestacked_bar.rb
|
69
96
|
- test/test_spider.rb
|
70
97
|
- test/test_stacked_bar.rb
|
71
|
-
- test/test_mini_bar.rb
|
72
|
-
- test/test_mini_pie.rb
|
73
|
-
- test/test_mini_side_bar.rb
|
74
98
|
test_files: []
|
75
99
|
|
76
100
|
rdoc_options: []
|