samhendley-scruffy 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. data/CHANGES.txt +115 -0
  2. data/LICENCE.txt +20 -0
  3. data/README.txt +66 -0
  4. data/lib/scruffy/components/background.rb +24 -0
  5. data/lib/scruffy/components/base.rb +57 -0
  6. data/lib/scruffy/components/data_markers.rb +26 -0
  7. data/lib/scruffy/components/graphs.rb +48 -0
  8. data/lib/scruffy/components/grid.rb +19 -0
  9. data/lib/scruffy/components/label.rb +17 -0
  10. data/lib/scruffy/components/legend.rb +105 -0
  11. data/lib/scruffy/components/style_info.rb +22 -0
  12. data/lib/scruffy/components/title.rb +19 -0
  13. data/lib/scruffy/components/value_markers.rb +32 -0
  14. data/lib/scruffy/components/viewport.rb +37 -0
  15. data/lib/scruffy/components.rb +21 -0
  16. data/lib/scruffy/formatters.rb +213 -0
  17. data/lib/scruffy/graph.rb +190 -0
  18. data/lib/scruffy/graph_state.rb +24 -0
  19. data/lib/scruffy/helpers/canvas.rb +41 -0
  20. data/lib/scruffy/helpers/layer_container.rb +95 -0
  21. data/lib/scruffy/helpers/meta.rb +5 -0
  22. data/lib/scruffy/helpers/point_container.rb +70 -0
  23. data/lib/scruffy/helpers.rb +12 -0
  24. data/lib/scruffy/layers/all_smiles.rb +137 -0
  25. data/lib/scruffy/layers/area.rb +46 -0
  26. data/lib/scruffy/layers/average.rb +67 -0
  27. data/lib/scruffy/layers/bar.rb +52 -0
  28. data/lib/scruffy/layers/base.rb +191 -0
  29. data/lib/scruffy/layers/line.rb +46 -0
  30. data/lib/scruffy/layers/pie.rb +123 -0
  31. data/lib/scruffy/layers/pie_slice.rb +119 -0
  32. data/lib/scruffy/layers/scatter.rb +21 -0
  33. data/lib/scruffy/layers/sparkline_bar.rb +39 -0
  34. data/lib/scruffy/layers/stacked.rb +87 -0
  35. data/lib/scruffy/layers.rb +24 -0
  36. data/lib/scruffy/rasterizers/batik_rasterizer.rb +39 -0
  37. data/lib/scruffy/rasterizers/rmagick_rasterizer.rb +27 -0
  38. data/lib/scruffy/rasterizers.rb +14 -0
  39. data/lib/scruffy/renderers/base.rb +95 -0
  40. data/lib/scruffy/renderers/cubed.rb +44 -0
  41. data/lib/scruffy/renderers/cubed3d.rb +53 -0
  42. data/lib/scruffy/renderers/empty.rb +22 -0
  43. data/lib/scruffy/renderers/pie.rb +20 -0
  44. data/lib/scruffy/renderers/reversed.rb +17 -0
  45. data/lib/scruffy/renderers/sparkline.rb +10 -0
  46. data/lib/scruffy/renderers/split.rb +48 -0
  47. data/lib/scruffy/renderers/standard.rb +36 -0
  48. data/lib/scruffy/renderers.rb +22 -0
  49. data/lib/scruffy/themes.rb +156 -0
  50. data/lib/scruffy/version.rb +9 -0
  51. data/lib/scruffy.rb +30 -0
  52. data/test/graph_creation_test.rb +101 -0
  53. data/test/test_helper.rb +2 -0
  54. metadata +135 -0
