image_paradise 0.1.12
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.
Potentially problematic release.
This version of image_paradise might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/LICENSE.md +38 -0
- data/README.md +179 -0
- data/USAGE.md +10 -0
- data/bin/black_white +10 -0
- data/bin/display_text_from_this_image +7 -0
- data/bin/image_paradise +7 -0
- data/bin/image_paradise_shell +7 -0
- data/bin/image_to_ascii +54 -0
- data/bin/image_to_pdf +7 -0
- data/bin/make_this_image_transparent +7 -0
- data/bin/rotate_left +7 -0
- data/bin/rotate_right +7 -0
- data/doc/README.gen +162 -0
- data/doc/TODO_FOR_THE_GTK_GUI.md +1 -0
- data/image_paradise.gemspec +50 -0
- data/lib/image_paradise.rb +5 -0
- data/lib/image_paradise/base/base.rb +91 -0
- data/lib/image_paradise/black_white.rb +89 -0
- data/lib/image_paradise/confree_generator/class.rb +614 -0
- data/lib/image_paradise/confree_generator/constants.rb +61 -0
- data/lib/image_paradise/confree_generator/gui/gtk_confree_generator.rb +752 -0
- data/lib/image_paradise/confree_generator/gui/insert_button.rb +78 -0
- data/lib/image_paradise/confree_generator/reset.rb +61 -0
- data/lib/image_paradise/confree_generator/shared/shared.rb +100 -0
- data/lib/image_paradise/constants.rb +43 -0
- data/lib/image_paradise/constants/image_file_types.rb +21 -0
- data/lib/image_paradise/create_animated_gif.rb +47 -0
- data/lib/image_paradise/crop/crop.rb +302 -0
- data/lib/image_paradise/gm_support.rb +34 -0
- data/lib/image_paradise/graphs.rb +36 -0
- data/lib/image_paradise/graphs/accumulator_bar.rb +29 -0
- data/lib/image_paradise/graphs/area.rb +64 -0
- data/lib/image_paradise/graphs/bar.rb +117 -0
- data/lib/image_paradise/graphs/bar_conversion.rb +53 -0
- data/lib/image_paradise/graphs/base.rb +1392 -0
- data/lib/image_paradise/graphs/bezier.rb +45 -0
- data/lib/image_paradise/graphs/bullet.rb +115 -0
- data/lib/image_paradise/graphs/deprecated.rb +42 -0
- data/lib/image_paradise/graphs/dot.rb +129 -0
- data/lib/image_paradise/graphs/line.rb +328 -0
- data/lib/image_paradise/graphs/mini/bar.rb +42 -0
- data/lib/image_paradise/graphs/mini/legend.rb +109 -0
- data/lib/image_paradise/graphs/mini/pie.rb +42 -0
- data/lib/image_paradise/graphs/mini/side_bar.rb +41 -0
- data/lib/image_paradise/graphs/net.rb +133 -0
- data/lib/image_paradise/graphs/photo_bar.rb +106 -0
- data/lib/image_paradise/graphs/pie.rb +139 -0
- data/lib/image_paradise/graphs/scatter.rb +264 -0
- data/lib/image_paradise/graphs/scene.rb +216 -0
- data/lib/image_paradise/graphs/side_bar.rb +144 -0
- data/lib/image_paradise/graphs/side_stacked_bar.rb +116 -0
- data/lib/image_paradise/graphs/spider.rb +163 -0
- data/lib/image_paradise/graphs/stacked_area.rb +73 -0
- data/lib/image_paradise/graphs/stacked_bar.rb +68 -0
- data/lib/image_paradise/graphs/stacked_mixin.rb +30 -0
- data/lib/image_paradise/graphs/themes.rb +117 -0
- data/lib/image_paradise/graphviz/README.md +2 -0
- data/lib/image_paradise/graphviz/generate_graphviz_image.rb +274 -0
- data/lib/image_paradise/gui/gtk/control_panel.rb +126 -0
- data/lib/image_paradise/identify.rb +145 -0
- data/lib/image_paradise/image_border.rb +231 -0
- data/lib/image_paradise/image_manipulations.rb +320 -0
- data/lib/image_paradise/image_paradise.rb +150 -0
- data/lib/image_paradise/image_to_ascii/image_to_ascii.rb +187 -0
- data/lib/image_paradise/image_to_pdf/image_to_pdf.rb +99 -0
- data/lib/image_paradise/label/README.md +2 -0
- data/lib/image_paradise/label/simple_label.rb +206 -0
- data/lib/image_paradise/optimizer.rb +483 -0
- data/lib/image_paradise/project/project.rb +29 -0
- data/lib/image_paradise/random_text_to_image.rb +363 -0
- data/lib/image_paradise/requires/common_base_requires.rb +17 -0
- data/lib/image_paradise/requires/require_colours.rb +9 -0
- data/lib/image_paradise/requires/require_gtk_components.rb +8 -0
- data/lib/image_paradise/requires/require_image_to_ascii.rb +7 -0
- data/lib/image_paradise/requires/require_the_image_paradise_project.rb +24 -0
- data/lib/image_paradise/requires/require_toplevel_methods.rb +21 -0
- data/lib/image_paradise/rotate/README.md +2 -0
- data/lib/image_paradise/rotate/rotate.rb +98 -0
- data/lib/image_paradise/shell/interactive.rb +156 -0
- data/lib/image_paradise/svg/README.md +5 -0
- data/lib/image_paradise/svg/circle.rb +106 -0
- data/lib/image_paradise/svg/feature.rb +48 -0
- data/lib/image_paradise/svg/rectangle.rb +154 -0
- data/lib/image_paradise/svg/svg.rb +102 -0
- data/lib/image_paradise/to_gif.rb +91 -0
- data/lib/image_paradise/to_jpg.rb +90 -0
- data/lib/image_paradise/toplevel_methods/add_black_border_to_this_image.rb +56 -0
- data/lib/image_paradise/toplevel_methods/crop.rb +28 -0
- data/lib/image_paradise/toplevel_methods/e.rb +16 -0
- data/lib/image_paradise/toplevel_methods/esystem.rb +19 -0
- data/lib/image_paradise/toplevel_methods/extract_text_from_this_image.rb +56 -0
- data/lib/image_paradise/toplevel_methods/file_related_code.rb +25 -0
- data/lib/image_paradise/toplevel_methods/flip_image_left_right.rb +32 -0
- data/lib/image_paradise/toplevel_methods/greyscale_this_image.rb +59 -0
- data/lib/image_paradise/toplevel_methods/help.rb +30 -0
- data/lib/image_paradise/toplevel_methods/make_this_image_transparent.rb +30 -0
- data/lib/image_paradise/toplevel_methods/menu.rb +92 -0
- data/lib/image_paradise/toplevel_methods/merge_these_images.rb +49 -0
- data/lib/image_paradise/toplevel_methods/mirror_image.rb +28 -0
- data/lib/image_paradise/toplevel_methods/misc.rb +31 -0
- data/lib/image_paradise/toplevel_methods/png_to_svg.rb +34 -0
- data/lib/image_paradise/toplevel_methods/roebe.rb +17 -0
- data/lib/image_paradise/toplevel_methods/to_png.rb +105 -0
- data/lib/image_paradise/toplevel_methods/wallpaper.rb +37 -0
- data/lib/image_paradise/toplevel_methods/write_this_text.rb +76 -0
- data/lib/image_paradise/version/version.rb +19 -0
- data/test/16x16_red_square_image_for_testing.png +0 -0
- data/test/testing_confree_generator.rb +8 -0
- data/test/testing_crop.rb +19 -0
- data/test/testing_image_magick_commands.rb +39 -0
- data/test/testing_image_paradise.rb +49 -0
- data/test/testing_the_svg_component.html +261 -0
- data/test/testing_the_svg_component.rb +106 -0
- metadata +217 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
require 'image_paradise/graphs/base.rb'
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Graph with individual horizontal bars instead of vertical bars.
|
|
9
|
+
|
|
10
|
+
module ImageParadise
|
|
11
|
+
|
|
12
|
+
class Gruff::SideBar < Gruff::Base
|
|
13
|
+
|
|
14
|
+
# Spacing factor applied between bars
|
|
15
|
+
attr_accessor :bar_spacing
|
|
16
|
+
|
|
17
|
+
def draw
|
|
18
|
+
@has_left_labels = true
|
|
19
|
+
super
|
|
20
|
+
|
|
21
|
+
return unless @has_data
|
|
22
|
+
draw_bars
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
def draw_bars
|
|
28
|
+
# Setup spacing.
|
|
29
|
+
#
|
|
30
|
+
@bar_spacing ||= 0.9
|
|
31
|
+
|
|
32
|
+
@bars_width = @graph_height / @column_count.to_f
|
|
33
|
+
@bar_width = @bars_width / @norm_data.size
|
|
34
|
+
@d = @d.stroke_opacity 0.0
|
|
35
|
+
height = Array.new(@column_count, 0)
|
|
36
|
+
length = Array.new(@column_count, @graph_left)
|
|
37
|
+
padding = (@bar_width * (1 - @bar_spacing)) / 2
|
|
38
|
+
|
|
39
|
+
# if we're a side stacked bar then we don't need to draw ourself at all
|
|
40
|
+
# because sometimes (due to different heights/min/max) you can actually
|
|
41
|
+
# see both graphs and it looks like crap
|
|
42
|
+
return if self.is_a?(Gruff::SideStackedBar)
|
|
43
|
+
|
|
44
|
+
@norm_data.each_with_index do |data_row, row_index|
|
|
45
|
+
@d = @d.fill data_row[DATA_COLOR_INDEX]
|
|
46
|
+
|
|
47
|
+
data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
|
|
48
|
+
|
|
49
|
+
# Using the original calcs from the stacked bar chart
|
|
50
|
+
# to get the difference between
|
|
51
|
+
# part of the bart chart we wish to stack.
|
|
52
|
+
temp1 = @graph_left + (@graph_width - data_point * @graph_width - height[point_index])
|
|
53
|
+
temp2 = @graph_left + @graph_width - height[point_index]
|
|
54
|
+
difference = temp2 - temp1
|
|
55
|
+
|
|
56
|
+
left_x = length[point_index] - 1
|
|
57
|
+
left_y = @graph_top + (@bars_width * point_index) + (@bar_width * row_index) + padding
|
|
58
|
+
right_x = left_x + difference
|
|
59
|
+
right_y = left_y + @bar_width * @bar_spacing
|
|
60
|
+
|
|
61
|
+
height[point_index] += (data_point * @graph_width)
|
|
62
|
+
|
|
63
|
+
@d = @d.rectangle(left_x, left_y, right_x, right_y)
|
|
64
|
+
|
|
65
|
+
# Calculate center based on bar_width and current row
|
|
66
|
+
|
|
67
|
+
if @use_data_label
|
|
68
|
+
label_center = @graph_top + (@bar_width * (row_index+point_index) + @bar_width / 2)
|
|
69
|
+
draw_label(label_center, row_index, @norm_data[row_index][DATA_LABEL_INDEX])
|
|
70
|
+
else
|
|
71
|
+
label_center = @graph_top + (@bars_width * point_index + @bars_width / 2)
|
|
72
|
+
draw_label(label_center, point_index)
|
|
73
|
+
end
|
|
74
|
+
if @show_labels_for_bar_values
|
|
75
|
+
val = (@label_formatting || '%.2f') % @norm_data[row_index][3][point_index]
|
|
76
|
+
draw_value_label(right_x+40, (@graph_top + (((row_index+point_index+1) * @bar_width) - (@bar_width / 2)))-12, val.commify, true)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
@d.draw(@base_image)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Instead of base class version, draws vertical background lines and label
|
|
86
|
+
def draw_line_markers
|
|
87
|
+
|
|
88
|
+
return if @hide_line_markers
|
|
89
|
+
|
|
90
|
+
@d = @d.stroke_antialias false
|
|
91
|
+
|
|
92
|
+
# Draw horizontal line markers and annotate with numbers
|
|
93
|
+
@d = @d.stroke(@marker_color)
|
|
94
|
+
@d = @d.stroke_width 1
|
|
95
|
+
number_of_lines = @marker_count || 5
|
|
96
|
+
number_of_lines = 1 if number_of_lines == 0
|
|
97
|
+
|
|
98
|
+
# TODO Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
|
|
99
|
+
increment = significant(@spread.to_f / number_of_lines)
|
|
100
|
+
(0..number_of_lines).each do |index|
|
|
101
|
+
|
|
102
|
+
line_diff = (@graph_right - @graph_left) / number_of_lines
|
|
103
|
+
x = @graph_right - (line_diff * index) - 1
|
|
104
|
+
@d = @d.line(x, @graph_bottom, x, @graph_top)
|
|
105
|
+
diff = index - number_of_lines
|
|
106
|
+
marker_label = diff.abs * increment + @minimum_value
|
|
107
|
+
|
|
108
|
+
unless @hide_line_numbers
|
|
109
|
+
@d.fill = @font_color
|
|
110
|
+
@d.font = @font if @font
|
|
111
|
+
@d.stroke = 'transparent'
|
|
112
|
+
@d.pointsize = scale_fontsize(@marker_font_size)
|
|
113
|
+
@d.gravity = CenterGravity
|
|
114
|
+
# TODO Center text over line
|
|
115
|
+
@d = @d.annotate_scaled(@base_image,
|
|
116
|
+
0, 0, # Width of box to draw text in
|
|
117
|
+
x, @graph_bottom + (LABEL_MARGIN * 2.0), # Coordinates of text
|
|
118
|
+
marker_label.to_s, @scale)
|
|
119
|
+
end # unless
|
|
120
|
+
@d = @d.stroke_antialias true
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
##
|
|
125
|
+
# Draw on the Y axis instead of the X
|
|
126
|
+
|
|
127
|
+
def draw_label(y_offset, index, label=nil)
|
|
128
|
+
if !@labels[index].nil? && @labels_seen[index].nil?
|
|
129
|
+
lbl = (@use_data_label) ? label : @labels[index]
|
|
130
|
+
@d.fill = @font_color
|
|
131
|
+
@d.font = @font if @font
|
|
132
|
+
@d.stroke = 'transparent'
|
|
133
|
+
@d.font_weight = NormalWeight
|
|
134
|
+
@d.pointsize = scale_fontsize(@marker_font_size)
|
|
135
|
+
@d.gravity = EastGravity
|
|
136
|
+
@d = @d.annotate_scaled(@base_image,
|
|
137
|
+
1, 1,
|
|
138
|
+
-@graph_left + LABEL_MARGIN * 2.0, y_offset,
|
|
139
|
+
lbl, @scale)
|
|
140
|
+
@labels_seen[index] = 1
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
end; end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
require 'image_paradise/graphs/base.rb'
|
|
6
|
+
require 'image_paradise/graphs/side_bar.rb'
|
|
7
|
+
require 'image_paradise/graphs/stacked_mixin.rb'
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# New gruff graph type added to enable sideways stacking bar charts
|
|
11
|
+
# (basically looks like a x/y flip of a standard stacking bar chart)
|
|
12
|
+
#
|
|
13
|
+
# alun.eyre@googlemail.com
|
|
14
|
+
module ImageParadise
|
|
15
|
+
|
|
16
|
+
class Gruff::SideStackedBar < Gruff::SideBar
|
|
17
|
+
|
|
18
|
+
include StackedMixin
|
|
19
|
+
|
|
20
|
+
# Spacing factor applied between bars
|
|
21
|
+
attr_accessor :bar_spacing
|
|
22
|
+
|
|
23
|
+
def draw
|
|
24
|
+
@has_left_labels = true
|
|
25
|
+
get_maximum_by_stack
|
|
26
|
+
super
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
def draw_bars
|
|
32
|
+
# Setup spacing.
|
|
33
|
+
#
|
|
34
|
+
# Columns sit stacked.
|
|
35
|
+
@bar_spacing ||= 0.9
|
|
36
|
+
|
|
37
|
+
@bar_width = @graph_height / @column_count.to_f
|
|
38
|
+
@d = @d.stroke_opacity 0.0
|
|
39
|
+
height = Array.new(@column_count, 0)
|
|
40
|
+
length = Array.new(@column_count, @graph_left)
|
|
41
|
+
padding = (@bar_width * (1 - @bar_spacing)) / 2
|
|
42
|
+
if @show_labels_for_bar_values
|
|
43
|
+
label_values = Array.new
|
|
44
|
+
0.upto(@column_count-1) {|i| label_values[i] = {:value => 0, :right_x => 0}}
|
|
45
|
+
end
|
|
46
|
+
@norm_data.each_with_index do |data_row, row_index|
|
|
47
|
+
data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
|
|
48
|
+
## using the original calcs from the stacked bar chart to get the difference between
|
|
49
|
+
## part of the bart chart we wish to stack.
|
|
50
|
+
temp1 = @graph_left + (@graph_width -
|
|
51
|
+
data_point * @graph_width -
|
|
52
|
+
height[point_index]) + 1
|
|
53
|
+
temp2 = @graph_left + @graph_width - height[point_index] - 1
|
|
54
|
+
difference = temp2 - temp1
|
|
55
|
+
|
|
56
|
+
@d = @d.fill data_row[DATA_COLOR_INDEX]
|
|
57
|
+
|
|
58
|
+
left_x = length[point_index] #+ 1
|
|
59
|
+
left_y = @graph_top + (@bar_width * point_index) + padding
|
|
60
|
+
right_x = left_x + difference
|
|
61
|
+
right_y = left_y + @bar_width * @bar_spacing
|
|
62
|
+
length[point_index] += difference
|
|
63
|
+
height[point_index] += (data_point * @graph_width - 2)
|
|
64
|
+
|
|
65
|
+
if @show_labels_for_bar_values
|
|
66
|
+
label_values[point_index][:value] += @norm_data[row_index][3][point_index]
|
|
67
|
+
label_values[point_index][:right_x] = right_x
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# if a data point is 0 it can result in weird really thing lines
|
|
71
|
+
# that shouldn't even be there being drawn on top of the existing
|
|
72
|
+
# bar - this is bad
|
|
73
|
+
if data_point != 0
|
|
74
|
+
@d = @d.rectangle(left_x, left_y, right_x, right_y)
|
|
75
|
+
# Calculate center based on bar_width and current row
|
|
76
|
+
end
|
|
77
|
+
# we still need to draw the labels
|
|
78
|
+
# Calculate center based on bar_width and current row
|
|
79
|
+
label_center = @graph_top + (@bar_width * point_index) + (@bar_width * @bar_spacing / 2.0)
|
|
80
|
+
draw_label(label_center, point_index)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
if @show_labels_for_bar_values
|
|
85
|
+
label_values.each_with_index { |data, i|
|
|
86
|
+
val = (@label_formatting || "%.2f") % data[:value]
|
|
87
|
+
draw_value_label(data[:right_x]+40, (@graph_top + (((i+1) * @bar_width) - (@bar_width / 2)))-12, val.commify, true)
|
|
88
|
+
}
|
|
89
|
+
end
|
|
90
|
+
@d.draw(@base_image)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# ========================================================================= #
|
|
94
|
+
# === larger_than_max?
|
|
95
|
+
# ========================================================================= #
|
|
96
|
+
def larger_than_max?(data_point, index=0)
|
|
97
|
+
max(data_point, index) > @maximum_value
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# ========================================================================= #
|
|
101
|
+
# === max
|
|
102
|
+
# ========================================================================= #
|
|
103
|
+
def max(data_point, index)
|
|
104
|
+
puts '---'
|
|
105
|
+
pp data_point
|
|
106
|
+
pp index
|
|
107
|
+
pp @data
|
|
108
|
+
puts '---'
|
|
109
|
+
@data.inject(0) {|sum, item|
|
|
110
|
+
value = item[DATA_VALUES_INDEX][index]
|
|
111
|
+
pp value
|
|
112
|
+
sum + value
|
|
113
|
+
}
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end; end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
require 'image_paradise/graphs/base.rb'
|
|
6
|
+
|
|
7
|
+
# =========================================================================== #
|
|
8
|
+
# Experimental!!! See also the Net graph.
|
|
9
|
+
#
|
|
10
|
+
# Submitted by Kevin Clark http://glu.ttono.us/
|
|
11
|
+
# =========================================================================== #
|
|
12
|
+
module ImageParadise
|
|
13
|
+
|
|
14
|
+
class Gruff::Spider < Gruff::Base
|
|
15
|
+
|
|
16
|
+
# Hide all text
|
|
17
|
+
attr_reader :hide_text
|
|
18
|
+
attr_accessor :hide_axes
|
|
19
|
+
attr_reader :transparent_background
|
|
20
|
+
attr_accessor :rotation
|
|
21
|
+
|
|
22
|
+
# ========================================================================= #
|
|
23
|
+
# === initialize
|
|
24
|
+
# ========================================================================= #
|
|
25
|
+
def initialize(max_value, target_width = 800)
|
|
26
|
+
super(target_width)
|
|
27
|
+
@max_value = max_value
|
|
28
|
+
@hide_legend = true;
|
|
29
|
+
@rotation = 0
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# ========================================================================= #
|
|
33
|
+
# === transparent_background=
|
|
34
|
+
# ========================================================================= #
|
|
35
|
+
def transparent_background=(value)
|
|
36
|
+
@transparent_background = value
|
|
37
|
+
@base_image = render_transparent_background if value
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# ========================================================================= #
|
|
41
|
+
# === draw
|
|
42
|
+
# ========================================================================= #
|
|
43
|
+
def draw
|
|
44
|
+
@hide_line_markers = true
|
|
45
|
+
super
|
|
46
|
+
return unless @has_data
|
|
47
|
+
# Setup basic positioning
|
|
48
|
+
# diameter = @graph_height # Variable not in use.
|
|
49
|
+
radius = @graph_height / 2.0
|
|
50
|
+
# top_x = @graph_left + (@graph_width - diameter) / 2.0
|
|
51
|
+
center_x = @graph_left + (@graph_width / 2.0)
|
|
52
|
+
center_y = @graph_top + (@graph_height / 2.0) - 25 # Move graph up a bit
|
|
53
|
+
|
|
54
|
+
@unit_length = radius / @max_value
|
|
55
|
+
|
|
56
|
+
# total_sum = sums_for_spider # Not in use.
|
|
57
|
+
# prev_degrees = 0.0 # Not in use.
|
|
58
|
+
additive_angle = (2 * Math::PI)/ @data.size
|
|
59
|
+
|
|
60
|
+
# current_angle = rotation * Math::PI / 180.0 # Not in use.
|
|
61
|
+
|
|
62
|
+
# Draw axes
|
|
63
|
+
draw_axes(center_x, center_y, radius, additive_angle) unless hide_axes
|
|
64
|
+
|
|
65
|
+
# Draw polygon
|
|
66
|
+
draw_polygon(center_x, center_y, additive_angle)
|
|
67
|
+
|
|
68
|
+
@d.draw(@base_image)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# ========================================================================= #
|
|
72
|
+
# === hide_text=
|
|
73
|
+
# ========================================================================= #
|
|
74
|
+
def hide_text=(value)
|
|
75
|
+
@hide_title = @hide_text = value
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
# ========================================================================= #
|
|
80
|
+
# === normalize_points
|
|
81
|
+
# ========================================================================= #
|
|
82
|
+
def normalize_points(value)
|
|
83
|
+
value * @unit_length
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# ========================================================================= #
|
|
87
|
+
# === draw_label
|
|
88
|
+
# ========================================================================= #
|
|
89
|
+
def draw_label(center_x, center_y, angle, radius, amount)
|
|
90
|
+
r_offset = 50 # The distance out from the center of the pie to get point
|
|
91
|
+
x_offset = center_x # The label points need to be tweaked slightly
|
|
92
|
+
y_offset = center_y + 0 # This one doesn't though
|
|
93
|
+
x = x_offset + ((radius + r_offset) * Math.cos(angle))
|
|
94
|
+
y = y_offset + ((radius + r_offset) * Math.sin(angle))
|
|
95
|
+
|
|
96
|
+
# Draw label
|
|
97
|
+
@d.fill = @marker_color
|
|
98
|
+
@d.font = @font if @font
|
|
99
|
+
@d.pointsize = scale_fontsize(legend_font_size)
|
|
100
|
+
@d.stroke = 'transparent'
|
|
101
|
+
@d.font_weight = BoldWeight
|
|
102
|
+
@d.gravity = CenterGravity
|
|
103
|
+
@d.annotate_scaled( @base_image,
|
|
104
|
+
0, 0,
|
|
105
|
+
x, y,
|
|
106
|
+
amount, @scale)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# ========================================================================= #
|
|
110
|
+
# === draw_axes
|
|
111
|
+
# ========================================================================= #
|
|
112
|
+
def draw_axes(center_x, center_y, radius, additive_angle, line_color = nil)
|
|
113
|
+
return if hide_axes
|
|
114
|
+
|
|
115
|
+
current_angle = rotation * Math::PI / 180.0
|
|
116
|
+
|
|
117
|
+
@data.each do |data_row|
|
|
118
|
+
@d.stroke(line_color || data_row[DATA_COLOR_INDEX])
|
|
119
|
+
@d.stroke_width 5.0
|
|
120
|
+
|
|
121
|
+
x_offset = radius * Math.cos(current_angle)
|
|
122
|
+
y_offset = radius * Math.sin(current_angle)
|
|
123
|
+
|
|
124
|
+
@d.line(center_x, center_y,
|
|
125
|
+
center_x + x_offset,
|
|
126
|
+
center_y + y_offset)
|
|
127
|
+
|
|
128
|
+
draw_label(center_x, center_y, current_angle, radius, data_row[DATA_LABEL_INDEX].to_s) unless hide_text
|
|
129
|
+
|
|
130
|
+
current_angle += additive_angle
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# ========================================================================= #
|
|
135
|
+
# === draw_polygon
|
|
136
|
+
# ========================================================================= #
|
|
137
|
+
def draw_polygon(center_x, center_y, additive_angle, color = nil)
|
|
138
|
+
points = []
|
|
139
|
+
current_angle = rotation * Math::PI / 180.0
|
|
140
|
+
|
|
141
|
+
@data.each { |data_row|
|
|
142
|
+
points << center_x + normalize_points(data_row[DATA_VALUES_INDEX].first) * Math.cos(current_angle)
|
|
143
|
+
points << center_y + normalize_points(data_row[DATA_VALUES_INDEX].first) * Math.sin(current_angle)
|
|
144
|
+
current_angle += additive_angle
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@d.stroke_width 1.0
|
|
148
|
+
@d.stroke(color || @marker_color)
|
|
149
|
+
@d.fill(color || @marker_color)
|
|
150
|
+
@d.fill_opacity 0.4
|
|
151
|
+
@d.polygon(*points)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# ========================================================================= #
|
|
155
|
+
# === sums_for_spider
|
|
156
|
+
# ========================================================================= #
|
|
157
|
+
def sums_for_spider
|
|
158
|
+
@data.inject(0.0) {|sum, data_row|
|
|
159
|
+
sum += data_row[DATA_VALUES_INDEX].first
|
|
160
|
+
}
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end; end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
require 'image_paradise/graphs/base.rb'
|
|
6
|
+
require 'image_paradise/graphs/stacked_mixin.rb'
|
|
7
|
+
|
|
8
|
+
module ImageParadise
|
|
9
|
+
|
|
10
|
+
class Gruff::StackedArea < Gruff::Base
|
|
11
|
+
|
|
12
|
+
include StackedMixin
|
|
13
|
+
|
|
14
|
+
attr_accessor :last_series_goes_on_bottom
|
|
15
|
+
# === draw
|
|
16
|
+
def draw
|
|
17
|
+
get_maximum_by_stack
|
|
18
|
+
super
|
|
19
|
+
|
|
20
|
+
return unless @has_data
|
|
21
|
+
|
|
22
|
+
@x_increment = @graph_width / (@column_count - 1).to_f
|
|
23
|
+
@d = @d.stroke 'transparent'
|
|
24
|
+
|
|
25
|
+
height = Array.new(@column_count, 0)
|
|
26
|
+
|
|
27
|
+
data_points = nil
|
|
28
|
+
iterator = last_series_goes_on_bottom ? :reverse_each : :each
|
|
29
|
+
@norm_data.send(iterator) do |data_row|
|
|
30
|
+
prev_data_points = data_points
|
|
31
|
+
data_points = Array.new
|
|
32
|
+
|
|
33
|
+
@d = @d.fill data_row[DATA_COLOR_INDEX]
|
|
34
|
+
|
|
35
|
+
data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
|
|
36
|
+
# Use incremented x and scaled y
|
|
37
|
+
new_x = @graph_left + (@x_increment * index)
|
|
38
|
+
new_y = @graph_top + (@graph_height - data_point * @graph_height - height[index])
|
|
39
|
+
|
|
40
|
+
height[index] += (data_point * @graph_height)
|
|
41
|
+
|
|
42
|
+
data_points << new_x
|
|
43
|
+
data_points << new_y
|
|
44
|
+
|
|
45
|
+
draw_label(new_x, index)
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if prev_data_points
|
|
50
|
+
poly_points = data_points.dup
|
|
51
|
+
(prev_data_points.length/2 - 1).downto(0) do |i|
|
|
52
|
+
poly_points << prev_data_points[2*i]
|
|
53
|
+
poly_points << prev_data_points[2*i+1]
|
|
54
|
+
end
|
|
55
|
+
poly_points << data_points[0]
|
|
56
|
+
poly_points << data_points[1]
|
|
57
|
+
else
|
|
58
|
+
poly_points = data_points.dup
|
|
59
|
+
poly_points << @graph_right
|
|
60
|
+
poly_points << @graph_bottom - 1
|
|
61
|
+
poly_points << @graph_left
|
|
62
|
+
poly_points << @graph_bottom - 1
|
|
63
|
+
poly_points << data_points[0]
|
|
64
|
+
poly_points << data_points[1]
|
|
65
|
+
end
|
|
66
|
+
@d = @d.polyline(*poly_points)
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
@d.draw(@base_image)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end; end
|