scruffy 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,2 +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
+
1
13
  require 'scruffy/rasterizers/rmagick_rasterizer.rb'
2
- require 'scruffy/rasterizers/batik_rasterizer.rb'
14
+ require 'scruffy/rasterizers/batik_rasterizer.rb'
@@ -1,25 +1,39 @@
1
- module Scruffy
2
- module Rasterizers
3
- class BatikRasterizer
4
- def initialize(options={})
5
- @command = options[:command]
6
- @temp_folder = options[:temp_folder]
7
- end
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
+ }
8
35
 
9
- def rasterize(svg, options={})
10
- File.open(@temp_folder + '/temp_svg.svg', 'w') { |file|
11
- file.write(svg)
12
- }
13
-
14
- `#{@command} -d #{@temp_folder} -m image/#{options[:as].downcase} #{@temp_folder}/temp_svg.svg`
15
-
16
- image = ""
17
- File.open(@temp_folder + '/temp_svg.' + options[:as].downcase, 'r') { |file|
18
- image = file.read
19
- }
20
-
21
- image
22
- end
36
+ image
23
37
  end
24
38
  end
25
39
  end
@@ -1,31 +1,28 @@
1
- module Scruffy
2
- # ===Scruffy Rasterizers
1
+ module Scruffy::Rasterizers
2
+
3
+ # == RMagickRasterizer
3
4
  #
4
5
  # Author:: Brasten Sager
5
- # Date:: August 10th, 2006
6
- #
7
- # These handle the job of rasterizing SVG images to other image formats.
8
- # At the moment, only RMagickRasterizer exists, but others may soon follow.
6
+ # Date:: August 14th, 2006
9
7
  #
10
- # I'm somewhat interesting in finding a way to integrate Apache Batik, as it's
11
- # SVG rendering seems to be superior to ImageMagick's.
12
- module Rasterizers
13
- class RMagickRasterizer
14
- def rasterize(svg, options={})
15
-
16
- # I know this seems weird, I'm open to suggestions.
17
- # I didn't want RMagick required unless absolutely necessary.
18
- require 'RMagick'
8
+ # The RMagickRasterizer converts SVG graphs to images using ImageMagick.
9
+ class RMagickRasterizer
10
+ def rasterize(svg, options={})
11
+
12
+ # I know this seems weird, I'm open to suggestions.
13
+ # I didn't want RMagick required unless absolutely necessary.
14
+ require 'RMagick'
19
15
 
20
- image = Magick::Image::from_blob(svg)[0]
21
-
22
- image.resize!(options[:size][0], options[:size][1], Magick::BoxFilter, 1.25) if options[:actual_size]
23
- if options[:to]
24
- image.write(options[:to]) { self.format = options[:as] }
25
- end
16
+ image = Magick::Image::from_blob(svg)[0]
26
17
 
27
- image.to_blob { self.format = options[:as] }
18
+ # Removed for now
19
+ # image.resize!(options[:size][0], options[:size][1], Magick::BoxFilter, 1.25) if options[:actual_size]
20
+
21
+ if options[:to]
22
+ image.write(options[:to]) { self.format = options[:as] }
28
23
  end
24
+
25
+ image.to_blob { self.format = options[:as] }
29
26
  end
30
27
  end
31
28
  end
@@ -1,5 +1,21 @@
1
+ # ===Scruffy Renderers
2
+ #
3
+ # Author:: Brasten Sager
4
+ # Date:: August 14th, 2006
5
+ #
6
+ # Renderers piece the entire graph together from a collection
7
+ # of components. Creating new renderers allows you to create
8
+ # entirely new layouts for your graphs.
9
+ #
10
+ # Scruffy::Renderers::Base contains the basic functionality needed
11
+ # by a layout. The easiest way to create a new layout is by subclassing
12
+ # Base.
13
+ module Scruffy::Renderers; end
14
+
1
15
  require 'scruffy/renderers/base'
16
+ require 'scruffy/renderers/empty'
2
17
  require 'scruffy/renderers/standard'
3
18
  require 'scruffy/renderers/reversed'
4
19
  require 'scruffy/renderers/cubed'
5
- require 'scruffy/renderers/split'
20
+ require 'scruffy/renderers/split'
21
+ require 'scruffy/renderers/cubed3d'
@@ -1,37 +1,45 @@
1
- module Scruffy
2
- module Renderers
3
- class Base
4
- include Scruffy::Helpers::Canvas
5
-
6
- attr_accessor :components
1
+ module Scruffy::Renderers
2
+ # ===Scruffy::Renderers::Base
3
+ #
4
+ # Author:: Brasten Sager
5
+ # Date:: August 14th, 2006
6
+ #
7
+ # Provides all the base functionality needed to render a graph, but
8
+ # does not provide a default layout.
9
+ #
10
+ # For a basic layout, see Scruffy::Renderers::Standard.
11
+ class Base
12
+ include Scruffy::Helpers::Canvas
13
+
14
+ attr_accessor :components
7
15
 
