ramhoj-scruffy 0.2.6

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 (55) hide show
  1. data/README.txt +66 -0
  2. data/lib/scruffy.rb +25 -0
  3. data/lib/scruffy/components.rb +21 -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/formatters.rb +213 -0
  16. data/lib/scruffy/graph.rb +190 -0
  17. data/lib/scruffy/graph_state.rb +24 -0
  18. data/lib/scruffy/helpers.rb +12 -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/layers.rb +24 -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/rasterizers.rb +14 -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/renderers.rb +22 -0
  39. data/lib/scruffy/renderers/base.rb +93 -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/themes.rb +156 -0
  49. data/lib/scruffy/version.rb +3 -0
  50. data/spec/output/array.svg +47 -0
  51. data/spec/output/hash.svg +47 -0
  52. data/spec/scruffy/graph_spec.rb +175 -0
  53. data/spec/scruffy/layers/base_spec.rb +30 -0
  54. data/spec/spec_helper.rb +8 -0
  55. metadata +155 -0
@@ -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
@@ -0,0 +1,48 @@
1
+ module Scruffy
2
+ module Renderers
3
+ # Renderer that splits the graphs up into four other little graphs.
4
+ class Split < Empty
5
+ def define_layout
6
+ super do |components|
7
+ components << Scruffy::Components::Title.new(:title, :position => [5, 2], :size => [90, 7])
8
+ components << Scruffy::Components::Label.new(:label_one, :text => self.options[:split_label] || '',
9
+ :position => [30, 54.5], :size => [40, 3])
10
+
11
+ # Viewports
12
+ components << Scruffy::Components::Viewport.new(:top, :position => [3, 20],
13
+ :size => [90, 30], &graph_block(:top))
14
+ components << Scruffy::Components::Viewport.new(:bottom, :position => [3, 65],
15
+ :size => [90, 30], &graph_block(:bottom))
16
+
17
+ components << Scruffy::Components::Legend.new(:legend, :position => [5, 11], :size => [90, 4])
18
+ end
19
+ end
20
+
21
+ protected
22
+ def labels
23
+ [component(:top).component(:labels), component(:bottom).component(:labels)]
24
+ end
25
+
26
+ def values
27
+ [component(:top).component(:values), component(:bottom).component(:values)]
28
+ end
29
+
30
+ def grids
31
+ [component(:top).component(:grid), component(:bottom).component(:grid)]
32
+ end
33
+
34
+
35
+ private
36
+ def graph_block(graph_filter)
37
+ block = Proc.new { |components|
38
+ components << Scruffy::Components::Grid.new(:grid, :position => [10, 0], :size => [90, 89])
39
+ components << Scruffy::Components::ValueMarkers.new(:values, :position => [0, 2], :size => [8, 89])
40
+ components << Scruffy::Components::DataMarkers.new(:labels, :position => [10, 92], :size => [90, 8])
41
+ components << Scruffy::Components::Graphs.new(:graphs, :position => [10, 0], :size => [90, 89], :only => graph_filter)
42
+ }
43
+
44
+ block
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,36 @@
1
+ module Scruffy::Renderers
2
+ class Standard < Empty
3
+
4
+ def define_layout
5
+ super do |components|
6
+ components << Scruffy::Components::Title.new(:title, :position => [5, 2], :size => [90, 7])
7
+ components << Scruffy::Components::Viewport.new(:view, :position => [2, 26], :size => [89, 66]) do |graph|
8
+ graph << Scruffy::Components::ValueMarkers.new(:values, :position => [0, 2], :size => [18, 89])
9
+ graph << Scruffy::Components::Grid.new(:grid, :position => [20, 0], :size => [80, 89], :stroke_width => 1)
10
+ graph << Scruffy::Components::DataMarkers.new(:labels, :position => [20, 92], :size => [80, 8])
11
+ graph << Scruffy::Components::Graphs.new(:graphs, :position => [20, 0], :size => [80, 89])
12
+ end
13
+ components << Scruffy::Components::Legend.new(:legend, :position => [5, 13], :size => [90, 6])
14
+ end
15
+ end
16
+
17
+ protected
18
+ def hide_values
19
+ super
20
+ component(:view).position[0] = -10
21
+ component(:view).size[0] = 100
22
+ end
23
+
24
+ def labels
25
+ [component(:view).component(:labels)]
26
+ end
27
+
28
+ def values
29
+ [component(:view).component(:values)]
30
+ end
31
+
32
+ def grids
33
+ [component(:view).component(:grid)]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,156 @@
1
+ # ===Scruffy Themes
2
+ #
3
+ # Author:: Brasten Sager & A.J. Ostman
4
+ # Date:: August 27th, 2006
5
+ #
6
+ # Scruffy Themes allow you to alter the colors and appearances of
7
+ # your graph.
8
+ module Scruffy::Themes
9
+
10
+ # ==Scruffy::Themes::Base
11
+ #
12
+ # Author:: Brasten Sager & A.J. Ostman
13
+ # Date:: August 27th, 2006
14
+ #
15
+ # The base theme class. Most themes can be constructed simply
16
+ # by instantiating a new Base object with a hash of color values.
17
+ #
18
+ # See Scruffy::Themes::Base#instantiate for examples.
19
+ class Base
20
+ attr_accessor :background # Background color or array of two colors
21
+ attr_accessor :colors # Array of colors for data graphs
22
+ attr_accessor :marker # Marker color for grid lines, values, etc.
23
+ attr_accessor :font_family # Font family: Not really supported. Maybe in the future.
24
+
25
+ # Returns a new Scruffy::Themes::Base object.
26
+ #
27
+ # Hash options:
28
+ # background:: background color.
29
+ # colors:: an array of color values to use for graphs.
30
+ # marker:: color used for grid lines, values, data points, etc.
31
+ # font_family:: in general, allows you to change the font used in the graph.
32
+ # This is not yet supported in most graph elements,
33
+ # and may be deprecated soon anyway.
34
+ def initialize(descriptor)
35
+ self.background = descriptor[:background]
36
+ self.colors = descriptor[:colors]
37
+ self.marker = descriptor[:marker]
38
+ self.font_family = descriptor[:font_family]
39
+ end
40
+
41
+ # Returns the next available color in the color array.
42
+ def next_color
43
+ @previous_color = 0 if @previous_color.nil?
44
+ @previous_color += 1
45
+
46
+ self.colors[(@previous_color-1) % self.colors.size]
47
+ end
48
+
49
+ # todo: Implement darken function.
50
+ def darken(color, shift=20); end
51
+
52
+ # todo: Implement lighten function.
53
+ def lighten(color, shift=20); end
54
+
55
+ end
56
+
57
+
58
+
59
+ # A basic default theme
60
+ # Based on http://www.wellstyled.com/tools/colorscheme2/index-en.html?tetrad;50;0;255;1;-1;1;-0.6;0.1;1;0.6;1;1;-1;1;-0.6;0.1;1;0.6;1;1;-1;1;-0.6;0.1;1;0.6;1;1;-1;1;-0.6;0.1;1;0.6;1;0
61
+ class Standard < Base
62
+ def initialize
63
+ super({
64
+ :background => ['#FFFFFF', '#FFFFFF'],
65
+ :marker => '#999999',
66
+ :colors => %w(#1919B3 #FFB200 #FFFF00 #660099 #E9E9FF #FFF7E6 #FFFFE6 #F7E6FF #0F0F6B #996B00 #999900 #3D005C)
67
+ })
68
+
69
+ end
70
+ end
71
+
72
+ # Keynote theme, based on Apple's Keynote presentation software.
73
+ #
74
+ # Color values used from Gruff's default theme.
75
+ class Keynote < Base
76
+ def initialize
77
+ super({
78
+ :background => [:black, '#4A465A'],
79
+ :marker => :white,
80
+ :colors => %w(#6886B4 #FDD84E #72AE6E #D1695E #8A6EAF #EFAA43 white)
81
+ })
82
+ end
83
+ end
84
+
85
+ # Roughly, roughly based on the color scheme of www.mephistoblog.com.
86
+ class Mephisto < Base
87
+ def initialize
88
+ super({
89
+ :background => ['#101010', '#999977'],
90
+ :marker => :white,
91
+ :colors => %w(#DD3300 #66AABB #225533 #992200)
92
+ })
93
+
94
+ end
95
+ end
96
+
97
+ # Based on the color scheme used by almost every Ruby blogger.
98
+ class RubyBlog < Base
99
+ def initialize
100
+ super({
101
+ :background => ['#670A0A', '#831515'],
102
+ :marker => '#DBD1C1',
103
+ :colors => %w(#007777 #444477 #994444 #77FFBB #D75A20)
104
+ })
105
+ end
106
+ end
107
+
108
+ # Inspired by http://www.colorschemer.com/schemes/
109
+ class Apples < Base
110
+ def initialize
111
+ super({
112
+ :background => ['#3B411F', '#4A465A'],
113
+ :marker => '#DBD1C1',
114
+ :colors => %w(#AA3322 #DD3322 #DD6644 #FFEE88 #BBCC66 #779933)
115
+ })
116
+ end
117
+ end
118
+
119
+ # Inspired by http://www.colorschemer.com/schemes/
120
+ class CareBears < Base
121
+ def initialize
122
+ super({
123
+ # Playing with Sky Background
124
+ # :background => ['#2774B6', '#5EA6D8'],
125
+ # :marker => :white,
126
+ :background => [:black, '#4A465A'],
127
+ :marker => :white,
128
+ :colors => %w(#FFBBBB #00CC33 #7788BB #EEAA44 #FFDD11 #44BBDD #DD6677)
129
+ })
130
+ end
131
+ end
132
+
133
+
134
+ # Inspired by http://www.colorschemer.com/schemes/
135
+ class Vitamins < Base
136
+ def initialize
137
+ super({
138
+ :background => [:black, '#4A465A'],
139
+ :marker => :white,
140
+ :colors => %w(#CC9933 #FFCC66 #CCCC99 #CCCC33 #99CC33 #3333CC #336699 #6633CC #9999CC #333366)
141
+ })
142
+ end
143
+ end
144
+
145
+ # Inspired by http://www.colorschemer.com/schemes/
146
+ class Tulips < Base
147
+ def initialize
148
+ super({
149
+ :background => ['#670A0A', '#831515'],
150
+ :marker => '#DBD1C1',
151
+ :colors => %w(#F2C8CA #BF545E #D2808E #97985C #B3B878 #A24550)
152
+ })
153
+ end
154
+ end
155
+
156
+ end
@@ -0,0 +1,3 @@
1
+ module Scruffy
2
+ VERSION = '0.2.6'
3
+ end
@@ -0,0 +1,47 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <?DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" type=""?>
3
+ <svg xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="360" xmlns="http://www.w3.org/2000/svg">
4
+ <g id="scruffy_graph">
5
+ <g transform="translate(0.0, 0.0)" id="background">
6
+ <defs>
7
+ <linearGradient x1="0%" y1="0%" x2="0%" y2="100%" id="BackgroundGradient">
8
+ <stop offset="5%" stop-color="#FFFFFF"/>
9
+ <stop offset="95%" stop-color="#FFFFFF"/>
10
+ </linearGradient>
11
+ </defs>
12
+ <rect fill="url(#BackgroundGradient)" width="600.0" height="360.0" x="0" y="0"/>
13
+ </g>
14
+ <g transform="translate(30.0, 7.2)" id="title">
15
+ <text fill="#999999" text-anchor="middle" class="title" font-size="25.2" x="270.0" font-family="" y="25.2" stroke-width="0" stroke="none">Graph</text>
16
+ </g>
17
+ <g transform="translate(12.0, 93.6)" id="view">
18
+ <g>
19
+ <g transform="translate(0.0, 4.752)" id="values">
20
+ <text fill="#999999" text-anchor="end" font-size="16.91712" x="96.12" font-family="" y="211.464">1</text>
21
+ <text fill="#999999" text-anchor="end" font-size="16.91712" x="96.12" font-family="" y="158.598">1</text>
22
+ <text fill="#999999" text-anchor="end" font-size="16.91712" x="96.12" font-family="" y="105.732">2</text>
23
+ <text fill="#999999" text-anchor="end" font-size="16.91712" x="96.12" font-family="" y="52.866">3</text>
24
+ <text fill="#999999" text-anchor="end" font-size="16.91712" x="96.12" font-family="" y="0.0">4</text>
25
+ </g>
26
+ <g transform="translate(106.8, 0.0)" id="grid">
27
+ <line x1="0" y1="0.0" x2="427.2" style="stroke: #999999; stroke-width: 1;" y2="0.0"/>
28
+ <line x1="0" y1="52.866" x2="427.2" style="stroke: #999999; stroke-width: 1;" y2="52.866"/>
29
+ <line x1="0" y1="105.732" x2="427.2" style="stroke: #999999; stroke-width: 1;" y2="105.732"/>
30
+ <line x1="0" y1="158.598" x2="427.2" style="stroke: #999999; stroke-width: 1;" y2="158.598"/>
31
+ <line x1="0" y1="211.464" x2="427.2" style="stroke: #999999; stroke-width: 1;" y2="211.464"/>
32
+ </g>
33
+ <g transform="translate(106.8, 218.592)" id="labels">
34
+ </g>
35
+ <g transform="translate(106.8, 0.0)" id="graphs">
36
+ <g class="graph_layer" id="component_graphs_graph_0">
37
+ <polyline fill="none" style="" stroke-width="1" stroke="#1919B3" points="0.0,183.881739130435 142.4,122.587826086957 427.2,0.0"/>
38
+ </g>
39
+ </g>
40
+ </g>
41
+ </g>
42
+ <g transform="translate(30.0, 46.8)" id="legend">
43
+ <rect fill="#1919B3" width="10.8" height="10.8" x="243.0" y="0"/>
44
+ <text fill="#999999" font-size="15.552" x="262.44" font-family="" y="11.664" style="color: #999999">Data</text>
45
+ </g>
46
+ </g>
47
+ </svg>