technical_graph 0.3.2 → 0.4.0

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.
@@ -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