8
- def render(options = {})
9
- options[:graph_id] ||= 'scruffy_graph'
10
- options[:complexity] ||= (global_complexity || :normal)
16
+ # Renders the graph and all components.
17
+ def render(options = {})
18
+ options[:graph_id] ||= 'scruffy_graph'
19
+ options[:complexity] ||= (global_complexity || :normal)
11
20
 
12
- svg = Builder::XmlMarkup.new(:indent => 2)
13
- svg.instruct!
14
- svg.instruct! 'DOCTYPE', 'svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" type'
15
- 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) {
16
- svg.g(:id => options[:graph_id]) {
17
- self.components.each do |component|
18
- component.render(svg,
19
- bounds_for( options[:size], component.position, component.size ),
20
- options)
21
- end
22
- }
23
- }
24
- svg.target!
25
- end
26
-
27
- private
28
- def global_complexity
29
- if Kernel.const_defined? "SCRUFFY_COMPLEXITY"
30
- SCRUFFY_COMPLEXITY
31
- else
32
- nil
21
+ svg = Builder::XmlMarkup.new(:indent => 2)
22
+ svg.instruct!
23
+ svg.instruct! 'DOCTYPE', 'svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" type'
24
+ 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) {
25
+ svg.g(:id => options[:graph_id]) {
26
+ self.components.each do |component|
27
+ component.render(svg,
28
+ bounds_for( options[:size], component.position, component.size ),
29
+ options)
33
30
  end
34
- end
31
+ }
32
+ }
33
+ svg.target!
35
34
  end
35
+
36
+ private
37
+ def global_complexity
38
+ if Kernel.const_defined? "SCRUFFY_COMPLEXITY"
39
+ SCRUFFY_COMPLEXITY
40
+ else
41
+ nil
42
+ end
43
+ end
36
44
  end
37
45
  end
@@ -1,36 +1,44 @@
1
- module Scruffy
2
- module Renderers
3
- # Renderer that splits the graphs up into four other little graphs.
4
- class Cubed < Base
5
- def initialize
6
- self.components = []
7
- self.components << Scruffy::Components::Background.new(:background, :position => [0,0], :size =>[100, 100])
8
- self.components << Scruffy::Components::Title.new(:title, :position => [5, 2], :size => [90, 7])
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 initialize
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
9
24
 
10
- # Viewports
11
- self.components << Scruffy::Components::Viewport.new(:top_left, :position => [10, 25],
12
- :size => [35, 30], &graph_block(:top_left))
13
- self.components << Scruffy::Components::Viewport.new(:top_left, :position => [55, 25],
14
- :size => [35, 30], &graph_block(:top_right))
15
- self.components << Scruffy::Components::Viewport.new(:top_left, :position => [10, 65],
16
- :size => [35, 30], &graph_block(:bottom_left))
17
- self.components << Scruffy::Components::Viewport.new(:top_left, :position => [55, 65],
18
- :size => [35, 30], &graph_block(:bottom_right))
19
-
20
- self.components << Scruffy::Components::Legend.new(:legend, :position => [5, 13], :size => [90, 5])
25
+ components << Scruffy::Components::Legend.new(:legend, :position => [5, 13], :size => [90, 5])
21
26
  end
22
-
23
- private
24
- def graph_block(graph_filter)
25
- block = Proc.new { |components|
26
- components << Scruffy::Components::Grid.new(:grid, :position => [10, 0], :size => [90, 89])
27
- components << Scruffy::Components::ValueMarkers.new(:value_markers, :position => [0, 2], :size => [8, 89])
28
- components << Scruffy::Components::DataMarkers.new(:data_markers, :position => [10, 92], :size => [90, 8])
29
- components << Scruffy::Components::Graphs.new(:graphs, :position => [10, 0], :size => [90, 89], :only => graph_filter)
30
- }
31
-
32
- block
33
- end
34
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
35
43
  end
36
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 initialize
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,23 @@
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 initialize
17
+ self.components = []
18
+ self.components << Scruffy::Components::Background.new(:background, :position => [0,0], :size =>[100, 100])
19
+
20
+ yield(components) if block_given?
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ module Scruffy
2
+ module Renderers
3
+ # Experimental, do not use.
4
+ class Sparkline < Base
5
+ def initialize
6
+ self.components = []
7
+ self.components << Scruffy::Components::Graphs.new(:sparkline, :position => [0, 0], :size => [100, 100])
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,70 +1,90 @@
1
- module Scruffy
2
- module Themes
3
- class Base
4
- attr_accessor :background
5
- attr_accessor :colors
6
- attr_accessor :marker
7
- attr_accessor :font_family
1
+ # ===Scruffy Themes
2
+ #
3
+ # Author:: Brasten Sager
4
+ # Date:: August 10th, 2006
5
+ #
6
+ # Scruffy Themes allow you to alter the colors and appearances of
7
+ # your graph.
8
+ module Scruffy::Themes
9
+ # ==Scruffy::Themes::Base
10
+ #
11
+ # Author:: Brasten Sager
12
+ # Date:: August 14th, 2006
13
+ #
14
+ # The base theme class. Most themes can be constructed simply
15
+ # by instantiating a new Base object with a hash of color values.
16
+ #
17
+ # See Scruffy::Themes::Base#instantiate for examples.
18
+ class Base
19
+ attr_accessor :background
20
+ attr_accessor :colors
21
+ attr_accessor :marker
22
+ attr_accessor :font_family
8
23
 
