rchart 1.2.2 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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