Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Removed main branch and added artwork directory

  • Loading branch information...
commit 8f6c8e3d481d8d43b991456f227e484cef6fffca 1 parent defc9aa
@topfunky authored
Showing with 85 additions and 5,362 deletions.
  1. +0 −98 History.txt
  2. +0 −21 MIT-LICENSE
  3. +0 −76 Manifest.txt
  4. +0 −40 README.txt
  5. +0 −54 Rakefile
  6. BIN  artwork/city_scene.psd
  7. 0  artwork/graphs/Backup of Untitled.key/.typeAttributes.dict
  8. +1 −0  artwork/graphs/Backup of Untitled.key/Contents/PkgInfo
  9. BIN  artwork/graphs/Backup of Untitled.key/index.apxl.gz
  10. BIN  artwork/graphs/Backup of Untitled.key/thumbs/st0.tiff
  11. BIN  artwork/graphs/Backup of Untitled.key/thumbs/st1.tiff
  12. BIN  artwork/graphs/Backup of Untitled.key/thumbs/st2.tiff
  13. BIN  artwork/graphs/Backup of Untitled.key/thumbs/st3.tiff
  14. 0  artwork/graphs/Untitled.key/.typeAttributes.dict
  15. +1 −0  artwork/graphs/Untitled.key/Contents/PkgInfo
  16. BIN  artwork/graphs/Untitled.key/index.apxl.gz
  17. BIN  artwork/graphs/Untitled.key/thumbs/st0.tiff
  18. BIN  artwork/graphs/Untitled.key/thumbs/st1.tiff
  19. BIN  artwork/graphs/Untitled.key/thumbs/st2.tiff
  20. BIN  artwork/graphs/Untitled.key/thumbs/st3.tiff
  21. BIN  artwork/graphs/samples.001.png
  22. BIN  artwork/graphs/samples.002.png
  23. BIN  artwork/graphs/samples.003.png
  24. BIN  artwork/graphs/samples.004.png
  25. +36 −0 artwork/gruff_controller.rb
  26. +32 −0 artwork/gruffs_helper.rb
  27. +15 −0 artwork/install_rmagick.sh
  28. BIN  artwork/mrplot-0.0.1.tar.gz
  29. BIN  artwork/plastik-blue.psd
  30. BIN  artwork/plastik-green.psd
  31. BIN  artwork/plastik-red.psd
  32. BIN  artwork/plastik-template.psd
  33. BIN  artwork/plastik.png
  34. BIN  assets/bubble.png
  35. BIN  assets/city_scene/background/0000.png
  36. BIN  assets/city_scene/background/0600.png
  37. BIN  assets/city_scene/background/2000.png
  38. BIN  assets/city_scene/clouds/cloudy.png
  39. BIN  assets/city_scene/clouds/partly_cloudy.png
  40. BIN  assets/city_scene/clouds/stormy.png
  41. BIN  assets/city_scene/grass/default.png
  42. BIN  assets/city_scene/haze/true.png
  43. BIN  assets/city_scene/number_sample/1.png
  44. BIN  assets/city_scene/number_sample/2.png
  45. BIN  assets/city_scene/number_sample/default.png
  46. BIN  assets/city_scene/sky/0000.png
  47. BIN  assets/city_scene/sky/0200.png
  48. BIN  assets/city_scene/sky/0400.png
  49. BIN  assets/city_scene/sky/0600.png
  50. BIN  assets/city_scene/sky/0800.png
  51. BIN  assets/city_scene/sky/1000.png
  52. BIN  assets/city_scene/sky/1200.png
  53. BIN  assets/city_scene/sky/1400.png
  54. BIN  assets/city_scene/sky/1500.png
  55. BIN  assets/city_scene/sky/1700.png
  56. BIN  assets/city_scene/sky/2000.png
  57. BIN  assets/pc306715.jpg
  58. BIN  assets/plastik/blue.png
  59. BIN  assets/plastik/green.png
  60. BIN  assets/plastik/red.png
  61. +0 −2  init.rb
  62. +0 −27 lib/gruff.rb
  63. +0 −27 lib/gruff/accumulator_bar.rb
  64. +0 −58 lib/gruff/area.rb
  65. +0 −83 lib/gruff/bar.rb
  66. +0 −46 lib/gruff/bar_conversion.rb
  67. +0 −1,073 lib/gruff/base.rb
  68. +0 −109 lib/gruff/bullet.rb
  69. +0 −39 lib/gruff/deprecated.rb
  70. +0 −105 lib/gruff/line.rb
  71. +0 −32 lib/gruff/mini/bar.rb
  72. +0 −77 lib/gruff/mini/legend.rb
  73. +0 −36 lib/gruff/mini/pie.rb
  74. +0 −35 lib/gruff/mini/side_bar.rb
  75. +0 −142 lib/gruff/net.rb
  76. +0 −100 lib/gruff/photo_bar.rb
  77. +0 −124 lib/gruff/pie.rb
  78. +0 −209 lib/gruff/scene.rb
  79. +0 −114 lib/gruff/side_bar.rb
  80. +0 −73 lib/gruff/side_stacked_bar.rb
  81. +0 −130 lib/gruff/spider.rb
  82. +0 −66 lib/gruff/stacked_area.rb
  83. +0 −53 lib/gruff/stacked_bar.rb
  84. +0 −23 lib/gruff/stacked_mixin.rb
  85. +0 −63 rails_generators/gruff/gruff_generator.rb
  86. +0 −32 rails_generators/gruff/templates/controller.rb
  87. +0 −24 rails_generators/gruff/templates/functional_test.rb
  88. +0 −123 test/gruff_test_case.rb
  89. +0 −50 test/test_accumulator_bar.rb
  90. +0 −134 test/test_area.rb
  91. +0 −283 test/test_bar.rb
  92. +0 −8 test/test_base.rb
  93. +0 −26 test/test_bullet.rb
  94. +0 −71 test/test_legend.rb
  95. +0 −493 test/test_line.rb
  96. +0 −32 test/test_mini_bar.rb
  97. +0 −20 test/test_mini_pie.rb
  98. +0 −37 test/test_mini_side_bar.rb
  99. +0 −230 test/test_net.rb
  100. +0 −41 test/test_photo.rb
  101. +0 −154 test/test_pie.rb
  102. +0 −100 test/test_scene.rb
  103. +0 −12 test/test_side_bar.rb
  104. +0 −89 test/test_sidestacked_bar.rb
  105. +0 −216 test/test_spider.rb
  106. +0 −52 test/test_stacked_bar.rb
