technical_graph 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,10 +21,18 @@ class GraphAxis
21
21
  @technical_graph.data_processor
22
22
  end
23
23
 
24
- def image_drawer
24
+ def image
25
25
  @technical_graph.image_drawer
26
26
  end
27
27
 
28
+ def drawer
29
+ image.drawer
30
+ end
31
+
32
+ def logger
33
+ @technical_graph.logger
34
+ end
35
+
28
36
  def truncate_string
29
37
  options[:truncate_string]
30
38
  end
@@ -62,6 +70,8 @@ class GraphAxis
62
70
 
63
71
  # Calculate axis using 2 methods
64
72
  def calc_axis(from, to, interval, count, fixed_interval)
73
+ t = Time.now
74
+
65
75
  axis = Array.new
66
76
  l = to - from
67
77
  current = from
@@ -71,12 +81,16 @@ class GraphAxis
71
81
  axis << current
72
82
  current += interval
73
83
  end
84
+ logger.debug "fixed interval axis calculation from #{from} to #{to} using int. #{interval}"
85
+ logger.debug " TIME COST #{Time.now - t}"
74
86
  return axis
75
87
 
76
88
  else
77
89
  (0...count).each do |i|
78
90
  axis << from + (l.to_f * i.to_f) / count.to_f
79
91
  end
92
+ logger.debug "fixed count axis calculation from #{from} to #{to} using count #{count}"
93
+ logger.debug " TIME COST #{Time.now - t}"
80
94
  return axis
81
95
 
82
96
  end
@@ -85,8 +99,12 @@ class GraphAxis
85
99
  # Enlarge image to maintain proper axis density
86
100
  def axis_distance_image_enlarge
87
101
  if options[:axis_density_enlarge_image]
102
+ t = Time.now
88
103
  x_axis_distance_image_enlarge
89
104
  y_axis_distance_image_enlarge
105
+
106
+ logger.debug "axis enlarged"
107
+ logger.debug " TIME COST #{Time.now - t}"
90
108
  end
91
109
  end
92
110
 
@@ -97,9 +115,9 @@ class GraphAxis
97
115
  return if a.size < 2
98
116
 
99
117
  ax = a[0]
100
- ax = image_drawer.calc_bitmap_y(ax).round
118
+ ax = image.calc_bitmap_y(ax).round
101
119
  bx = a[1]
102
- bx = image_drawer.calc_bitmap_y(bx).round
120
+ bx = image.calc_bitmap_y(bx).round
103
121
 
104
122
  axis_distance = (bx - ax).abs
105
123
 
@@ -117,9 +135,9 @@ class GraphAxis
117
135
  return if a.size < 2
118
136
 
119
137
  ay = a[0]
120
- ay = image_drawer.calc_bitmap_y(ay).round
138
+ ay = image.calc_bitmap_y(ay).round
121
139
  by = a[1]
122
- by = image_drawer.calc_bitmap_y(by).round
140
+ by = image.calc_bitmap_y(by).round
123
141
 
124
142
  axis_distance = (by - ay).abs
125
143
 
@@ -134,228 +152,62 @@ class GraphAxis
134
152
  def render_on_image(image)
135
153
  @image = image
136
154
 
137
- render_values_axis
138
- render_parameters_axis
139
-
140
- render_values_zero_axis
141
- render_parameters_zero_axis
142
-
155
+ render_axis
156
+ render_zero_axis
143
157
  render_axis_labels
144
158
  end
145
159
 
