Changeset 162
- Timestamp:
- 08/24/06 08:21:41 (2 years ago)
- Files:
-
- trunk/Rakefile (modified) (1 diff)
- trunk/examples/line_graph.rb (modified) (1 diff)
- trunk/lib/SVG (deleted)
- trunk/lib/ruport.rb (modified) (1 diff)
- trunk/lib/ruport/format/engine.rb (modified) (1 diff)
- trunk/lib/ruport/format/plugin.rb (modified) (5 diffs)
- trunk/test/test_graph.rb (modified) (5 diffs)
- trunk/test/test_latex.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Rakefile
r150 r162 44 44 spec.add_dependency('pdf-writer', '>= 1.1.3') 45 45 spec.add_dependency("mailfactory", ">= 1.2.2") 46 spec.add_dependency('scruffy', '>= 0.2.2') 46 47 end 47 48 spec.author = "Gregory Brown" trunk/examples/line_graph.rb
r107 r162 10 10 graph = Ruport::Format.graph_object :plugin => :svg, :data => data 11 11 12 # The SVG:Graph library accepts a wide range of options to style the resulting graph. 13 # These are set using a simple hash. The ones used below are approximately 1/3 of the available 14 # options. 15 options = { 16 :graph_style => :line, 17 :height => 500, 18 :width => 600, 19 :graph_title => "Global Average Temperature vs. Number of Pirates", 20 :show_graph_title => true, 21 :x_title => "Number of Pirates (approx.)", 22 :show_x_title => true, 23 :y_title => "Global Average Temperature (C)", 24 :show_y_title => true, 25 :key => false, 26 :min_scale_value => 13, 27 :scale_integers => true, 28 :no_css => true 29 } 30 31 # apply the options to the graph 32 graph.options = options 12 # there are currently only a handful of options for customising the 13 # appearance of the graph. The ones listed here are all of them at 14 # the current time. 15 graph.width = 700 16 graph.height = 500 17 graph.title = "A Simple Line Graph" 18 graph.style = :line # other options: bar, smiles, area, stacked 33 19 34 20 # render the graph and print it to stdout. To save the output to a file, try: trunk/lib/ruport.rb
r150 r162 13 13 module Ruport 14 14 15 #begin; require 'rubygems'; rescue LoadError; nil end15 begin; require 'rubygems'; rescue LoadError; nil end 16 16 17 17 VERSION = "0.5.99" trunk/lib/ruport/format/engine.rb
r152 r162 106 106 class Format::Engine::Graph < Ruport::Format::Engine 107 107 108 attributes [:width, :height, :style, :title] 109 108 110 renderer do 109 111 super trunk/lib/ruport/format/plugin.rb
r160 r162 1 class InvalidGraphDataError < RuntimeError; end 2 class InvalidGraphOptionError < RuntimeError; end 3 1 4 require 'bigdecimal' 2 5 require 'tempfile' … … 122 125 @body << "\\end{longtable}\n" 123 126 124 if options[:format] == :pdf 125 generate_pdf 126 else 127 @report_header + @body + @report_footer 128 end 129 end 130 131 # much of the code in this method is derived from the rtex rails plugin, written 132 # by Bruce Williams. 133 # http://codefluency.com/code/rtex-rails-plugin/ 134 action :generate_pdf do 135 136 temp = Tempfile.new('ruport') 137 temp.binmode # For Windows 138 temp.puts @report_header + @body + @report_footer 139 temp.close 140 latex_return = '' 141 Dir.chdir(File.dirname(temp.path)) do 142 latex_return = `pdflatex --interaction=nonstopmode '#{temp.path}'` 143 end 144 145 pdfpath = temp.path.sub(/\..*?$/,'')+'.pdf' 146 147 File.unlink temp.path.sub( /\..*?$/,'.aux') 148 File.unlink temp.path.sub( /\..*?$/,'.log') 149 150 if File.exists?(pdfpath) 151 return File.open(pdfpath,'rb'){ |f| f.read } 152 #FIXME: the line below will never be executed 153 File.unlink pdfpath 154 else 155 raise RenderingError, "Could not generate PDF:\n#{latex_return}" 156 end 127 @report_header + @body + @report_footer 157 128 end 158 129 … … 167 138 data.each { |r| 168 139 if data.column_names.size != r.data.size 169 raise ArgumentError, "Column names and data do not match"140 raise InvalidGraphDataError, "Column names and data do not match" 170 141 end 171 142 r.data.each { |c| … … 174 145 c.kind_of?(Fixnum) || c.kind_of?(BigDecimal) 175 146 rescue 176 raise ArgumentError, "Unable to convert #{c.to_s} into a number"147 raise InvalidGraphDataError, "Unable to convert #{c.to_s} into a number" 177 148 end 178 149 } 179 150 } 180 151 181 raise RuntimeError, 'You must provide an options hash before rendering a graph' if self.options.nil? 182 183 # load the appropriate SVG::Graph class based on the graph_style option 184 case options[:graph_style] 185 when :bar 186 require "SVG/Graph/Bar" 187 graphclass = SVG::Graph::Bar 188 when :bar_horizontal 189 require "SVG/Graph/BarHorizontal" 190 graphclass = SVG::Graph::BarHorizontal 191 when :line 192 require "SVG/Graph/Line" 193 graphclass = SVG::Graph::Line 194 when :pie 195 require "SVG/Graph/Pie" 196 graphclass = SVG::Graph::Pie 197 else 198 raise "Unsupported graph type requested" 199 end 200 201 # create an instance of the graphing class 202 options[:fields] = data.column_names 203 @graph = graphclass.new(options) 152 raise InvalidGraphOptionError, 'You must provide a width before rendering a graph' if eng.width.nil? 153 raise InvalidGraphOptionError, 'You must provide a height before rendering a graph' if eng.height.nil? 154 raise InvalidGraphOptionError, 'You must provide a style before rendering a graph' if eng.style.nil? 155 if eng.style != :area && eng.style != :bar && 156 eng.style != :line && 157 eng.style != :smiles && 158 eng.style != :stacked 159 raise InvalidGraphOptionError, 'Invalid graph style' 160 end 161 162 require 'scruffy' 163 @graph = Scruffy::Graph.new 164 @graph.title = eng.title unless eng.title.nil? 165 @graph.theme = Scruffy::Themes::Mephisto.new 166 @graph.point_markers = @data.column_names 167 @graph_style = eng.style 168 @graph_width = eng.width 169 @graph_height = eng.height 204 170 } 205 171 … … 207 173 208 174 data.each_with_index { |r,i| 209 @graph.add_data({ 210 :data => r.data, 211 :title => r.tags[0] || 'series ' + (i+1).to_s 212 }) 175 @graph.add(@graph_style, 176 r.tags[0] || 'series ' + (i+1).to_s, 177 r.data) 213 178 } 214 179 215 180 # return the rendered graph 216 @graph. burn()181 @graph.render(:size => [@graph_width, @graph_height]) 217 182 end 218 183 trunk/test/test_graph.rb
r116 r162 15 15 def test_bar 16 16 graph = Ruport::Format.graph_object :plugin => :svg, :data => @data 17 graph.options = {:graph_style => :bar} 17 graph.title = "A Simple Bar Graph" 18 graph.width = 600 19 graph.height = 500 20 graph.style = :bar 18 21 output = graph.render 19 22 … … 21 24 end 22 25 23 # basic test to ensure horizontal pie charts render24 def test_bar_horizontal25 graph = Ruport::Format.graph_object :plugin => :svg, :data => @data26 graph.options = {:graph_style => :bar_horizontal}27 output = graph.render28 29 assert_not_equal nil, output30 end31 32 26 # basic test to ensure line charts render 33 27 def test_line 34 28 graph = Ruport::Format.graph_object :plugin => :svg, :data => @data 35 graph.options = {:graph_style => :line} 29 graph.title = "A Simple Line Graph" 30 graph.width = 600 31 graph.height = 500 32 graph.style = :line 33 36 34 output = graph.render 37 38 assert_not_equal nil, output39 end40 41 # basic test to ensure pie charts render42 def test_pie43 graph = Ruport::Format.graph_object :plugin => :svg, :data => @data44 graph.options = {:graph_style => :pie}45 output = graph.render46 47 35 assert_not_equal nil, output 48 36 end … … 51 39 def test_mismatched_headings 52 40 graph = Ruport::Format.graph_object :plugin => :svg, :data => @data_mismatched_headings 53 graph.options = {:graph_style => :line} 41 graph.title = "Mismatched Headings" 42 graph.width = 600 43 graph.height = 500 44 graph.style = :line 54 45 55 assert_raises( ArgumentError) {46 assert_raises(InvalidGraphDataError) { 56 47 output = graph.render 57 48 } … … 61 52 def test_floats 62 53 graph = Ruport::Format.graph_object :plugin => :svg, :data => @data_float 63 graph.options = {:graph_style => :line} 54 graph.title = "Graphing Floats" 55 graph.width = 600 56 graph.height = 500 57 graph.style = :line 64 58 output = graph.render 65 59 … … 70 64 def test_not_numbers 71 65 graph = Ruport::Format.graph_object :plugin => :svg, :data => @data_not_numbers 72 graph.options = {:graph_style => :line} 66 graph.title = "Graphing Things That Aren't Numbers" 67 graph.width = 600 68 graph.height = 500 69 graph.style = :line 73 70 74 assert_raises( ArgumentError) {71 assert_raises(InvalidGraphDataError) { 75 72 output = graph.render 76 73 } 77 74 end 78 75 79 # ensure an exception is raised if user tries to render a graph without setting any options80 def test_ no_options76 # ensure an exception is raised if non numeric data is graphed 77 def test_missing_required_option 81 78 graph = Ruport::Format.graph_object :plugin => :svg, :data => @data 79 graph.title = "Rendering a graph with a missing option" 80 graph.height = 500 81 graph.style = :line 82 82 83 assert_raises( RuntimeError) {83 assert_raises(InvalidGraphOptionError) { 84 84 output = graph.render 85 85 } 86 87 end88 89 # test to make sure user requested options are applied to the resulting graph90 def test_options_applied_to_rendered_graph91 graph = Ruport::Format.graph_object :plugin => :svg, :data => @data92 graph.options = {:graph_style => :line, :graph_title => 'Test', :show_graph_title => true, :no_css => true}93 output = graph.render94 95 # ensure the requested graph title is included in the SVG output. If that's there, we can96 # assume the rest are as well97 assert_not_equal nil, output[/class='mainTitle'/]98 99 86 end 100 87 trunk/test/test_latex.rb
r159 r162 13 13 report = Ruport::Format.table_object :plugin => :latex, :data => @data 14 14 output = report.render 15 assert_not_equal nil, output 15 assert_equal "\\documentclass", output[/\\documentclass/] 16 assert_equal "\\begin{document}", output[/\\begin\{document\}/] 17 assert_equal "\\end{document}", output[/\\end\{document\}/] 16 18 end 17 19 18 def test_table_to_pdf19 unless `pdflatex`20 report = Ruport::Format.table_object :plugin => :latex, :data => @data21 report.options = {:format => :pdf}22 output = report.render23 24 assert_not_equal nil, output25 end26 end27 20 end
