technical_graph 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -137,6 +137,10 @@ Layer options Hash
137
137
  * layer_options[:label] - label used in legend
138
138
  * layer_options[:color] - color of graph layer, ex.: 'red', 'green', '#FFFF00'
139
139
  * layer_options[:antialias] - use anti-aliasing for this, default false, override options[:layers_antialias]
140
+ * layer_options[:value_labels] - write values near 'dots', default true
141
+ * layer_options[:simple_smoother] - 'smooth' data, default false
142
+ * layer_options[:simple_smoother_level] - strength of smoothing, this is level of window used for processing, default 3
143
+ * layer_options[:simple_smoother_strategy] - strategy used for smoothing data, you can choose between :rectangular or :gauss, default :rectangular
140
144
 
141
145
 
142
146
  Contributing to technical-graph
data/Rakefile CHANGED
@@ -33,8 +33,8 @@ Jeweler::RubygemsDotOrgTasks.new
33
33
 
34
34
  desc "Remove all images created during tests"
35
35
  task :clean do
36
- `rm *.svg`
37
- `rm *.png`
36
+ `rm samples/tests/*.svg`
37
+ `rm samples/tests/*.png`
38
38
  end
39
39
 
40
40
  desc "Clean and release"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -49,6 +49,9 @@ class TechnicalGraph
49
49
  @axis.render_on_image(@image)
50
50
  # draw layers
51
51
  @layers.each do |l|
52
+ # external processing
53
+ l.process
54
+ # drawing
52
55
  @image_drawer.render_data_layer(l)
53
56
  end
54
57
  # draw legend
@@ -1,6 +1,7 @@
1
1
  #encoding: utf-8
2
2
 
3
3
  require 'technical_graph/graph_color_library'
4
+ require 'technical_graph/data_layer_processor'
4
5
 
5
6
  # Stores only data used for one layer
6
7
  # Instances of this class are used elsewhere
@@ -13,12 +14,27 @@ class DataLayer
13
14
 
14
15
  @data_params[:color] ||= GraphColorLibrary.instance.get_color
15
16
  @data_params[:label] ||= ''
17
+ # default true, write values near dots
18
+ @data_params[:value_labels] = false if options[:value_labels] == false
19
+
20
+ # smoothing parameters
21
+ # by default it is false
22
+ @data_params[:simple_smoother] = true if options[:simple_smoother] == true
23
+ @data_params[:simple_smoother_level] ||= 3
24
+ @data_params[:simple_smoother_strategy] ||= DataLayerProcessor::DEFAULT_STRATEGY
25
+ # was already done
26
+ @data_params[:processor_finished] = false
27
+
28
+ @processor = DataLayerProcessor.new(self)
16
29
 
17
30
  # set data and append initial data
18
31
  clear_data
19
32
  append_data(d)
20
33
  end
21
34
 
35
+ # can be used to approximation and other data processing
36
+ attr_reader :processor
37
+
22
38
  # Accessor for setting chart data for layer to draw
23
39
  def append_data(d)
24
40
  if d.kind_of? Array
@@ -33,6 +49,18 @@ class DataLayer
33
49
  # Array of {:x =>, :y =>}
34
50
  attr_reader :data
35
51
 
52
+ # Run external processor (smoothing, ...)
53
+ def process
54
+ if simple_smoother and not processor_finished?
55
+ @processor.strategy = simple_smoother_strategy
56
+ @processor.level = simple_smoother_level
57
+ @processor.generate_vector
58
+ @data = @processor.process
59
+
60
+ processor_finished!
61
+ end
62
+ end
63
+
36
64
  # Additional parameters
37
65
  attr_reader :data_params
38
66
 
@@ -49,6 +77,36 @@ class DataLayer
49
77
  return @data_params[:label]
50
78
  end
51
79
 
