ramhoj-scruffy 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
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>