@@ -0,0 +1,119 @@
1
+ module Scruffy::Layers
2
+ # ==Scruffy::Layers::PieSlice
3
+ #
4
+ # Author:: A.J. Ostman
5
+ # Date:: August 14th, 2006
6
+ #
7
+ # Basic Pie Chart Slice..
8
+
9
+ class PieSlice < Base
10
+
11
+ # Setup Constants
12
+ RADIANS = Math::PI / 180
13
+ MARKER_OFFSET_RATIO = 1.2
14
+ MARKER_FONT_SIZE = 6
15
+
16
+ attr_accessor :diameter
17
+ attr_accessor :percent_used
18
+ attr_accessor :degree_offset
19
+ attr_accessor :scaler
20
+ attr_accessor :center_x, :center_y
21
+
22
+ def draw(svg, coords, options = {})
23
+ # Scaler is the multiplier to normalize the values to a percentage across
24
+ # the Pie Chart
25
+ @scaler = options[:scaler] || 1
26
+
27
+ # Degree Offset is degrees by which the pie chart is twisted when it
28
+ # begins
29
+ @degree_offset = options[:degree_offset] || @options[:degree_offset] || 0
30
+
31
+ # Percent Used keeps track of where in the pie chart we are
32
+ @percent_used = options[:percent_used] || @options[:percent_used] || 0
33
+
34
+ # Diameter of the pie chart defaults to 80% of the height
35
+ @diameter = relative(options[:diameter]) || relative(@options[:diameter]) || relative(80.0)
36
+
37
+ # Stroke
38
+ stroke = options[:stroke] || @options[:stroke] || "none"
39
+
40
+ # Shadow
41
+ shadow = options[:shadow] || @options[:shadow_] || false
42
+ shadow_x = relative(options[:shadow_x]) || relative(@options[:shadow_x]) || relative(-0.5)
43
+ shadow_y = relative(options[:shadow_y]) || relative(@options[:shadow_y]) || relative(0.5)
44
+ shadow_color = options[:shadow_color] || @options[:shadow_color] || "white"
45
+ shadow_opacity = options[:shadow_opacity] || @options[:shadow_opacity] || 0.06
46
+
47
+ # Coordinates for the center of the pie chart.
48
+ @center_x = relative_width(options[:center_x]) || relative_width(@options[:center_x]) || relative_width(50)
49
+ @center_y = relative_height(options[:center_y]) || relative_height(@options[:center_y]) || relative_height(50)
50
+ radius = @diameter / 2.0
51
+
52
+ # Graphing calculated using percent of graph. We later multiply by 3.6 to
53
+ # convert to 360 degree system.
54
+ percent = @scaler * sum_values
55
+
56
+
57
+ # Calculate the Radian Start Point
58
+ radians_start = ((@percent_used * 3.6) + @degree_offset) * RADIANS
59
+ # Calculate the Radian End Point
60
+ radians_end = ((@percent_used + percent) * 3.6 + @degree_offset) * RADIANS
61
+
62
+ radians_mid_point = radians_start + ((radians_end - radians_start) / 2)
63
+
64
+ if options[:explode]
65
+ @center_x = @center_x + (Math.sin(radians_mid_point) * relative(options[:explode]))
66
+ @center_y = @center_y - (Math.cos(radians_mid_point) * relative(options[:explode]))
67
+ end
68
+
69
+
70
+ # Calculate the beginning coordinates
71
+ x_start = @center_x + (Math.sin(radians_start) * radius)
72
+ y_start = @center_y - (Math.cos(radians_start) * radius)
73
+
74
+ # Calculate the End Coords
75
+ x_end = @center_x + (Math.sin(radians_end) * radius)
76
+ y_end = @center_y - (Math.cos(radians_end) * radius)
77
+
78
+
79
+
80
+ # If percentage is really really close to 100% then draw a circle instead!
81
+ if percent >= 99.9999
82
+
83
+ if shadow
84
+ svg.circle(:cx => "#{@center_x + shadow_x}", :cy => "#{@center_y + shadow_y}", :r=>"#{radius}",:stroke => "none",
85
+ :fill => shadow_color.to_s, :style => "fill-opacity: #{shadow_opacity.to_s};")
86
+ end
87
+
88
+ svg.circle(:cx => "#{@center_x}", :cy => "#{@center_y}", :r=>"#{radius}",:stroke => stroke, :fill => color.to_s)
89
+
90
+ else
91
+ if shadow
92
+ svg.path(:d => "M#{@center_x + shadow_x},#{@center_y + shadow_y} L#{x_start + shadow_x},#{y_start + shadow_y} A#{radius},#{radius} 0, #{percent >= 50 ? '1' : '0'}, 1, #{x_end + shadow_x} #{y_end + shadow_y} Z",
93
+ :fill => shadow_color.to_s, :style => "fill-opacity: #{shadow_opacity.to_s};")
94
+ end
95
+
96
+ svg.path(:d => "M#{@center_x},#{@center_y} L#{x_start},#{y_start} A#{radius},#{radius} 0, #{percent >= 50 ? '1' : '0'}, 1, #{x_end} #{y_end} Z",
97
+ :stroke => stroke, :fill => color.to_s)
98
+ end
99
+
100
+ text_x = @center_x + (Math.sin(radians_mid_point) * radius * MARKER_OFFSET_RATIO)
101
+ text_y = @center_y - (Math.cos(radians_mid_point) * radius * MARKER_OFFSET_RATIO)
102
+
103
+ svg.text("#{sprintf('%d', percent)}%",
104
+ :x => text_x,
105
+ :y => text_y + relative(MARKER_FONT_SIZE / 2),
106
+ 'font-size' => relative(MARKER_FONT_SIZE),
107
+ 'font-family' => options[:theme].font_family,
108
+ :fill => (options[:theme].marker || 'black').to_s,
109
+ 'text-anchor' => 'middle')
110
+ end
111
+
112
+ protected
113
+ def generate_coordinates(options = {})
114
+ # Coordinate Generation didn't make much sense here. Overridden just
115
+ # because Brasten said this would be overridden.
116
+ end
117
+ end
118
+
119
+ end
@@ -0,0 +1,21 @@
1
+ module Scruffy::Layers
2
+ # ==Scruffy::Layers::Line
3
+ #
4
+ # Author:: Mat Schaffer
5
+ # Date:: March 20th, 2007
6
+ #
7
+ # Simple scatter graph
8
+ class Scatter < Base
9
+
10
+ # Renders scatter graph.
11
+ def draw(svg, coords, options={})
12
+ svg.g(:class => 'shadow', :transform => "translate(#{relative(0.5)}, #{relative(0.5)})") {
13
+ coords.each { |coord| svg.circle( :cx => coord.first, :cy => coord.last + relative(0.9), :r => relative(2),
14
+ :style => "stroke-width: #{relative(2)}; stroke: black; opacity: 0.35;" ) }
15
+ }
16
+
17
+ coords.each { |coord| svg.circle( :cx => coord.first, :cy => coord.last, :r => relative(2),
18
+ :style => "stroke-width: #{relative(2)}; stroke: #{color.to_s}; fill: #{color.to_s}" ) }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ module Scruffy
2
+ module Layers
3
+ # Experimental, do not use.
4
+ class SparklineBar < Base
5
+
6
+ def draw(svg, coords, options = {})
7
+ zero_point = @height / 2.0
8
+
9
+ coords.each do |coord|
10
+ x, y, bar_height = (coord.first-(@bar_width * 0.5)), coord.last, (height - coord.last)
11
+
12
+ bar_color = (y > zero_point) ? 'black' : 'red'
13
+ bar_height = (bar_height - zero_point)
14
+
15
+ #y = (bar_height < 0) ?
16
+
17
+ # svg.rect( :x => x, :y => zero_point, :width => @bar_width, :height => ,
18
+ # :fill => bar_color, :stroke => 'none', 'style' => "opacity: #{opacity}" )
19
+ end
20
+ end
21
+
22
+ protected
23
+ def generate_coordinates(options = {})
24
+ @bar_width = (width / points.size) * 0.9
25
+ options[:point_distance] = (width - (width / points.size)) / (points.size - 1).to_f
26
+
27
+ #TODO iteration by index on points. Needs to change
28
+ coords = (0...points.size).map do |idx|
29
+ x_coord = (options[:point_distance] * idx) + (width / points.size * 0.5)
30
+
31
+ relative_percent = ((points[idx] == min_value) ? 0 : ((points[idx] - min_value) / (max_value - min_value).to_f))
32
+ y_coord = (height - (height * relative_percent))
33
+ [x_coord, y_coord]
34
+ end
35
+ coords
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,87 @@
1
+ module Scruffy::Layers
2
+ # ==Scruffy::Layers::Stacked
3
+ #
4
+ # Author:: Brasten Sager
5
+ # Date:: August 12th, 2006
6
+ #
7
+ # Provides a generic way for stacking graphs. This may or may not
8
+ # do what you'd expect under every situation, but it at least kills
9
+ # a couple birds with one stone (stacked bar graphs and stacked area
10
+ # graphs work fine).
11
+ class Stacked < Base
12
+ include Scruffy::Helpers::LayerContainer
13
+
14
+ # Returns new Stacked graph.
15
+ #
16
+ # You can provide a block for easily adding layers during (just after) initialization.
17
+ # Example:
18
+ # Stacked.new do |stacked|
19
+ # stacked << Scruffy::Layers::Line.new( ... )
20
+ # stacked.add(:bar, 'My Bar', [...])
21
+ # end
22
+ #
23
+ # The initialize method passes itself to the block, and since stacked is a LayerContainer,
24
+ # layers can be added just as if they were being added to Graph.
25
+ def initialize(options={}, &block)
26
+ super(options)
27
+
28
+ block.call(self) # Allow for population of data with a block during initialization.
29
+ end
30
+
31
+ # Overrides Base#render to fiddle with layers' points to achieve a stacked effect.
32
+ def render(svg, options = {})
33
+ #TODO ensure this works with new points
34
+ current_points = points.dup
35
+
36
+ layers.each do |layer|
37
+ real_points = layer.points
38
+ layer.points = current_points
39
+ layer_options = options.dup
40
+ layer_options[:color] = layer.preferred_color || layer.color || options[:theme].next_color
41
+ layer.render(svg, layer_options)
42
+ options.merge(layer_options)
43
+ layer.points = real_points
44
+
45
+ layer.points.each_with_index { |val, idx| current_points[idx] -= val }
46
+ end
47
+ end
48
+
49
+ # A stacked graph has many data sets. Return legend information for all of them.
50
+ def legend_data
51
+ if relevant_data?
52
+ retval = []
53
+ layers.each do |layer|
54
+ retval << layer.legend_data
55
+ end
56
+ retval
57
+ else
58
+ nil
59
+ end
60
+ end
61
+
62
+ # TODO, special points accessor
63
+ def points
64
+ longest_arr = layers.inject(nil) do |longest, layer|
65
+ longest = layer.points if (longest.nil? || longest.size < layer.points.size)
66
+ end
67
+
68
+ summed_points = (0...longest_arr.size).map do |idx|
69
+ layers.inject(nil) do |sum, layer|
70
+ if sum.nil? && !layer.points[idx].nil?
71
+ sum = layer.points[idx]
72
+ elsif !layer.points[idx].nil?
73
+ sum += layer.points[idx]
74
+ end
75
+
76
+ sum
77
+ end
78
+ end
79
+
80
+ summed_points
81
+ end
82
+
83
+ def points=(val)
84
+ throw ArgumentsError, "Stacked layers cannot accept points, only other layers."
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,24 @@
1
+ # ==Scruffy::Layers
2
+ #
3
+ # Author:: Brasten Sager
4
+ # Date:: August 10th, 2006
5
+ #
6
+ # See documentation in Scruffy::Layers::Base
7
+ #
8
+ module Scruffy::Layers
9
+
10
+ # Should be raised whenever a predictable error during rendering occurs,
11
+ # particularly if you do not want to terminate the graph rendering process.
12
+ class RenderError < StandardError; end
13
+
14
+ end
15
+
16
+ require 'scruffy/layers/base'
17
+ require 'scruffy/layers/area'
18
+ require 'scruffy/layers/all_smiles'
19
+ require 'scruffy/layers/bar'
20
+ require 'scruffy/layers/line'
21
+ require 'scruffy/layers/average'
22
+ require 'scruffy/layers/stacked'
23
+ require 'scruffy/layers/pie'
24
+ require 'scruffy/layers/pie_slice'
@@ -0,0 +1,39 @@
1
+ module Scruffy::Rasterizers
2
+ # == Scruffy::Rasterizers::BatikRasterizer
3
+ #
4
+ # Author:: Brasten Sager
5
+ # Date:: August 14th, 2006
6
+ #
7
+ # Purely experimental. Can be used to rasterize SVG graphs with
8
+ # Apache Batik.
9
+ class BatikRasterizer
10
+ # Returns new BatikRasterizer.
11
+ #
12
+ # Options:
13
+ # command:: Command needed to execute Batik. (ie: 'java -classpath {...}')
14
+ # temp_folder:: Folder for storing temporary files being passed between Scruffy and Batik.
15
+ def initialize(options={})
16
+ @command = options[:command]
17
+ @temp_folder = options[:temp_folder]
18
+ end
19
+
20
+ # Rasterize graph.
21
+ #
22
+ # Options:
23
+ # as:: Image format to generate (PNG, JPG, et al.)
24
+ def rasterize(svg, options={})
25
+ File.open(@temp_folder + '/temp_svg.svg', 'w') { |file|
26
+ file.write(svg)
27
+ }
28
+
29
+ `#{@command} -d #{@temp_folder} -m image/#{options[:as].downcase} #{@temp_folder}/temp_svg.svg`
30
+
31
+ image = ""
32
+ File.open(@temp_folder + '/temp_svg.' + options[:as].downcase, 'r') { |file|
33
+ image = file.read
34
+ }
35
+
36
+ image
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ module Scruffy::Rasterizers
2
+
3
+ # == RMagickRasterizer
4
+ #
5
+ # Author:: Brasten Sager
6
+ # Date:: August 14th, 2006
7
+ #
8
+ # The RMagickRasterizer converts SVG graphs to images using ImageMagick.
9
+ class RMagickRasterizer
10
+ def rasterize(svg, options={})
11
+ # I know this seems weird, I'm open to suggestions.
12
+ # I didn't want RMagick required unless absolutely necessary.
13
+ require 'RMagick'
14
+
15
+ image = Magick::Image::from_blob(svg)[0]
16
+
17
+ # Removed for now
18
+ # image.resize!(options[:size][0], options[:size][1], Magick::BoxFilter, 1.25) if options[:actual_size]
19
+
20
+ if options[:to]
21
+ image.write(options[:to]) { self.format = options[:as] }
22
+ end
23
+
24
+ image.to_blob { self.format = options[:as] }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ # ===Scruffy Rasterizers
2
+ #
3
+ # Author:: Brasten Sager
4
+ # Date:: August 10th, 2006
5
+ #
6
+ # These handle the job of rasterizing SVG images to other image formats.
7
+ # At the moment, only RMagickRasterizer exists, but others may soon follow.
8
+ #
9
+ # I'm somewhat interesting in finding a way to integrate Apache Batik, as it's
10
+ # SVG rendering seems to be superior to ImageMagick's.
11
+ module Scruffy::Rasterizers; end
12
+
13
+ require 'scruffy/rasterizers/rmagick_rasterizer.rb'
14
+ require 'scruffy/rasterizers/batik_rasterizer.rb'
@@ -0,0 +1,95 @@
1
+ require 'builder'
2
+ module Scruffy::Renderers
3
+ # ===Scruffy::Renderers::Base
4
+ #
5
+ # Author:: Brasten Sager
6
+ # Date:: August 14th, 2006
7
+ #
8
+ # Provides all the base functionality needed to render a graph, but
9
+ # does not provide a default layout.
10
+ #
11
+ # For a basic layout, see Scruffy::Renderers::Standard.
12
+ class Base
13
+ include Scruffy::Helpers::Canvas
14
+
15
+ attr_accessor :options
16
+
17
+ def initialize(options = {})
18
+ self.components = []
19
+ self.options = options
20
+ define_layout
21
+ end
22
+
23
+ # Renders the graph and all components.
24
+ def render(options = {})
25
+ options[:graph_id] ||= 'scruffy_graph'
26
+ options[:complexity] ||= (global_complexity || :normal)
27
+
28
+ # Allow subclasses to muck with components prior to renders.
29
+ rendertime_renderer = self.clone
30
+ rendertime_renderer.instance_eval { before_render if respond_to?(:before_render) }
31
+
32
+ svg = Builder::XmlMarkup.new(:indent => 2)
33
+ unless options[:no_doctype_header]
34
+ svg.instruct!
35
+ svg.instruct! 'DOCTYPE', 'svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" type'
36
+ end
37
+ svg.svg(:xmlns => "http://www.w3.org/2000/svg", 'xmlns:xlink' => "http://www.w3.org/1999/xlink", :width => options[:size].first, :height => options[:size].last) {
38
+ svg.g(:id => options[:graph_id]) {
39
+ rendertime_renderer.components.each do |component|
40
+ component.render(svg,
41
+ bounds_for( options[:size], component.position, component.size ),
42
+ options)
43
+ end
44
+ }
45
+ }
46
+ svg.target!
47
+ end
48
+
49
+ def before_render
50
+ if self.options
51
+ set_values(self.options[:values]) if (self.options[:values] && self.options[:values] != :hide)
52
+ hide_grid if (self.options[:grid] == :hide)
53
+ hide_values if (self.options[:values] == :hide)
54
+ hide_labels if (self.options[:labels] == :hide)
55
+ end
56
+ end
57
+
58
+ def method_missing(sym, *args)
59
+ self.options = {} if self.options.nil?
60
+
61
+ if args.size > 0
62
+ self.options[sym] = args[0]
63
+ else
64
+ return self.options[sym]
65
+ end
66
+ end
67
+
68
+ protected
69
+ def hide_grid
70
+ grids.each { |grid| grid.visible = false }
71
+ end
72
+
73
+ def set_values(val)
74
+ values.each { |value| value.markers = val }
75
+ grids.each { |grid| grid.markers = val }
76
+ end
77
+
78
+ def hide_values
79
+ values.each { |value| value.visible = false }
80
+ end
81
+
82
+ def hide_labels
83
+ labels.each { |label| label.visible = false }
84
+ end
85
+
86
+ private
87
+ def global_complexity
88
+ if Kernel.const_defined? "SCRUFFY_COMPLEXITY"
89
+ SCRUFFY_COMPLEXITY
90
+ else
91
+ nil
92
+ end
93
+ end
94
+ end # base
95
+ end
@@ -0,0 +1,44 @@
1
+ module Scruffy::Renderers
2
+ # ===Scruffy::Renderers::Cubed
3
+ #
4
+ # Author:: Brasten Sager
5
+ # Date:: August 14th, 2006
6
+ #
7
+ # Graph layout consisting of four separate graphs arranged in a 2x2 grid.
8
+ class Cubed < Empty
9
+ VIEWPORT_SIZE = [35, 30]
10
+ VIEWPORTS = { :top_left => [10, 25],
11
+ :top_right => [55, 25],
12
+ :bottom_left => [10, 65],
13
+ :bottom_right => [55, 65] }
14
+
15
+ # Returns a Cubed instance.
16
+ def define_layout
17
+ super do |components|
18
+ components << Scruffy::Components::Title.new(:title, :position => [5, 2], :size => [90, 7])
19
+
20
+ VIEWPORTS.each_pair do |category, position|
21
+ components << Scruffy::Components::Viewport.new(category, :position => position,
22
+ :size => VIEWPORT_SIZE, &graph_block(category))
23
+ end
24
+
25
+ components << Scruffy::Components::Legend.new(:legend, :position => [5, 13], :size => [90, 5])
26
+ end
27
+ end
28
+
29
+ private
30
+ # Returns a typical graph layout.
31
+ #
32
+ # These are squeezed into viewports.
33
+ def graph_block(graph_filter)
34
+ block = Proc.new { |components|
35
+ components << Scruffy::Components::Grid.new(:grid, :position => [10, 0], :size => [90, 89])
36
+ components << Scruffy::Components::ValueMarkers.new(:value_markers, :position => [0, 2], :size => [8, 89])
37
+ components << Scruffy::Components::DataMarkers.new(:data_markers, :position => [10, 92], :size => [90, 8])
38
+ components << Scruffy::Components::Graphs.new(:graphs, :position => [10, 0], :size => [90, 89], :only => graph_filter)
39
+ }
40
+
41
+ block
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,53 @@
1
+ module Scruffy::Renderers
2
+ # ===Scruffy::Renderers::Cubed3d
3
+ #
4
+ # Author:: Brasten Sager
5
+ # Date:: August 17th, 2006
6
+ #
7
+ # A 3-dimensional cube effect.
8
+ class Cubed3d < Empty
9
+ VIEWPORT_SIZE = [25, 45]
10
+ VIEWPORTS = { :top_left => [10, 25],
11
+ :top_right => [55, 25],
12
+ :bottom_left => [10, 65],
13
+ :bottom_right => [55, 65] }
14
+
15
+ # Returns a Cubed instance.
16
+ def define_layout
17
+ super do |components|
18
+ components << Scruffy::Components::Title.new(:title, :position => [5, 2], :size => [90, 7])
19
+
20
+ components << Scruffy::Components::Viewport.new(:one, :position => [10, 50],
21
+ :size => VIEWPORT_SIZE, :skewY => '-25',
22
+ &graph_block(:one))
23
+ components << Scruffy::Components::Viewport.new(:two, :position => [30, 50],
24
+ :size => VIEWPORT_SIZE, :skewY => '-25',
25
+ &graph_block(:two))
26
+ components << Scruffy::Components::Viewport.new(:three, :position => [50, 50],
27
+ :size => VIEWPORT_SIZE, :skewY => '-25',
28
+ &graph_block(:three))
29
+ components << Scruffy::Components::Viewport.new(:four, :position => [70, 50],
30
+ :size => VIEWPORT_SIZE, :skewY => '-25',
31
+ &graph_block(:four))
32
+
33
+
34
+ components << Scruffy::Components::Legend.new(:legend, :position => [5, 13], :size => [90, 5])
35
+ end
36
+ end
37
+
38
+ private
39
+ # Returns a typical graph layout.
40
+ #
41
+ # These are squeezed into viewports.
42
+ def graph_block(graph_filter)
43
+ block = Proc.new { |components|
44
+ components << Scruffy::Components::Grid.new(:grid, :position => [10, 0], :size => [90, 89])
45
+ components << Scruffy::Components::ValueMarkers.new(:value_markers, :position => [0, 2], :size => [8, 89])
46
+ components << Scruffy::Components::DataMarkers.new(:data_markers, :position => [10, 92], :size => [90, 8])
47
+ components << Scruffy::Components::Graphs.new(:graphs, :position => [10, 0], :size => [90, 89], :only => graph_filter)
48
+ }
49
+
50
+ block
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,22 @@
1
+ module Scruffy::Renderers
2
+ # ===Scruffy::Renderers::Empty
3
+ #
4
+ # Author:: Brasten Sager
5
+ # Date:: August 17th, 2006
6
+ #
7
+ # An Empty graph isn't completely empty, it adds a background componenet
8
+ # to itself before handing other all other layout responsibilities to it's
9
+ # subclasses or caller.
10
+ class Empty < Base
11
+
12
+ # Returns a renderer with just a background.
13
+ #
14
+ # If a block is provided, the components array is passed to
15
+ # the block, allowing callers to add components during initialize.
16
+ def define_layout
17
+ self.components << Scruffy::Components::Background.new(:background, :position => [0,0], :size =>[100, 100])
18
+
19
+ yield(self.components) if block_given?
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ module Scruffy::Renderers
2
+ # ===Scruffy::Renderers::Base
3
+ #
4
+ # Author:: A.J. Ostman
5
+ # Date:: August 14th, 2006
6
+ #
7
+ # Provides a more appropriate rendering for Pie Charts.
8
+ # Does not show grid or Data markers, but does add Pie Value Markers.
9
+ class Pie < Base
10
+
11
+ def initialize
12
+ self.components = []
13
+ self.components << Scruffy::Components::Background.new(:background, :position => [0,0], :size =>[100, 100])
14
+ self.components << Scruffy::Components::Graphs.new(:graphs, :position => [-15, 12], :size => [90, 88])
15
+ self.components << Scruffy::Components::Title.new(:title, :position => [5, 2], :size => [90, 7])
16
+ self.components << Scruffy::Components::Legend.new(:legend, :position => [60, 15], :size => [40, 88], :vertical_legend => true)
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,17 @@
1
+ module Scruffy
2
+ module Renderers
3
+ class Reversed < Base
4
+
5
+ def define_layout
6
+ self.components << Scruffy::Components::Background.new(:background, :position => [0,0], :size =>[100, 100])
7
+ self.components << Scruffy::Components::Title.new(:title, :position => [98, 95], :size => [1, 3], :text_anchor => 'end')
8
+ #self.components << Scruffy::Components::Grid.new(:grid, :position => [14, 12], :size => [78.5, 70])
9
+ self.components << Scruffy::Components::ValueMarkers.new(:value_markers, :position => [2, 14], :size => [10, 70])
10
+ self.components << Scruffy::Components::DataMarkers.new(:data_markers, :position => [14, 3.5], :size => [78.5, 4])
11
+ self.components << Scruffy::Components::Graphs.new(:graphs, :position => [14, 12], :size => [78.5, 70])
12
+ self.components << Scruffy::Components::Legend.new(:legend, :position => [3, 90], :size => [55, 6])
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ module Scruffy
2
+ module Renderers
3
+ # Experimental, do not use.
4
+ class Sparkline < Base
5
+ def define_layout
6
+ self.components << Scruffy::Components::Graphs.new(:sparkline, :position => [0, 0], :size => [100, 100])
7
+ end
8
+ end
9
+ end
10
+ end