tlconnor-scruffy 0.2.17
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.
- data/CHANGES.txt +115 -0
- data/LICENCE.txt +20 -0
- data/Manifest.txt +74 -0
- data/README.txt +66 -0
- data/lib/scruffy.rb +30 -0
- data/lib/scruffy/components.rb +22 -0
- data/lib/scruffy/components/axes.rb +23 -0
- data/lib/scruffy/components/background.rb +24 -0
- data/lib/scruffy/components/base.rb +57 -0
- data/lib/scruffy/components/data_markers.rb +41 -0
- data/lib/scruffy/components/graphs.rb +52 -0
- data/lib/scruffy/components/grid.rb +57 -0
- data/lib/scruffy/components/label.rb +17 -0
- data/lib/scruffy/components/legend.rb +147 -0
- data/lib/scruffy/components/style_info.rb +22 -0
- data/lib/scruffy/components/title.rb +19 -0
- data/lib/scruffy/components/value_markers.rb +25 -0
- data/lib/scruffy/components/viewport.rb +37 -0
- data/lib/scruffy/formatters.rb +233 -0
- data/lib/scruffy/graph.rb +205 -0
- data/lib/scruffy/graph_state.rb +29 -0
- data/lib/scruffy/helpers.rb +13 -0
- data/lib/scruffy/helpers/canvas.rb +41 -0
- data/lib/scruffy/helpers/layer_container.rb +119 -0
- data/lib/scruffy/helpers/marker_helper.rb +25 -0
- data/lib/scruffy/helpers/meta.rb +5 -0
- data/lib/scruffy/helpers/point_container.rb +99 -0
- data/lib/scruffy/layers.rb +28 -0
- data/lib/scruffy/layers/all_smiles.rb +137 -0
- data/lib/scruffy/layers/area.rb +46 -0
- data/lib/scruffy/layers/average.rb +67 -0
- data/lib/scruffy/layers/bar.rb +73 -0
- data/lib/scruffy/layers/base.rb +211 -0
- data/lib/scruffy/layers/box.rb +114 -0
- data/lib/scruffy/layers/line.rb +46 -0
- data/lib/scruffy/layers/multi.rb +74 -0
- data/lib/scruffy/layers/multi_bar.rb +51 -0
- data/lib/scruffy/layers/pie.rb +123 -0
- data/lib/scruffy/layers/pie_slice.rb +119 -0
- data/lib/scruffy/layers/scatter.rb +29 -0
- data/lib/scruffy/layers/sparkline_bar.rb +39 -0
- data/lib/scruffy/layers/stacked.rb +87 -0
- data/lib/scruffy/rasterizers.rb +14 -0
- data/lib/scruffy/rasterizers/batik_rasterizer.rb +39 -0
- data/lib/scruffy/rasterizers/mini_magick_rasterizer.rb +24 -0
- data/lib/scruffy/rasterizers/rmagick_rasterizer.rb +27 -0
- data/lib/scruffy/renderers.rb +23 -0
- data/lib/scruffy/renderers/axis_legend.rb +41 -0
- data/lib/scruffy/renderers/base.rb +95 -0
- data/lib/scruffy/renderers/cubed.rb +44 -0
- data/lib/scruffy/renderers/cubed3d.rb +53 -0
- data/lib/scruffy/renderers/empty.rb +22 -0
- data/lib/scruffy/renderers/pie.rb +20 -0
- data/lib/scruffy/renderers/reversed.rb +17 -0
- data/lib/scruffy/renderers/sparkline.rb +10 -0
- data/lib/scruffy/renderers/split.rb +48 -0
- data/lib/scruffy/renderers/standard.rb +37 -0
- data/lib/scruffy/themes.rb +177 -0
- data/lib/scruffy/version.rb +9 -0
- data/test/graph_creation_test.rb +286 -0
- data/test/test_helper.rb +2 -0
- metadata +150 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
module Scruffy::Layers
|
2
|
+
# ==Scruffy::Layers::Line
|
3
|
+
#
|
4
|
+
# Author:: Mat Schaffer
|
5
|
+
# Date:: March 20th, 2007
|
6
|
+
#
|
7
|
+
# Simple scatter graph
|
8
|
+
class Scatter < Base
|
9
|
+
|
10
|
+
include Scruffy::Helpers::Marker
|
11
|
+
|
12
|
+
# Renders scatter graph.
|
13
|
+
def draw(svg, coords, options={})
|
14
|
+
|
15
|
+
options.merge!(@options)
|
16
|
+
|
17
|
+
if options[:shadow]
|
18
|
+
svg.g(:class => 'shadow', :transform => "translate(#{relative(0.5)}, #{relative(0.5)})") {
|
19
|
+
coords.each { |coord| svg.circle( :cx => coord.first, :cy => coord.last + relative(0.9), :r => relative(2),
|
20
|
+
:style => "stroke-width: #{relative(2)}; stroke: black; opacity: 0.35;" ) }
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
coords.each { |coord| svg.circle( :cx => coord.first, :cy => coord.last, :r => relative(2),
|
25
|
+
:style => "stroke-width: #{relative(2)}; stroke: #{color.to_s}; fill: #{color.to_s}" ) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Scruffy
|
2
|
+
module Layers
|
3
|
+
# Experimental, do not use.
|
4
|
+
class SparklineBar < Base
|
5
|
+
|
6
|
+
def draw(svg, coords, options = {})
|
7
|
+
zero_point = @height / 2.0
|
8
|
+
|
9
|
+
coords.each do |coord|
|
10
|
+
x, y, bar_height = (coord.first-(@bar_width * 0.5)), coord.last, (height - coord.last)
|
11
|
+
|
12
|
+
bar_color = (y > zero_point) ? 'black' : 'red'
|
13
|
+
bar_height = (bar_height - zero_point)
|
14
|
+
|
15
|
+
#y = (bar_height < 0) ?
|
16
|
+
|
17
|
+
# svg.rect( :x => x, :y => zero_point, :width => @bar_width, :height => ,
|
18
|
+
# :fill => bar_color, :stroke => 'none', 'style' => "opacity: #{opacity}" )
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
def generate_coordinates(options = {})
|
24
|
+
@bar_width = (width / points.size) * 0.9
|
25
|
+
options[:point_distance] = (width - (width / points.size)) / (points.size - 1).to_f
|
26
|
+
|
27
|
+
#TODO iteration by index on points. Needs to change
|
28
|
+
coords = (0...points.size).map do |idx|
|
29
|
+
x_coord = (options[:point_distance] * idx) + (width / points.size * 0.5)
|
30
|
+
|
31
|
+
relative_percent = ((points[idx] == min_value) ? 0 : ((points[idx] - min_value) / (max_value - min_value).to_f))
|
32
|
+
y_coord = (height - (height * relative_percent))
|
33
|
+
[x_coord, y_coord]
|
34
|
+
end
|
35
|
+
coords
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Scruffy::Layers
|
2
|
+
# ==Scruffy::Layers::Stacked
|
3
|
+
#
|
4
|
+
# Author:: Brasten Sager
|
5
|
+
# Date:: August 12th, 2006
|
6
|
+
#
|
7
|
+
# Provides a generic way for stacking graphs. This may or may not
|
8
|
+
# do what you'd expect under every situation, but it at least kills
|
9
|
+
# a couple birds with one stone (stacked bar graphs and stacked area
|
10
|
+
# graphs work fine).
|
11
|
+
class Stacked < Base
|
12
|
+
include Scruffy::Helpers::LayerContainer
|
13
|
+
|
14
|
+
# Returns new Stacked graph.
|
15
|
+
#
|
16
|
+
# You can provide a block for easily adding layers during (just after) initialization.
|
17
|
+
# Example:
|
18
|
+
# Stacked.new do |stacked|
|
19
|
+
# stacked << Scruffy::Layers::Line.new( ... )
|
20
|
+
# stacked.add(:bar, 'My Bar', [...])
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# The initialize method passes itself to the block, and since stacked is a LayerContainer,
|
24
|
+
# layers can be added just as if they were being added to Graph.
|
25
|
+
def initialize(options={}, &block)
|
26
|
+
super(options)
|
27
|
+
|
28
|
+
block.call(self) # Allow for population of data with a block during initialization.
|
29
|
+
end
|
30
|
+
|
31
|
+
# Overrides Base#render to fiddle with layers' points to achieve a stacked effect.
|
32
|
+
def render(svg, options = {})
|
33
|
+
#TODO ensure this works with new points
|
34
|
+
current_points = points
|
35
|
+
|
36
|
+
layers.each do |layer|
|
37
|
+
real_points = layer.points
|
38
|
+
layer.points = current_points
|
39
|
+
layer_options = options.dup
|
40
|
+
layer_options[:color] = layer.preferred_color || layer.color || options[:theme].next_color
|
41
|
+
layer.render(svg, layer_options)
|
42
|
+
options.merge(layer_options)
|
43
|
+
layer.points = real_points
|
44
|
+
|
45
|
+
layer.points.each_with_index { |val, idx| current_points[idx] -= val }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# A stacked graph has many data sets. Return legend information for all of them.
|
50
|
+
def legend_data
|
51
|
+
if relevant_data?
|
52
|
+
retval = []
|
53
|
+
layers.each do |layer|
|
54
|
+
retval << layer.legend_data
|
55
|
+
end
|
56
|
+
retval
|
57
|
+
else
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# TODO, special points accessor
|
63
|
+
def points
|
64
|
+
longest_arr = layers.inject(nil) do |longest, layer|
|
65
|
+
longest = layer.points if (longest.nil? || longest.size < layer.points.size)
|
66
|
+
end
|
67
|
+
|
68
|
+
summed_points = (0...longest_arr.size).map do |idx|
|
69
|
+
layers.inject(nil) do |sum, layer|
|
70
|
+
if sum.nil? && !layer.points[idx].nil?
|
71
|
+
sum = layer.points[idx]
|
72
|
+
elsif !layer.points[idx].nil?
|
73
|
+
sum += layer.points[idx]
|
74
|
+
end
|
75
|
+
|
76
|
+
sum
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
summed_points
|
81
|
+
end
|
82
|
+
|
83
|
+
def points=(val)
|
84
|
+
throw ArgumentsError, "Stacked layers cannot accept points, only other layers."
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +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
|
+
|
13
|
+
require 'scruffy/rasterizers/rmagick_rasterizer.rb'
|
14
|
+
require 'scruffy/rasterizers/batik_rasterizer.rb'
|
@@ -0,0 +1,39 @@
|
|
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
|
+
}
|
35
|
+
|
36
|
+
image
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Scruffy::Rasterizers
|
2
|
+
|
3
|
+
# == MiniMagickRasterizer
|
4
|
+
#
|
5
|
+
# Author:: Tim Connor
|
6
|
+
# Date:: Feb 9th, 2010
|
7
|
+
#
|
8
|
+
# The MiniMagickRasterizer converts SVG graphs to images using MiniMagick.
|
9
|
+
class MiniMagickRasterizer
|
10
|
+
def rasterize(svg, options={})
|
11
|
+
require 'mini_magick'
|
12
|
+
|
13
|
+
image = MiniMagick::Image::from_blob(svg)
|
14
|
+
|
15
|
+
image.format(options[:as]) do |cmd|
|
16
|
+
cmd.background "#0000" # Transparent background
|
17
|
+
end if options[:as]
|
18
|
+
|
19
|
+
image.write(options[:to]) if options[:to]
|
20
|
+
image.to_blob
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Scruffy::Rasterizers
|
2
|
+
|
3
|
+
# == RMagickRasterizer
|
4
|
+
#
|
5
|
+
# Author:: Brasten Sager
|
6
|
+
# Date:: August 14th, 2006
|
7
|
+
#
|
8
|
+
# The RMagickRasterizer converts SVG graphs to images using ImageMagick.
|
9
|
+
class RMagickRasterizer
|
10
|
+
def rasterize(svg, options={})
|
11
|
+
# I know this seems weird, I'm open to suggestions.
|
12
|
+
# I didn't want RMagick required unless absolutely necessary.
|
13
|
+
require 'RMagick'
|
14
|
+
|
15
|
+
image = Magick::Image::from_blob(svg)[0]
|
16
|
+
|
17
|
+
# Removed for now
|
18
|
+
# image.resize!(options[:size][0], options[:size][1], Magick::BoxFilter, 1.25) if options[:actual_size]
|
19
|
+
|
20
|
+
if options[:to]
|
21
|
+
image.write(options[:to]) { self.format = options[:as] }
|
22
|
+
end
|
23
|
+
|
24
|
+
image.to_blob { self.format = options[:as] }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
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
|
+
|
15
|
+
require 'scruffy/renderers/base'
|
16
|
+
require 'scruffy/renderers/empty'
|
17
|
+
require 'scruffy/renderers/standard'
|
18
|
+
require 'scruffy/renderers/axis_legend'
|
19
|
+
require 'scruffy/renderers/reversed'
|
20
|
+
require 'scruffy/renderers/cubed'
|
21
|
+
require 'scruffy/renderers/split'
|
22
|
+
require 'scruffy/renderers/cubed3d'
|
23
|
+
require 'scruffy/renderers/pie'
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Scruffy::Renderers
|
2
|
+
class AxisLegend < Empty
|
3
|
+
|
4
|
+
def define_layout
|
5
|
+
super do |components|
|
6
|
+
components << Scruffy::Components::Title.new(:title, :position => [5, 2], :size => [90, 7])
|
7
|
+
|
8
|
+
|
9
|
+
components << Scruffy::Components::Viewport.new(:view, :position => [6, 22], :size => [90, 66]) do |graph|
|
10
|
+
graph << Scruffy::Components::ValueMarkers.new(:values, :position => [0, 2], :size => [8, 89])
|
11
|
+
graph << Scruffy::Components::Grid.new(:grid, :position => [10, 0], :size => [90, 89], :stroke_width => 1)
|
12
|
+
graph << Scruffy::Components::VGrid.new(:vgrid, :position => [10, 0], :size => [90, 89], :stroke_width => 1)
|
13
|
+
graph << Scruffy::Components::DataMarkers.new(:labels, :position => [10, 92], :size => [90, 8])
|
14
|
+
graph << Scruffy::Components::Graphs.new(:graphs, :position => [10, 0], :size => [90, 89])
|
15
|
+
end
|
16
|
+
components << Scruffy::Components::YLegend.new(:y_legend, :position => [1, 26], :size => [5, 66])
|
17
|
+
components << Scruffy::Components::XLegend.new(:x_legend, :position => [5, 92], :size => [90, 6])
|
18
|
+
components << Scruffy::Components::Legend.new(:legend, :position => [5, 13], :size => [90, 6])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
def hide_values
|
24
|
+
super
|
25
|
+
component(:view).position[0] = -10
|
26
|
+
component(:view).size[0] = 100
|
27
|
+
end
|
28
|
+
|
29
|
+
def labels
|
30
|
+
[component(:view).component(:labels)]
|
31
|
+
end
|
32
|
+
|
33
|
+
def values
|
34
|
+
[component(:view).component(:values)]
|
35
|
+
end
|
36
|
+
|
37
|
+
def grids
|
38
|
+
[component(:view).component(:grid),component(:view).component(:vgrid)]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'builder'
|
2
|
+
module Scruffy::Renderers
|
3
|
+
# ===Scruffy::Renderers::Base
|
4
|
+
#
|
5
|
+
# Author:: Brasten Sager
|
6
|
+
# Date:: August 14th, 2006
|
7
|
+
#
|
8
|
+
# Provides all the base functionality needed to render a graph, but
|
9
|
+
# does not provide a default layout.
|
10
|
+
#
|
11
|
+
# For a basic layout, see Scruffy::Renderers::Standard.
|
12
|
+
class Base
|
13
|
+
include Scruffy::Helpers::Canvas
|
14
|
+
|
15
|
+
attr_accessor :options
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
self.components = []
|
19
|
+
self.options = options
|
20
|
+
define_layout
|
21
|
+
end
|
22
|
+
|
23
|
+
# Renders the graph and all components.
|
24
|
+
def render(options = {})
|
25
|
+
options[:graph_id] ||= 'scruffy_graph'
|
26
|
+
options[:complexity] ||= (global_complexity || :normal)
|
27
|
+
|
28
|
+
# Allow subclasses to muck with components prior to renders.
|
29
|
+
rendertime_renderer = self.clone
|
30
|
+
rendertime_renderer.instance_eval { before_render if respond_to?(:before_render) }
|
31
|
+
|
32
|
+
svg = Builder::XmlMarkup.new(:indent => 2)
|
33
|
+
unless options[:no_doctype_header]
|
34
|
+
svg.instruct!
|
35
|
+
svg.instruct! 'DOCTYPE', 'svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" type'
|
36
|
+
end
|
37
|
+
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) {
|
38
|
+
svg.g(:id => options[:graph_id]) {
|
39
|
+
rendertime_renderer.components.each do |component|
|
40
|
+
component.render(svg,
|
41
|
+
bounds_for( options[:size], component.position, component.size ),
|
42
|
+
options)
|
43
|
+
end
|
44
|
+
}
|
45
|
+
}
|
46
|
+
svg.target!
|
47
|
+
end
|
48
|
+
|
49
|
+
def before_render
|
50
|
+
if self.options
|
51
|
+
set_values(self.options[:values]) if (self.options[:values] && self.options[:values] != :hide)
|
52
|
+
hide_grid if (self.options[:grid] == :hide)
|
53
|
+
hide_values if (self.options[:values] == :hide)
|
54
|
+
hide_labels if (self.options[:labels] == :hide)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def method_missing(sym, *args)
|
59
|
+
self.options = {} if self.options.nil?
|
60
|
+
|
61
|
+
if args.size > 0
|
62
|
+
self.options[sym] = args[0]
|
63
|
+
else
|
64
|
+
return self.options[sym]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
def hide_grid
|
70
|
+
grids.each { |grid| grid.visible = false }
|
71
|
+
end
|
72
|
+
|
73
|
+
def set_values(val)
|
74
|
+
values.each { |value| value.markers = val }
|
75
|
+
grids.each { |grid| grid.markers = val }
|
76
|
+
end
|
77
|
+
|
78
|
+
def hide_values
|
79
|
+
values.each { |value| value.visible = false }
|
80
|
+
end
|
81
|
+
|
82
|
+
def hide_labels
|
83
|
+
labels.each { |label| label.visible = false }
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
def global_complexity
|
88
|
+
if Kernel.const_defined? "SCRUFFY_COMPLEXITY"
|
89
|
+
SCRUFFY_COMPLEXITY
|
90
|
+
else
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end # base
|
95
|
+
end
|
@@ -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
|