80
+ # Write values near dots
81
+ def value_labels
82
+ return @data_params[:value_labels]
83
+ end
84
+
85
+ # Turn on smoothing processor
86
+ def simple_smoother
87
+ return @data_params[:simple_smoother]
88
+ end
89
+
90
+ # Smoother level
91
+ def simple_smoother_level
92
+ return @data_params[:simple_smoother_level]
93
+ end
94
+
95
+ # Smoother strategy
96
+ def simple_smoother_strategy
97
+ return @data_params[:simple_smoother_strategy]
98
+ end
99
+
100
+ # Was already processed?
101
+ def processor_finished?
102
+ @data_params[:processor_finished]
103
+ end
104
+
105
+ # Mark as processed
106
+ def processor_finished!
107
+ @data_params[:processor_finished] = true
108
+ end
109
+
52
110
  # Clear data
53
111
  def clear_data
54
112
  @data = Array.new
@@ -0,0 +1,212 @@
1
+ #encoding: utf-8
2
+
3
+ # Approximate data layer
4
+
5
+ class DataLayerProcessor
6
+ STRATEGIES = {
7
+ :rectangular => 'generate_vector_rectangular',
8
+ :gauss => 'generate_vector_gauss'
9
+ }
10
+ DEFAULT_STRATEGY = :rectangular
11
+
12
+ MIN_LEVEL = 1
13
+ MAX_LEVEL = 200
14
+
15
+ # use 'x' axis for processing also
16
+ PROCESS_WITH_PARAMETER_DISTANCE = false
17
+
18
+ # default Gauss coefficient
19
+ DEFAULT_GAUSS_COEFF = 0.2
20
+
21
+ def initialize(data_layer)
22
+ @data_layer = data_layer
23
+ @strategy = DEFAULT_STRATEGY
24
+ @level = MIN_LEVEL
25
+ @vector = Array.new
26
+ @gauss_coeff = DEFAULT_GAUSS_COEFF
27
+ end
28
+
29
+ attr_reader :vector
30
+ attr_accessor :gauss_coeff
31
+
32
+ # Level of approximation
33
+ def level=(l)
34
+ @level = l.to_i if l.to_i >= MIN_LEVEL and l.to_i < MAX_LEVEL
35
+ end
36
+
37
+ attr_reader :level
38
+
39
+ # Choose other strategy from STRATEGIES
40
+ def strategy=(s)
41
+ method = STRATEGIES[s]
42
+ @strategy = s unless method.nil?
43
+ end
44
+
45
+ attr_reader :strategy
46
+
47
+
48
+ # This vector will be used to process values (Y'es)
49
+ # Use proper strategy
50
+ def generate_vector
51
+ method = STRATEGIES[@strategy]
52
+ if method.nil?
53
+ method = STRATEGIES[DEFAULT_STRATEGY]
54
+ end
55
+ return self.send(method)
56
+ end
57
+
58
+ # Process values
59
+ def process
60
+ t = Time.now
61
+ old_data = @data_layer.data
62
+ new_data = Array.new
63
+
64
+ (0...old_data.size).each do |i|
65
+ new_data << {
66
+ :x => old_data[i][:x],
67
+ :y => process_part(old_data, i)
68
+ }
69
+ end
70
+
71
+ puts "Smoothing completed, level #{level}, data size #{old_data.size}, time #{Time.now - t}"
72
+
73
+ return new_data
74
+ end
75
+
76
+ # Process part (size depends on level)
77
+ def process_part(old_data, position)
78
+ # neutral data, used where position is near edge to calculate new value
79
+ neutral_data = {
80
+ :x => old_data[position][:x],
81
+ :y => old_data[position][:y]
82
+ }
83
+ part_array = Array.new(level, neutral_data)
84
+
85
+ # add data from old_data to part_array
86
+ offset = (level/2.0).floor
87
+ # copying data
88
+ (0...level).each do |l|
89
+ copy_pos = position + l - offset
90
+ # if copy_pos is inside data
91
+ if copy_pos >= 0 and old_data.size > copy_pos
92
+ part_array[l] = old_data[copy_pos]
93
+ end
94
+ end
95
+ # here we should have part_array and vector
96
+ # and now do some magic :]
97
+
98
+ if PROCESS_WITH_PARAMETER_DISTANCE == false
99
+ y_sum = 0.0
100
+ (0...level).each do |l|
101
+ y_sum += part_array[l][:y] * vector[l]
102
+ end
103
+ return y_sum
104
+ else
105
+ # TODO bugs!, issues with NaN
106
+ # waged average using inverted distance
107
+ _sum = 0.0
108
+ _wages = 0.0
109
+ _x_position = old_data[position][:x]
110
+
111
+ (0...level).each do |l|
112
+ _x_distance = (part_array[l][:x] - _x_position).abs
113
+ _wage = (1.0 / _x_distance)
114
+
115
+ unless _wage.nan?
116
+ _wages += _wage
117
+ _sum += (part_array[l][:y] * vector[l]) / _x_distance
118
+ end
119
+ end
120
+ y = _sum.to_f / _wages.to_f
121
+ puts y
122
+ return y
123
+ end
124
+
125
+ end
126
+
127
+
128
+ # This vector will be used to process values (Y'es), linear algorithm
129
+ def generate_vector_rectangular
130
+ @vector = Array.new
131
+ # calculated
132
+ (1..level).each do |i|
133
+ @vector << 1.0 / level.to_f
134
+ end
135
+ return @vector
136
+ end
137
+
138
+ # This vector will be used to process values (Y'es), linear algorithm
139
+ def generate_vector_gauss
140
+ # http://www.techotopia.com/index.php/Ruby_Math_Functions_and_Methods#Ruby_Math_Constants
141
+ # http://pl.wikipedia.org/wiki/Okno_czasowe
142
+
143
+ # calculation
144
+ count = (level.to_f / 2.0).floor + 1
145
+
146
+ v = Array.new
147
+ # calculated
148
+ (1..count).each do |i|
149
+ v << Math::E ** ((-0.5) * (i*gauss_coeff) ** 2)
150
+ end
151
+
152
+ @vector = make_mirror(v, level)
153
+
154
+ normalize_vector
155
+
156
+ return @vector
157
+ end
158
+
159
+ # Multiply vector to have sum eq. 1.0
160
+ def normalize_vector
161
+ s = 0.0
162
+ @vector.each do |v|
163
+ s += v
164
+ end
165
+
166
+ new_vector = Array.new
167
+
168
+ @vector.each do |v|
169
+ new_vector << v / s
170
+ end
171
+
172
+ @vector = new_vector
173
+
174
+ return @vector
175
+ end
176
+
177
+ # Make mirror array
178
+ # size = 7 => [ i[3], i[2], i[1], i[0], i[1], i[2], i[3] ]
179
+ # size = 8 => [ i[3], i[2], i[1], i[0], i[0], i[1], i[2], i[3] ]
180
+ def make_mirror(input, size)
181
+ a = Array.new(size, 0.1)
182
+ if size.even?
183
+ # two 'first' in central
184
+ c_left = size/2 - 1
185
+ c_right = size/2
186
+
187
+ a[c_left] = input[0]
188
+ a[c_right] = input[0]
189
+ else
190
+ # there is one 'first'
191
+ c_left = (size/2.0).floor
192
+ c_right = (size/2.0).floor
193
+
194
+ a[c_left] = input[0]
195
+ # a[c_right] = input[0]
196
+ end
197
+
198
+ # the rest
199
+ i = 0
200
+ while c_left > 0
201
+ i += 1
202
+ c_left -= 1
203
+ c_right += 1
204
+
205
+ a[c_left] = input[i]
206
+ a[c_right] = input[i]
207
+ end
208
+
209
+ return a
210
+ end
211
+
212
+ end
@@ -215,14 +215,16 @@ class GraphImageDrawer
215
215
  end
