scruffy 0.2.0 → 0.2.1

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.
@@ -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