samhendley-scruffy 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
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
data/CHANGES.txt ADDED
@@ -0,0 +1,115 @@
1
+ = Scruffy Changelog
2
+
3
+ == Version 0.2.6
4
+ (December 12th, 2008)
5
+ * Forked from the official 0.2.5 release (http://github.com/delano/scruffy/)
6
+ * Added stroke_width and style attributes to Line
7
+ * Added toggleable shadow and dots attributes to Line
8
+ * Changed the default Line to not include shadow or dots and to have a width of 1 pixel.
9
+ * Added stroke_width for Component::Graph. Default is now 1.
10
+ * Changed the default theme to one appropriate for hi-res charts
11
+ * Removed website from release
12
+
13
+ == Version 0.2.3
14
+ (July 4th, 2008)
15
+ * Got pie charts working
16
+ * Added rough capability for legend to run vertically (better for Pie chart)
17
+ * Added some checks in the Pie initializer so that you simply pass a Hash of
18
+ name => values, instead of adding PieSlices in a block.
19
+ * Added a simplistic unit test that outputs a pie and line chart in PNG & SVG.
20
+ * Quite a lot of hard-wired values in here. Whole thing needs a spring clean.
21
+
22
+ == Version 0.2.2
23
+ (August 19th, 2006)
24
+
25
+ * Removed all font-family and text-rendering attributes from elements.
26
+ - These were causing issues with Batik and Adobe Viewer. Horrible font problems.
27
+ * Added require 'builder' to renderers/base.rb
28
+ * Added minor shadows to most graph types. Adds some depth perception.
29
+ * Added graph.layout as an alias of renderer. (graph.layout looks nicer).
30
+ * Added markers, values, grid options.
31
+
32
+ == Version 0.2.1
33
+ (August 18th, 2006)
34
+
35
+ * Mostly documentation.
36
+ * Added Builder 2.0 dependency to gem spec.
37
+ * Removed minimum size hack in RMagickRasterizer, for now.
38
+
39
+
40
+ == Version 0.2.0
41
+ (August 14th, 2006)
42
+
43
+ - Lots of changes, hold on tight:
44
+
45
+ * Redesigned rendering system to a component-based design.
46
+ All objects on the canvas are components that can be re-arranged via renderers.
47
+ * Created default renderer for basic Gruff-like layout.
48
+ * Added Reversed and Cubed renderers to demonstrate the customization abilities (plus, they're cool).
49
+ * Added Split renderer.
50
+ * Created Viewport component to help with Cubed.
51
+ - Viewport lets you scale it's inner components and move around the
52
+ graph. Its components' sizes and positions are relative to the viewport,
53
+ not the graph.
54
+ * Set title to respect marker color if available.
55
+ * Respects :to option in Graph#render for SVG output to file.
56
+ * Stacked layer type -- accepts layers which it then uses to create a stacked graph. Such as Bar graphs
57
+ and Area graphs.
58
+ * Abstracted out layer_container functionality to helper module (for stacked graph)
59
+ * Renamed value_transformers to value_formatters.
60
+ * Refined Value Formatters.
61
+ - Created default: Number.
62
+ - Respects float precision
63
+ - Allows for "auto-precision", which will use the largest precision (up to a customizable limit)
64
+ necessary to portray the values correctly. ie: 5.1, 6.32, 7.142 becomes '5.100', '6.320', '7.142'
65
+ * Modified Legend component, Layers, and Graph component to respect categories.
66
+ - ie: Creating a Bar layer with :category => :sales and a Graph with :category => :qa will result in
67
+ the Bay layer not being displayed. Allows for more than one Graph viewport on a screen with different
68
+ layers.
69
+ * Improved rasterizing at smaller sizes( < 300px) by rasterizing the image at a larger size first, then
70
+ allowing RMagick to resize the image with specific filtering/blurring. Actually looks better than just
71
+ rasterizing the SVG at the small size from the beginning.
72
+ * Fixed Opacity on stacked graphs.
73
+ * Added Style (invisible) components to allow for CSS styling. (Not recommended, however.)
74
+ * Added Label component for arbitrary text.
75
+ * Created Theme object in place of theme hash.
76
+
77
+ == Version 0.1.0
78
+ (August 11th, 2006)
79
+
80
+ * First public release!
81
+ * Legend rendering
82
+ * Rasterizing graph to multiple image types (graph.render :as => 'PNG')
83
+
84
+ == Version 0.0.12
85
+ (August 10th, 2006)
86
+ This is not a public release.
87
+
88
+ * Rearranged Layers into a better class/module arrangement.
89
+
90
+ == Version 0.0.11
91
+ (August 10th, 2006)
92
+ This is not a public release.
93
+
94
+ * Fixed gem issue.
95
+
96
+ == Version 0.0.10
97
+ (August 10th, 2006)
98
+
99
+ This is not a public release.
100
+
101
+
102
+ * Removed bogus changelog.
103
+
104
+
105
+ == Version 0.0.9
106
+ (August 10th, 2006)
107
+
108
+ This is not a public release.
109
+
110
+ * Initial release.
111
+ * Standard renderer.
112
+ * Marker transformers: currency, percentages.
113
+ * Basic Graphs: Area, Bar, Line.
114
+ * Advanced Graphs: Average, AllSmiles.
115
+ * Initial documentation.
data/LICENCE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006 Brasten Sager (brasten@nagilum.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.txt ADDED
@@ -0,0 +1,66 @@
1
+ = scruffy, unofficial release
2
+
3
+ This is a fork from based on the official 0.2.5 release. See below for
4
+ further a longer description.
5
+
6
+ == DESCRIPTION:
7
+
8
+ * scruffy.rubyforge.org
9
+
10
+ Author:: Brasten Sager (brasten@nagilum.com)
11
+ Date:: July 8, 2008
12
+ Release:: 0.2.5
13
+
14
+ Scruffy is a Ruby library for generating high quality, good looking graphs. It is designed
15
+ to be easy to use and highly customizable.
16
+
17
+ For basic usage instructions, refer to the documentation for Scruffy::Graph.
18
+
19
+
20
+ == FORK DESCRIPTION
21
+
22
+ * http://github.com/delano/scruffy/
23
+
24
+ Author:: Delano Mandelbaum (delano@solutious.com)
25
+ Author:: Kalin Harvey
26
+ Date:: December 12, 2008
27
+
28
+ We love scruffy. Our motivation for creating a forking is to make it useful for hi-resolution
29
+ graphs and charts. We would love to get our changes in to the official release but until
30
+ that time they will be available at the GitHub URI above.
31
+
32
+ CHANGES.txt contains everything we've been up to.
33
+
34
+
35
+ == FEATURES
36
+
37
+ * Renders to SVG or bitmap (PNG, JPG)
38
+
39
+ == PROBLEMS:
40
+
41
+ * 0.2.3 version has missing legend text when rendering to bitmap. This is strange because the text is there in the SVG before it goes to RMagick.
42
+
43
+ == SYNOPSIS:
44
+
45
+ graph = Scruffy::Graph.new
46
+ graph.title = "Sample Line Graph"
47
+ graph.renderer = Scruffy::Renderers::Standard.new
48
+
49
+ graph.add :line, 'Example', [20, 100, 70, 30, 106]
50
+
51
+ graph.render :to => "line_test.svg"
52
+ graph.render :width => 300, :height => 200,
53
+ :to => "line_test.png", :as => 'png'
54
+
55
+ == REQUIREMENTS:
56
+
57
+ * Needs RMagick and Magic installed, if you wish to render to bitmap.
58
+
59
+ == INSTALL:
60
+
61
+ * sudo gem install scruffy
62
+
63
+
64
+ == LICENSE:
65
+
66
+ See Licence.txt
@@ -0,0 +1,24 @@
1
+ module Scruffy
2
+ module Components
3
+ class Background < Base
4
+ def draw(svg, bounds, options={})
5
+ fill = "#EEEEEE"
6
+ case options[:theme].background
7
+ when Symbol, String
8
+ fill = options[:theme].background.to_s
9
+ when Array
10
+ fill = "url(#BackgroundGradient)"
11
+ svg.defs {
12
+ svg.linearGradient(:id=>'BackgroundGradient', :x1 => '0%', :y1 => '0%', :x2 => '0%', :y2 => '100%') {
13
+ svg.stop(:offset => '5%', 'stop-color' => options[:theme].background[0])
14
+ svg.stop(:offset => '95%', 'stop-color' => options[:theme].background[1])
15
+ }
16
+ }
17
+ end
18
+
19
+ # Render background (maybe)
20
+ svg.rect(:width => bounds[:width], :height => bounds[:height], :x => "0", :y => "0", :fill => fill) unless fill.nil?
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,57 @@
1
+ module Scruffy
2
+ module Components
3
+ # ===Scruffy::Components::Base
4
+ #
5
+ # Common attributes for all components, and a standard render method
6
+ # that calls draw after setting up the drawing transformations.
7
+ class Base
8
+ attr_reader :id
9
+
10
+ # In terms of percentages: [10, 10] == 10% by 10%
11
+ attr_accessor :position
12
+ attr_accessor :size
13
+ attr_accessor :options
14
+ attr_accessor :visible
15
+
16
+ # Options:
17
+ # stroke_width:: numeric value for width of line (0.1 - 10, default: 1)
18
+ def initialize(id, options = {})
19
+ @id = id.to_sym
20
+ @position = options[:position] || [0, 0]
21
+ @size = options[:size] || [100, 100]
22
+ @visible = options[:visible] || true
23
+
24
+ @options = options
25
+ end
26
+
27
+ def render(svg, bounds, options={})
28
+ if @visible
29
+ unless bounds.nil?
30
+ @render_height = bounds[:height]
31
+
32
+ svg.g(:id => id.to_s,
33
+ :transform => "translate(#{bounds.delete(:x)}, #{bounds.delete(:y)})") {
34
+
35
+ draw(svg, bounds, options.merge(@options))
36
+ }
37
+ else
38
+ process(svg, options.merge(@options))
39
+ end
40
+ end
41
+ end
42
+
43
+ def draw(svg, bounds, options={})
44
+ # Override this if visual component
45
+ end
46
+
47
+ def process(svg, options={})
48
+ # Override this NOT a visual component
49
+ end
50
+
51
+ protected
52
+ def relative(pct)
53
+ @render_height * ( pct / 100.to_f )
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,26 @@
1
+ module Scruffy
2
+ module Components
3
+
4
+ class DataMarkers < Base
5
+
6
+ def draw(svg, bounds, options={})
7
+ unless options[:point_markers].nil?
8
+ point_distance = bounds[:width] / (options[:point_markers].size - 1).to_f
9
+
10
+ (0...options[:point_markers].size).map do |idx|
11
+ x_coord = point_distance * idx
12
+ svg.text(options[:point_markers][idx],
13
+ :x => x_coord,
14
+ :y => bounds[:height],
15
+ 'font-size' => relative(90),
16
+ 'font-family' => options[:theme].font_family,
17
+ :fill => (options[:theme].marker || 'white').to_s,
18
+ 'text-anchor' => 'middle') unless options[:point_markers][idx].nil?
19
+ end
20
+ end
21
+ end # draw
22
+
23
+ end # class
24
+
25
+ end
26
+ end
@@ -0,0 +1,48 @@
1
+ module Scruffy
2
+ module Components
3
+
4
+ # Component for displaying Graphs layers.
5
+ #
6
+ # Is passed all graph layers from the Graph object.
7
+ #
8
+ # (This may change as the capability for Graph filtering and such fills out.)
9
+ class Graphs < Base
10
+ STACKED_OPACITY = 0.85;
11
+
12
+ def draw(svg, bounds, options={})
13
+ # If Graph is limited to a category, reject layers outside of it's scope.
14
+ applicable_layers = options[:layers].reject do |l|
15
+ if @options[:only]
16
+ (l.options[:category].nil? && l.options[:categories].nil?) ||
17
+ (!l.options[:category].nil? && l.options[:category] != @options[:only]) ||
18
+ (!l.options[:categories].nil? && !l.options[:categories].include?(@options[:only]))
19
+ else
20
+ false
21
+ end
22
+ end
23
+
24
+ applicable_layers.each_with_index do |layer, idx|
25
+ layer_options = {}
26
+ layer_options[:index] = idx
27
+ layer_options[:min_value] = options[:min_value]
28
+ layer_options[:max_value] = options[:max_value]
29
+ layer_options[:complexity] = options[:complexity]
30
+ layer_options[:size] = [bounds[:width], bounds[:height]]
31
+ layer_options[:color] = layer.preferred_color || layer.color || options[:theme].next_color
32
+ layer_options[:opacity] = opacity_for(idx)
33
+ layer_options[:theme] = options[:theme]
34
+
35
+ svg.g(:id => "component_#{id}_graph_#{idx}", :class => 'graph_layer') {
36
+ layer.render(svg, layer_options)
37
+ }
38
+ end # applicable_layers
39
+ end # draw
40
+
41
+ protected
42
+ def opacity_for(idx)
43
+ (idx == 0) ? 1.0 : (@options[:stacked_opacity] || STACKED_OPACITY)
44
+ end
45
+
46
+ end #class
47
+ end
48
+ end
@@ -0,0 +1,19 @@
1
+ module Scruffy
2
+ module Components
3
+ class Grid < Base
4
+ attr_accessor :markers
5
+
6
+ def draw(svg, bounds, options={})
7
+ markers = (options[:markers] || self.markers) || 5
8
+
9
+ stroke_width = options[:stroke_width]
10
+
11
+ (0...markers).each do |idx|
12
+ marker = ((1 / (markers - 1).to_f) * idx) * bounds[:height]
13
+ svg.line(:x1 => 0, :y1 => marker, :x2 => bounds[:width], :y2 => marker, :style => "stroke: #{options[:theme].marker.to_s}; stroke-width: #{stroke_width};")
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,17 @@
1
+ module Scruffy
2
+ module Components
3
+ class Label < Base
4
+ def draw(svg, bounds, options={})
5
+ svg.text(@options[:text],
6
+ :class => 'text',
7
+ :x => (bounds[:width] / 2),
8
+ :y => bounds[:height],
9
+ 'font-size' => relative(100),
10
+ 'font-family' => options[:theme].font_family,
11
+ :fill => options[:theme].marker,
12
+ :stroke => 'none', 'stroke-width' => '0',
13
+ 'text-anchor' => (@options[:text_anchor] || 'middle'))
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,105 @@
1
+ module Scruffy::Components
2
+
3
+ class Legend < Base
4
+ FONT_SIZE = 80
5
+
6
+ def draw(svg, bounds, options={})
7
+ vertical = options[:vertical_legend]
8
+ legend_info = relevant_legend_info(options[:layers])
9
+ @line_height, x, y, size = 0
10
+ if vertical
11
+ set_line_height = 0.08 * bounds[:height]
12
+ @line_height = bounds[:height] / legend_info.length
13
+ @line_height = set_line_height if @line_height >
14
+ set_line_height
15
+ else
16
+ set_line_height = 0.90 * bounds[:height]
17
+ @line_height = set_line_height
18
+ end
19
+
20
+ text_height = @line_height * FONT_SIZE / 100
21
+ # #TODO how does this related to @points?
22
+ active_width, points = layout(legend_info, vertical)
23
+
24
+ offset = (bounds[:width] - active_width) / 2 # Nudge over a bit for true centering
25
+
26
+ # Render Legend
27
+ points.each_with_index do |point, idx|
28
+ if vertical
29
+ x = 0
30
+ y = point
31
+ size = @line_height * 0.5
32
+ else
33
+ x = offset + point
34
+ y = 0
35
+ size = relative(50)
36
+ end
37
+
38
+ # "#{x} #{y} #{@line_height} #{size}"
39
+
40
+ svg.rect(:x => x,
41
+ :y => y,
42
+ :width => size,
43
+ :height => size,
44
+ :fill => legend_info[idx][:color])
45
+
46
+ svg.text(legend_info[idx][:title],
47
+ :x => x + @line_height,
48
+ :y => y + text_height * 0.75,
49
+ 'font-size' => text_height,
50
+ 'font-family' => options[:theme].font_family,
51
+ :style => "color: #{options[:theme].marker || 'white'}",
52
+ :fill => (options[:theme].marker || 'white'))
53
+ end
54
+ end # draw
55
+
56
+ protected
57
+ # Collects Legend Info from the provided Layers.
58
+ #
59
+ # Automatically filters by legend's categories.
60
+ def relevant_legend_info(layers, categories=(@options[:category] ? [@options[:category]] : @options[:categories]))
61
+ legend_info = layers.inject([]) do |arr, layer|
62
+ if categories.nil? ||
63
+ (categories.include?(layer.options[:category]) ||
64
+ (layer.options[:categories] && (categories & layer.options[:categories]).size > 0) )
65
+
66
+ data = layer.legend_data
67
+ arr << data if data.is_a?(Hash)
68
+ arr = arr + data if data.is_a?(Array)
69
+ end
70
+ arr
71
+ end
72
+ end # relevant_legend_info
73
+
74
+ # Returns an array consisting of the total width needed by the legend
75
+ # information, as well as an array of @x-coords for each element. If
76
+ # vertical, then these are @y-coords, and @x is 0
77
+ #
78
+ # ie: [200, [0, 50, 100, 150]]
79
+ def layout(legend_info_array, vertical = false)
80
+ if vertical
81
+ longest = 0
82
+ legend_info_array.each {|elem|
83
+ cur_length = relative(50) * elem[:title].length
84
+ longest = longest < cur_length ? cur_length : longest
85
+ }
86
+ y_positions = []
87
+ (0..legend_info_array.length - 1).each {|y|
88
+ y_positions << y * @line_height
89
+ }
90
+ [longest, y_positions]
91
+ else
92
+ legend_info_array.inject([0, []]) do |enum, elem|
93
+ enum[0] += (relative(50) * 2) if enum.first != 0 # Add spacer between elements
94
+ enum[1] << enum.first # Add location to points
95
+ enum[0] += relative(50) # Add room for color box
96
+ enum[0] += (relative(50) * elem[:title].length) # Add room for text
97
+
98
+ [enum.first, enum.last]
99
+ end
100
+ end
101
+ end
102
+
103
+ end # class Legend
104
+
105
+ end # Scruffy::Components
@@ -0,0 +1,22 @@
1
+ module Scruffy
2
+ module Components
3
+ # Component used for adding CSS styling to SVG graphs.
4
+ #
5
+ # In hindsight, ImageMagick and Mozilla SVG's handling of CSS styling is
6
+ # extremely inconsistant, so use this at your own risk.
7
+ class StyleInfo < Base
8
+ def initialize(*args)
9
+ super
10
+
11
+ @visible = false
12
+ end
13
+ def process(svg, options={})
14
+ svg.defs {
15
+ svg.style(:type => "text/css") {
16
+ svg.cdata!("\n#{options[:selector]} {\n #{options[:style]}\n}\n")
17
+ }
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ module Scruffy
2
+ module Components
3
+ class Title < Base
4
+ def draw(svg, bounds, options={})
5
+ if options[:title]
6
+ svg.text(options[:title],
7
+ :class => 'title',
8
+ :x => (bounds[:width] / 2),
9
+ :y => bounds[:height],
10
+ 'font-size' => relative(100),
11
+ 'font-family' => options[:theme].font_family,
12
+ :fill => options[:theme].marker,
13
+ :stroke => 'none', 'stroke-width' => '0',
14
+ 'text-anchor' => (@options[:text_anchor] || 'middle'))
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ module Scruffy
2
+ module Components
3
+ class ValueMarkers < Base
4
+ attr_accessor :markers
5
+
6
+ def draw(svg, bounds, options={})
7
+ markers = (options[:markers] || self.markers) || 5
8
+ all_values = []
9
+
10
+ (0...markers).each do |idx|
11
+ marker = ((1 / (markers - 1).to_f) * idx) * bounds[:height]
12
+ all_values << (options[:max_value] - options[:min_value]) * ((1 / (markers - 1).to_f) * idx) + options[:min_value]
13
+ end
14
+
15
+ (0...markers).each do |idx|
16
+ marker = ((1 / (markers - 1).to_f) * idx) * bounds[:height]
17
+ marker_value = (options[:max_value] - options[:min_value]) * ((1 / (markers - 1).to_f) * idx) + options[:min_value]
18
+ marker_value = options[:value_formatter].route_format(marker_value, idx, options.merge({:all_values => all_values})) if options[:value_formatter]
19
+
20
+ svg.text( marker_value.to_s,
21
+ :x => bounds[:width],
22
+ :y => (bounds[:height] - marker),
23
+ 'font-size' => relative(8),
24
+ 'font-family' => options[:theme].font_family,
25
+ :fill => ((options.delete(:marker_color_override) || options[:theme].marker) || 'white').to_s,
26
+ 'text-anchor' => 'end')
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,37 @@
1
+ module Scruffy::Components
2
+ # Component used to limit other visual components to a certain area on the graph.
3
+ class Viewport < Base
4
+ include Scruffy::Helpers::Canvas
5
+
6
+ def initialize(*args, &block)
7
+ super(*args)
8
+
9
+ self.components = []
10
+ block.call(self.components) if block
11
+ end
12
+
13
+ def draw(svg, bounds, options={})
14
+ svg.g(options_for) {
15
+ self.components.each do |component|
16
+ component.render(svg,
17
+ bounds_for([bounds[:width], bounds[:height]],
18
+ component.position,
19
+ component.size),
20
+ options)
21
+ end
22
+ }
23
+ end
24
+
25
+ private
26
+ def options_for
27
+ options = {}
28
+ %w(skewX skewY).each do |option|
29
+ if @options[option.to_sym]
30
+ options[:transform] ||= ''
31
+ options[:transform] = options[:transform] + "#{option.to_s}(#{@options[option.to_sym]})"
32
+ end
33
+ end
34
+ options
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ # ===Scruffy Components
2
+ #
3
+ # Author:: Brasten Sager
4
+ # Date:: August 16th, 2006
5
+ #
6
+ # Components make up the visual elements of a Scruffy graph.
7
+ #
8
+ # For examples, see Scruffy::Components::Base.
9
+ module Scruffy::Components; end
10
+
11
+ require 'scruffy/components/base'
12
+ require 'scruffy/components/title'
13
+ require 'scruffy/components/background'
14
+ require 'scruffy/components/graphs'
15
+ require 'scruffy/components/grid'
16
+ require 'scruffy/components/value_markers'
17
+ require 'scruffy/components/data_markers'
18
+ require 'scruffy/components/legend'
19
+ require 'scruffy/components/style_info'
20
+ require 'scruffy/components/viewport'
21
+ require 'scruffy/components/label'