216
216
 
217
217
  # labels
218
- coords.each do |c|
219
- string_label = "#{truncate_string % c[:dy]}"
220
- layer_text.text(
221
- c[:ax] + 5, c[:ay],
222
- string_label
223
- )
218
+ if l.value_labels
219
+ coords.each do |c|
220
+ string_label = "#{truncate_string % c[:dy]}"
221
+ layer_text.text(
222
+ c[:ax] + 5, c[:ay],
223
+ string_label
224
+ )
225
+ end
226
+ layer_text.draw(@image)
224
227
  end
225
- layer_text.draw(@image)
226
228
 
227
229
  # lines and circles
228
230
  coords.each do |c|
@@ -244,8 +246,8 @@ class GraphImageDrawer
244
246
 
245
247
  # used for auto positioning of legend
246
248
  if legend_auto_position
247
- @drawn_points << {:x => c[:ax], :y => c[:ay]}
248
- @drawn_points << {:x => c[:bx], :y => c[:by]}
249
+ @drawn_points << { :x => c[:ax], :y => c[:ay] }
250
+ @drawn_points << { :x => c[:bx], :y => c[:by] }
249
251
  end
250
252
  end
251
253
  layer_line.draw(@image)
@@ -264,14 +266,14 @@ class GraphImageDrawer
264
266
 
