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 CHANGED
@@ -11,9 +11,9 @@ begin
11
11
  gem.homepage = "http://github.com/amardaxini/rchart"
12
12
  gem.authors = ["amardaxini"]
13
13
  gem.rubyforge_project = "rchart"
14
- # gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
15
- gem.add_development_dependency "ruby-gd",">=0.8.0"
16
- gem.files = [Dir['fonts/*'],Dir['examples/*'],".document", ".gitignore","LICENSE","README.rdoc","Rakefile","VERSION", "lib/rchart.rb","lib/rdata.rb","lib/version.rb","test/helper.rb","test/test_rchart.rb"]
14
+ # gem.add_development_dependency "ruby-gd",">=0.8.0"
15
+ gem.add_development_dependency "rgd2-ffij"
16
+ gem.files = [Dir['fonts/*'],Dir['examples/*'],Dir['lib/*.rb'],".document", ".gitignore","LICENSE","README.rdoc","Rakefile","VERSION", "test/helper.rb","test/test_rchart.rb"]
17
17
  gem.requirements << "libgd-ruby, libpng-dev, libgd-dev package are required"
18
18
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
19
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.2
1
+ 2.0.1
@@ -0,0 +1,166 @@
1
+ module BarChart
2
+ # This function will draw a bar graph using all the registered series.
3
+ # When creating a bar graph, don't forget to set the with_margin parameter of the draw_scale function to true.
4
+ # Setting shadow to true will draw a shadow behind each series, this will also slow down a bit the renderer engine.
5
+
6
+ def draw_bar_graph(data,data_description,shadow=false,alpha=100)
7
+ data_description = self.validate_data_description("drawBarGraph",data_description)
8
+ validate_data("drawBarGraph",data)
9
+
10
+ # graph_id = 0
11
+ series = (data_description["values"]).count
12
+ series_width = @division_width / (series+1)
13
+ serie_x_offset = @division_width / 2 - series_width / 2
14
+
15
+ y_zero = @g_area_y2 - ((0-@vmin) * @division_ratio)
16
+ y_zero = @g_area_y2 if ( y_zero> @g_area_y2 )
17
+ serie_id = 0
18
+ color_id =0
19
+ id = 0
20
+ data_description["values"].each do |col_name|
21
+ data_description["description"].each do |key_i,value_i|
22
+ if ( key_i == col_name )
23
+ color_id = id
24
+ id = id+1
25
+ end
26
+ end
27
+ x_pos = @g_area_x1 + @g_area_x_offset - serie_x_offset + series_width * serie_id
28
+ # x_last = -1
29
+ data.each do |key|
30
+ if ( !key[col_name].nil?)
31
+ if ( key[col_name].is_a?(Numeric) )
32
+ value = key[col_name]
33
+ y_pos = @g_area_y2 - ((value-@vmin) * @division_ratio)
34
+ # Save point into the image map if option activated */
35
+ if (@build_map )
36
+ #add_to_image_map(x_pos+1,[y_zero,y_pos].min,x_pos+series_width-1,[y_zero,y_pos].max,data_description["description"][col_name],data[key][col_name].data_description["unit"]["y"],"Bar")
37
+ end
38
+ if ( shadow && alpha == 100 )
39
+ draw_rectangle(x_pos+1,y_zero,x_pos+series_width-1,y_pos,25,25,25)
40
+ end
41
+ draw_filled_rectangle(x_pos+1,y_zero,x_pos+series_width-1,y_pos,@palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"],true,alpha)
42
+ end
43
+ x_pos = x_pos + @division_width
44
+ end
45
+ end
46
+ serie_id = serie_id+1
47
+ end
48
+ end
49
+
50
+ # This function will draw a stacked bar graph using all the registered series.
51
+ # When creating a bar graph, don't forget to set the with_margin parameter of the draw_scale function to true.
52
+ # Don't forget to change the automatic scaling to Rchart::SCALE_ADDALL to have an accurate scaling mode.
53
+ # You can specify the transparency and if the bars must be contiguous or with space (default)
54
+ def draw_stacked_bar_graph(data,data_description,alpha=50,contiguous=false)
55
+ # /* Validate the Data and data_description array */
56
+ data_description = validate_data_description("draw_bar_graph",data_description)
57
+ validate_data("draw_bar_graph",data)
58
+ graph_id = 0
59
+ series = (data_description["values"].count)
60
+ if ( contiguous )
61
+ series_width = @division_width
62
+ else
63
+ series_width = @division_width * 0.8
64
+ end
65
+ y_zero = @g_area_y2 - ((0-@vmin) * @division_ratio)
66
+ y_zero = @g_area_y2 if ( y_zero > @g_area_y2 )
67
+ series_id = 0
68
+ last_value = {}
69
+ id = 0
70
+ color_id = 0
71
+ data_description["values"].each do |col_name|
72
+ data_description["description"].each do |key_i,value_i|
73
+ if ( key_i == col_name )
74
+ color_id = id
75
+ id = id+1
76
+ end
77
+ end
78
+ x_pos = @g_area_x1 + @g_area_x_offset - series_width / 2
79
+ x_last = -1
80
+ data.each do |key|
81
+ if ( !key[col_name].nil?)
82
+ if ( key[col_name].is_a?(Numeric) )
83
+ value = key[col_name]
84
+ if (!last_value[key].nil?)
85
+ y_pos = @g_area_y2 - (((value+last_value[key])-@vmin) * @division_ratio)
86
+ y_bottom = @g_area_y2 - ((last_value[key]-@vmin) * @division_ratio)
87
+ last_value[key] += value
88
+ else
89
+ y_pos = @g_area_y2 - ((value-@vmin) * @division_ratio)
90
+ y_bottom = y_zero
91
+ last_value[key] = value
92
+ end
93
+ # Save point into the image map if option activated
94
+ if ( @build_map )
95
+ #add_to_image_map(x_pos+1,[y_bottom,y_pos].min,x_pos+series_width-1,[y_bottom,y_pos].max,data_description["description"][col_name],data[key][col_name].data_description["unit"]["y"],"sBar")
96
+ end
97
+ draw_filled_rectangle(x_pos+1,y_bottom,x_pos+series_width-1,y_pos,@palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"],true,alpha)
98
+ end
99
+ end
100
+ x_pos = x_pos + @division_width
101
+ end
102
+ series_id+=1
103
+ end
104
+ end
105
+ # This function will draw a superposed bar graph using all the registered series.
106
+ # You can provide the alpha value used when merging all series layers.
107
+
108
+ def draw_overlay_bar_graph(data,data_description,alpha=50)
109
+ data_description = validate_data_description("draw_overlay_bar_graph",data_description)
110
+ validate_data("draw_overlay_bar_graph",data)
111
+ layer_width = @g_area_x2-@g_area_x1
112
+ layer_height = @g_area_y2-@g_area_y1
113
+ graph_id = 0
114
+ color_id =0
115
+ id =0
116
+ data_description["values"].each do |col_name|
117
+ data_description["description"].each do |key_i,value_i|
118
+ if ( key_i == col_name )
119
+ color_id = id
120
+ id = id+1
121
+ end
122
+ end
123
+ @layers[graph_id] = image_create_true_color(layer_width,layer_height)
124
+ image_filled_rectangle(@layers[graph_id],0,0,layer_width,layer_height,255,255,255)
125
+ image_color_transparent(@layers[graph_id],255,255,255)
126
+ x_width = @division_width / 4
127
+ x_pos = @g_area_x_offset
128
+ y_zero = layer_height - ((0-@vmin) * @division_ratio)
129
+ x_last = -1
130
+ points_count = 2
131
+ data.each do |key|
132
+ if(!key[col_name].nil?)
133
+ if(key[col_name].is_a?(Numeric))
134
+ value = key[col_name]
135
+ if (value.is_a?(Numeric) )
136
+ y_pos = layer_height - ((value-@vmin) * @division_ratio)
137
+ image_filled_rectangle(@layers[graph_id],x_pos-x_width,y_pos,x_pos+x_width,y_zero,@palette[graph_id]["r"],@palette[graph_id]["g"],@palette[graph_id]["b"])
138
+ x1 = (x_pos - x_width + @g_area_x1).floor
139
+ y1 = (y_pos+@g_area_y1).floor + 0.2
140
+ x2 = (x_pos + x_width + @g_area_x1).floor
141
+ y2 = @g_area_y2 - ((0-@vmin) * @division_ratio)
142
+ x1 = @g_area_x1 + 1 if ( x1 <= @g_area_x1 )
143
+ x2 = @g_area_x2 - 1 if ( x2 >= @g_area_x2 )
144
+
145
+ # Save point into the image map if option activated */
146
+ if ( @build_map )
147
+ #add_to_image_map(x1,[y1,y2].min,x2,[y1,y2].max,data_description["description"][col_name],data[key][col_name].data_description["unit"]["y"],"oBar")
148
+ end
149
+ draw_line(x1,y1,x2,y1,@palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"],true)
150
+ end
151
+ end
152
+ end
153
+ x_pos = x_pos + @division_width
154
+ end
155
+ graph_id+=1
156
+ end
157
+ i=0
158
+ while (i<=(graph_id-1))
159
+ image_copy_merge(@layers[i],@picture,@g_area_x1,@g_area_y1,0,0,layer_width,layer_height,alpha)
160
+ image_destroy(@layers[i])
161
+ # image_destroy(@layers[i])
162
+ i=i+1
163
+ end
164
+ end
165
+
166
+ end
@@ -0,0 +1,56 @@
1
+ module ColorPalette
2
+ # This function can be used to change the color of one series.
3
+ # series id are starting at 0 for associated data serie #1.
4
+ # You must provide an rgb color.
5
+ def set_color_palette(id,r,g,b)
6
+ b,g,r=validate_color(b, g, r)
7
+ @palette[id]["r"] = r
8
+ @palette[id]["g"] = g
9
+ @palette[id]["b"] = b
10
+ end
11
+
12
+ # Create a color palette shading from one color to another
13
+ # This function will fill the color palette with 10 shades between the two RGB colors 0,0,0 and 100,100,100.This will produce grey shades. (Palette id 0-9 will be filled)
14
+ def create_color_gradient_palette(r1,g1,b1,r2,g2,b2,shades)
15
+ r_factor = (r2-r1)/shades
16
+ g_factor = (g2-g1)/shades
17
+ b_factor = (b2-b1)/shades
18
+ i= 0
19
+ while(i<= shades-1)
20
+ @palette[i]["r"] = r1+r_factor*i
21
+ @palette[i]["g"] = g1+g_factor*i
22
+ @palette[i]["b"] = b1+b_factor*i
23
+ i = i+1
24
+ end
25
+ end
26
+ # This function will load the color scheme from a text file.
27
+ # This file must be formatted with three values per line ( r,g,b ).
28
+ # By default the delimiter is a coma but you can specify it.
29
+ def load_color_palette_from_file(file_name)
30
+ color_id = 0
31
+ File.open(file_name,"r") do |infile|
32
+ while (line = infile.gets)
33
+ values = line.split(",")
34
+ if ( values.length == 3 )
35
+ @palette[color_id]["r"] = values[0].to_i
36
+ @palette[color_id]["g"] = values[1].to_i
37
+ @palette[color_id]["b"] = values[2].to_i
38
+ color_id+=1
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ # Load palette from array [[r,g,b],[r1,g1,b1]]
45
+ def load_color_palette(color_palette)
46
+ color_id = 0
47
+ color_palette.each do |palette|
48
+ if palette.length == 3
49
+ @palette[color_id]["r"] = palette[0].to_i
50
+ @palette[color_id]["g"] = palette[1].to_i
51
+ @palette[color_id]["b"] = palette[2].to_i
52
+ color_id+=1
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,271 @@
1
+ module CubicChart
2
+ # This function will draw a curved line graph using all the registered series.
3
+ # This curve is using a cubic algorithm to process the average values between two points.
4
+ # You have to specify the accuracy between two points, typically a 0.1 value is acceptable. the smaller the value is, the longer it will take to process the graph.
5
+ def draw_cubic_curve(data,data_description,accuracy=0.1,serie_name="")
6
+
7
+ data_description = self.validate_data_description("draw_cubic_curve",data_description)
8
+ self.validate_data("draw_cubic_curve",data)
9
+ graph_id = 0
10
+ id = 0
11
+ color_id =0
12
+
13
+ data_description["values"].each do |col_name|
14
+ if ( serie_name == "" || serie_name == col_name )
15
+ x_in = []
16
+ y_in =[]
17
+ y_t = []
18
+ u = []
19
+ x_in[0] = 0
20
+ y_in[0] = 0
21
+
22
+ data_description["description"].each do |key_i,value_i|
23
+ if ( key_i == col_name )
24
+ color_id = id
25
+ id = id+1
26
+ end
27
+ end
28
+ index = 1
29
+ x_last = -1
30
+ missing = []
31
+ data.each do |key|
32
+ if(!key[col_name].nil?)
33
+ val = key[col_name]
34
+
35
+ x_in[index] = index
36
+ #y_in[index] = val
37
+ #my hack TODO "" convet missing values to zero
38
+ y_in[index] = val if ((val).is_a?(Numeric))
39
+ y_in[index] = 0 if (!(val).is_a?(Numeric))
40
+ ######
41
+ missing[index]=true if (!(val).is_a?(Numeric))
42
+ index=index+1
43
+ end
44
+ end
45
+ index= index-1
46
+ y_t[0] = 0
47
+ y_t[1] = 0
48
+ u[0] = 0
49
+ u[1] = 0
50
+ i =2
51
+ y_last =0
52
+
53
+ while(i<=index-1)
54
+ sig = (x_in[i]-x_in[i-1])*1.0/(x_in[i+1]-x_in[i-1]) #rescue 0
55
+ p=sig*y_t[i-1]+2
56
+ y_t[i]=(sig-1)/p
57
+ u[i]=(y_in[i+1]-y_in[i])*1.0/(x_in[i+1]-x_in[i])-(y_in[i]-y_in[i-1])*1.0/(x_in[i]-x_in[i-1]) #rescue 0
58
+ u[i]=(6*u[i]/(x_in[i+1]-x_in[i-1])-sig*u[i-1])/p #rescue 0
59
+ i=i+1
60
+ end
61
+ qn = 0
62
+ un = 0
63
+ y_t[index] = (un - qn * u[index-1]) / (qn * y_t[index-1] + 1)
64
+ k = index-1
65
+ while k>=1
66
+ y_t[k]=y_t[k]* y_t[k+1]+u[k]
67
+ k=k-1
68
+ end
69
+ x_pos = @g_area_x1 + @g_area_x_offset
70
+ x =1
71
+ while x<=index
72
+ klo=1
73
+ khi=index
74
+ k = khi-klo
75
+ while k>1
76
+ k=khi-klo
77
+ if x_in[k]>=x
78
+ khi=k
79
+ else
80
+ klo=k
81
+ end
82
+ end
83
+ klo=khi-1
84
+ h = x_in[khi]-x_in[klo]
85
+ a = (x_in[khi]-x)/h rescue 1
86
+ b = (x-x_in[klo])/h rescue 1
87
+ value = a*y_in[klo]+b*y_in[khi]+((a*a*a-a)*y_t[klo]+(b*b*b-b)*y_t[khi])*(h*h)/6
88
+ y_pos = @g_area_y2-((value-@vmin)*@division_ratio)
89
+ #TODO Check(x_last!=-1 && !missing[x.floor].nil? && !missing[(x+1).floor].nil? )
90
+ #UPDATED
91
+ if (x_last!=-1 && missing[x.floor].nil? && missing[(x+1).floor].nil? )
92
+ self.draw_line(x_last,y_last,x_pos,y_pos, @palette[id]["r"],@palette[id]["g"],@palette[id]["b"],true)
93
+ end
94
+ x_last = x_pos
95
+ y_last = y_pos
96
+ x_pos = x_pos +@division_width*accuracy
97
+ x=x+accuracy
98
+ end
99
+ #Add potentialy missing values
100
+ x_pos = x_pos - @division_width * accuracy
101
+ if ( x_pos < (@g_area_x2 - @g_area_x_offset) )
102
+ y_pos = @g_area_y2 - ((y_in[index]-@vmin) * @division_ratio)
103
+ self.draw_line(x_last,y_last,@g_area_x2-@g_area_x_offset,y_pos,@palette[id]["r"],@palette[id]["g"],@palette[id]["b"],true)
104
+ end
105
+ graph_id += 1
106
+ end
107
+ end
108
+ end
109
+ # This function will draw a filled curved line graph using all the registered series.
110
+ # This curve is using a cubic algorythm to process the average values between two points.
111
+ # You have to specify the accuracy between two points, typicaly a 0.1 value is acceptable. the smaller the value is, the longer it will take to process the graph.
112
+ # You can provide the alpha value used when merging all series layers.
113
+ # If around_zero is set to true, the area drawn will be between the 0 axis and the line graph value.
114
+
115
+ def draw_filled_cubic_curve(data,data_description,accuracy=0.1,alpha=100,around_zero=false)
116
+ data_description = self.validate_data_description("draw_filled_cubic_curve",data_description)
117
+ self.validate_data("draw_filled_cubic_curve",data)
118
+ layer_width = @g_area_x2-@g_area_x1
119
+ layer_height = @g_area_y2-@g_area_y1
120
+ y_zero = layer_height - ((0-@vmin) * @division_ratio)
121
+ y_zero = layer_height if ( y_zero > layer_height )
122
+ graph_id = 0
123
+ id = 0
124
+ color_id =0
125
+ data_description["values"].each do |col_name|
126
+ x_in = []
127
+ y_in =[]
128
+ y_t = []
129
+ u = []
130
+ x_in[0] = 0
131
+ y_in[0] = 0
132
+ data_description["description"].each do |key_i,value_i|
133
+ if ( key_i == col_name )
134
+ color_id = id
135
+ id = id+1
136
+ end
137
+ end
138
+ index = 1
139
+ x_last = -1
140
+ missing = []
141
+ data.each do |key|
142
+ if(!key[col_name].nil?)
143
+ val = key[col_name]
144
+ x_in[index] = index
145
+ y_in[index] = val
146
+ missing[index]=true if ((val).is_a?(Numeric))
147
+ index=index+1
148
+ end
149
+ end
150
+ index= index-1
151
+ y_t[0] = 0
152
+ y_t[1] = 0
153
+ u[1] = 0
154
+ i =2
155
+ y_last =0
156
+
157
+ while(i<index)
158
+ sig = (x_in[i]-x_in[i-1])*1.0/(x_in[i+1]-x_in[i-1]) #rescue 0
159
+ p=sig*y_t[i-1]+2
160
+ y_t[i]=(sig-1)/p
161
+ u[i]=(y_in[i+1]-y_in[i])*1.0/(x_in[i+1]-x_in[i])-(y_in[i]-y_in[i-1])*1.0/(x_in[i]-x_in[i-1]) #rescue 0
162
+ u[i]=(6*u[i]/(x_in[i+1]-x_in[i-1])-sig*u[i-1])/p #rescue 0
163
+ i=i+1
164
+ end
165
+ qn = 0
166
+ un = 0
167
+ y_t[index] = (un - qn * u[index-1]) / (qn * y_t[index-1] + 1)
168
+ k = index-1
169
+ while k>=1
170
+ y_t[k]=y_t[k]* y_t[k+1]+u[k]
171
+ k=k-1
172
+ end
173
+ points = []
174
+ points << @g_area_x_offset
175
+ points << layer_height
176
+ @layers[0] = image_create_true_color(layer_width,layer_height)
177
+ image_filled_rectangle(@layers[0],0,0,layer_width,layer_height, 255,255,255)
178
+ image_color_transparent(@layers[0], 255,255,255)
179
+ y_last = nil
180
+ x_pos = @g_area_x_offset
181
+ points_count= 2
182
+ x=1
183
+ while(x<=index)
184
+ klo=1
185
+ khi=index
186
+ k = khi-klo
187
+ while k>1
188
+ k=khi-klo
189
+ if x_in[k]>=x
190
+ khi=k
191
+ else
192
+ klo=k
193
+ end
194
+ end
195
+ klo=khi-1
196
+ h = x_in[khi]-x_in[klo]
197
+ a = (x_in[khi]-x)/h rescue 1
198
+ b = (x-x_in[klo])/h rescue 1
199
+ value = a*y_in[klo]+b*y_in[khi]+((a*a*a-a)*y_t[klo]+(b*b*b-b)*y_t[khi])*(h*h)/6
200
+ y_pos = layer_height - ((value-@vmin) * @division_ratio)
201
+
202
+ a_points = []
203
+ if ( !y_last.nil? && around_zero && (missing[x.floor].nil?) && (missing[(x+1).floor].nil?))
204
+
205
+ a_points << x_last
206
+ a_points << y_last
207
+ a_points << x_pos
208
+ a_points << y_pos
209
+ a_points << x_pos
210
+ a_points << y_zero
211
+ a_points << x_last
212
+ a_points << y_zero
213
+ #check No of points here 4 is pass check in image filled_polygon
214
+ image_filled_polygon(@layers[0], a_points, @palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"],4)
215
+ end
216
+ if ( missing[(x.floor)].nil? || y_last.nil?)
217
+ points_count = points_count+1
218
+ points << x_pos
219
+ points << y_pos
220
+ else
221
+ points_count = points_count+1
222
+ points << x_last
223
+ points << y_last
224
+ end
225
+ y_last = y_pos
226
+ x_last = x_pos
227
+ x_pos = x_pos + @division_width * accuracy
228
+ x=x+accuracy
229
+ end
230
+
231
+ #// Add potentialy missing values
232
+ # a_points = []
233
+ x_pos = x_pos - @division_width * accuracy
234
+ if ( x_pos < (layer_width-@g_area_x_offset) )
235
+ y_pos = layer_height - ((y_in[index]-@vmin) * @division_ratio)
236
+ if ( !y_last.nil? && around_zero )
237
+ a_points << x_last
238
+ a_points << y_last
239
+ a_points << (layer_width-@g_area_x_offset)
240
+ a_points << y_pos
241
+ a_points << (layer_width-@g_area_x_offset)
242
+ a_points << y_zero
243
+ a_points << x_last
244
+ a_points << y_zero
245
+ # imagefilledpolygon(@layers[0],a_points,4,$C_Graph)
246
+ image_filled_polygon(@layers[0], a_points, @palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"],4)
247
+ end
248
+
249
+ if ( y_in[klo] != "" && y_in[khi] != "" || y_last.nil? )
250
+
251
+ points_count +=1
252
+ points << (layer_width-@g_area_x_offset).floor
253
+ points << (y_pos).floor
254
+ end
255
+ end
256
+
257
+ points << (layer_width-@g_area_x_offset).floor
258
+ points << layer_height.floor
259
+
260
+ if ( !around_zero )
261
+ image_filled_polygon(@layers[0], points, @palette[color_id]["r"],@palette[color_id]["g"],@palette[color_id]["b"],points_count)
262
+ end
263
+
264
+ image_copy_merge(@layers[0],@picture,@g_area_x1,@g_area_y1,0,0,layer_width,layer_height,alpha)
265
+ image_destroy(@layers[0])
266
+
267
+ draw_cubic_curve(data, data_description,accuracy,col_name)
268
+ graph_id+=1
269
+ end
270
+ end
271
+ end