View
98 History.txt
@@ -1,98 +0,0 @@
-== 0.3.2
-
-* Include init.rb for use as a Rails plugin.
-
-
-== 0.3.1
-
-* Fixed missing bullet graph bug (experimental, will be in a future release).
-
-== 0.3.0
-
-* Fixed bug where pie graphs weren't drawing their label correctly.
-
-== 0.2.9
-
-* Patch to make SideBar accurate instead of stacked [Marik]
-* Will be extracting net, pie, stacked, and side-stacked to separate gem
- in next release.
-
-== 0.2.8
-
-* New accumulator bar graph (experimental)
-* Better mini graphs
-* Bug fixes
-
-== 0.2.7
-
-* Regenerated Manifest.txt
-* Added scene sample to package
-* Added mini side_bar (EXPERIMENTAL)
-* Added @zero_degree option to Gruff::Pie so first slice can start somewhere other than 3 o'clock
-* Increased size of numbers in Gruff::Mini::Pie
-* Added legend_box_size accessor
-
-== 0.2.6
-
-* Fixed missing side_bar.rb in Manifest.txt
-
-== 0.2.5
-
-* New mini graph types (Experimental)
-* Marker lines can be different color than text labels
-* Theme definition cleanup
-
-== 0.2.4
-
-* Added option to hide line numbers
-* Fixed code that was causing warnings
-
-== 0.2.3
-
-* Cleaned up measurements so the graph expands to fill the available space
-* Added x-axis and y-axis label options
-
-== 0.1.2
-
-* minimum_value and maximum_value can be set after data() to manually scale the graph
-* Fixed infinite loop bug when values are all equal
-* Added experimental net and spider graphs
-* Added non-linear scene graph for a simple interface to complex layered graphs
-* Initial refactoring of tests
-* A host of other bug fixes
-
-== 0.0.8
-
-* NEW Sidestacked Bar Graphs. [Alun Eyre]
-* baseline_value larger than data will now show correctly. [Mike Perham]
-* hide_dots and hide_lines are now options for line graphs.
-
-== 0.0.6
-
-* Fixed hang when no data is passed.
-
-== 0.0.4
-
-* Added bar graphs
-* Added area graphs
-* Added pie graphs
-* Added render_image_background for using images as background on a theme
-* Fixed small size legend centering issue
-* Added initial line marker rounding to significant digits (Christian Winkler)
-* Line graphs line width is scaled with number of points being drawn (Christian Winkler)
-
-== 0.0.3
-
-* Added option to draw line graphs without the lines (points only), thanks to Eric Hodel
-* Removed font-minimum check so graphs look better at 300px width
-
-== 0.0.2
-
-* Fixed to_blob (thanks to Carlos Villela)
-* Added bar graphs (initial functionality...will be enhanced)
-* Removed rendered test output from gem
-
-== 0.0.1
-
-* Initial release.
-* Line graphs only. Other graph styles coming soon.
View
21 MIT-LICENSE
@@ -1,21 +0,0 @@
-Copyright (c) 2005 Geoffrey Grosenbach boss@topfunky.com
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
View
76 Manifest.txt
@@ -1,76 +0,0 @@
-History.txt
-MIT-LICENSE
-Manifest.txt
-README.txt
-Rakefile
-assets/bubble.png
-assets/city_scene/background/0000.png
-assets/city_scene/background/0600.png
-assets/city_scene/background/2000.png
-assets/city_scene/clouds/cloudy.png
-assets/city_scene/clouds/partly_cloudy.png
-assets/city_scene/clouds/stormy.png
-assets/city_scene/grass/default.png
-assets/city_scene/haze/true.png
-assets/city_scene/number_sample/1.png
-assets/city_scene/number_sample/2.png
-assets/city_scene/number_sample/default.png
-assets/city_scene/sky/0000.png
-assets/city_scene/sky/0200.png
-assets/city_scene/sky/0400.png
-assets/city_scene/sky/0600.png
-assets/city_scene/sky/0800.png
-assets/city_scene/sky/1000.png
-assets/city_scene/sky/1200.png
-assets/city_scene/sky/1400.png
-assets/city_scene/sky/1500.png
-assets/city_scene/sky/1700.png
-assets/city_scene/sky/2000.png
-assets/pc306715.jpg
-assets/plastik/blue.png
-assets/plastik/green.png
-assets/plastik/red.png
-init.rb
-lib/gruff.rb
-lib/gruff/accumulator_bar.rb
-lib/gruff/area.rb
-lib/gruff/bar.rb
-lib/gruff/bar_conversion.rb
-lib/gruff/base.rb
-lib/gruff/deprecated.rb
-lib/gruff/line.rb
-lib/gruff/mini/bar.rb
-lib/gruff/mini/legend.rb
-lib/gruff/mini/pie.rb
-lib/gruff/mini/side_bar.rb
-lib/gruff/net.rb
-lib/gruff/photo_bar.rb
-lib/gruff/pie.rb
-lib/gruff/scene.rb
-lib/gruff/side_bar.rb
-lib/gruff/side_stacked_bar.rb
-lib/gruff/spider.rb
-lib/gruff/stacked_area.rb
-lib/gruff/stacked_bar.rb
-lib/gruff/stacked_mixin.rb
-rails_generators/gruff/gruff_generator.rb
-rails_generators/gruff/templates/controller.rb
-rails_generators/gruff/templates/functional_test.rb
-test/gruff_test_case.rb
-test/test_accumulator_bar.rb
-test/test_area.rb
-test/test_bar.rb
-test/test_base.rb
-test/test_legend.rb
-test/test_line.rb
-test/test_mini_bar.rb
-test/test_mini_pie.rb
-test/test_mini_side_bar.rb
-test/test_net.rb
-test/test_photo.rb
-test/test_pie.rb
-test/test_scene.rb
-test/test_side_bar.rb
-test/test_sidestacked_bar.rb
-test/test_spider.rb
-test/test_stacked_bar.rb
View
40 README.txt
@@ -1,40 +0,0 @@
-== Gruff Graphs
-
-A library for making beautiful graphs.
-
-== Samples
-
-http://nubyonrails.com/pages/gruff
-
-== Documentation
-
-http://gruff.rubyforge.org
-
-See the test suite in test/line_test.rb for examples.
-
-== Rails Plugin
-
-Gruff is easy to use with Rails.
-
- gem install gruff
- cd vendor/plugins && gem unpack gruff
-
-== WARNING
-
-This is beta-quality software. It works well according to my tests, but the API may change and other features will be added.
-
-== Source
-
-The source for this project is now kept at GitHub:
-
-http://github.com/topfunky/gruff/tree/master
-
-== CONTRIBUTE
-
-Patches appreciated, especially if they are in Git format (with metadata so your name shows up in the commit logs).
-
-Use these instructions:
-
-http://gweezlebur.com/2008/2/1/so-you-want-to-contribute-to-merb-core-part-1
-
-http://gweezlebur.com/2008/2/9/contributing-to-merb-part-2
View
54 Rakefile
@@ -1,54 +0,0 @@
-require 'rubygems'
-require 'hoe'
-$:.unshift(File.dirname(__FILE__) + "/lib")
-require 'gruff'
-
-Hoe.new('Gruff', Gruff::VERSION) do |p|
- p.name = "gruff"
- p.author = "Geoffrey Grosenbach"
- p.description = "Beautiful graphs for one or multiple datasets. Can be used on websites or in documents."
- p.email = 'boss@topfunky.com'
- p.summary = "Beautiful graphs for one or multiple datasets."
- p.url = "http://nubyonrails.com/pages/gruff"
- p.clean_globs = ['test/output/*.png']
- p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
- p.remote_rdoc_dir = '' # Release to root
-end
-
-desc "Simple require on packaged files to make sure they are all there"
-task :verify => :package do
- # An error message will be displayed if files are missing
- if system %(ruby -e "require 'pkg/gruff-#{Gruff::VERSION}/lib/gruff'")
- puts "\nThe library files are present"
- end
-end
-
-task :release => :verify
-
-namespace :test do
-
- desc "Run mini tests"
- task :mini => :clean do
- Dir['test/test_mini*'].each do |file|
- system "ruby #{file}"
- end
-
- end
-
-end
-
-##
-# Catch unmatched tasks and run them as a unit test.
-#
-# Makes it possible to do
-#
-# rake pie
-#
-# To run the +test/test_pie+ and +test/test_mini_pie+ files.
-
-rule '' do |t|
- # Rake::Task["clean"].invoke
- Dir["test/test_*#{t.name}*.rb"].each do |filename|
- system "ruby #{filename}"
- end
-end
View
BIN  artwork/city_scene.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0  artwork/graphs/Backup of Untitled.key/.typeAttributes.dict
No changes.
View
1  artwork/graphs/Backup of Untitled.key/Contents/PkgInfo
@@ -0,0 +1 @@
+????????
View
BIN  artwork/graphs/Backup of Untitled.key/index.apxl.gz
Binary file not shown
View
BIN  artwork/graphs/Backup of Untitled.key/thumbs/st0.tiff
Binary file not shown
View
BIN  artwork/graphs/Backup of Untitled.key/thumbs/st1.tiff
Binary file not shown
View
BIN  artwork/graphs/Backup of Untitled.key/thumbs/st2.tiff
Binary file not shown
View
BIN  artwork/graphs/Backup of Untitled.key/thumbs/st3.tiff
Binary file not shown
View
0  artwork/graphs/Untitled.key/.typeAttributes.dict
No changes.
View
1  artwork/graphs/Untitled.key/Contents/PkgInfo
@@ -0,0 +1 @@
+????????
View
BIN  artwork/graphs/Untitled.key/index.apxl.gz
Binary file not shown
View
BIN  artwork/graphs/Untitled.key/thumbs/st0.tiff
Binary file not shown
View
BIN  artwork/graphs/Untitled.key/thumbs/st1.tiff
Binary file not shown
View
BIN  artwork/graphs/Untitled.key/thumbs/st2.tiff
Binary file not shown
View
BIN  artwork/graphs/Untitled.key/thumbs/st3.tiff
Binary file not shown
View
BIN  artwork/graphs/samples.001.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  artwork/graphs/samples.002.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  artwork/graphs/samples.003.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  artwork/graphs/samples.004.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
36 artwork/gruff_controller.rb
@@ -0,0 +1,36 @@
+
+# Handles requests for gruff graphs.
+#
+# You shouldn't need to edit or extend this, but you can read
+# the documentation for GruffHelper to see how to call it from
+# another view.
+#
+# AUTHOR
+# Carlos Villela [mailto:cv@lixo.org]
+# Geoffrey Grosenbach[mailto:boss@topfunky.com]
+#
+# http://lixo.org
+# http://topfunky.com
+#
+require_gem 'gruff'
+
+class GruffController < ApplicationController
+ layout nil
+
+ def index
+ opts = @session['gruff_opts']
+ data = @session['gruff_data']
+
+ raise "No Gruff data or options set in the session" if data.nil? or opts.nil?
+
+ g = Gruff::Line.new(475)
+ g.title = opts[:title]
+ g.labels = opts[:labels]
+ g.theme_37signals
+
+ data.each_pair {|k,v| g.data(k, v) }
+
+ send_data(g.to_blob, :disposition => 'inline', :type => 'image/png', :filename => "gruff.png")
+ end
+
+end
View
32 artwork/gruffs_helper.rb
@@ -0,0 +1,32 @@
+
+# Provides a tag for embedding gruff graphs into your Rails app.
+#
+# To use, load it in your controller with
+#
+# helper :gruff
+#
+# AUTHOR
+#
+# Carlos Villela [mailto:cv@lixo.org]
+# Geoffrey Grosenbach[mailto:boss@topfunky.com]
+#
+# http://lixo.org
+# http://topfunky.com
+#
+# License
+#
+# This code is licensed under the MIT license.
+#
+module GruffsHelper
+
+ # Call with a name-values hash and an options hash (title and labels supported for now).
+ # You can also pass :class => 'some_css_class' ('gruff' by default).
+ def gruff_tag(data={}, opts={})
+
+ @session['gruff_opts']=opts
+ @session['gruff_data']=data
+
+ "<img src=\"/gruff\" class=\"#{opts[:class] || 'gruff'}\" alt=\"Gruff Graph\" />"
+ end
+
+end
View
15 artwork/install_rmagick.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Install libraries for rmagick, using darwinports.
+#
+# Geoffrey Grosenbach boss@topfunky.com
+#
+
+sudo port install jpeg
+sudo port install libpng
+sudo port install libwmf
+sudo port install tiff
+sudo port install lcms
+sudo port install freetype
+sudo port install imagemagick
+sudo gem install rmagick
View
BIN  artwork/mrplot-0.0.1.tar.gz
Binary file not shown
View
BIN  artwork/plastik-blue.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  artwork/plastik-green.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  artwork/plastik-red.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  artwork/plastik-template.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  artwork/plastik.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  assets/bubble.png
Deleted file not rendered
View
BIN  assets/city_scene/background/0000.png
Deleted file not rendered
View
BIN  assets/city_scene/background/0600.png
Deleted file not rendered
View
BIN  assets/city_scene/background/2000.png
Deleted file not rendered
View
BIN  assets/city_scene/clouds/cloudy.png
Deleted file not rendered
View
BIN  assets/city_scene/clouds/partly_cloudy.png
Deleted file not rendered
View
BIN  assets/city_scene/clouds/stormy.png
Deleted file not rendered
View
BIN  assets/city_scene/grass/default.png
Deleted file not rendered
View
BIN  assets/city_scene/haze/true.png
Deleted file not rendered
View
BIN  assets/city_scene/number_sample/1.png
Deleted file not rendered
View
BIN  assets/city_scene/number_sample/2.png
Deleted file not rendered
View
BIN  assets/city_scene/number_sample/default.png
Deleted file not rendered
View
BIN  assets/city_scene/sky/0000.png
Deleted file not rendered
View
BIN  assets/city_scene/sky/0200.png
Deleted file not rendered
View
BIN  assets/city_scene/sky/0400.png
Deleted file not rendered
View
BIN  assets/city_scene/sky/0600.png
Diff not rendered
View
BIN  assets/city_scene/sky/0800.png
Diff not rendered
View
BIN  assets/city_scene/sky/1000.png
Diff not rendered
View
BIN  assets/city_scene/sky/1200.png
Diff not rendered
View
BIN  assets/city_scene/sky/1400.png
Diff not rendered
View
BIN  assets/city_scene/sky/1500.png
Diff not rendered
View
BIN  assets/city_scene/sky/1700.png
Diff not rendered
View
BIN  assets/city_scene/sky/2000.png
Diff not rendered
View
BIN  assets/pc306715.jpg
Diff not rendered
View
BIN  assets/plastik/blue.png
Diff not rendered
View
BIN  assets/plastik/green.png
Diff not rendered
View
BIN  assets/plastik/red.png
Diff not rendered
View
2  init.rb
@@ -1,2 +0,0 @@
-# For Rails
-require 'gruff'
View
27 lib/gruff.rb
@@ -1,27 +0,0 @@
-# Extra full path added to fix loading errors on some installations.
-
-%w(
- base
- area
- bar
- line
- pie
- spider
- net
- stacked_area
- stacked_bar
- side_stacked_bar
- side_bar
- accumulator_bar
-
- scene
-
- mini/legend
- mini/bar
- mini/pie
- mini/side_bar
-).each do |filename|
- require File.dirname(__FILE__) + "/gruff/#{filename}"
-end
-
-# TODO bullet
View
27 lib/gruff/accumulator_bar.rb
@@ -1,27 +0,0 @@
-require File.dirname(__FILE__) + '/base'
-
-##
-# A special bar graph that shows a single dataset as a set of
-# stacked bars. The bottom bar shows the running total and
-# the top bar shows the new value being added to the array.
-
-class Gruff::AccumulatorBar < Gruff::StackedBar
-
- def draw
- raise(Gruff::IncorrectNumberOfDatasetsException) unless @data.length == 1
-
- accumulator_array = []
- index = 0
-
- increment_array = @data.first[DATA_VALUES_INDEX].inject([]) {|memo, value|
- memo << ((index > 0) ? (value + memo.max) : value)
- accumulator_array << memo[index] - value
- index += 1
- memo
- }
- data "Accumulator", accumulator_array
-
- super
- end
-
-end
View
58 lib/gruff/area.rb
@@ -1,58 +0,0 @@
-
-require File.dirname(__FILE__) + '/base'
-
-class Gruff::Area < Gruff::Base
-
- def draw
- super
-
- return unless @has_data
-
- @x_increment = @graph_width / (@column_count - 1).to_f
- @d = @d.stroke 'transparent'
-
- @norm_data.each do |data_row|
- poly_points = Array.new
- prev_x = prev_y = 0.0
- @d = @d.fill data_row[DATA_COLOR_INDEX]
-
- data_row[1].each_with_index do |data_point, index|
- # Use incremented x and scaled y
- new_x = @graph_left + (@x_increment * index)
- new_y = @graph_top + (@graph_height - data_point * @graph_height)
-
- if prev_x > 0 and prev_y > 0 then
- poly_points << new_x
- poly_points << new_y
-
- #@d = @d.polyline(prev_x, prev_y, new_x, new_y)
- else
- poly_points << @graph_left
- poly_points << @graph_bottom - 1
- poly_points << new_x
- poly_points << new_y
-
- #@d = @d.polyline(@graph_left, @graph_bottom, new_x, new_y)
- end
-
- draw_label(new_x, index)
-
- prev_x = new_x
- prev_y = new_y
- end
-
- # Add closing points, draw polygon
- poly_points << @graph_right
- poly_points << @graph_bottom - 1
- poly_points << @graph_left
- poly_points << @graph_bottom - 1
-
- @d = @d.polyline(*poly_points)
-
- end
-
- @d.draw(@base_image)
- end
-
-
-end
View
83 lib/gruff/bar.rb
@@ -1,83 +0,0 @@
-require File.dirname(__FILE__) + '/base'
-require File.dirname(__FILE__) + '/bar_conversion'
-
-class Gruff::Bar < Gruff::Base
-
- def draw
- # Labels will be centered over the left of the bar if
- # there are more labels than columns. This is basically the same
- # as where it would be for a line graph.
- @center_labels_over_point = (@labels.keys.length > @column_count ? true : false)
-
- super
- return unless @has_data
-
- draw_bars
- end
-
-protected
-
- def draw_bars
- # Setup spacing.
- #
- # Columns sit side-by-side.
- spacing_factor = 0.9 # space between the bars
- @bar_width = @graph_width / (@column_count * @data.length).to_f
-
- @d = @d.stroke_opacity 0.0
-
- # Setup the BarConversion Object
- conversion = Gruff::BarConversion.new()
- conversion.graph_height = @graph_height
- conversion.graph_top = @graph_top
-
- # Set up the right mode [1,2,3] see BarConversion for further explanation
- if @minimum_value >= 0 then
- # all bars go from zero to positiv
- conversion.mode = 1
- else
- # all bars go from 0 to negativ
- if @maximum_value <= 0 then
- conversion.mode = 2
- else
- # bars either go from zero to negativ or to positiv
- conversion.mode = 3
- conversion.spread = @spread
- conversion.minimum_value = @minimum_value
- conversion.zero = -@minimum_value/@spread
- end
- end
-
- # iterate over all normalised data
- @norm_data.each_with_index do |data_row, row_index|
-
- data_row[1].each_with_index do |data_point, point_index|
- # Use incremented x and scaled y
- # x
- left_x = @graph_left + (@bar_width * (row_index + point_index + ((@data.length - 1) * point_index)))
- right_x = left_x + @bar_width * spacing_factor
- # y
- conv = []
- conversion.getLeftYRightYscaled( data_point, conv )
-
- # create new bar
- @d = @d.fill data_row[DATA_COLOR_INDEX]
- @d = @d.rectangle(left_x, conv[0], right_x, conv[1])
-
- # Calculate center based on bar_width and current row
- label_center = @graph_left +
- (@data.length * @bar_width * point_index) +
- (@data.length * @bar_width / 2.0)
- # Subtract half a bar width to center left if requested
- draw_label(label_center - (@center_labels_over_point ? @bar_width / 2.0 : 0.0), point_index)
- end
-
- end
-
- # Draw the last label if requested
- draw_label(@graph_right, @column_count) if @center_labels_over_point
-
- @d.draw(@base_image)
- end
-
-end
View
46 lib/gruff/bar_conversion.rb
@@ -1,46 +0,0 @@
-##
-# Original Author: David Stokar
-#
-# This class perfoms the y coordinats conversion for the bar class.
-#
-# There are three cases:
-#
-# 1. Bars all go from zero in positive direction
-# 2. Bars all go from zero to negative direction
-# 3. Bars either go from zero to positive or from zero to negative
-#
-class Gruff::BarConversion
- attr_writer :mode
- attr_writer :zero
- attr_writer :graph_top
- attr_writer :graph_height
- attr_writer :minimum_value
- attr_writer :spread
-
- def getLeftYRightYscaled( data_point, result )
- case @mode
- when 1 then # Case one
- # minimum value >= 0 ( only positiv values )
- result[0] = @graph_top + @graph_height*(1 - data_point) + 1
- result[1] = @graph_top + @graph_height - 1
- when 2 then # Case two
- # only negativ values
- result[0] = @graph_top + 1
- result[1] = @graph_top + @graph_height*(1 - data_point) - 1
- when 3 then # Case three
- # positiv and negativ values
- val = data_point-@minimum_value/@spread
- if ( data_point >= @zero ) then
- result[0] = @graph_top + @graph_height*(1 - (val-@zero)) + 1
- result[1] = @graph_top + @graph_height*(1 - @zero) - 1
- else
- result[0] = @graph_top + @graph_height*(1 - (val-@zero)) + 1
- result[1] = @graph_top + @graph_height*(1 - @zero) - 1
- end
- else
- result[0] = 0.0
- result[1] = 0.0
- end
- end
-
-end
View
1,073 lib/gruff/base.rb
@@ -1,1073 +0,0 @@
-require 'rubygems'
-require 'RMagick'
-
-require File.dirname(__FILE__) + '/deprecated'
-
-# = Gruff. Graphs.
-#
-# Author:: Geoffrey Grosenbach boss@topfunky.com
-#
-# Originally Created:: October 23, 2005
-#
-# Extra thanks to Tim Hunter for writing RMagick, and also contributions by
-# Jarkko Laine, Mike Perham, Andreas Schwarz, Alun Eyre, Guillaume Theoret,
-# David Stokar, Paul Rogers, Dave Woodward, Frank Oxener, Kevin Clark, Cies
-# Breijs, Richard Cowin, and a cast of thousands.
-#
-# See Gruff::Base#theme= for setting themes.
-module Gruff
-
- # This is the version of Gruff you are using.
- VERSION = '0.3.2'
-
- class Base
-
- include Magick
- include Deprecated
-
- # Draw extra lines showing where the margins and text centers are
- DEBUG = false
-
- # Used for navigating the array of data to plot
- DATA_LABEL_INDEX = 0
- DATA_VALUES_INDEX = 1
- DATA_COLOR_INDEX = 2
-
- # Space around text elements. Mostly used for vertical spacing
- LEGEND_MARGIN = TITLE_MARGIN = LABEL_MARGIN = 10.0
-
- DEFAULT_TARGET_WIDTH = 800
-
- # Blank space above the graph
- attr_accessor :top_margin
-
- # Blank space below the graph
- attr_accessor :bottom_margin
-
- # Blank space to the right of the graph
- attr_accessor :right_margin
-
- # Blank space to the left of the graph
- attr_accessor :left_margin
-
- # A hash of names for the individual columns, where the key is the array
- # index for the column this label represents.
- #
- # Not all columns need to be named.
- #
- # Example: 0 => 2005, 3 => 2006, 5 => 2007, 7 => 2008
- attr_accessor :labels
-
- # Used internally for spacing.
- #
- # By default, labels are centered over the point they represent.
- attr_accessor :center_labels_over_point
-
- # Used internally for horizontal graph types.
- attr_accessor :has_left_labels
-
- # A label for the bottom of the graph
- attr_accessor :x_axis_label
-
- # A label for the left side of the graph
- attr_accessor :y_axis_label
-
- # attr_accessor :x_axis_increment
-
- # Manually set increment of the horizontal marking lines
- attr_accessor :y_axis_increment
-
- # Get or set the list of colors that will be used to draw the bars or lines.
- attr_accessor :colors
-
- # The large title of the graph displayed at the top
- attr_accessor :title
-
- # Font used for titles, labels, etc. Works best if you provide the full
- # path to the TTF font file. RMagick must be built with the Freetype
- # libraries for this to work properly.
- #
- # Tries to find Bitstream Vera (Vera.ttf) in the location specified by
- # ENV['MAGICK_FONT_PATH']. Uses default RMagick font otherwise.
- #
- # The font= method below fulfills the role of the writer, so we only need
- # a reader here.
- attr_reader :font
-
- attr_accessor :font_color
-
- # Prevent drawing of line markers
- attr_accessor :hide_line_markers
-
- # Prevent drawing of the legend
- attr_accessor :hide_legend
-
- # Prevent drawing of the title
- attr_accessor :hide_title
-
- # Prevent drawing of line numbers
- attr_accessor :hide_line_numbers
-
- # Message shown when there is no data. Fits up to 20 characters. Defaults
- # to "No Data."
- attr_accessor :no_data_message
-
- # The font size of the large title at the top of the graph
- attr_accessor :title_font_size
-
- # Optionally set the size of the font. Based on an 800x600px graph.
- # Default is 20.
- #
- # Will be scaled down if graph is smaller than 800px wide.
- attr_accessor :legend_font_size
-
- # The font size of the labels around the graph
- attr_accessor :marker_font_size
-
- # The color of the auxiliary lines
- attr_accessor :marker_color
-
- # The number of horizontal lines shown for reference
- attr_accessor :marker_count
-
- # You can manually set a minimum value instead of having the values
- # guessed for you.
- #
- # Set it after you have given all your data to the graph object.
- attr_accessor :minimum_value
-
- # You can manually set a maximum value, such as a percentage-based graph
- # that always goes to 100.
- #
- # If you use this, you must set it after you have given all your data to
- # the graph object.
- attr_accessor :maximum_value
-
- # Set to false if you don't want the data to be sorted with largest avg
- # values at the back.
- attr_accessor :sort
-
- # Experimental
- attr_accessor :additional_line_values
-
- # Experimental
- attr_accessor :stacked
-
- # Optionally set the size of the colored box by each item in the legend.
- # Default is 20.0
- #
- # Will be scaled down if graph is smaller than 800px wide.
- attr_accessor :legend_box_size
-
- # 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.).
- #
- # Or, send a geometry string for other ratios ('800x400', '400x225').
- #
- # Looks for Bitstream Vera as the default font. Expects an environment var
- # of MAGICK_FONT_PATH to be set. (Uses RMagick's default font otherwise.)
- def initialize(target_width=DEFAULT_TARGET_WIDTH)
- @top_margin = @bottom_margin = @left_margin = @right_margin = 20.0
-
- if not Numeric === target_width
- geometric_width, geometric_height = target_width.split('x')
- @columns = geometric_width.to_f
- @rows = geometric_height.to_f
- else
- @columns = target_width.to_f
- @rows = target_width.to_f * 0.75
- end
-
- initialize_ivars
-
- reset_themes
- theme_keynote
- end
-
- # Set instance variables for this object.
- #
- # Subclasses can override this, call super, then set values separately.
- #
- # This makes it possible to set defaults in a subclass but still allow
- # developers to change this values in their program.
- def initialize_ivars
- # Internal for calculations
- @raw_columns = 800.0
- @raw_rows = 800.0 * (@rows/@columns)
- @column_count = 0
- @marker_count = nil
- @maximum_value = @minimum_value = nil
- @has_data = false
- @data = Array.new
- @labels = Hash.new
- @labels_seen = Hash.new
- @sort = true
- @title = nil
-
- @scale = @columns / @raw_columns
-
- vera_font_path = File.expand_path('Vera.ttf', ENV['MAGICK_FONT_PATH'])
- @font = File.exists?(vera_font_path) ? vera_font_path : nil
-
- @marker_font_size = 21.0
- @legend_font_size = 20.0
- @title_font_size = 36.0
-
- @legend_box_size = 20.0
-
- @no_data_message = "No Data"
-
- @hide_line_markers = @hide_legend = @hide_title = @hide_line_numbers = false
- @center_labels_over_point = true
- @has_left_labels = false
-
- @additional_line_values = []
- @additional_line_colors = []
- @theme_options = {}
-
- @x_axis_label = @y_axis_label = nil
- @y_axis_increment = nil
- @stacked = nil
- @norm_data = nil
- end
-
- # Sets the top, bottom, left and right margins to +margin+.
- def margins=(margin)
- @top_margin = @left_margin = @right_margin = @bottom_margin = margin
- end
-
- # Sets the font for graph text to the font at +font_path+.
- def font=(font_path)
- @font = font_path
- @d.font = @font
- end
-
- # Add a color to the list of available colors for lines.
- #
- # Example:
- # add_color('#c0e9d3')
- def add_color(colorname)
- @colors << colorname
- end
-
- # Replace the entire color list with a new array of colors. You need to
- # have one more color than the number of datasets you intend to draw. Also
- # aliased as the colors= setter method.
- #
- # Example:
- # replace_colors ['#cc99cc', '#d9e043', '#34d8a2']
- def replace_colors(color_list=[])
- @colors = color_list
- end
-
- # You can set a theme manually. Assign a hash to this method before you
- # send your data.
- #
- # graph.theme = {
- # :colors => %w(orange purple green white red),
- # :marker_color => 'blue',
- # :background_colors => %w(black grey)
- # }
- #
- # :background_image => 'squirrel.png' is also possible.
- #
- # (Or hopefully something better looking than that.)
- #
- def theme=(options)
- reset_themes()
-
- defaults = {
- :colors => ['black', 'white'],
- :additional_line_colors => [],
- :marker_color => 'white',
- :font_color => 'black',
- :background_colors => nil,
- :background_image => nil
- }
- @theme_options = defaults.merge options
-
- @colors = @theme_options[:colors]
- @marker_color = @theme_options[:marker_color]
- @font_color = @theme_options[:font_color] || @marker_color
- @additional_line_colors = @theme_options[:additional_line_colors]
-
- render_background
- end
-
- # A color scheme similar to the popular presentation software.
- def theme_keynote
- # Colors
- @blue = '#6886B4'
- @yellow = '#FDD84E'
- @green = '#72AE6E'
- @red = '#D1695E'
- @purple = '#8A6EAF'
- @orange = '#EFAA43'
- @white = 'white'
- @colors = [@yellow, @blue, @green, @red, @purple, @orange, @white]
-
- self.theme = {
- :colors => @colors,
- :marker_color => 'white',
- :font_color => 'white',
- :background_colors => ['black', '#4a465a']
- }
- end
-
- # A color scheme plucked from the colors on the popular usability blog.
- def theme_37signals
- # Colors
- @green = '#339933'
- @purple = '#cc99cc'
- @blue = '#336699'
- @yellow = '#FFF804'
- @red = '#ff0000'
- @orange = '#cf5910'
- @black = 'black'
- @colors = [@yellow, @blue, @green, @red, @purple, @orange, @black]
-
- self.theme = {
- :colors => @colors,
- :marker_color => 'black',
- :font_color => 'black',
- :background_colors => ['#d1edf5', 'white']
- }
- end
-
- # A color scheme from the colors used on the 2005 Rails keynote
- # presentation at RubyConf.
- def theme_rails_keynote
- # Colors
- @green = '#00ff00'
- @grey = '#333333'
- @orange = '#ff5d00'
- @red = '#f61100'
- @white = 'white'
- @light_grey = '#999999'
- @black = 'black'
- @colors = [@green, @grey, @orange, @red, @white, @light_grey, @black]
-
- self.theme = {
- :colors => @colors,
- :marker_color => 'white',
- :font_color => 'white',
- :background_colors => ['#0083a3', '#0083a3']
- }
- end
-
- # A color scheme similar to that used on the popular podcast site.
- def theme_odeo
- # Colors
- @grey = '#202020'
- @white = 'white'
- @dark_pink = '#a21764'
- @green = '#8ab438'
- @light_grey = '#999999'
- @dark_blue = '#3a5b87'
- @black = 'black'
- @colors = [@grey, @white, @dark_blue, @dark_pink, @green, @light_grey, @black]
-
- self.theme = {
- :colors => @colors,
- :marker_color => 'white',
- :font_color => 'white',
- :background_colors => ['#ff47a4', '#ff1f81']
- }
- end
-
- # A pastel theme
- def theme_pastel
- # Colors
- @colors = [
- '#a9dada', # blue
- '#aedaa9', # green
- '#daaea9', # peach
- '#dadaa9', # yellow
- '#a9a9da', # dk purple
- '#daaeda', # purple
- '#dadada' # grey
- ]
-
- self.theme = {
- :colors => @colors,
- :marker_color => '#aea9a9', # Grey
- :font_color => 'black',
- :background_colors => 'white'
- }
- end
-
- # A greyscale theme
- def theme_greyscale
- # Colors
- @colors = [
- '#282828', #
- '#383838', #
- '#686868', #
- '#989898', #
- '#c8c8c8', #
- '#e8e8e8', #
- ]
-
- self.theme = {
- :colors => @colors,
- :marker_color => '#aea9a9', # Grey
- :font_color => 'black',
- :background_colors => 'white'
- }
- end
-
- # Parameters are an array where the first element is the name of the dataset
- # and the value is an array of values to plot.
- #
- # Can be called multiple times with different datasets for a multi-valued
- # graph.
- #
- # If the color argument is nil, the next color from the default theme will
- # be used.
- #
- # NOTE: If you want to use a preset theme, you must set it before calling
- # data().
- #
- # Example:
- # data("Bart S.", [95, 45, 78, 89, 88, 76], '#ffcc00')
- def data(name, data_points=[], color=nil)
- data_points = Array(data_points) # make sure it's an array
- @data << [name, data_points, (color || increment_color)]
- # Set column count if this is larger than previous counts
- @column_count = (data_points.length > @column_count) ? data_points.length : @column_count
-
- # Pre-normalize
- data_points.each_with_index do |data_point, index|
- next if data_point.nil?
-
- # Setup max/min so spread starts at the low end of the data points
- if @maximum_value.nil? && @minimum_value.nil?
- @maximum_value = @minimum_value = data_point
- end
-
- # TODO Doesn't work with stacked bar graphs
- # Original: @maximum_value = larger_than_max?(data_point, index) ? max(data_point, index) : @maximum_value
- @maximum_value = larger_than_max?(data_point) ? data_point : @maximum_value
- @has_data = true if @maximum_value > 0
-
- @minimum_value = less_than_min?(data_point) ? data_point : @minimum_value
- @has_data = true if @minimum_value < 0
- end
- end
-
- # Writes the graph to a file. Defaults to 'graph.png'
- #
- # Example:
- # write('graphs/my_pretty_graph.png')
- def write(filename="graph.png")
- draw()
- @base_image.write(filename)
- end
-
- # Return the graph as a rendered binary blob.
- def to_blob(fileformat='PNG')
- draw()
- return @base_image.to_blob do
- self.format = fileformat
- end
- end
-
-
-
-protected
-
- # Overridden by subclasses to do the actual plotting of the graph.
- #
- # Subclasses should start by calling super() for this method.
- def draw
- make_stacked if @stacked
- setup_drawing
-
- debug {
- # Outer margin
- @d.rectangle( @left_margin, @top_margin,
- @raw_columns - @right_margin, @raw_rows - @bottom_margin)
- # Graph area box
- @d.rectangle( @graph_left, @graph_top, @graph_right, @graph_bottom)
- }
- end
-
- # Calculates size of drawable area and draws the decorations.
- #
- # * line markers
- # * legend
- # * title
- def setup_drawing
- # Maybe should be done in one of the following functions for more granularity.
- unless @has_data
- draw_no_data()
- return
- end
-
- normalize()
- setup_graph_measurements()
- sort_norm_data() if @sort # Sort norm_data with avg largest values set first (for display)
-
- draw_legend()
- draw_line_markers()
- draw_axis_labels()
- draw_title
- end
-
- # Make copy of data with values scaled between 0-100
- def normalize(force=false)
- if @norm_data.nil? || force
- @norm_data = []
- return unless @has_data
-
- calculate_spread
-
- @data.each do |data_row|
- norm_data_points = []
- data_row[DATA_VALUES_INDEX].each do |data_point|
- if data_point.nil?
- norm_data_points << nil
- else
- norm_data_points << ((data_point.to_f - @minimum_value.to_f ) / @spread)
- end
- end
- @norm_data << [data_row[DATA_LABEL_INDEX], norm_data_points, data_row[DATA_COLOR_INDEX]]
- end
- end
- end
-
- def calculate_spread # :nodoc:
- @spread = @maximum_value.to_f - @minimum_value.to_f
- @spread = @spread > 0 ? @spread : 1
- end
-
- # Calculates size of drawable area, general font dimensions, etc.
- def setup_graph_measurements
- @marker_caps_height = @hide_line_markers ? 0 :
- calculate_caps_height(@marker_font_size)
- @title_caps_height = @hide_title ? 0 :
- calculate_caps_height(@title_font_size)
- @legend_caps_height = @hide_legend ? 0 :
- calculate_caps_height(@legend_font_size)
-
- if @hide_line_markers
- (@graph_left,
- @graph_right_margin,
- @graph_bottom_margin) = [@left_margin, @right_margin, @bottom_margin]
- else
- longest_left_label_width = 0
- if @has_left_labels
- longest_left_label_width = calculate_width(@marker_font_size,
- labels.values.inject('') { |value, memo| (value.to_s.length > memo.to_s.length) ? value : memo }) * 1.25
- else
- longest_left_label_width = calculate_width(@marker_font_size,
- label(@maximum_value.to_f))
- end
-
- # Shift graph if left line numbers are hidden
- line_number_width = @hide_line_numbers && !@has_left_labels ?
- 0.0 :
- (longest_left_label_width + LABEL_MARGIN * 2)
-
- @graph_left = @left_margin +
- line_number_width +
- (@y_axis_label.nil? ? 0.0 : @marker_caps_height + LABEL_MARGIN * 2)
- # Make space for half the width of the rightmost column label.
- # Might be greater than the number of columns if between-style bar markers are used.
- last_label = @labels.keys.sort.last.to_i
- extra_room_for_long_label = (last_label >= (@column_count-1) && @center_labels_over_point) ?
- calculate_width(@marker_font_size, @labels[last_label])/2.0 :
- 0
- @graph_right_margin = @right_margin + extra_room_for_long_label
-
- @graph_bottom_margin = @bottom_margin +
- @marker_caps_height + LABEL_MARGIN
- end
-
- @graph_right = @raw_columns - @graph_right_margin
- @graph_width = @raw_columns - @graph_left - @graph_right_margin
-
- # When @hide title, leave a TITLE_MARGIN space for aesthetics.
- # Same with @hide_legend
- @graph_top = @top_margin +
- (@hide_title ? TITLE_MARGIN : @title_caps_height + TITLE_MARGIN * 2) +
- (@hide_legend ? LEGEND_MARGIN : @legend_caps_height + LEGEND_MARGIN * 2)
-
- x_axis_label_height = @x_axis_label.nil? ? 0.0 :
- @marker_caps_height + LABEL_MARGIN
- @graph_bottom = @raw_rows - @graph_bottom_margin - x_axis_label_height
- @graph_height = @graph_bottom - @graph_top
- end
-
- # Draw the optional labels for the x axis and y axis.
- def draw_axis_labels
- unless @x_axis_label.nil?
- # X Axis
- # Centered vertically and horizontally by setting the
- # height to 1.0 and the width to the width of the graph.
- x_axis_label_y_coordinate = @graph_bottom + LABEL_MARGIN * 2 + @marker_caps_height
-
- # TODO Center between graph area
- @d.fill = @font_color
- @d.font = @font if @font
- @d.stroke('transparent')
- @d.pointsize = scale_fontsize(@marker_font_size)
- @d.gravity = NorthGravity
- @d = @d.annotate_scaled( @base_image,
- @raw_columns, 1.0,
- 0.0, x_axis_label_y_coordinate,
- @x_axis_label, @scale)
- debug { @d.line 0.0, x_axis_label_y_coordinate, @raw_columns, x_axis_label_y_coordinate }
- end
-
- unless @y_axis_label.nil?
- # Y Axis, rotated vertically
- @d.rotation = 90.0
- @d.gravity = CenterGravity
- @d = @d.annotate_scaled( @base_image,
- 1.0, @raw_rows,
- @left_margin + @marker_caps_height / 2.0, 0.0,
- @y_axis_label, @scale)
- @d.rotation = -90.0
- end
- end
-
- # Draws horizontal background lines and labels
- def draw_line_markers
- return if @hide_line_markers
-
- @d = @d.stroke_antialias false
-
- if @y_axis_increment.nil?
- # Try to use a number of horizontal lines that will come out even.
- #
- # TODO Do the same for larger numbers...100, 75, 50, 25
- if @marker_count.nil?
- (3..7).each do |lines|
- if @spread % lines == 0.0
- @marker_count = lines
- break
- end
- end
- @marker_count ||= 4
- end
- @increment = (@spread > 0) ? significant(@spread / @marker_count) : 1
- else
- # TODO Make this work for negative values
- @maximum_value = [@maximum_value.ceil, @y_axis_increment].max
- @minimum_value = @minimum_value.floor
- calculate_spread
- normalize(true)
-
- @marker_count = (@spread / @y_axis_increment).to_i
- @increment = @y_axis_increment
- end
- @increment_scaled = @graph_height.to_f / (@spread / @increment)
-
- # Draw horizontal line markers and annotate with numbers
- (0..@marker_count).each do |index|
- y = @graph_top + @graph_height - index.to_f * @increment_scaled
-
- @d = @d.stroke(@marker_color)
- @d = @d.stroke_width 1
- @d = @d.line(@graph_left, y, @graph_right, y)
-
- marker_label = index * @increment + @minimum_value.to_f
-
- unless @hide_line_numbers
- @d.fill = @font_color
- @d.font = @font if @font
- @d.stroke('transparent')
- @d.pointsize = scale_fontsize(@marker_font_size)
- @d.gravity = EastGravity
-
- # Vertically center with 1.0 for the height
- @d = @d.annotate_scaled( @base_image,
- @graph_left - LABEL_MARGIN, 1.0,
- 0.0, y,
- label(marker_label), @scale)
- end
- end
-
- # # Submitted by a contibutor...the utility escapes me
- # i = 0
- # @additional_line_values.each do |value|
- # @increment_scaled = @graph_height.to_f / (@maximum_value.to_f / value)
- #
- # y = @graph_top + @graph_height - @increment_scaled
- #
- # @d = @d.stroke(@additional_line_colors[i])
- # @d = @d.line(@graph_left, y, @graph_right, y)
- #
- #
- # @d.fill = @additional_line_colors[i]
- # @d.font = @font if @font
- # @d.stroke('transparent')
- # @d.pointsize = scale_fontsize(@marker_font_size)
- # @d.gravity = EastGravity
- # @d = @d.annotate_scaled( @base_image,
- # 100, 20,
- # -10, y - (@marker_font_size/2.0),
- # "", @scale)
- # i += 1
- # end
-
- @d = @d.stroke_antialias true
- end
-
- # Draws a legend with the names of the datasets matched to the colors used
- # to draw them.
- def draw_legend
- return if @hide_legend
-
- @legend_labels = @data.collect {|item| item[DATA_LABEL_INDEX] }
-
- legend_square_width = @legend_box_size # small square with color of this item
-
- # May fix legend drawing problem at small sizes
- @d.font = @font if @font
- @d.pointsize = @legend_font_size
-
- metrics = @d.get_type_metrics(@base_image, @legend_labels.join(''))
- legend_text_width = metrics.width
- legend_width = legend_text_width +
- (@legend_labels.length * legend_square_width * 2.7)
- legend_left = (@raw_columns - legend_width) / 2
- legend_increment = legend_width / @legend_labels.length.to_f
-
- current_x_offset = legend_left
- current_y_offset = @hide_title ?
- @top_margin + LEGEND_MARGIN :
- @top_margin +
- TITLE_MARGIN + @title_caps_height +
- LEGEND_MARGIN
-
- debug { @d.line 0.0, current_y_offset, @raw_columns, current_y_offset }
-
- @legend_labels.each_with_index do |legend_label, index|
-
- # Draw label
- @d.fill = @font_color
- @d.font = @font if @font
- @d.pointsize = scale_fontsize(@legend_font_size)
- @d.stroke('transparent')
- @d.font_weight = NormalWeight
- @d.gravity = WestGravity
- @d = @d.annotate_scaled( @base_image,
- @raw_columns, 1.0,
- current_x_offset + (legend_square_width * 1.7), current_y_offset,
- legend_label.to_s, @scale)
-
- # Now draw box with color of this dataset
- @d = @d.stroke('transparent')
- @d = @d.fill @data[index][DATA_COLOR_INDEX]
- @d = @d.rectangle(current_x_offset,
- current_y_offset - legend_square_width / 2.0,
- current_x_offset + legend_square_width,
- current_y_offset + legend_square_width / 2.0)
-
- @d.pointsize = @legend_font_size
- metrics = @d.get_type_metrics(@base_image, legend_label.to_s)
- current_string_offset = metrics.width + (legend_square_width * 2.7)
- current_x_offset += current_string_offset
- end
- @color_index = 0
- end
-
- # Draws a title on the graph.
- def draw_title
- return if (@hide_title || @title.nil?)
-
- @d.fill = @font_color
- @d.font = @font if @font
- @d.stroke('transparent')
- @d.pointsize = scale_fontsize(@title_font_size)
- @d.font_weight = BoldWeight
- @d.gravity = NorthGravity
- @d = @d.annotate_scaled( @base_image,
- @raw_columns, 1.0,
- 0, @top_margin,
- @title, @scale)
- end
-
- # Draws column labels below graph, centered over x_offset
- #--
- # TODO Allow WestGravity as an option
- def draw_label(x_offset, index)
- return if @hide_line_markers
-
- if !@labels[index].nil? && @labels_seen[index].nil?
- y_offset = @graph_bottom + LABEL_MARGIN
-
- @d.fill = @font_color
- @d.font = @font if @font
- @d.stroke('transparent')
- @d.font_weight = NormalWeight
- @d.pointsize = scale_fontsize(@marker_font_size)
- @d.gravity = NorthGravity
- @d = @d.annotate_scaled(@base_image,
- 1.0, 1.0,
- x_offset, y_offset,
- @labels[index], @scale)
- @labels_seen[index] = 1
- debug { @d.line 0.0, y_offset, @raw_columns, y_offset }
- end
- end
-
- # Shows an error message because you have no data.
- def draw_no_data
- @d.fill = @font_color
- @d.font = @font if @font
- @d.stroke('transparent')
- @d.font_weight = NormalWeight
- @d.pointsize = scale_fontsize(80)
- @d.gravity = CenterGravity
- @d = @d.annotate_scaled( @base_image,
- @raw_columns, @raw_rows/2.0,
- 0, 10,
- @no_data_message, @scale)
- end
-
- # Finds the best background to render based on the provided theme options.
- #
- # Creates a @base_image to draw on.
- def render_background
- case @theme_options[:background_colors]
- when Array
- @base_image = render_gradiated_background(*@theme_options[:background_colors])
- when String
- @base_image = render_solid_background(@theme_options[:background_colors])
- else
- @base_image = render_image_background(*@theme_options[:background_image])
- end
- end
-
- # Make a new image at the current size with a solid +color+.
- def render_solid_background(color)
- Image.new(@columns, @rows) {
- self.background_color = color
- }
- end
-
- # Use with a theme definition method to draw a gradiated background.
- def render_gradiated_background(top_color, bottom_color)
- Image.new(@columns, @rows,
- GradientFill.new(0, 0, 100, 0, top_color, bottom_color))
- end
-
- # Use with a theme to use an image (800x600 original) background.
- def render_image_background(image_path)
- image = Image.read(image_path)
- if @scale != 1.0
- image[0].resize!(@scale) # TODO Resize with new scale (crop if necessary for wide graph)
- end
- image[0]
- end
-
- # Use with a theme to make a transparent background
- def render_transparent_background
- Image.new(@columns, @rows) do
- self.background_color = 'transparent'
- end
- end
-
- # Resets everything to defaults (except data).
- def reset_themes
- @color_index = 0
- @labels_seen = {}
- @theme_options = {}
-
- @d = Draw.new
- # Scale down from 800x600 used to calculate drawing.
- @d = @d.scale(@scale, @scale)
- end
-
- def scale(value) # :nodoc:
- value * @scale
- end
-
- # Return a comparable fontsize for the current graph.
- def scale_fontsize(value)
- new_fontsize = value * @scale
- # return new_fontsize < 10.0 ? 10.0 : new_fontsize
- return new_fontsize
- end
-
- def clip_value_if_greater_than(value, max_value) # :nodoc:
- (value > max_value) ? max_value : value
- end
-
- # Overridden by subclasses such as stacked bar.
- def larger_than_max?(data_point, index=0) # :nodoc:
- data_point > @maximum_value
- end
-
- def less_than_min?(data_point, index=0) # :nodoc:
- data_point < @minimum_value
- end
-
- # Overridden by subclasses that need it.
- def max(data_point, index) # :nodoc:
- data_point
- end
-
- # Overridden by subclasses that need it.
- def min(data_point, index) # :nodoc:
- data_point
- end
-
- def significant(inc) # :nodoc:
- return 1.0 if inc == 0 # Keep from going into infinite loop
- factor = 1.0
- while (inc < 10)
- inc *= 10
- factor /= 10
- end
-
- while (inc > 100)
- inc /= 10
- factor *= 10
- end
-
- res = inc.floor * factor
- if (res.to_i.to_f == res)
- res.to_i
- else
- res
- end
- end
-
- # Sort with largest overall summed value at front of array so it shows up
- # correctly in the drawn graph.
- def sort_norm_data
- @norm_data.sort! { |a,b| sums(b[1]) <=> sums(a[1]) }
- end
-
- def sums(data_set) # :nodoc:
- total_sum = 0
- data_set.collect {|num| total_sum += num.to_f }
- total_sum
- end
-
- # Used by StackedBar and child classes.
- #
- # May need to be moved to the StackedBar class.
- def get_maximum_by_stack
- # Get sum of each stack
- max_hash = {}
- @data.each do |data_set|
- data_set[DATA_VALUES_INDEX].each_with_index do |data_point, i|
- max_hash[i] = 0.0 unless max_hash[i]
- max_hash[i] += data_point.to_f
- end
- end
-
- # @maximum_value = 0
- max_hash.keys.each do |key|
- @maximum_value = max_hash[key] if max_hash[key] > @maximum_value
- end
- @minimum_value = 0
- end
-
- def make_stacked # :nodoc:
- stacked_values = Array.new(@column_count, 0)
- @data.each do |value_set|
- value_set[1].each_with_index do |value, index|
- stacked_values[index] += value
- end
- value_set[1] = stacked_values.dup
- end
- end
-
-private
-
- # Takes a block and draws it if DEBUG is true.
- #
- # Example:
- # debug { @d.rectangle x1, y1, x2, y2 }
- def debug
- if DEBUG
- @d = @d.fill 'transparent'
- @d = @d.stroke 'turquoise'
- @d = yield
- end
- end
-
- # Uses the next color in your color list.
- def increment_color
- if @color_index == 0
- @color_index += 1
- return @colors[0]
- else
- if @color_index < @colors.length
- @color_index += 1
- return @colors[@color_index - 1]
- else
- # Start over
- @color_index = 0
- return @colors[-1]
- end
- end
- end
-
- # Return a formatted string representing a number value that should be
- # printed as a label.
- def label(value)
- if (@spread.to_f % @marker_count.to_f == 0) || !@y_axis_increment.nil?
- return value.to_i.to_s
- end
-
- if @spread > 10.0
- sprintf("%0i", value)
- elsif @spread >= 3.0
- sprintf("%0.2f", value)
- else
- value.to_s
- end
- end
-
- # Returns the height of the capital letter 'X' for the current font and
- # size.
- #
- # Not scaled since it deals with dimensions that the regular scaling will
- # handle.
- def calculate_caps_height(font_size)
- @d.pointsize = font_size
- @d.get_type_metrics(@base_image, 'X').height
- end
-
- # Returns the width of a string at this pointsize.
- #
- # Not scaled since it deals with dimensions that the regular
- # scaling will handle.
- def calculate_width(font_size, text)
- @d.pointsize = font_size
- @d.get_type_metrics(@base_image, text.to_s).width
- end
-
- end # Gruff::Base
-
- class IncorrectNumberOfDatasetsException < StandardError; end
-
-end # Gruff
-
-module Magick
-
- class Draw
-
- # Additional method to scale annotation text since Draw.scale doesn't.
- def annotate_scaled(img, width, height, x, y, text, scale)
- scaled_width = (width * scale) >= 1 ? (width * scale) : 1
- scaled_height = (height * scale) >= 1 ? (height * scale) : 1
-
- self.annotate( img,
- scaled_width, scaled_height,
- x * scale, y * scale,
- text)
- end
-
- end
-
-end # Magick
-
View
109 lib/gruff/bullet.rb
@@ -1,109 +0,0 @@
-require File.dirname(__FILE__) + '/base'
-
-class Gruff::Bullet < Gruff::Base
-
- def initialize(target_width="400x40")
- if not Numeric === target_width
- geometric_width, geometric_height = target_width.split('x')
- @columns = geometric_width.to_f
- @rows = geometric_height.to_f
- else
- @columns = target_width.to_f
- @rows = target_width.to_f / 5.0
- end
-
- initialize_ivars
-
- reset_themes
- theme_greyscale
- @title_font_size = 20
- end
-
- def data(value, maximum_value, options={})
- @value = value.to_f
- @maximum_value = maximum_value.to_f
- @options = options
- @options.map { |k, v| @options[k] = v.to_f if v === Numeric }
- end
-
- # def setup_drawing
- # # Maybe should be done in one of the following functions for more granularity.
- # unless @has_data
- # draw_no_data()
- # return
- # end
- #
- # normalize()
- # setup_graph_measurements()
- # sort_norm_data() if @sort # Sort norm_data with avg largest values set first (for display)
- #
- # draw_legend()
- # draw_line_markers()
- # draw_axis_labels()
- # draw_title
- # end
-
- def draw
- # TODO Left label
- # TODO Bottom labels and markers
- # @graph_bottom
- # Calculations are off 800x???
-
- @colors.reverse!
-
- draw_title
-
- @margin = 30.0
- @thickness = @raw_rows / 6.0
- @right_margin = @margin
- @graph_left = @title_width * 1.3 rescue @margin # HACK Need to calculate real width
- @graph_width = @raw_columns - @graph_left - @right_margin
- @graph_height = @thickness * 3.0
-
- # Background
- @d = @d.fill @colors[0]
- @d = @d.rectangle(@graph_left, 0, @graph_left + @graph_width, @graph_height)
-
- [:high, :low].each_with_index do |indicator, index|
- next unless @options.has_key?(indicator)
- @d = @d.fill @colors[index + 1]
- indicator_width_x = @graph_left + @graph_width * (@options[indicator] / @maximum_value)
- @d = @d.rectangle(@graph_left, 0, indicator_width_x, @graph_height)
- end
-
- if @options.has_key?(:target)
- @d = @d.fill @font_color
- target_x = @graph_left + @graph_width * (@options[:target] / @maximum_value)
- half_thickness = @thickness / 2.0
- @d = @d.rectangle(target_x, half_thickness, target_x + half_thickness, @thickness * 2 + half_thickness)
- end
-
- # Value
- @d = @d.fill @font_color
- @d = @d.rectangle(@graph_left, @thickness, @graph_left + @graph_width * (@value / @maximum_value), @thickness * 2)
-
- @d.draw(@base_image)
- end
-
- def draw_title
- return unless @title
-
- @font_height = calculate_caps_height(scale_fontsize(@title_font_size))
- @title_width = calculate_width(@title_font_size, @title)
-
- @d.fill = @font_color
- @d.font = @font if @font
- @d.stroke('transparent')
- @d.font_weight = NormalWeight
- @d.pointsize = scale_fontsize(@title_font_size)
- @d.gravity = NorthWestGravity
- @d = @d.annotate_scaled(*[
- @base_image,
- 1.0, 1.0,
- @font_height/2, @font_height/2,
- @title,
- @scale
- ])
- end
-
-end
View
39 lib/gruff/deprecated.rb
@@ -1,39 +0,0 @@
-
-##
-# A mixin for methods that need to be deleted or have been
-# replaced by cleaner code.
-
-module Gruff
- module Deprecated
-
- def scale_measurements
- setup_graph_measurements
- end
-
- def total_height
- @rows + 10
- end
-
- def graph_top
- @graph_top * @scale
- end
-
- def graph_height
- @graph_height * @scale
- end
-
- def graph_left
- @graph_left * @scale
- end
-
- def graph_width
- @graph_width * @scale
- end
-
- # TODO Should be calculate_graph_height
- # def setup_graph_height
- # @graph_height = @graph_bottom - @graph_top
- # end
-
- end
-end
View
105 lib/gruff/line.rb
@@ -1,105 +0,0 @@
-
-require File.dirname(__FILE__) + '/base'
-
-##
-# Here's how to make a Line graph:
-#
-# g = Gruff::Line.new
-# g.title = "A Line Graph"
-# g.data 'Fries', [20, 23, 19, 8]
-# g.data 'Hamburgers', [50, 19, 99, 29]
-# g.write("test/output/line.png")
-#
-# There are also other options described below, such as #baseline_value, #baseline_color, #hide_dots, and #hide_lines.
-
-class Gruff::Line < Gruff::Base
-
- # Draw a dashed line at the given value
- attr_accessor :baseline_value
-
- # Color of the baseline
- attr_accessor :baseline_color
-
- # Hide parts of the graph to fit more datapoints, or for a different appearance.
- attr_accessor :hide_dots, :hide_lines
-
- # Call with target pixel width of graph (800, 400, 300), and/or 'false' to omit lines (points only).
- #
- # g = Gruff::Line.new(400) # 400px wide with lines
- #
- # g = Gruff::Line.new(400, false) # 400px wide, no lines (for backwards compatibility)
- #
- # g = Gruff::Line.new(false) # Defaults to 800px wide, no lines (for backwards compatibility)
- #
- # The preferred way is to call hide_dots or hide_lines instead.
- def initialize(*args)
- raise ArgumentError, "Wrong number of arguments" if args.length > 2
- if args.empty? or ((not Numeric === args.first) && (not String === args.first)) then
- super()
- else
- super args.shift
- end
-
- @hide_dots = @hide_lines = false
- @baseline_color = 'red'
- @baseline_value = nil
- end
-
- def draw
- super
-
- return unless @has_data
-
- # Check to see if more than one datapoint was given. NaN can result otherwise.
- @x_increment = (@column_count > 1) ? (@graph_width / (@column_count - 1).to_f) : @graph_width
-
- if (defined?(@norm_baseline)) then
- level = @graph_top + (@graph_height - @norm_baseline * @graph_height)
- @d = @d.push
- @d.stroke_color @baseline_color
- @d.fill_opacity 0.0
- @d.stroke_dasharray(10, 20)
- @d.stroke_width 5
- @d.line(@graph_left, level, @graph_left + @graph_width, level)
- @d = @d.pop
- end
-
- @norm_data.each do |data_row|
- prev_x = prev_y = nil
-
- data_row[1].each_with_index do |data_point, index|
- new_x = @graph_left + (@x_increment * index)
- next if data_point.nil?
-
- draw_label(new_x, index)
-
- new_y = @graph_top + (@graph_height - data_point * @graph_height)
-
- # Reset each time to avoid thin-line errors
- @d = @d.stroke data_row[DATA_COLOR_INDEX]
- @d = @d.fill data_row[DATA_COLOR_INDEX]
- @d = @d.stroke_opacity 1.0
- @d = @d.stroke_width clip_value_if_greater_than(@columns / (@norm_data.first[1].size * 4), 5.0)
-
- if !@hide_lines and !prev_x.nil? and !prev_y.nil? then
- @d = @d.line(prev_x, prev_y, new_x, new_y)
- end
- circle_radius = clip_value_if_greater_than(@columns / (@norm_data.first[1].size * 2.5), 5.0)
- @d = @d.circle(new_x, new_y, new_x - circle_radius, new_y) unless @hide_dots
-
- prev_x = new_x
- prev_y = new_y
- end
-
- end
-
- @d.draw(@base_image)
- end
-
- def normalize
- @maximum_value = [@maximum_value.to_f, @baseline_value.to_f].max
- super
- @norm_baseline = (@baseline_value.to_f / @maximum_value.to_f) if @baseline_value
- end
-
-end
View
32 lib/gruff/mini/bar.rb
@@ -1,32 +0,0 @@
-##
-#
-# Makes a small bar graph suitable for display at 200px or even smaller.
-#
-module Gruff
- module Mini
-
- class Bar < Gruff::Bar
-
- include Gruff::Mini::Legend
-
- def draw
- @hide_legend = true
- @hide_title = true
- @hide_line_numbers = true
-
- @marker_font_size = 50.0
- @minimum_value = 0.0
- @legend_font_size = 60.0
-
- expand_canvas_for_vertical_legend
-
- super
-
- draw_vertical_legend
- @d.draw(@base_image)
- end
-
- end
-
- end
-end
View
77 lib/gruff/mini/legend.rb
@@ -1,77 +0,0 @@
-module Gruff
- module Mini
- module Legend
-
- ##
- # The canvas needs to be bigger so we can put the legend beneath it.
-
- def expand_canvas_for_vertical_legend
- @original_rows = @raw_rows
- @rows += @data.length * calculate_caps_height(scale_fontsize(@legend_font_size)) * 1.7
- render_background
- end
-
- ##
- # Draw the legend beneath the existing graph.
-
- def draw_vertical_legend
-
- @legend_labels = @data.collect {|item| item[Gruff::Base::DATA_LABEL_INDEX] }
-
- legend_square_width = 40.0 # small square with color of this item
- legend_square_margin = 10.0
- @legend_left_margin = 100.0
- legend_top_margin = 40.0
-
- # May fix legend drawing problem at small sizes
- @d.font = @font if @font
- @d.pointsize = @legend_font_size
-
- current_x_offset = @legend_left_margin
- current_y_offset = @original_rows + legend_top_margin
-
- debug { @d.line 0.0, current_y_offset, @raw_columns, current_y_offset }
-
- @legend_labels.each_with_index do |legend_label, index|
-
- # Draw label
- @d.fill = @font_color
- @d.font = @font if @font
- @d.pointsize = scale_fontsize(@legend_font_size)
- @d.stroke = 'transparent'
- @d.font_weight = Magick::NormalWeight
- @d.gravity = Magick::WestGravity
- @d = @d.annotate_scaled( @base_image,
- @raw_columns, 1.0,
- current_x_offset + (legend_square_width * 1.7), current_y_offset,
- truncate_legend_label(legend_label), @scale)
-
- # Now draw box with color of this dataset
- @d = @d.stroke 'transparent'
- @d = @d.fill @data[index][Gruff::Base::DATA_COLOR_INDEX]
- @d = @d.rectangle(current_x_offset,
- current_y_offset - legend_square_width / 2.0,
- current_x_offset + legend_square_width,
- current_y_offset + legend_square_width / 2.0)
-
- current_y_offset += calculate_caps_height(@legend_font_size) * 1.7
- end
- @color_index = 0
- end
-
- ##
- # Shorten long labels so they will fit on the canvas.
- #
- # Department of Hu...
-
- def truncate_legend_label(label)
- truncated_label = label.to_s
- while calculate_width(scale_fontsize(@legend_font_size), truncated_label) > (@columns - @legend_left_margin - @right_margin) && (truncated_label.length > 1)
- truncated_label = truncated_label[0..truncated_label.length-2]
- end
- truncated_label + (truncated_label.length < label.to_s.length ? "" : '')
- end
-
- end