9
- def initialize(descriptor)
10
- self.background = descriptor[:background]
11
- self.colors = descriptor[:colors]
12
- self.marker = descriptor[:marker]
13
- self.font_family = descriptor[:font_family]
14
- end
15
-
16
- def next_color
17
- @previous_color = 0 if @previous_color.nil?
18
- @previous_color += 1
19
-
20
- self.colors[(@previous_color-1) % self.colors.size]
21
- end
22
-
23
- def darken(color, shift=20)
24
-
25
- end
26
-
27
- def lighten(color, shift=20)
28
-
29
- end
30
- end
31
-
32
- # Keynote theme, based on Apple's Keynote presentation software.
24
+ # Returns a new Scruffy::Themes::Base object.
33
25
  #
34
- # Color values used from Gruff's default theme.
35
- class Keynote < Base
36
- def initialize
37
- super({
38
- :background => [:black, '#4A465A'],
39
- :marker => :white,
40
- :colors => %w(#6886B4 #FDD84E #72AE6E #D1695E #8A6EAF #EFAA43 white)
41
- })
42
- end
43
- end
44
-
45
- # Roughly, roughly based on the color scheme of www.mephistoblog.com.
46
- class Mephisto < Base
47
- def initialize
48
- super({
49
- :background => ['#101010', '#999977'],
50
- :marker => :white,
51
- :colors => %w(#DD3300 #66AABB #225533 #992200)
52
- })
53
-
54
- end
26
+ # Hash options:
27
+ # background:: background color.
28
+ # colors:: an array of color values to use for graphs.
29
+ # marker:: color used for grid lines, values, data points, etc.
30
+ # font_family:: in general, allows you to change the font used in the graph.
31
+ # This is not yet supported in most graph elements.
32
+ def initialize(descriptor)
33
+ self.background = descriptor[:background]
34
+ self.colors = descriptor[:colors]
35
+ self.marker = descriptor[:marker]
36
+ self.font_family = descriptor[:font_family]
55
37
  end
56
38
 
57
- # Based on the color scheme used by almost every Ruby blogger.
58
- class RubyBlog < Base
59
- def initialize
60
- super({
61
- :background => ['#670A0A', '#831515'],
62
- :marker => '#DBD1C1',
63
- :colors => %w(#007777 #444477 #994444 #77FFBB #D75A20)
64
- })
65
- end
39
+ # Returns the next available color in the color array.
40
+ def next_color
41
+ @previous_color = 0 if @previous_color.nil?
42
+ @previous_color += 1
43
+
44
+ self.colors[(@previous_color-1) % self.colors.size]
66
45
  end
46
+
47
+ # todo: Implement darken function.
48
+ def darken(color, shift=20); end
67
49
 
50
+ # todo: Implement lighten function.
51
+ def lighten(color, shift=20); end
68
52
 
69
53
  end
54
+
55
+ # Keynote theme, based on Apple's Keynote presentation software.
56
+ #
57
+ # Color values used from Gruff's default theme.
58
+ class Keynote < Base
59
+ def initialize
60
+ super({
61
+ :background => [:black, '#4A465A'],
62
+ :marker => :white,
63
+ :colors => %w(#6886B4 #FDD84E #72AE6E #D1695E #8A6EAF #EFAA43 white)
64
+ })
65
+ end
66
+ end
67
+
68
+ # Roughly, roughly based on the color scheme of www.mephistoblog.com.
69
+ class Mephisto < Base
70
+ def initialize
71
+ super({
72
+ :background => ['#101010', '#999977'],
73
+ :marker => :white,
74
+ :colors => %w(#DD3300 #66AABB #225533 #992200)
75
+ })
76
+
77
+ end
78
+ end
79
+
80
+ # Based on the color scheme used by almost every Ruby blogger.
81
+ class RubyBlog < Base
82
+ def initialize
83
+ super({
84
+ :background => ['#670A0A', '#831515'],
85
+ :marker => '#DBD1C1',
86
+ :colors => %w(#007777 #444477 #994444 #77FFBB #D75A20)
87
+ })
88
+ end
89
+ end
70
90
  end