265
267
  # check 8 places:
266
268
  positions = [
267
- {:x => legend_margin, :y => 0 + legend_margin}, # top-left
268
- {:x => width/2, :y => 0 + legend_margin}, # top-center
269
- {:x => width - legend_margin - legend_width, :y => 0 + legend_margin}, # top-right
270
- {:x => legend_margin, :y => height/2}, # middle-left
271
- {:x => width - legend_margin - legend_width, :y => height/2}, # middle-right
272
- {:x => legend_margin, :y => height - legend_margin - legend_height}, # bottom-left
273
- {:x => width/2, :y => height - legend_margin - legend_height}, # bottom-center
274
- {:x => width - legend_margin - legend_width, :y => height - legend_margin - legend_height}, # bottom-right
269
+ { :x => legend_margin, :y => 0 + legend_margin }, # top-left
270
+ { :x => width/2, :y => 0 + legend_margin }, # top-center
271
+ { :x => width - legend_margin - legend_width, :y => 0 + legend_margin }, # top-right
272
+ { :x => legend_margin, :y => height/2 }, # middle-left
273
+ { :x => width - legend_margin - legend_width, :y => height/2 }, # middle-right
274
+ { :x => legend_margin, :y => height - legend_margin - legend_height }, # bottom-left
275
+ { :x => width/2, :y => height - legend_margin - legend_height }, # bottom-center
276
+ { :x => width - legend_margin - legend_width, :y => height - legend_margin - legend_height }, # bottom-right
275
277
  ]
276
278
 
277
279
  # calculate nearest distance of all drawn points
@@ -279,7 +281,7 @@ class GraphImageDrawer
279
281
  p[:distance] = (width ** 2 + height ** 2) ** 0.5 # max distance, diagonal of graph
280
282
  @drawn_points.each do |dp|
281
283
  # calculate drawn point distance to being checked now legend position
282
- two_points_distance = ( (p[:x] - dp[:x]) ** 2 + (p[:y] - dp[:y]) ** 2 ) ** 0.5
284
+ two_points_distance = ((p[:x] - dp[:x]) ** 2 + (p[:y] - dp[:y]) ** 2) ** 0.5
283
285
  # modify only if distance is closer
284
286
  if p[:distance] > two_points_distance
285
287
  p[:distance] = two_points_distance
@@ -288,7 +290,7 @@ class GraphImageDrawer
288
290
  end
289
291
 
290
292
  # chose position with hihest distance
291
- positions.sort!{|a,b| a[:distance] <=> b[:distance]}
293
+ positions.sort! { |a, b| a[:distance] <=> b[:distance] }
292
294
  best_position = positions.last
293
295
  options[:legend_x] = best_position[:x]
294
296
  options[:legend_y] = best_position[:y]