146
- def axis_antialias
147
- options[:axis_antialias] == true
148
- end
149
-
150
-
151
- def render_values_axis
152
- plot_axis_y_line = Magick::Draw.new
153
- plot_axis_y_text = Magick::Draw.new
154
-
155
- plot_axis_y_line.stroke_antialias(axis_antialias)
156
- plot_axis_y_text.text_antialias(image_drawer.font_antialias)
157
-
158
- plot_axis_y_line.fill_opacity(0)
159
- plot_axis_y_line.stroke(options[:axis_color])
160
- plot_axis_y_line.stroke_opacity(1.0)
161
- plot_axis_y_line.stroke_width(1.0)
162
- plot_axis_y_line.stroke_linecap('square')
163
- plot_axis_y_line.stroke_linejoin('miter')
164
-
165
- plot_axis_y_text.pointsize(options[:axis_font_size])
166
- plot_axis_y_text.font_family('helvetica')
167
- plot_axis_y_text.font_style(Magick::NormalStyle)
168
- plot_axis_y_text.text_align(Magick::LeftAlign)
169
- plot_axis_y_text.text_undercolor(options[:background_color])
170
-
171
- value_axis.each do |y|
172
- by = image_drawer.calc_bitmap_y(y)
173
- plot_axis_y_line.line(
174
- 0, by.round,
175
- @image.columns-1, by.round
176
- )
177
-
178
- string_label = "#{truncate_string % y}"
179
-
180
- plot_axis_y_text.text(
181
- 5,
182
- by.round + 15,
183
- string_label
184
- )
185
- end
186
-
187
- t = Time.now
188
- plot_axis_y_line.draw(@image)
189
- puts "Y axis time #{Time.now - t}, drawing lines"
190
- t = Time.now
191
- plot_axis_y_text.draw(@image)
192
- puts "Y axis time #{Time.now - t}, drawing text"
193
- end
194
-
195
- def render_parameters_axis
196
-
197
- plot_axis_x_line = Magick::Draw.new
198
- plot_axis_x_text = Magick::Draw.new
199
-
200
- plot_axis_x_line.stroke_antialias(axis_antialias)
201
- plot_axis_x_text.text_antialias(axis_antialias)
202
-
203
- plot_axis_x_line.fill_opacity(0)
204
- plot_axis_x_line.stroke(options[:axis_color])
205
- plot_axis_x_line.stroke_opacity(1.0)
206
- plot_axis_x_line.stroke_width(1.0)
207
- plot_axis_x_line.stroke_linecap('square')
208
- plot_axis_x_line.stroke_linejoin('miter')
209
-
210
- plot_axis_x_text.pointsize(options[:axis_font_size])
211
- plot_axis_x_text.font_family('helvetica')
212
- plot_axis_x_text.font_style(Magick::NormalStyle)
213
- plot_axis_x_text.text_align(Magick::LeftAlign)
214
- plot_axis_x_text.text_undercolor(options[:background_color])
215
-
216
- parameter_axis.each do |x|
217
- bx = image_drawer.calc_bitmap_x(x)
218
- plot_axis_x_line.line(
219
- bx.round, 0,
220
- bx.round, @image.rows-1
221
- )
222
-
223
- string_label = "#{truncate_string % x}"
224
-
225
- plot_axis_x_text.text(
226
- bx.round + 5,
227
- @image.rows - 15,
228
- string_label
229
- )
230
- end
231
-
232
- t = Time.now
233
- plot_axis_x_line.draw(@image)
234
- puts "X axis time #{Time.now - t}, drawing lines"
235
- t = Time.now
236
- plot_axis_x_text.draw(@image)
237
- puts "X axis time #{Time.now - t}, drawing lines"
238
-
239
- end
240
-
241
- # TODO: make it DRY
242
- def render_values_zero_axis
243
- plot_axis_y_line = Magick::Draw.new
244
- plot_axis_y_text = Magick::Draw.new
245
-
246
- plot_axis_y_line.stroke_antialias(axis_antialias)
247
- plot_axis_y_text.text_antialias(image_drawer.font_antialias)
248
-
249
- plot_axis_y_line.fill_opacity(0)
250
- plot_axis_y_line.stroke(options[:axis_color])
251
- plot_axis_y_line.stroke_opacity(1.0)
252
- plot_axis_y_line.stroke_width(2.0)
253
- plot_axis_y_line.stroke_linecap('square')
254
- plot_axis_y_line.stroke_linejoin('miter')
255
-
256
- plot_axis_y_text.pointsize(options[:axis_font_size])
257
- plot_axis_y_text.font_family('helvetica')
258
- plot_axis_y_text.font_style(Magick::NormalStyle)
259
- plot_axis_y_text.text_align(Magick::LeftAlign)
260
- plot_axis_y_text.text_undercolor(options[:background_color])
261
-
262
- y = 0.0
263
- by = image_drawer.calc_bitmap_y(y)
264
- plot_axis_y_line.line(
265
- 0, by.round,
266
- @image.columns-1, by.round
267
- )
268
-
269
- plot_axis_y_text.text(
270
- 5,
271
- by.round + 15,
272
- "#{y}"
160
+ def antialias
161
+ options[:antialias] == true
162
+ end
163
+
164
+ # Render normal axis
165
+ def render_axis
166
+ drawer.axis(
167
+ # X
168
+ parameter_axis.collect { |x| image.calc_bitmap_x(x).to_i },
169
+ # Y
170
+ value_axis.collect { |y| image.calc_bitmap_y(y).to_i },
171
+ # options
172
+ { :color => options[:axis_color], :width => 1 },
173
+ # draw labels
174
+ options[:axis_value_and_param_labels],
175
+ # X axis labels
176
+ parameter_axis,
177
+ # Y axis labels
178
+ value_axis
273
179
  )
274
-
275
- # TODO: why normal axis does not need it?
276
- plot_axis_y_line.draw(@image)
277
- plot_axis_y_text.draw(@image)
278
180
  end
279
181
 
280
- def render_parameters_zero_axis
281
-
282
- plot_axis_x_line = Magick::Draw.new
283
- plot_axis_x_text = Magick::Draw.new
284
-
285
- plot_axis_x_line.stroke_antialias(axis_antialias)
286
- plot_axis_x_text.text_antialias(image_drawer.font_antialias)
287
-
288
- plot_axis_x_line.fill_opacity(0)
289
- plot_axis_x_line.stroke(options[:axis_color])
290
- plot_axis_x_line.stroke_opacity(1.0)
291
- plot_axis_x_line.stroke_width(2.0)
292
- plot_axis_x_line.stroke_linecap('square')
293
- plot_axis_x_line.stroke_linejoin('miter')
294
-
295
- plot_axis_x_text.pointsize(options[:axis_font_size])
296
- plot_axis_x_text.font_family('helvetica')
297
- plot_axis_x_text.font_style(Magick::NormalStyle)
298
- plot_axis_x_text.text_align(Magick::LeftAlign)
299
- plot_axis_x_text.text_undercolor(options[:background_color])
300
-
301
- x = 0.0
302
- bx = image_drawer.calc_bitmap_x(x)
303
- plot_axis_x_line.line(
304
- bx.round, 0,
305
- bx.round, @image.rows-1
182
+ # Render axis for zeros
183
+ def render_zero_axis
184
+ drawer.axis(
185
+ # X - 0
186
+ image.calc_bitmap_x(0.0).to_i,
187
+ # Y - 0
188
+ image.calc_bitmap_y(0.0).to_i,
189
+ # options, slightly wider
190
+ { :color => options[:axis_color], :width => 2 },
191
+ # draw label
192
+ options[:axis_zero_labels],
193
+ # X label,
194
+ [0.0],
195
+ # Y label
196
+ [0.0]
306
197
  )
307
-
308
- plot_axis_x_text.text(
309
- bx.round + 15,
310
- @image.rows - 15,
311
- "#{x}"
312
- )
313
-
314
- # TODO: why normal axis does not need it?
315
- plot_axis_x_line.draw(@image)
316
- plot_axis_x_text.draw(@image)
317
198
  end
318
199
 
319
- def render_axis_labels
320
- if options[:x_axis_label].to_s.size > 0
321
- plot_axis_text = Magick::Draw.new
322
- plot_axis_text.text_antialias(image_drawer.font_antialias)
323
-
324
- plot_axis_text.pointsize(options[:axis_label_font_size])
325
- plot_axis_text.font_family('helvetica')
326
- plot_axis_text.font_style(Magick::NormalStyle)
327
- #plot_axis_text.text_align(Magick::LeftAlign)
328
- plot_axis_text.text_align(Magick::CenterAlign)
329
- plot_axis_text.text_undercolor(options[:background_color])
330
-
331
- plot_axis_text.text(
332
- (@image.columns / 2).to_i,
333
- @image.rows - 40,
334
- options[:x_axis_label].to_s
335
- )
336
- plot_axis_text.draw(@image)
337
- end
338
200
 
339
- if options[:y_axis_label].to_s.size > 0
340
- plot_axis_text = Magick::Draw.new
341
- plot_axis_text.text_antialias(image_drawer.font_antialias)
342
-
343
- plot_axis_text.pointsize(options[:axis_label_font_size])
344
- plot_axis_text.font_family('helvetica')
345
- plot_axis_text.font_style(Magick::NormalStyle)
346
- #plot_axis_text.text_align(Magick::LeftAlign)
347
- plot_axis_text.text_align(Magick::CenterAlign)
348
- plot_axis_text.text_undercolor(options[:background_color])
349
-
350
- plot_axis_text = plot_axis_text.rotate(90)
351
- plot_axis_text.text(
352
- (@image.rows / 2).to_i,
353
- -40,
354
- options[:y_axis_label].to_s
355
- )
356
-
357
- plot_axis_text.draw(@image)
358
- end
201
+ def render_axis_labels
202
+ drawer.axis_labels(
203
+ options[:x_axis_label].to_s,
204
+ options[:y_axis_label].to_s,
205
+ {
206
+ :color => options[:axis_color],
207
+ :width => 1,
208
+ :size => options[:axis_label_font_size],
209
+ }
210
+ )
359
211
  end
360
212
 
361
213
  end
@@ -6,7 +6,8 @@ require 'singleton'
6
6
 
7
7
  class GraphColorLibrary
8
8
  include Singleton
9
-
9
+
10
+ # rock solid colors
10
11
  # http://www.imagemagick.org/script/color.php
11
12
  BASIC_COLORS = [
12
13
  'blue',
@@ -15,37 +16,52 @@ class GraphColorLibrary
15
16
  'purple'
16
17
  ]
17
18
 
19
+ # other random picked up, SVG need #RGB and I'm too lazy :]
18
20
  ADDITIONAL_COLORS = [
19
- 'tomato',
20
- 'sienna1',
21
- 'chocolate2',
22
- 'DarkGoldenrod4',
23
- 'OliveDrab4',
24
- 'ForestGreen',
25
- 'turquoise',
26
- 'DarkCyan',
27
- 'CadetBlue4',
28
- 'DeepSkyBlue4',
29
- 'DodgerBlue2',
30
- 'CornflowerBlue',
31
- 'MidnightBlue',
32
- 'MediumPurple3',
33
- 'magenta4',
34
- 'orchid4',
35
- 'DeepPink3',
36
- 'PaleVioletRed4',
37
- 'firebrick3'
21
+ '#8B3626', #'tomato',
22
+ '#FF8247', #'sienna1',
23
+ #'chocolate2',
24
+ #'DarkGoldenrod4',
25
+ #'OliveDrab4',
26
+ #'ForestGreen',
27
+ #'turquoise',
28
+ #'DarkCyan',
29
+ #'CadetBlue4',
30
+ #'DeepSkyBlue4',
31
+ #'DodgerBlue2',
32
+ #'CornflowerBlue',
33
+ #'MidnightBlue',
34
+ #'MediumPurple3',
35
+ #'magenta4',
36
+ #'orchid4',
37
+ #'DeepPink3',
38
+ #'PaleVioletRed4',
39
+ #'firebrick3'
38
40
  ]
39
41
 
40
42
  FAIL_COLOR = 'black'
41
43
 
42
44
  def initialize
43
- @colors = BASIC_COLORS + ADDITIONAL_COLORS.sort {rand}
45
+ @colors = BASIC_COLORS + ADDITIONAL_COLORS.sort { rand }
46
+ end
47
+
48
+ # not too bright
49
+ MAX_INTENSITY = 0xbb
50
+
51
+ # Best solution, create random color JIT
52
+ def random_color
53
+ str = "#"
54
+ 3.times do
55
+ str += colour = "%02x" % (rand * MAX_INTENSITY)
56
+ end
57
+ return str
44
58
  end
45
59
 
46
60
  def get_color
47
61
  color = @colors.shift
48
- return FAIL_COLOR if color.nil?
62
+ #return FAIL_COLOR if color.nil?
63
+ # better, create random colors just in time
64
+ return random_color if color.nil?
49
65
  return color
50
66
  end
51
67
 
@@ -17,6 +17,10 @@ class GraphDataProcessor
17
17
  @technical_graph.layers
18
18
  end
19
19
 
20
+ def logger
21
+ @technical_graph.logger
22
+ end
23
+
20
24
  def initialize(technical_graph)
21
25
  @technical_graph = technical_graph
22
26
 
@@ -121,7 +125,7 @@ class GraphDataProcessor
121
125
  # ranges are set, can't change
122
126
  return if fixed?
123
127
 
124
- # updating ranges
128
+ # updating ranges, enlarging
125
129
  self.raw_y_max = data_layer.y_max if not data_layer.y_max.nil? and data_layer.y_max > self.raw_y_max
126
130
  self.raw_x_max = data_layer.x_max if not data_layer.x_max.nil? and data_layer.x_max > self.raw_x_max
127
131
 
@@ -149,6 +153,8 @@ class GraphDataProcessor
149
153
 
150
154
  # Calculate zoomed X position for Array of X'es
151
155
  def calc_x_zoomed(old_xes)
156
+ t = Time.now
157
+
152
158
  # default zoom
153
159
  if self.zoom_x == 1.0
154
160
  return old_xes
@@ -162,11 +168,15 @@ class GraphDataProcessor
162
168
  new_xes << (a + d * self.zoom_x)
163
169
  end
164
170
 
171
+ logger.debug "calc_x_zoomed for #{old_xes.size}"
172
+ logger.debug " TIME COST #{Time.now - t}"
165
173
  return new_xes
166
174
  end
167
175
 
168
176
  # Calculate zoomed Y position for Array of Y'es
169
177
  def calc_y_zoomed(old_yes)
178
+ t = Time.now
179
+
170
180
  # default zoom
171
181
  if self.zoom_y == 1.0
172
182
  return old_yes
@@ -180,6 +190,8 @@ class GraphDataProcessor
180
190
  new_yes << (a + d * self.zoom_y)
181
191
  end
182
192
 
193
+ logger.debug "calc_y_zoomed for #{old_yes.size}"
194
+ logger.debug " TIME COST #{Time.now - t}"
183
195
  return new_yes
184
196
  end
185
197