rchart 1.2.2 → 2.0.1
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/Rakefile +3 -3
- data/VERSION +1 -1
- data/lib/bar_chart.rb +166 -0
- data/lib/color_palette.rb +56 -0
- data/lib/cubic_chart.rb +271 -0
- data/lib/gd2_helper.rb +161 -0
- data/lib/graph.rb +24 -0
- data/lib/graph_helper.rb +414 -0
- data/lib/layout.rb +247 -0
- data/lib/legend.rb +243 -0
- data/lib/line_chart.rb +164 -0
- data/lib/pie_chart.rb +479 -0
- data/lib/plot_chart.rb +192 -0
- data/lib/rchart.rb +13 -3189
- data/lib/rchart_helper.rb +265 -0
- data/lib/rdata.rb +15 -14
- data/lib/scale.rb +538 -0
- metadata +49 -16
data/lib/line_chart.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
module LineChart
|
2
|
+
# This function will draw a line graph using all the registered series.
|
3
|
+
def draw_line_graph(data,data_description,serie_name="")
|
4
|
+
data_description = self.validate_data_description("draw_line_graph",data_description)
|
5
|
+
self.validate_data("draw_line_graph",data)
|
6
|
+
graph_id = 0
|
7
|
+
color_id =0
|
8
|
+
id =0
|
9
|
+
data_description["values"].each do |col_name|
|
10
|
+
data_description["description"].each do |key_i,value_i|
|
11
|
+
if ( key_i == col_name )
|
12
|
+
color_id = id
|
13
|
+
id = id+1
|
14
|
+
end
|
15
|
+
end
|
16
|
+
if ( serie_name == "" || serie_name == col_name )
|
17
|
+
x_pos = @g_area_x1 + @g_area_x_offset
|
18
|
+
x_last = -1
|
19
|
+
y_last = -1
|
20
|
+
data.each do |key|
|
21
|
+
if(!key[col_name].nil?)
|
22
|
+
value = key[col_name]
|
23
|
+
if(value.is_a?(Numeric))
|
24
|
+
y_pos= @g_area_y2 - ((value-@vmin) * @division_ratio)
|
25
|
+
else
|
26
|
+
y_pos= @g_area_y2 - ((0-@vmin) * @division_ratio)
|
27
|
+
end
|
28
|
+
# /* Save point into the image map if option activated */
|
29
|
+
if ( @build_map )
|
30
|
+
#self.add_to_image_map(x_pos-3,y_pos-3,x_pos+3,y_pos+3,data_description["description"][col_name],data[key][col_name].data_description["unit"]["y"],"Line")
|
31
|
+
end
|
32
|
+
x_last = -1 if(!value.is_a?(Numeric))
|
33
|
+
if ( x_last != -1 )
|
34
|
+
self.draw_line(x_last,y_last,x_pos,y_pos,@palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"],true)
|
35
|
+
end
|
36
|
+
x_last = x_pos
|
37
|
+
y_last = y_pos
|
38
|
+
x_last = -1 if(!value.is_a?(Numeric))
|
39
|
+
end
|
40
|
+
x_pos = x_pos + @division_width
|
41
|
+
end
|
42
|
+
graph_id+=1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
# This function will draw a filled line graph using all the registered series.
|
47
|
+
# You can provide the alpha value used when merging all series layers.
|
48
|
+
# If around_zero is set to true, the area drawn will be between the 0 axis and the line graph value.
|
49
|
+
|
50
|
+
def draw_filled_line_graph(data,data_description,alpha=100,around_zero=false)
|
51
|
+
empty = -2147483647
|
52
|
+
data_description = self.validate_data_description("draw_filled_line_graph",data_description)
|
53
|
+
self.validate_data("draw_filled_line_graph",data)
|
54
|
+
layer_width = @g_area_x2-@g_area_x1
|
55
|
+
layer_height = @g_area_y2-@g_area_y1
|
56
|
+
graph_id = 0
|
57
|
+
id =0
|
58
|
+
color_id =0
|
59
|
+
data_description["values"].each do |col_name|
|
60
|
+
data_description["description"].each do |key_i,value_i|
|
61
|
+
if ( key_i == col_name )
|
62
|
+
color_id = id
|
63
|
+
id = id+1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
a_points = []
|
68
|
+
a_points << @g_area_x_offset
|
69
|
+
a_points << layer_height
|
70
|
+
@layers[0] = image_create_true_color(layer_width,layer_height)
|
71
|
+
c_white = allocate_color(@layers[0],255,255,255)
|
72
|
+
image_filled_rectangle(@layers[0],0,0,layer_width,layer_height,255,255,255)
|
73
|
+
image_color_transparent(@layers[0],255,255,255)
|
74
|
+
|
75
|
+
xpos = @g_area_x_offset
|
76
|
+
xlast = -1
|
77
|
+
points_count = 2
|
78
|
+
y_zero = layer_height - ((0-@vmin) * @division_ratio)
|
79
|
+
y_zero = layer_height if ( y_zero > layer_height )
|
80
|
+
ylast = empty
|
81
|
+
|
82
|
+
data.each do |key|
|
83
|
+
value = key[col_name]
|
84
|
+
if key[col_name].is_a?(Numeric)
|
85
|
+
ypos = layer_height - ((value-@vmin) * @division_ratio)
|
86
|
+
else
|
87
|
+
ypos = layer_height - ((0-@vmin) * @division_ratio)
|
88
|
+
end
|
89
|
+
# Save point into the image map if option activated */
|
90
|
+
if ( @build_map )
|
91
|
+
#self.add_to_image_map(xpos-3,ypos-3,xpos+3,ypos+3,data_description["description"][col_name],key[col_name].data_description["unit"]["Y"],"FLine")
|
92
|
+
end
|
93
|
+
if ( !(value.is_a?(Numeric)))
|
94
|
+
points_count+=1
|
95
|
+
a_points << xlast
|
96
|
+
a_points << layer_height
|
97
|
+
ylast = empty
|
98
|
+
else
|
99
|
+
points_count+=1
|
100
|
+
if ( ylast != empty )
|
101
|
+
a_points << xpos
|
102
|
+
a_points << ypos
|
103
|
+
else
|
104
|
+
points_count+=1
|
105
|
+
a_points << xpos
|
106
|
+
a_points << layer_height
|
107
|
+
a_points << xpos
|
108
|
+
a_points << ypos
|
109
|
+
end
|
110
|
+
|
111
|
+
if (ylast !=empty && around_zero)
|
112
|
+
points = []
|
113
|
+
points << xlast
|
114
|
+
points << ylast
|
115
|
+
points << xpos
|
116
|
+
points << ypos
|
117
|
+
points << xpos
|
118
|
+
points << y_zero
|
119
|
+
points << xlast
|
120
|
+
points << y_zero
|
121
|
+
c_graph = allocate_color(@layers[0],@palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"])
|
122
|
+
image_filled_polygon(@layers[0],points,@palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"],4)
|
123
|
+
end
|
124
|
+
ylast = ypos
|
125
|
+
end
|
126
|
+
xlast = xpos
|
127
|
+
xpos = xpos + @division_width
|
128
|
+
end
|
129
|
+
|
130
|
+
a_points << layer_width - @g_area_x_offset
|
131
|
+
a_points << layer_height
|
132
|
+
|
133
|
+
if ( around_zero == false )
|
134
|
+
c_graph = allocate_color(@layers[0],@palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"])
|
135
|
+
image_filled_polygon(@layers[0],a_points,@palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"],points_count)
|
136
|
+
end
|
137
|
+
|
138
|
+
image_copy_merge(@layers[0],@picture,@g_area_x1,@g_area_y1,0,0,layer_width,layer_height,alpha)
|
139
|
+
image_destroy(@layers[0])
|
140
|
+
graph_id+=1
|
141
|
+
draw_line_graph(data,data_description,col_name)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
# This function will draw a scatter line graph.
|
145
|
+
# You must specify the x and y series that will be used.
|
146
|
+
# You can optionaly set the color index in the current palette.
|
147
|
+
def draw_xy_graph(data,data_description,y_serie_name,x_serie_name,palette_id=0)
|
148
|
+
y_last = -1
|
149
|
+
x_last = -1
|
150
|
+
data.each do |key|
|
151
|
+
if ( !key[y_serie_name].nil? && !key[x_serie_name].nil? )
|
152
|
+
x= key[x_serie_name]
|
153
|
+
y = key[y_serie_name]
|
154
|
+
y = @g_area_y2 - ((y-@vmin) * @division_ratio)
|
155
|
+
x= @g_area_x1 + ((x-@v_x_min) * @x_division_ratio)
|
156
|
+
if (x_last != -1 && y_last != -1)
|
157
|
+
draw_line(x_last,y_last,x,y,@palette[palette_id]["r"],@palette[palette_id]["g"],@palette[palette_id]["b"],true)
|
158
|
+
end
|
159
|
+
x_last = x
|
160
|
+
y_last = y
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
data/lib/pie_chart.rb
ADDED
@@ -0,0 +1,479 @@
|
|
1
|
+
module PieChart
|
2
|
+
# This function will draw a classical non-exploded pie chart.
|
3
|
+
# * To do so you must specify the data & data_description array.Only one serie of data is allowed for pie graph.
|
4
|
+
# * You can associate a description of each value in another serie by marking it using the set_abscise_label_serie function.
|
5
|
+
# * You must specify the center position of the chart. You can also optionally specify the radius of the pie and if the percentage should be printed.
|
6
|
+
# * r,g,b can be used to set the color of the line that will surround each pie slices.
|
7
|
+
# * You can specify the number of decimals you want to be displayed in the labels (default is 0 )
|
8
|
+
# By default no labels are written around the pie chart. You can use the following modes for the draw_labels parameter
|
9
|
+
# * Rchart:: PIE_NOLABEL No labels displayed
|
10
|
+
# * Rchart:: PIE_PERCENTAGE Percentages are displayed
|
11
|
+
# * Rchart:: PIE_LABELS Series labels displayed
|
12
|
+
# * Rchart:: PIE_PERCENTAGE_LABEL Series labels & percentage displayed
|
13
|
+
# This will draw a pie graph centered at (150-150) with a radius of 100, no labels
|
14
|
+
# * chart.draw_basic_pie_graph(chart_data.get_data,chart_data.get_data_description,150,150)
|
15
|
+
# This will draw a pie graph centered at (150-150) with a radius of 50 and percentages
|
16
|
+
# * chart.draw_basic_pie_graph(chart_data.get_data,chart_data.get_data_description,150,150,50,Rchart::PIE_PERCENTAGE)
|
17
|
+
# This will draw a pie graph centered at (150-150) with a radius of 100, captions and black borders
|
18
|
+
# * chart.draw_basic_pie_graph(chart_data.get_data,chart_data.get_data_description,150,150,100,Rchart::PIE_PERCENTAGE,0,0,0)
|
19
|
+
def draw_basic_pie_graph(data,data_description,x_pos,y_pos,radius=100,draw_labels=Rchart::PIE_NOLABEL,r=255,g=255,b=255,decimals=0)
|
20
|
+
data_description = validate_data_description("draw_basic_pie_graph",data_description,false)
|
21
|
+
validate_data("drawBasicPieGraph",data)
|
22
|
+
# Determine pie sum
|
23
|
+
series = 0
|
24
|
+
pie_sum = 0
|
25
|
+
i_values = []
|
26
|
+
r_values = []
|
27
|
+
i_labels = []
|
28
|
+
data_description["values"].each do|col_name|
|
29
|
+
if (col_name != data_description["position"])
|
30
|
+
series = series+1
|
31
|
+
data.each do |key|
|
32
|
+
if (!key[col_name].nil?)
|
33
|
+
pie_sum = pie_sum + key[col_name]
|
34
|
+
i_values << key[col_name]
|
35
|
+
i_labels << key[data_description["position"]]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# Validate serie
|
43
|
+
if ( series != 1 )
|
44
|
+
raise_fatal("Pie chart can only accept one serie of data.")
|
45
|
+
end
|
46
|
+
splice_ratio = 360.0 / pie_sum
|
47
|
+
splice_percent = 100.0 / pie_sum
|
48
|
+
|
49
|
+
#Calculate all polygons
|
50
|
+
angle = 0
|
51
|
+
top_plots = []
|
52
|
+
i_values.each_with_index do |value,key|
|
53
|
+
|
54
|
+
top_plots[key]= [x_pos]
|
55
|
+
top_plots[key]<< y_pos
|
56
|
+
# Process labels position & size
|
57
|
+
caption = ""
|
58
|
+
if ( !(draw_labels == Rchart::PIE_NOLABEL) )
|
59
|
+
t_angle = angle+(value*splice_ratio/2)
|
60
|
+
if (draw_labels == Rchart::PIE_PERCENTAGE)
|
61
|
+
caption = ((value * (10**decimals) * splice_percent)/(10**decimals)).round.to_s+"%"
|
62
|
+
elsif (draw_labels == Rchart::PIE_LABELS)
|
63
|
+
caption = i_labels[key]
|
64
|
+
elsif (draw_labels == Rchart::PIE_PERCENTAGE_LABEL)
|
65
|
+
caption = i_labels[key].to_s+"\r\n"+"."+((value * (10**decimals) * splice_percent)/(10**decimals)).round.to_s+"%"
|
66
|
+
elsif (draw_labels == Rchart::PIE_PERCENTAGE_LABEL)
|
67
|
+
caption = i_labels[key].to_s+"\r\n"+"."+((value * (10**decimals) * splice_percent)/(10**decimals)).round.to_s+"%"
|
68
|
+
end
|
69
|
+
position = image_ftb_box(@font_size,0,@font_name,caption)
|
70
|
+
text_width = position[2]-position[0]
|
71
|
+
text_height = (position[1].abs)+(position[3].abs)
|
72
|
+
|
73
|
+
tx = Math.cos((t_angle) * Math::PI / 180 ) * (radius+10) + x_pos
|
74
|
+
|
75
|
+
if ( t_angle > 0 && t_angle < 180 )
|
76
|
+
ty = Math.sin((t_angle) * Math::PI / 180 ) * (radius+10) + y_pos + 4
|
77
|
+
else
|
78
|
+
ty = Math.sin((t_angle) * Math::PI / 180 ) * (radius+4) + y_pos - (text_height/2)
|
79
|
+
end
|
80
|
+
tx = tx - text_width if ( t_angle > 90 && t_angle < 270 )
|
81
|
+
|
82
|
+
c_text_color = allocate_color(@picture,70,70,70)
|
83
|
+
image_ttf_text(@picture,@font_size,0,tx,ty,c_text_color,@font_name,caption)
|
84
|
+
end
|
85
|
+
# Process pie slices
|
86
|
+
i_angle = angle
|
87
|
+
while(i_angle <=angle+value*splice_ratio)
|
88
|
+
|
89
|
+
top_x = (Math.cos(i_angle * Math::PI / 180 )) * radius + x_pos
|
90
|
+
top_y = (Math.sin(i_angle * Math::PI/ 180 )) * radius + y_pos
|
91
|
+
top_plots[key] << (top_x)
|
92
|
+
top_plots[key] <<(top_y)
|
93
|
+
i_angle = i_angle+0.5
|
94
|
+
end
|
95
|
+
top_plots[key]<< x_pos
|
96
|
+
top_plots[key] << y_pos
|
97
|
+
angle = i_angle
|
98
|
+
end
|
99
|
+
poly_plots = top_plots
|
100
|
+
# Draw Top polygons
|
101
|
+
poly_plots.each_with_index do |value,key|
|
102
|
+
image_filled_polygon(@picture, poly_plots[key], @palette[key]["r"],@palette[key]["g"],@palette[key]["b"])
|
103
|
+
end
|
104
|
+
draw_circle(x_pos-0.5,y_pos-0.5,radius,r,g,b)
|
105
|
+
draw_circle(x_pos-0.5,y_pos-0.5,radius+0.5,r,g,b)
|
106
|
+
# Draw Top polygons
|
107
|
+
top_plots.each_with_index do |value,key|
|
108
|
+
j = 0
|
109
|
+
while(j<=top_plots[key].count-4 )
|
110
|
+
draw_line(top_plots[key][j],top_plots[key][j+1],top_plots[key][j+2],top_plots[key][j+3],r,g,b)
|
111
|
+
j =j+2
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# This function will draw a 3D pie graph.
|
117
|
+
# * To do so you must specify the data & data_description array.
|
118
|
+
# * Only one serie of data is allowed for pie graph.
|
119
|
+
# * You can associate a description of each value in another serie by marking it using the set_abscise_label_serie function. You must specify the center position of the chart.
|
120
|
+
# * You can also optionally specify the radius of the pie, if the percentage should be printed, the 3D skew factor and the height of all splices.
|
121
|
+
# * If enhance_colors is set to true, pie edges will be enhanced.
|
122
|
+
# * If splice_distance is greated than 0, the pie will be exploded.
|
123
|
+
# * You can specify the number of decimals you want to be displayed in the labels (default is 0 ).
|
124
|
+
# By default no labels are written around the pie chart. You can use the following modes for the draw_labels parameter:
|
125
|
+
# * Rchart:: PIE_NOLABEL No labels displayed
|
126
|
+
# * Rchart:: PIE_PERCENTAGE Percentages are displayed
|
127
|
+
# * Rchart:: PIE_LABELS Series labels displayed
|
128
|
+
# * Rchart:: PIE_PERCENTAGE_LABEL Series labels & percentage displayed
|
129
|
+
# This will draw a pie graph centered at (150-150) with a radius of 100, no labels
|
130
|
+
# * chart.draw_pie_graph(chart_data.get_data,chart_data.get_data_description,150,150)
|
131
|
+
# This will draw a pie graph centered at (150-150) with a radius of 50 and percentages
|
132
|
+
# * chart.draw_pie_graph(chart_data.get_data,chart_data.get_data_description,150,150,50,Rchart::PIE_PERCENTAGE)
|
133
|
+
# This will draw a pie graph centered at (150-150) with a radius of 100, captions and a skew factor of 30
|
134
|
+
# * chart.draw_pie_graph(chart_data.get_data,chart_data.get_data_description,150,150,100,Rchart::PIE_PERCENTAGE,true,30)
|
135
|
+
# This will draw a pie graph (..) exploded
|
136
|
+
# * chart.draw_pie_graph(chart_data.get_data,chart_data.get_data_description,150,150,100,Rchart::PIE_PERCENTAGE,true,30,10,10)
|
137
|
+
def draw_pie_graph(data,data_description,x_pos,y_pos,radius=100,draw_labels=Rchart::PIE_NOLABEL,enhance_colors=true,skew=60,splice_height=20,splice_distance=0,decimals=0)
|
138
|
+
data_description = validate_data_description("draw_pie_graph",data_description,false)
|
139
|
+
validate_data("draw_pie_graph",data)
|
140
|
+
|
141
|
+
#Determine pie sum
|
142
|
+
series = 0
|
143
|
+
pie_sum= 0
|
144
|
+
rpie_sum = 0
|
145
|
+
i_values = []
|
146
|
+
r_values = []
|
147
|
+
i_labels = []
|
148
|
+
series = 0
|
149
|
+
|
150
|
+
data_description["values"].each do|col_name|
|
151
|
+
if (col_name != data_description["position"])
|
152
|
+
series = series+1
|
153
|
+
data.each do |key|
|
154
|
+
if (!key[col_name].nil?)
|
155
|
+
if (key[col_name] == 0)
|
156
|
+
i_values << 0
|
157
|
+
r_values << 0
|
158
|
+
i_labels << 0
|
159
|
+
i_labels<< key[data_description["position"]]
|
160
|
+
else
|
161
|
+
pie_sum+= key[col_name]
|
162
|
+
i_values << key[col_name]
|
163
|
+
i_labels << key[data_description["position"]]
|
164
|
+
r_values << key[col_name]
|
165
|
+
rpie_sum += key[col_name]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# Validate serie
|
173
|
+
|
174
|
+
#RaiseFatal("Pie chart can only accept one serie of data.")
|
175
|
+
#puts "Error Pie chart can only accept one serie of data." if ( series != 1 )
|
176
|
+
splice_distance_ratio = splice_distance
|
177
|
+
skew_height = (radius * skew) / 100
|
178
|
+
splice_ratio = ((360 - splice_distance_ratio *i_values.count*1.0) / pie_sum)
|
179
|
+
splice_percent = 100.0 / pie_sum
|
180
|
+
r_splice_percent = 100.0 / rpie_sum
|
181
|
+
#Calculate all polygons
|
182
|
+
angle = 0
|
183
|
+
c_dev = 5
|
184
|
+
top_plots = []
|
185
|
+
bot_plots = []
|
186
|
+
atop_plots = []
|
187
|
+
abot_plots = []
|
188
|
+
i_values.each_with_index do |value,key|
|
189
|
+
x_cent_pos = Math.cos((angle-c_dev+(value*splice_ratio+splice_distance_ratio)/2) * 3.1418 / 180 ) * splice_distance + x_pos
|
190
|
+
y_cent_pos = Math.sin((angle-c_dev+(value*splice_ratio+splice_distance_ratio)/2) * 3.1418 / 180 ) * splice_distance + y_pos
|
191
|
+
x_cent_pos2 = Math.cos((angle+c_dev+(value*splice_ratio+splice_distance_ratio)/2) * 3.1418 / 180 ) * splice_distance + x_pos
|
192
|
+
y_cent_pos2 = Math.sin((angle+c_dev+(value*splice_ratio+splice_distance_ratio)/2) * 3.1418 / 180 ) * splice_distance + y_pos
|
193
|
+
top_plots[key] = [(x_cent_pos).round]
|
194
|
+
bot_plots[key] = [(x_cent_pos).round]
|
195
|
+
top_plots[key] << (y_cent_pos).round
|
196
|
+
bot_plots[key] << (y_cent_pos + splice_height).round
|
197
|
+
atop_plots[key] = [x_cent_pos]
|
198
|
+
abot_plots[key] = [x_cent_pos]
|
199
|
+
atop_plots[key] << y_cent_pos
|
200
|
+
abot_plots[key] << y_cent_pos + splice_height
|
201
|
+
# Process labels position & size
|
202
|
+
caption = ""
|
203
|
+
if ( !(draw_labels == Rchart::PIE_NOLABEL) )
|
204
|
+
|
205
|
+
t_angle = angle+(value*splice_ratio/2)
|
206
|
+
if (draw_labels == Rchart::PIE_PERCENTAGE)
|
207
|
+
caption = ((r_values[key] * (10**decimals) * r_splice_percent)/(10**decimals)).round.to_s+"%"
|
208
|
+
elsif (draw_labels == Rchart::PIE_LABELS)
|
209
|
+
caption = i_labels[key]
|
210
|
+
elsif (draw_labels == Rchart::PIE_PERCENTAGE_LABEL)
|
211
|
+
caption = i_labels[key].to_s+"\r\n"+(((value * 10**decimals) * splice_percent)/(10**decimals)).round.to_s+"%"
|
212
|
+
end
|
213
|
+
position = image_ftb_box(@font_size,0,@font_name,caption)
|
214
|
+
text_width =position[2]-position[0]
|
215
|
+
text_height = ( position[1]).abs+(position[3]).abs
|
216
|
+
|
217
|
+
tx = Math.cos((t_angle) * Math::PI / 180 ) * (radius + 10)+ x_pos
|
218
|
+
|
219
|
+
if ( t_angle > 0 && t_angle < 180 )
|
220
|
+
ty = Math.sin((t_angle) * Math::PI / 180 ) * (skew_height + 10) + y_pos + splice_height + 4
|
221
|
+
else
|
222
|
+
ty = Math.sin((t_angle) * Math::PI / 180 ) * (skew_height + 4) + y_pos - (text_height/2)
|
223
|
+
end
|
224
|
+
if ( t_angle > 90 && t_angle < 270 )
|
225
|
+
tx = tx - text_width
|
226
|
+
end
|
227
|
+
#c_text_color = $this->AllocateColor(@picture,70,70,70)
|
228
|
+
c_text_color = allocate_color(@picture,70,70,70)
|
229
|
+
image_ttf_text(@picture,@font_size,0,tx,ty,c_text_color,@font_name,caption)
|
230
|
+
end
|
231
|
+
|
232
|
+
# Process pie slices
|
233
|
+
|
234
|
+
i_angle = angle
|
235
|
+
i_angle = i_angle.to_f
|
236
|
+
|
237
|
+
while(i_angle <=angle+value*splice_ratio)
|
238
|
+
|
239
|
+
top_x = (Math.cos(i_angle * Math::PI / 180 )) * radius + x_pos
|
240
|
+
top_y = (Math.sin(i_angle * Math::PI/ 180 )) * skew_height + y_pos
|
241
|
+
|
242
|
+
top_plots[key] << (top_x).round
|
243
|
+
bot_plots[key] <<(top_x).round
|
244
|
+
top_plots[key] <<(top_y).round
|
245
|
+
bot_plots[key] << (top_y + splice_height).round
|
246
|
+
atop_plots[key] << top_x
|
247
|
+
abot_plots[key] << top_x
|
248
|
+
atop_plots[key] << top_y
|
249
|
+
abot_plots[key] << top_y + splice_height
|
250
|
+
i_angle=i_angle+0.5
|
251
|
+
end
|
252
|
+
top_plots[key] << (x_cent_pos2).round
|
253
|
+
bot_plots[key] << (x_cent_pos2).round
|
254
|
+
top_plots[key] << (y_cent_pos2).round
|
255
|
+
bot_plots[key] << (y_cent_pos2 + splice_height).round
|
256
|
+
atop_plots[key] << x_cent_pos2
|
257
|
+
abot_plots[key] << x_cent_pos2
|
258
|
+
atop_plots[key] << y_cent_pos2
|
259
|
+
abot_plots[key] << y_cent_pos2 + splice_height
|
260
|
+
angle = i_angle + splice_distance_ratio
|
261
|
+
end
|
262
|
+
|
263
|
+
# Draw Bottom polygons
|
264
|
+
i_values.each_with_index do |val,key|
|
265
|
+
c_graph_lo = allocate_color(@picture,@palette[key]["r"]-20,@palette[key]["g"]-20,@palette[key]["b"]-20)
|
266
|
+
image_filled_polygon(@picture,bot_plots[key],@palette[key]["r"]-20,@palette[key]["g"]-20,@palette[key]["b"]-20)
|
267
|
+
if (enhance_colors)
|
268
|
+
en = -10
|
269
|
+
else
|
270
|
+
en = 0
|
271
|
+
end
|
272
|
+
j =0
|
273
|
+
while(j<=(abot_plots[key].length)-4)
|
274
|
+
draw_line(abot_plots[key][j],abot_plots[key][j+1],abot_plots[key][j+2],abot_plots[key][j+3],@palette[key]["r"]+en,@palette[key]["g"]+en,@palette[key]["b"]+en)
|
275
|
+
j= j+2
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# Draw pie layers
|
280
|
+
if ( enhance_colors )
|
281
|
+
color_ratio = 30 / splice_height
|
282
|
+
else
|
283
|
+
color_ratio = 25 / splice_height
|
284
|
+
end
|
285
|
+
i = splice_height-1
|
286
|
+
while(i>=1)
|
287
|
+
i_values.each_with_index do |val,key|
|
288
|
+
c_graph_lo = allocate_color(@picture,@palette[key]["r"]-10,@palette[key]["g"]-10,@palette[key]["b"]-10)
|
289
|
+
plots =[]
|
290
|
+
plot = 0
|
291
|
+
top_plots[key].each_with_index do |value2,key2|
|
292
|
+
plot = plot+1
|
293
|
+
if ( plot % 2 == 1 )
|
294
|
+
plots << value2
|
295
|
+
else
|
296
|
+
plots << value2+i
|
297
|
+
end
|
298
|
+
end
|
299
|
+
image_filled_polygon(@picture,plots,@palette[key]["r"]-10,@palette[key]["g"]-10,@palette[key]["b"]-10)
|
300
|
+
index = (plots).count
|
301
|
+
if (enhance_colors )
|
302
|
+
color_factor = -20 + (splice_height - $i) * color_ratio
|
303
|
+
else
|
304
|
+
color_factor = 0
|
305
|
+
end
|
306
|
+
|
307
|
+
draw_antialias_pixel(plots[0],plots[1],@palette[key]["r"]+color_factor,@palette[key]["g"]+color_factor,@palette[key]["b"]+color_factor)
|
308
|
+
draw_antialias_pixel(plots[2],plots[3],@palette[key]["r"]+color_factor,@palette[key]["g"]+color_factor,@palette[key]["b"]+color_factor)
|
309
|
+
draw_antialias_pixel(plots[index-4],plots[index-3],@palette[key]["r"]+color_factor,@palette[key]["g"]+color_factor,@palette[key]["b"]+color_factor)
|
310
|
+
end
|
311
|
+
i = i-1
|
312
|
+
end
|
313
|
+
#Draw Top polygons
|
314
|
+
key = i_values.length-1
|
315
|
+
while(key>=0)
|
316
|
+
c_graph_lo = allocate_color(@picture,@palette[key]["r"],@palette[key]["g"],@palette[key]["b"])
|
317
|
+
image_filled_polygon(@picture,top_plots[key],@palette[key]["r"],@palette[key]["g"],@palette[key]["b"])
|
318
|
+
|
319
|
+
if ( enhance_colors )
|
320
|
+
en = 10
|
321
|
+
else
|
322
|
+
en = 0
|
323
|
+
end
|
324
|
+
j = 0
|
325
|
+
|
326
|
+
while(j<=(atop_plots[key]).length-4)
|
327
|
+
draw_line(atop_plots[key][j],atop_plots[key][j+1],atop_plots[key][j+2],atop_plots[key][j+3],@palette[key]["r"]+en,@palette[key]["g"]+en,@palette[key]["b"]+en)
|
328
|
+
j = j+2
|
329
|
+
end
|
330
|
+
key = key -1
|
331
|
+
end
|
332
|
+
end
|
333
|
+
# This function is an alias of the draw_flat_pie_graph function.
|
334
|
+
def draw_flat_pie_graph_with_shadow(data,data_description,x_pos,y_pos,radius=100,draw_labels=Rchart::PIE_NOLABEL,splice_distance=0,decimals=0)
|
335
|
+
draw_flat_pie_graph(data,data_description,x_pos+@shadow_x_distance,y_pos+@shadow_y_distance,radius,Rchart::PIE_NOLABEL,splice_distance,decimals,true)
|
336
|
+
draw_flat_pie_graph(data,data_description,x_pos,y_pos,radius,draw_labels,splice_distance,decimals,false)
|
337
|
+
end
|
338
|
+
|
339
|
+
# This function will draw a flat 2D pie graph.
|
340
|
+
# To do so you must specify the data & data_description array.
|
341
|
+
# * Only one serie of data is allowed for pie graph.
|
342
|
+
# * You can associate a description of each value in another serie by marking it using the set_abscise_label_serie function. You must specify the center position of the chart.
|
343
|
+
# * You can also optionally specify the radius of the pie and if the percentage should be printed.
|
344
|
+
# * If splice_distance is greated than 0, the pie will be exploded.
|
345
|
+
# * You can specify the number of decimals you want to be displayed in the labels (default is 0 )
|
346
|
+
# By default no labels are written around the pie chart. You can use the following modes for the draw_labels parameter:
|
347
|
+
# * Rchart:: PIE_NOLABEL No labels displayed
|
348
|
+
# * Rchart:: PIE_PERCENTAGE Percentages are displayed
|
349
|
+
# * Rchart:: PIE_LABELS Series labels displayed
|
350
|
+
# * Rchart:: PIE_PERCENTAGE_LABEL Series labels & percentage displayed
|
351
|
+
# This will draw a pie graph centered at (150-150) with a radius of 100, no labels
|
352
|
+
# * chart.draw_flat_pie_graph(chart_data.get_data,chart_data.get_data_description,150,150)
|
353
|
+
# This will draw a pie graph centered at (150-150) with a radius of 50 and percentages
|
354
|
+
# * chart.draw_flat_pie_graph(chart_data.get_data,chart_data.get_data_description,150,150,50,Rchart::PIE_PERCENTAGE)
|
355
|
+
# This will draw a pie graph centered at (150-150) with a radius of 100, captions and slightly exploded
|
356
|
+
# * chart.draw_flat_pie_graph(chart_data.get_data,chart_data.get_data_description,150,150,100,Rchart::PIE_PERCENTAGE,4)
|
357
|
+
|
358
|
+
def draw_flat_pie_graph(data,data_description,x_pos,y_pos,radius=100,draw_labels=Rchart::PIE_NOLABEL,splice_distance=0,decimals=0,all_black=false)
|
359
|
+
data_description = validate_data_description("draw_flat_pie_graph",data_description,false)
|
360
|
+
validate_data("draw_flat_pie_graph",data)
|
361
|
+
shadow_status = @shadow_active
|
362
|
+
@shadow_active = false
|
363
|
+
# Determine pie sum
|
364
|
+
series = 0
|
365
|
+
pie_sum = 0
|
366
|
+
i_values = []
|
367
|
+
r_values = []
|
368
|
+
i_labels = []
|
369
|
+
data_description["values"].each do|col_name|
|
370
|
+
if (col_name != data_description["position"])
|
371
|
+
series = series+1
|
372
|
+
data.each do |key|
|
373
|
+
if (!key[col_name].nil?)
|
374
|
+
pie_sum = pie_sum + key[col_name]
|
375
|
+
i_values << key[col_name]
|
376
|
+
i_labels << key[data_description["position"]]
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
#Validate serie
|
383
|
+
if ( series != 1 )
|
384
|
+
raise_fatal("Pie chart can only accept one serie of data.")
|
385
|
+
return -1
|
386
|
+
end
|
387
|
+
|
388
|
+
splice_ratio = 360.0 / pie_sum
|
389
|
+
splice_percent = 100.0 / pie_sum
|
390
|
+
# Calculate all polygons
|
391
|
+
angle = 0
|
392
|
+
top_plots = []
|
393
|
+
i_values.each_with_index do |value,key|
|
394
|
+
x_offset = Math.cos((angle+(value*1.0/2*splice_ratio)) * Math::PI / 180 ) * splice_distance
|
395
|
+
y_offset = Math.sin((angle+(value*1.0/2*splice_ratio)) * Math::PI / 180 ) * splice_distance
|
396
|
+
|
397
|
+
top_plots[key] = [(x_pos + x_offset).round]
|
398
|
+
top_plots[key] << (y_pos + y_offset).round
|
399
|
+
if ( all_black )
|
400
|
+
rc = @shadow_r_color
|
401
|
+
gc = @shadow_g_color
|
402
|
+
bc = @shadow_b_color
|
403
|
+
else
|
404
|
+
rc = @palette[key]["r"]
|
405
|
+
gc = @palette[key]["g"]
|
406
|
+
bc = @palette[key]["b"]
|
407
|
+
end
|
408
|
+
x_line_last = ""
|
409
|
+
y_line_last = ""
|
410
|
+
# Process labels position & size
|
411
|
+
caption = ""
|
412
|
+
if ( !(draw_labels == Rchart::PIE_NOLABEL) )
|
413
|
+
t_angle = angle+(value*splice_ratio/2)
|
414
|
+
if (draw_labels == Rchart::PIE_PERCENTAGE)
|
415
|
+
caption = ((value * (10**decimals) * splice_percent)/(10**decimals)).round.to_s+"%"
|
416
|
+
elsif (draw_labels == Rchart::PIE_LABELS)
|
417
|
+
caption = i_labels[key]
|
418
|
+
elsif (draw_labels == Rchart::PIE_PERCENTAGE_LABEL)
|
419
|
+
caption = i_labels[key].to_s+".\r\n"+((value * (10**decimals) * splice_percent)/(10**decimals)).round.to_s+"%"
|
420
|
+
elsif (draw_labels == Rchart::PIE_PERCENTAGE_LABEL)
|
421
|
+
caption = i_labels[key].to_s+".\r\n"+((value * (10**decimals) * splice_percent)/(10**decimals)).round.to_s+"%"
|
422
|
+
end
|
423
|
+
position = image_ftb_box(@font_size,0,@font_name,caption)
|
424
|
+
text_width = position[2]-position[0]
|
425
|
+
text_height = (position[1].abs)+(position[3].abs)
|
426
|
+
|
427
|
+
tx = Math.cos((t_angle) * Math::PI / 180 ) * (radius+10+splice_distance) + x_pos
|
428
|
+
if ( t_angle > 0 && t_angle < 180 )
|
429
|
+
ty = Math.sin((t_angle) * Math::PI / 180 ) * (radius+10+splice_distance) + y_pos + 4
|
430
|
+
else
|
431
|
+
ty = Math.sin((t_angle) * Math::PI / 180 ) * (radius+splice_distance+4) + y_pos - (text_height*1.0/2)
|
432
|
+
end
|
433
|
+
tx = tx - text_width if ( t_angle > 90 && t_angle < 270 )
|
434
|
+
c_text_color = allocate_color(@picture,70,70,70)
|
435
|
+
image_ttf_text(@picture,@font_size,0,tx,ty,c_text_color,@font_name,caption)
|
436
|
+
end
|
437
|
+
|
438
|
+
# Process pie slices
|
439
|
+
if ( !all_black )
|
440
|
+
line_color =allocate_color(@picture,rc,gc,bc)
|
441
|
+
else
|
442
|
+
line_color = allocate_color(@picture,rc,gc,bc)
|
443
|
+
end
|
444
|
+
x_line_last = ""
|
445
|
+
y_line_last = ""
|
446
|
+
i_angle=angle
|
447
|
+
while(i_angle<=angle+value*splice_ratio)
|
448
|
+
pos_x = Math.cos(i_angle * Math::PI / 180 ) * radius + x_pos + x_offset
|
449
|
+
pos_y = Math.sin(i_angle * Math::PI / 180 ) * radius + y_pos + y_offset
|
450
|
+
top_plots[key]<< (pos_x).round
|
451
|
+
top_plots[key] << (pos_y).round
|
452
|
+
if ( i_angle == angle || i_angle == angle+value*splice_ratio || i_angle+0.5 > angle+value*splice_ratio)
|
453
|
+
draw_line(x_pos+x_offset,y_pos+y_offset,pos_x,pos_y,rc,gc,bc)
|
454
|
+
end
|
455
|
+
if ( x_line_last != "" )
|
456
|
+
draw_line(x_line_last,y_line_last,pos_x,pos_y,rc,gc,bc)
|
457
|
+
end
|
458
|
+
x_line_last = pos_x
|
459
|
+
y_line_last = pos_y
|
460
|
+
i_angle=i_angle+0.5
|
461
|
+
end
|
462
|
+
|
463
|
+
top_plots[key] << (x_pos + x_offset).round
|
464
|
+
top_plots[key]<< (y_pos + y_offset).round
|
465
|
+
angle = i_angle
|
466
|
+
end
|
467
|
+
poly_plots = top_plots
|
468
|
+
# Draw Top polygons
|
469
|
+
poly_plots.each_with_index do |value,key|
|
470
|
+
if ( !all_black )
|
471
|
+
image_filled_polygon(@picture,poly_plots[key],@palette[key]["r"],@palette[key]["g"],@palette[key]["b"])
|
472
|
+
else
|
473
|
+
image_filled_polygon(@picture,poly_plots[key],@shadow_r_color,@shadow_g_color,@shadow_b_color)
|
474
|
+
end
|
475
|
+
end
|
476
|
+
@shadow_active = shadow_status
|
477
|
+
|
478
|
+
end
|
479
|
+
end
|