@@ -318,7 +320,7 @@ class GraphImageDrawer
318
320
 
319
321
  layers.each do |l|
320
322
  legend_text.fill(l.color)
321
-
323
+
322
324
  string_label = l.label
323
325
  legend_text.text(
324
326
  x, y,
@@ -82,7 +82,7 @@ class TestTechnicalAutocolor < Test::Unit::TestCase
82
82
 
83
83
  @tg.render
84
84
 
85
- @tg.image_drawer.save_to_file('test_autocolor.png')
85
+ @tg.image_drawer.save_to_file('samples/tests/test_autocolor.png')
86
86
  @tg.image_drawer.to_png.class.should == String
87
87
 
88
88
  end
@@ -58,8 +58,8 @@ class TestTechnicalAxisEnlarge < Test::Unit::TestCase
58
58
 
59
59
  @tg.render
60
60
 
61
- @tg.image_drawer.save_to_file('test_axis_enlarge.png')
62
- @tg.image_drawer.save_to_file('test_axis_enlarge.svg')
61
+ @tg.image_drawer.save_to_file('samples/tests/test_axis_enlarge.png')
62
+ @tg.image_drawer.save_to_file('samples/tests/test_axis_enlarge.svg')
63
63
  @tg.image_drawer.to_png.class.should == String
64
64
 
65
65
  end
@@ -67,7 +67,7 @@ class TestTechnicalGraph < Test::Unit::TestCase
67
67
  layer.data.size.should == 2 * @data_size
68
68
 
69
69
  # @tg.render
70
- # @tg.image.save_to_file('test1.png')
70
+ # @tg.image.save_to_file('samples/tests/test1.png')
71
71
  end
72
72
 
73
73
  should 'has ability to filter records with similar x\'es' do
@@ -262,7 +262,7 @@ class TestTechnicalGraphAxis < Test::Unit::TestCase
262
262
  @tg.axis.parameter_axis.should == [-8.0, -6.0, -4.0, -2.0, 0.0, 2.0, 4.0, 6.0]
263
263
  @tg.axis.value_axis.should == [-4.0, -2.0, 0.0, 2.0]
264
264
 
265
- @tg.image_drawer.save_to_file('test1.png')
265
+ @tg.image_drawer.save_to_file('samples/tests/test1.png')
266
266
  end
267
267
 
268
268
 
@@ -297,7 +297,7 @@ class TestTechnicalGraphAxis < Test::Unit::TestCase
297
297
 
298
298
  @tg.render
299
299
 
300
- @tg.image_drawer.save_to_file('test2.png')
300
+ @tg.image_drawer.save_to_file('samples/tests/test2.png')
301
301
  end
302
302
 
303
303
  end
@@ -86,7 +86,7 @@ class TestTechnicalMultilayer < Test::Unit::TestCase
86
86
 
87
87
  @tg.render
88
88
 
89
- @tg.image_drawer.save_to_file('test_multilayer.png')
89
+ @tg.image_drawer.save_to_file('samples/tests/test_multilayer.png')
90
90
  @tg.image_drawer.to_png.class.should == String
91
91
 
92
92
  end
@@ -54,7 +54,7 @@ class TestTechnicalSimpleGraph < Test::Unit::TestCase
54
54
 
55
55
  @tg.render
56
56
 
57
- @tg.image_drawer.save_to_file('test_simple.png')
57
+ @tg.image_drawer.save_to_file('samples/tests/test_simple.png')
58
58
  @tg.image_drawer.to_png.class.should == String
59
59
 
60
60
  end
@@ -0,0 +1,214 @@
1
+ require 'helper'
2
+
3
+ class TestTechnicalSmoother < Test::Unit::TestCase
4
+ context 'calculations' do
5
+ setup do
6
+ max = 500
7
+
8
+ # adding simple layer
9
+ @layer_params = {
10
+ :antialias => true,
11
+ :label => 'first',
12
+ :value_labels => false,
13
+ :simple_smother => 4
14
+ }
15
+ @layer_data = Array.new
16
+ (0..max).each do |i|
17
+ x = -10.0 + (20.0 * i.to_f / max.to_f)
18
+ y = 10.0 * Math.cos(i.to_f * (0.5 * 3.14 / max.to_f))
19
+
20
+ y += rand
21
+ x += rand / max.to_f
22
+
23
+ @layer_data << { :x => x, :y => y }
24
+ end
25
+
26
+
27
+ @data_layer = DataLayer.new(@layer_data, @layer_params)
28
+ @processor = @data_layer.processor
29
+ end
30
+
31
+ should 'do some basic tests' do
32
+ @processor.should.kind_of? DataLayerProcessor
33
+ end
34
+
35
+ should 'calculated vector has proper size and sum eq. 1.0' do
36
+ @processor.generate_vector.should.kind_of? Array
37
+ @processor.generate_vector.size.should == @processor.level
38
+
39
+ DataLayerProcessor::STRATEGIES.keys.each do |s|
40
+ @processor.strategy = s
41
+ @processor.strategy.should == s
42
+
43
+ (1...10).each do |i|
44
+ @processor.level = i
45
+ @processor.level.should == i
46
+
47
+ @processor.generate_vector.size.should == @processor.level
48
+
49
+ s = 0.0
50
+ @processor.generate_vector.each do |t|
51
+ s += t
52
+ end
53
+ s.should be_within(0.01).of(1.0)
54
+
55
+ # puts @processor.vector.inspect
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ should 'processed data has the same size that old one' do
62
+ DataLayerProcessor::STRATEGIES.keys.each do |s|
63
+ @processor.strategy = s
64
+ @processor.strategy.should == s
65
+ (1...9).each do |i|
66
+ @processor.level = i
67
+ @processor.level.should == i
68
+
69
+ @processor.generate_vector.size.should == @processor.level
70
+
71
+ new_data = @processor.process
72
+ new_data.size.should == @data_layer.data.size
73
+
74
+ # add as new layer
75
+ #@data_layer = DataLayer.new(@layer_data, @layer_params)
76
+ # @tg.add_layer(new_data, @layer_params)
77
+ end
78
+ end
79
+ end
80
+
81
+ should 'create simple graph with unprocessed and processed layer (gauss)' do
82
+ tg = TechnicalGraph.new(
83
+ {
84
+ :width => 2000,
85
+ :height => 1500,
86
+ }
87
+ )
88
+ max = 1000
89
+
90
+ # adding simple layer
91
+ layer_params = {
92
+ :antialias => true,
93
+ :color => 'red',
94
+ :label => 'raw',
95
+ :value_labels => false,
96
+ # :simple_smother => 8
97
+ }
98
+ layer_data = Array.new
99
+ (0..max).each do |i|
100
+ x = -10.0 + (20.0 * i.to_f / max.to_f)
101
+ y = 10.0 * Math.cos(i.to_f * (0.5 * 3.14 / max.to_f))
102
+
103
+ y += rand
104
+ x += rand / max.to_f
105
+
106
+ layer_data << { :x => x, :y => y }
107
+ end
108
+
109
+ # non processed
110
+ tg.add_layer(layer_data, layer_params)
111
+
112
+ # process and add
113
+ approx = layer_data_b = tg.layers[0].processor
114
+ approx.strategy = :gauss
115
+ approx.level = 9
116
+ approx.generate_vector
117
+
118
+ layer_data_b = approx.process
119
+ layer_params_b = {
120
+ :antialias => false,
121
+ :color => 'blue',
122
+ :label => 'processed',
123
+ :value_labels => false,
124
+ # :simple_smother => 9
125
+ }
126
+ tg.add_layer(layer_data_b, layer_params_b)
127
+
128
+ tg.render
129
+ tg.image_drawer.save_to_file('samples/tests/test_simple_gauss.png')
130
+ end
131
+
132
+ should 'create simple graph using only layer params' do
133
+ tg = TechnicalGraph.new(
134
+ {
135
+ :width => 5000,
136
+ :height => 3000,
137
+
138
+ :legend => true,
139
+ :legend_auto => true,
140
+ :legend_width => 90,
141
+ :legend_margin => 60,
142
+ :legend_x => 50,
143
+ :legend_y => 50,
144
+ }
145
+ )
146
+ max = 2000
147
+
148
+ layer_data = Array.new
149
+ (0..max).each do |i|
150
+ x = -10.0 + (20.0 * i.to_f / max.to_f)
151
+ y = 10.0 * Math.cos(i.to_f * (2.0 * 3.14 / max.to_f))
152
+
153
+ y += rand * 4.0
154
+ x += rand / max.to_f
155
+
156
+ layer_data << { :x => x, :y => y }
157
+ end
158
+
159
+ # adding simple layer
160
+ layer_params = {
161
+ :antialias => false,
162
+ :color => 'red',
163
+ :label => 'raw',
164
+ :value_labels => false,
165
+ :simple_smoother => true,
166
+ :simple_smoother_level => 1,
167
+ :simple_smoother_strategy => :gauss
168
+ }
169
+ #tg.add_layer(layer_data.clone, layer_params)
170
+ #layer_params_b = layer_params.merge({
171
+ # :color => 'blue',
172
+ # :label => 'processed - level 3',
173
+ # :simple_smoother_level => 3,
174
+ # :simple_smoother => true
175
+ #})
176
+ #tg.add_layer(layer_data.clone, layer_params)
177
+ layer_params_c = layer_params.clone.merge({
178
+ :color => 'green',
179
+ :label => 'processed - level 100',
180
+ :simple_smoother_level => 100,
181
+ :simple_smoother => true
182
+ })
183
+ #tg.add_layer(layer_data.clone, layer_params)
184
+ #layer_params_d = layer_params.clone.merge({
185
+ # :color => 'brown',
186
+ # :label => 'processed - level 50',
187
+ # :simple_smoother_level => 50,
188
+ # :simple_smoother => true
189
+ #})
190
+ tg.add_layer(layer_data.clone, layer_params)
191
+ #tg.add_layer(layer_data.clone, layer_params_b)
192
+ tg.add_layer(layer_data.clone, layer_params_c)
193
+ #tg.add_layer(layer_data.clone, layer_params_d)
194
+
195
+
196
+ layer_params_e = layer_params.clone.merge({
197
+ :color => 'blue',
198
+ :label => 'processed (rectangular) - level 100',
199
+ :simple_smoother_level => 100,
200
+ :simple_smoother => true,
201
+ :simple_smoother_strategy => :rectangular
202
+ })
203
+ tg.add_layer(layer_data.clone, layer_params_e)
204
+
205
+
206
+ tg.render
207
+ tg.image_drawer.save_to_file('samples/tests/test_smoothing_multiple.png')
208
+ end
209
+
210
+
211
+ end
212
+
213
+
214
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: technical_graph
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 0.2.0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Aleksander Kwiatkowski
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-10-09 00:00:00 +02:00
18
+ date: 2011-10-12 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -122,6 +122,7 @@ files:
122
122
  - VERSION
123
123
  - lib/technical_graph.rb
124
124
  - lib/technical_graph/data_layer.rb
125
+ - lib/technical_graph/data_layer_processor.rb
125
126
  - lib/technical_graph/graph_axis.rb
126
127
  - lib/technical_graph/graph_color_library.rb
127
128
  - lib/technical_graph/graph_data_processor.rb
@@ -133,6 +134,7 @@ files:
133
134
  - test/test_technical_graph_axis.rb
134
135
  - test/test_technical_multilayer.rb
135
136
  - test/test_technical_simple_graph.rb
137
+ - test/test_technical_smoother.rb
136
138
  has_rdoc: true
137
139
  homepage: http://github.com/akwiatkowski/technical_graph
138
140
  licenses: