gruffy 0.1.2 → 0.7.1.dev

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,37 +0,0 @@
1
- ##
2
- #
3
- # Makes a small bar graph suitable for display at 200px or even smaller.
4
- #
5
- module Gruffy
6
- module Mini
7
-
8
- class Bar < Gruffy::Bar
9
-
10
- include Gruffy::Mini::Legend
11
-
12
- def initialize_ivars
13
- super
14
-
15
- @hide_legend = true
16
- @hide_title = true
17
- @hide_line_numbers = true
18
-
19
- @marker_font_size = 50.0
20
- @minimum_value = 0.0
21
- @maximum_value = 0.0
22
- @legend_font_size = 60.0
23
- end
24
-
25
- def draw
26
- expand_canvas_for_vertical_legend
27
-
28
- super
29
-
30
- draw_vertical_legend
31
- @d.draw(@base_image)
32
- end
33
-
34
- end
35
-
36
- end
37
- end
@@ -1,114 +0,0 @@
1
- module Gruffy
2
- module Mini
3
- module Legend
4
-
5
- attr_accessor :hide_mini_legend, :legend_position
6
-
7
- def initialize(*)
8
- @hide_mini_legend = false
9
- @legend_position = nil
10
- super
11
- end
12
-
13
- ##
14
- # The canvas needs to be bigger so we can put the legend beneath it.
15
-
16
- def expand_canvas_for_vertical_legend
17
- return if @hide_mini_legend
18
-
19
- @legend_labels = @data.collect {|item| item[Gruffy::Base::DATA_LABEL_INDEX] }
20
-
21
- legend_height = scale_fontsize(
22
- @data.length * calculate_line_height +
23
- @top_margin + @bottom_margin)
24
-
25
- @original_rows = @raw_rows
26
- @original_columns = @raw_columns
27
-
28
- case @legend_position
29
- when :right then
30
- @rows = [@rows, legend_height].max
31
- @columns += calculate_legend_width + @left_margin
32
- else
33
- @rows += @data.length * calculate_caps_height(scale_fontsize(@legend_font_size)) * 1.7
34
- end
35
- render_background
36
- end
37
-
38
- def calculate_line_height
39
- calculate_caps_height(@legend_font_size) * 1.7
40
- end
41
-
42
- def calculate_legend_width
43
- width = @legend_labels.map { |label| calculate_width(@legend_font_size, label) }.max
44
- scale_fontsize(width + 40*1.7)
45
- end
46
-
47
- ##
48
- # Draw the legend beneath the existing graph.
49
-
50
- def draw_vertical_legend
51
- return if @hide_mini_legend
52
-
53
- legend_square_width = 40.0 # small square with color of this item
54
- @legend_left_margin = 100.0
55
- legend_top_margin = 40.0
56
-
57
- # May fix legend drawing problem at small sizes
58
- @d.font = @font if @font
59
- @d.pointsize = @legend_font_size
60
-
61
- case @legend_position
62
- when :right then
63
- current_x_offset = @original_columns + @left_margin
64
- current_y_offset = @top_margin + legend_top_margin
65
- else
66
- current_x_offset = @legend_left_margin
67
- current_y_offset = @original_rows + legend_top_margin
68
- end
69
-
70
- debug { @d.line 0.0, current_y_offset, @raw_columns, current_y_offset }
71
-
72
- @legend_labels.each_with_index do |legend_label, index|
73
-
74
- # Draw label
75
- @d.fill = @font_color
76
- @d.font = @font if @font
77
- @d.pointsize = scale_fontsize(@legend_font_size)
78
- @d.stroke = 'transparent'
79
- @d.font_weight = Magick::NormalWeight
80
- @d.gravity = Magick::WestGravity
81
- @d = @d.annotate_scaled( @base_image,
82
- @raw_columns, 1.0,
83
- current_x_offset + (legend_square_width * 1.7), current_y_offset,
84
- truncate_legend_label(legend_label), @scale)
85
-
86
- # Now draw box with color of this dataset
87
- @d = @d.stroke 'transparent'
88
- @d = @d.fill @data[index][Gruffy::Base::DATA_COLOR_INDEX]
89
- @d = @d.rectangle(current_x_offset,
90
- current_y_offset - legend_square_width / 2.0,
91
- current_x_offset + legend_square_width,
92
- current_y_offset + legend_square_width / 2.0)
93
-
94
- current_y_offset += calculate_line_height
95
- end
96
- @color_index = 0
97
- end
98
-
99
- ##
100
- # Shorten long labels so they will fit on the canvas.
101
- #
102
- # Department of Hu...
103
-
104
- def truncate_legend_label(label)
105
- truncated_label = label.to_s
106
- while calculate_width(scale_fontsize(@legend_font_size), truncated_label) > (@columns - @legend_left_margin - @right_margin) && (truncated_label.length > 1)
107
- truncated_label = truncated_label[0..truncated_label.length-2]
108
- end
109
- truncated_label + (truncated_label.length < label.to_s.length ? "..." : '')
110
- end
111
-
112
- end
113
- end
114
- end
@@ -1,36 +0,0 @@
1
- ##
2
- #
3
- # Makes a small pie graph suitable for display at 200px or even smaller.
4
- #
5
- module Gruffy
6
- module Mini
7
-
8
- class Pie < Gruffy::Pie
9
-
10
- include Gruffy::Mini::Legend
11
-
12
- def initialize_ivars
13
- super
14
-
15
- @hide_legend = true
16
- @hide_title = true
17
- @hide_line_numbers = true
18
-
19
- @marker_font_size = 60.0
20
- @legend_font_size = 60.0
21
- end
22
-
23
- def draw
24
- expand_canvas_for_vertical_legend
25
-
26
- super
27
-
28
- draw_vertical_legend
29
-
30
- @d.draw(@base_image)
31
- end # def draw
32
-
33
- end # class Pie
34
-
35
- end
36
- end
@@ -1,35 +0,0 @@
1
- ##
2
- #
3
- # Makes a small pie graph suitable for display at 200px or even smaller.
4
- #
5
- module Gruffy
6
- module Mini
7
-
8
- class SideBar < Gruffy::SideBar
9
-
10
- include Gruffy::Mini::Legend
11
-
12
- def initialize_ivars
13
- super
14
- @hide_legend = true
15
- @hide_title = true
16
- @hide_line_numbers = true
17
-
18
- @marker_font_size = 50.0
19
- @legend_font_size = 50.0
20
- end
21
-
22
- def draw
23
- expand_canvas_for_vertical_legend
24
-
25
- super
26
-
27
- draw_vertical_legend
28
-
29
- @d.draw(@base_image)
30
- end
31
-
32
- end
33
-
34
- end
35
- end
@@ -1,127 +0,0 @@
1
- require File.dirname(__FILE__) + '/base'
2
-
3
- # Experimental!!! See also the Spider graph.
4
- class Gruffy::Net < Gruffy::Base
5
-
6
- # Hide parts of the graph to fit more datapoints, or for a different appearance.
7
- attr_accessor :hide_dots
8
-
9
- # Dimensions of lines and dots; calculated based on dataset size if left unspecified
10
- attr_accessor :line_width
11
- attr_accessor :dot_radius
12
-
13
- def initialize(*args)
14
- super
15
-
16
- @hide_dots = false
17
- @hide_line_numbers = true
18
- @sorted_drawing = true
19
- end
20
-
21
- def draw
22
- super
23
-
24
- return unless @has_data
25
-
26
- @radius = @graph_height / 2.0
27
- @center_x = @graph_left + (@graph_width / 2.0)
28
- @center_y = @graph_top + (@graph_height / 2.0) - 10 # Move graph up a bit
29
-
30
- @x_increment = @graph_width / (@column_count - 1).to_f
31
- circle_radius = dot_radius ||
32
- clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 2.5), 5.0)
33
-
34
- @d = @d.stroke_opacity 1.0
35
- @d = @d.stroke_width line_width ||
36
- clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 4), 5.0)
37
-
38
- if defined?(@norm_baseline)
39
- level = @graph_top + (@graph_height - @norm_baseline * @graph_height)
40
- @d = @d.push
41
- @d.stroke_color @baseline_color
42
- @d.fill_opacity 0.0
43
- @d.stroke_dasharray(10, 20)
44
- @d.stroke_width 5
45
- @d.line(@graph_left, level, @graph_left + @graph_width, level)
46
- @d = @d.pop
47
- end
48
-
49
- @norm_data.each do |data_row|
50
- @d = @d.stroke data_row[DATA_COLOR_INDEX]
51
- @d = @d.fill data_row[DATA_COLOR_INDEX]
52
-
53
- data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
54
- next if data_point.nil?
55
-
56
- rad_pos = index * Math::PI * 2 / @column_count
57
- point_distance = data_point * @radius
58
- start_x = @center_x + Math::sin(rad_pos) * point_distance
59
- start_y = @center_y - Math::cos(rad_pos) * point_distance
60
-
61
- next_index = index + 1 < data_row[DATA_VALUES_INDEX].length ? index + 1 : 0
62
-
63
- next_rad_pos = next_index * Math::PI * 2 / @column_count
64
- next_point_distance = data_row[DATA_VALUES_INDEX][next_index] * @radius
65
- end_x = @center_x + Math::sin(next_rad_pos) * next_point_distance
66
- end_y = @center_y - Math::cos(next_rad_pos) * next_point_distance
67
-
68
- @d = @d.line(start_x, start_y, end_x, end_y)
69
-
70
- @d = @d.circle(start_x, start_y, start_x - circle_radius, start_y) unless @hide_dots
71
- end
72
-
73
- end
74
-
75
- @d.draw(@base_image)
76
- end
77
-
78
-
79
- # the lines connecting in the center, with the first line vertical
80
- def draw_line_markers
81
- return if @hide_line_markers
82
-
83
-
84
- # have to do this here (AGAIN)... see draw() in this class
85
- # because this funtion is called before the @radius, @center_x and @center_y are set
86
- @radius = @graph_height / 2.0
87
- @center_x = @graph_left + (@graph_width / 2.0)
88
- @center_y = @graph_top + (@graph_height / 2.0) - 10 # Move graph up a bit
89
-
90
-
91
- # Draw horizontal line markers and annotate with numbers
92
- @d = @d.stroke(@marker_color)
93
- @d = @d.stroke_width 1
94
-
95
-
96
- (0..@column_count-1).each do |index|
97
- rad_pos = index * Math::PI * 2 / @column_count
98
-
99
- @d = @d.line(@center_x, @center_y, @center_x + Math::sin(rad_pos) * @radius, @center_y - Math::cos(rad_pos) * @radius)
100
-
101
-
102
- marker_label = labels[index] ? labels[index].to_s : '000'
103
-
104
- draw_label(@center_x, @center_y, rad_pos * 360 / (2 * Math::PI), @radius, marker_label)
105
- end
106
- end
107
-
108
- private
109
-
110
- def draw_label(center_x, center_y, angle, radius, amount)
111
- r_offset = 1.1
112
- x_offset = center_x # + 15 # The label points need to be tweaked slightly
113
- y_offset = center_y # + 0 # This one doesn't though
114
- x = x_offset + (radius * r_offset * Math.sin(deg2rad(angle)))
115
- y = y_offset - (radius * r_offset * Math.cos(deg2rad(angle)))
116
-
117
- # Draw label
118
- @d.fill = @marker_color
119
- @d.font = @font if @font
120
- @d.pointsize = scale_fontsize(20)
121
- @d.stroke = 'transparent'
122
- @d.font_weight = BoldWeight
123
- @d.gravity = CenterGravity
124
- @d.annotate_scaled(@base_image, 0, 0, x, y, amount, @scale)
125
- end
126
-
127
- end
@@ -1,100 +0,0 @@
1
- require File.dirname(__FILE__) + '/base'
2
-
3
- # EXPERIMENTAL!
4
- #
5
- # Doesn't work yet.
6
- #
7
- class Gruffy::PhotoBar < Gruffy::Base
8
-
9
- # TODO
10
- #
11
- # define base and cap in yml
12
- # allow for image directory to be located elsewhere
13
- # more exact measurements for bar heights (go all the way to the bottom of the graph)
14
- # option to tile images instead of use a single image
15
- # drop base label a few px lower so photo bar graphs can have a base dropping over the lower marker line
16
- #
17
-
18
- # The name of a pre-packaged photo-based theme.
19
- attr_reader :theme
20
-
21
- # def initialize(target_width=800)
22
- # super
23
- # init_photo_bar_graphics()
24
- # end
25
-
26
- def draw
27
- super
28
- return unless @has_data
29
-
30
- return # TODO Remove for further development
31
-
32
- init_photo_bar_graphics()
33
-
34
- #Draw#define_clip_path()
35
- #Draw#clip_path(pathname)
36
- #Draw#composite....with bar graph image OverCompositeOp
37
- #
38
- # See also
39
- #
40
- # Draw.pattern # define an image to tile as the filling of a draw object
41
- #
42
-
43
- # Setup spacing.
44
- #
45
- # Columns sit side-by-side.
46
- spacing_factor = 0.9
47
- @bar_width = @norm_data[0][DATA_COLOR_INDEX].columns
48
-
49
- @norm_data.each_with_index do |data_row, row_index|
50
-
51
- data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
52
- data_point = 0 if data_point.nil?
53
- # Use incremented x and scaled y
54
- left_x = @graph_left + (@bar_width * (row_index + point_index + ((@data.length - 1) * point_index)))
55
- left_y = @graph_top + (@graph_height - data_point * @graph_height) + 1
56
- right_x = left_x + @bar_width * spacing_factor
57
- right_y = @graph_top + @graph_height - 1
58
-
59
- bar_image_width = data_row[DATA_COLOR_INDEX].columns
60
- bar_image_height = right_y.to_f - left_y.to_f
61
-
62
- # Crop to scale for data
63
- bar_image = data_row[DATA_COLOR_INDEX].crop(0, 0, bar_image_width, bar_image_height)
64
-
65
- @d.gravity = NorthWestGravity
66
- @d = @d.composite(left_x, left_y, bar_image_width, bar_image_height, bar_image)
67
-
68
- # Calculate center based on bar_width and current row
69
- label_center = @graph_left + (@data.length * @bar_width * point_index) + (@data.length * @bar_width / 2.0)
70
- draw_label(label_center, point_index)
71
- end
72
-
73
- end
74
-
75
- @d.draw(@base_image)
76
- end
77
-
78
-
79
- # Return the chosen theme or the default
80
- def theme
81
- @theme || 'plastik'
82
- end
83
-
84
- protected
85
-
86
- # Sets up colors with a list of images that will be used.
87
- # Images should be 340px tall
88
- def init_photo_bar_graphics
89
- color_list = Array.new
90
- theme_dir = File.dirname(__FILE__) + '/../../assets/' + theme
91
-
92
- Dir.open(theme_dir).each do |file|
93
- next unless /\.png$/.match(file)
94
- color_list << Image.read("#{theme_dir}/#{file}").first
95
- end
96
- @colors = color_list
97
- end
98
-
99
- end
100
-