patch-SVG.txt

Brad Beattie, 2009-03-26 22:23

Download (18.1 KB)

 
1
### Eclipse Workspace Patch 1.0
2
#P Redmine
3
Index: lib/SVG/Graph/Plot.rb
4
===================================================================
5
--- lib/SVG/Graph/Plot.rb	(revision 2632)
6
+++ lib/SVG/Graph/Plot.rb	(working copy)
7
@@ -88,16 +88,18 @@
8
     class Plot < Graph
9
 
10
       # In addition to the defaults set by Graph::initialize, sets
11
+      # [show_data_values] true
12
       # [show_data_points] true
13
       # [area_fill] false
14
       # [stacked] false
15
       def set_defaults
16
         init_with(
17
-          :show_data_points  => true,
18
-          :area_fill         => false,
19
-          :stacked           => false
20
-        )
21
-        self.top_align = self.right_align = self.top_font = self.right_font = 1
22
+                  :show_data_values  => true,
23
+                  :show_data_points  => true,
24
+                  :area_fill         => false,
25
+                  :stacked           => false
26
+                 )
27
+                 self.top_align = self.right_align = self.top_font = self.right_font = 1
28
       end
29
 
30
       # Determines the scaling for the X axis divisions.
31
@@ -128,20 +130,20 @@
32
       # Set the minimum value of the Y axis
33
       attr_accessor :min_y_value
34
 
35
-      
36
+
37
       # Adds data to the plot.  The data must be in X,Y pairs; EG
38
       #   [ 1, 2 ]    # A data set with 1 point: (1,2)
39
       #   [ 1,2, 5,6] # A data set with 2 points: (1,2) and (5,6)  
40
       def add_data data
41
         @data = [] unless @data
42
-       
43
+
44
         raise "No data provided by #{conf.inspect}" unless data[:data] and
45
-          data[:data].kind_of? Array
46
+        data[:data].kind_of? Array
47
         raise "Data supplied must be x,y pairs!  "+
48
           "The data provided contained an odd set of "+
49
           "data points" unless data[:data].length % 2 == 0
50
         return if data[:data].length == 0
51
-          
52
+
53
         x = []
54
         y = []
55
         data[:data].each_index {|i|
56
@@ -205,7 +207,7 @@
57
         max = @data.collect{|x| x[:data][X][-1]}.max
58
         dx = (max - values[-1]).to_f / (values[-1] - values[-2])
59
         (@graph_width.to_f - font_size*2*right_font) /
60
-           (values.length + dx - right_align)
61
+          (values.length + dx - right_align)
62
       end
63
 
64
 
65
@@ -238,14 +240,18 @@
66
       def field_height
67
         values = get_y_values
68
         max = @data.collect{|x| x[:data][Y].max }.max
69
-        dx = (max - values[-1]).to_f / (values[-1] - values[-2])
70
+        if values.length == 1
71
+          dx = values[-1]
72
+        else
73
+          dx = (max - values[-1]).to_f / (values[-1] - values[-2])
74
+        end
75
         (@graph_height.to_f - font_size*2*top_font) /
76
-           (values.length + dx - top_align)
77
+          (values.length + dx - top_align)
78
       end
79
 
80
       def draw_data
81
         line = 1
82
-        
83
+
84
         x_min, x_max, x_div = x_range
85
         y_min, y_max, y_div = y_range
86
         x_step = (@graph_width.to_f - font_size*2) / (x_max-x_min)
87
@@ -290,7 +296,7 @@
88
                 })
89
                 add_popup(x, y, format( x_points[idx], y_points[idx] )) if add_popups
90
               end
91
-              make_datapoint_text( x, y-6, y_points[idx] )
92
+              make_datapoint_text( x, y-6, y_points[idx] ) if show_data_values
93
             }
94
           end
95
           line += 1
96
Index: lib/SVG/Graph/BarHorizontal.rb
97
===================================================================
98
--- lib/SVG/Graph/BarHorizontal.rb	(revision 2632)
99
+++ lib/SVG/Graph/BarHorizontal.rb	(working copy)
100
@@ -103,28 +103,41 @@
101
       def draw_data
102
         minvalue = min_value
103
         fieldheight = field_height
104
-        fieldwidth = (@graph_width.to_f - font_size*2*right_font ) /
105
+
106
+        unit_size = (@graph_width.to_f - font_size*2*right_font ) /
107
                         (get_x_labels.max - get_x_labels.min )
108
         bargap = bar_gap ? (fieldheight < 10 ? fieldheight / 2 : 10) : 0
109
 
110
-        subbar_height = fieldheight - bargap
111
-        subbar_height /= @data.length if stack == :side
112
+        bar_height = fieldheight - bargap
113
+        bar_height /= @data.length if stack == :side
114
+        y_mod = (bar_height / 2) + (font_size / 2)
115
         
116
         field_count = 1
117
-        y_mod = (subbar_height / 2) + (font_size / 2)
118
         @config[:fields].each_index { |i|
119
           dataset_count = 0
120
           for dataset in @data
121
-            y = @graph_height - (fieldheight * field_count)
122
-            y += (subbar_height * dataset_count) if stack == :side
123
-            x = (dataset[:data][i] - minvalue) * fieldwidth
124
+            value = dataset[:data][i]
125
+            
126
+            top = @graph_height - (fieldheight * field_count)
127
+            top += (bar_height * dataset_count) if stack == :side
128
+            # cases (assume 0 = +ve):
129
+            #   value  min  length          left
130
+            #    +ve   +ve  value.abs - min minvalue.abs
131
+            #    +ve   -ve  value.abs - 0   minvalue.abs
132
+            #    -ve   -ve  value.abs - 0   minvalue.abs + value
133
+            length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size
134
+            left = (minvalue.abs + (value < 0 ? value : 0)) * unit_size
135
 
136
-            @graph.add_element( "path", {
137
-              "d" => "M0 #{y} H#{x} v#{subbar_height} H0 Z",
138
+            @graph.add_element( "rect", {
139
+              "x" => left.to_s,
140
+              "y" => top.to_s,
141
+              "width" => length.to_s,
142
+              "height" => bar_height.to_s,
143
               "class" => "fill#{dataset_count+1}"
144
             })
145
+
146
             make_datapoint_text( 
147
-              x+5, y+y_mod, dataset[:data][i], "text-anchor: start; "
148
+              left+length+5, top+y_mod, value, "text-anchor: start; "
149
               )
150
             dataset_count += 1
151
           end
152
Index: lib/SVG/Graph/Pie.rb
153
===================================================================
154
--- lib/SVG/Graph/Pie.rb	(revision 2632)
155
+++ lib/SVG/Graph/Pie.rb	(working copy)
156
@@ -222,6 +222,7 @@
157
           y_start = radius-(Math.cos(radians) * radius)
158
           radians = (prev_percent+percent) * rad_mult
159
           x_end = radius+(Math.sin(radians) * radius)
160
+          x_end -= 0.00001 if @data.length == 1
161
           y_end = radius-(Math.cos(radians) * radius)
162
           path = "M#{radius},#{radius} L#{x_start},#{y_start} "+
163
             "A#{radius},#{radius} "+
164
@@ -257,7 +258,7 @@
165
             ty = -(Math.cos(radians) * expand_gap)
166
             translate = "translate( #{tx} #{ty} )"
167
             wedge.attributes["transform"] = translate
168
-            clear.attributes["transform"] = translate
169
+            clear.attributes["transform"] = translate if clear
170
           end
171
 
172
           if show_shadow
173
Index: lib/SVG/Graph/Bar.rb
174
===================================================================
175
--- lib/SVG/Graph/Bar.rb	(revision 2632)
176
+++ lib/SVG/Graph/Bar.rb	(working copy)
177
@@ -96,37 +96,48 @@
178
       end
179
 
180
       def draw_data
181
-        fieldwidth = field_width
182
-        maxvalue = max_value
183
         minvalue = min_value
184
+        fieldwidth = field_width
185
 
186
-        fieldheight =  (@graph_height.to_f - font_size*2*top_font) / 
187
+        unit_size =  (@graph_height.to_f - font_size*2*top_font) / 
188
                           (get_y_labels.max - get_y_labels.min)
189
         bargap = bar_gap ? (fieldwidth < 10 ? fieldwidth / 2 : 10) : 0
190
 
191
-        subbar_width = fieldwidth - bargap
192
-        subbar_width /= @data.length if stack == :side
193
-        x_mod = (@graph_width-bargap)/2 - (stack==:side ? subbar_width/2 : 0)
194
-        # Y1
195
-        p2 = @graph_height
196
-        # to X2
197
+        bar_width = fieldwidth - bargap
198
+        bar_width /= @data.length if stack == :side
199
+        x_mod = (@graph_width-bargap)/2 - (stack==:side ? bar_width/2 : 0)
200
+ 
201
+        bottom = @graph_height
202
+
203
         field_count = 0
204
         @config[:fields].each_index { |i|
205
           dataset_count = 0
206
           for dataset in @data
207
-            # X1
208
-            p1 = (fieldwidth * field_count)
209
-            # to Y2
210
-            p3 = @graph_height - ((dataset[:data][i] - minvalue) * fieldheight)
211
-            p1 += subbar_width * dataset_count if stack == :side
212
-            @graph.add_element( "path", {
213
-              "class" => "fill#{dataset_count+1}",
214
-              "d" => "M#{p1} #{p2} V#{p3} h#{subbar_width} V#{p2} Z"
215
+          
216
+            # cases (assume 0 = +ve):
217
+            #   value  min  length
218
+            #    +ve   +ve  value - min
219
+            #    +ve   -ve  value - 0
220
+            #    -ve   -ve  value.abs - 0
221
+          
222
+            value = dataset[:data][i]
223
+            
224
+            left = (fieldwidth * field_count)
225
+            
226
+            length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size
227
+            # top is 0 if value is negative
228
+            top = bottom - (((value < 0 ? 0 : value) - minvalue) * unit_size)
229
+            left += bar_width * dataset_count if stack == :side
230
+ 
231
+            @graph.add_element( "rect", {
232
+              "x" => left.to_s,
233
+              "y" => top.to_s,
234
+              "width" => bar_width.to_s,
235
+              "height" => length.to_s,
236
+              "class" => "fill#{dataset_count+1}"
237
             })
238
-            make_datapoint_text(
239
-              p1 + subbar_width/2.0,
240
-              p3 - 6,
241
-              dataset[:data][i].to_s)
242
+
243
+            make_datapoint_text(left + bar_width/2.0, top - 6, value.to_s)
244
             dataset_count += 1
245
           end
246
           field_count += 1
247
Index: lib/SVG/Graph/TimeSeries.rb
248
===================================================================
249
--- lib/SVG/Graph/TimeSeries.rb	(revision 2632)
250
+++ lib/SVG/Graph/TimeSeries.rb	(working copy)
251
@@ -145,7 +145,7 @@
252
       def add_data data
253
         @data = [] unless @data
254
        
255
-        raise "No data provided by #{conf.inspect}" unless data[:data] and
256
+        raise "No data provided by #{@data.inspect}" unless data[:data] and
257
                                                     data[:data].kind_of? Array
258
         raise "Data supplied must be x,y pairs!  "+
259
           "The data provided contained an odd set of "+
260
@@ -191,13 +191,13 @@
261
         rv = []
262
         min, max, scale_division = x_range
263
         if timescale_divisions
264
-          timescale_divisions =~ /(\d+) ?(days|weeks|months|years|hours|minutes|seconds)?/
265
-          division_units = $2 ? $2 : "days"
266
+          timescale_divisions =~ /(\d+) ?(day|week|month|year|hour|minute|second)?/
267
+          division_units = $2 ? $2 : "day"
268
           amount = $1.to_i
269
           if amount
270
             step =  nil
271
             case division_units
272
-            when "months"
273
+            when "month"
274
               cur = min
275
               while cur < max
276
                 rv << cur
277
@@ -209,7 +209,7 @@
278
                 end
279
                 cur = Time.local(*arr).to_i
280
               end
281
-            when "years"
282
+            when "year"
283
               cur = min
284
               while cur < max
285
                 rv << cur
286
@@ -217,15 +217,15 @@
287
                 arr[5] += amount
288
                 cur = Time.local(*arr).to_i
289
               end
290
-            when "weeks"
291
+            when "week"
292
               step = 7 * 24 * 60 * 60 * amount
293
-            when "days"
294
+            when "day"
295
               step = 24 * 60 * 60 * amount
296
-            when "hours"
297
+            when "hour"
298
               step = 60 * 60 * amount
299
-            when "minutes"
300
+            when "minute"
301
               step = 60 * amount
302
-            when "seconds"
303
+            when "second"
304
               step = amount
305
             end
306
             min.step( max, step ) {|v| rv << v} if step
307
Index: lib/SVG/Graph/BarBase.rb
308
===================================================================
309
--- lib/SVG/Graph/BarBase.rb	(revision 2632)
310
+++ lib/SVG/Graph/BarBase.rb	(working copy)
311
@@ -43,18 +43,17 @@
312
 			protected
313
 
314
       def max_value
315
-        return @data.collect{|x| x[:data].max}.max
316
+        @data.collect{|x| x[:data].max}.max
317
       end
318
 
319
       def min_value
320
         min = 0
321
-
322
-        if (min_scale_value.nil? == false) then
323
+        if min_scale_value.nil? 
324
+          min = @data.collect{|x| x[:data].min}.min
325
+          min = min > 0 ? 0 : min
326
+        else
327
           min = min_scale_value
328
-        else
329
-          min = @data.collect{|x| x[:data].min}.min
330
         end
331
-
332
         return min
333
       end
334
 
335
Index: lib/SVG/Graph/Graph.rb
336
===================================================================
337
--- lib/SVG/Graph/Graph.rb	(revision 2632)
338
+++ lib/SVG/Graph/Graph.rb	(working copy)
339
@@ -105,12 +105,12 @@
340
 
341
         init_with({
342
           :width                => 500,
343
-          :height               => 300,
344
+          :height                => 300,
345
           :show_x_guidelines    => false,
346
           :show_y_guidelines    => true,
347
           :show_data_values     => true,
348
 
349
-          :min_scale_value      => 0,
350
+#          :min_scale_value      => 0,
351
 
352
           :show_x_labels        => true,
353
           :stagger_x_labels     => false,
354
@@ -137,14 +137,14 @@
355
           :key                  => true, 
356
           :key_position          => :right, # bottom or right
357
 
358
-          :font_size            =>10,
359
-          :title_font_size      =>12,
360
+          :font_size            =>12,
361
+          :title_font_size      =>16,
362
           :subtitle_font_size   =>14,
363
-          :x_label_font_size    =>11,
364
+          :x_label_font_size    =>12,
365
           :x_title_font_size    =>14,
366
-          :y_label_font_size    =>11,
367
+          :y_label_font_size    =>12,
368
           :y_title_font_size    =>14,
369
-          :key_font_size        => 9,
370
+          :key_font_size        =>10,
371
           
372
           :no_css               =>false,
373
           :add_popups           =>false,
374
@@ -392,7 +392,7 @@
375
         @border_right = 7
376
         if key and key_position == :right
377
           val = keys.max { |a,b| a.length <=> b.length }
378
-          @border_right += val.length * key_font_size * 0.7 
379
+          @border_right += val.length * key_font_size * 0.6 
380
           @border_right += KEY_BOX_SIZE
381
           @border_right += 10    # Some padding around the box
382
         end
383
@@ -421,7 +421,7 @@
384
         t.attributes["style"] = "fill: #000; "+
385
           (x+txt_width > width ? "text-anchor: end;" : "text-anchor: start;")
386
         t.text = label.to_s
387
-        t.attributes["id"] = t.id.to_s
388
+        t.attributes["id"] = t.object_id.to_s
389
 
390
         @foreground.add_element( "circle", {
391
           "cx" => x.to_s,
392
@@ -429,9 +429,9 @@
393
           "r" => "10",
394
           "style" => "opacity: 0",
395
           "onmouseover" => 
396
-            "document.getElementById(#{t.id}).setAttribute('visibility', 'visible' )",
397
+            "document.getElementById(#{t.object_id}).setAttribute('visibility', 'visible' )",
398
           "onmouseout" => 
399
-            "document.getElementById(#{t.id}).setAttribute('visibility', 'hidden' )",
400
+            "document.getElementById(#{t.object_id}).setAttribute('visibility', 'hidden' )",
401
         })
402
 
403
       end
404
@@ -446,11 +446,11 @@
405
           @border_bottom += 10
406
         end
407
         if show_x_labels
408
-          max_x_label_height_px = rotate_x_labels ? 
409
+		  max_x_label_height_px = (not rotate_x_labels) ? 
410
+            x_label_font_size :
411
             get_x_labels.max{|a,b| 
412
-              a.length<=>b.length
413
-            }.length * x_label_font_size * 0.6 :
414
-            x_label_font_size
415
+              a.to_s.length<=>b.to_s.length
416
+            }.to_s.length * x_label_font_size * 0.6
417
           @border_bottom += max_x_label_height_px
418
           @border_bottom += max_x_label_height_px + 10 if stagger_x_labels
419
         end
420
@@ -723,7 +723,7 @@
421
             })
422
             group.add_element( "text", {
423
               "x" => (KEY_BOX_SIZE + 5).to_s,
424
-              "y" => (y_offset + KEY_BOX_SIZE - 2).to_s,
425
+              "y" => (y_offset + KEY_BOX_SIZE).to_s,
426
               "class" => "keyText"
427
             }).text = key_name.to_s
428
             key_count += 1
429
@@ -737,10 +737,11 @@
430
             x_offset = @border_left + 20
431
             y_offset = @border_top + @graph_height + 5
432
             if show_x_labels
433
-              max_x_label_height_px = rotate_x_labels ? 
434
-                get_x_labels.max{|a,b| 
435
-                  a.length<=>b.length
436
-                }.length * x_label_font_size :
437
+			  max_x_label_height_px = (not rotate_x_labels) ? 
438
+				x_label_font_size :
439
+				get_x_labels.max{|a,b| 
440
+				  a.to_s.length<=>b.to_s.length
441
+				}.to_s.length * x_label_font_size * 0.6
442
                 x_label_font_size
443
               y_offset += max_x_label_height_px
444
               y_offset += max_x_label_height_px + 5 if stagger_x_labels
445
@@ -883,41 +884,41 @@
446
   fill:#ffffff;
447
 }
448
 .graphBackground{
449
-  fill:#f5f5f5;
450
+  fill:#f0f0f0;
451
 }
452
 
453
 /* graphs titles */
454
 .mainTitle{
455
   text-anchor: middle;
456
-  fill: #555555;
457
+  fill: #000000;
458
   font-size: #{title_font_size}px;
459
-  font-family: "Verdana", sans-serif;
460
-  font-weight: bold;
461
+  font-family: "Arial", sans-serif;
462
+  font-weight: normal;
463
 }
464
 .subTitle{
465
   text-anchor: middle;
466
   fill: #999999;
467
   font-size: #{subtitle_font_size}px;
468
-  font-family: "Verdana", sans-serif;
469
+  font-family: "Arial", sans-serif;
470
   font-weight: normal;
471
 }
472
 
473
 .axis{
474
-  stroke: #666666;
475
+  stroke: #000000;
476
   stroke-width: 1px;
477
 }
478
 
479
 .guideLines{
480
   stroke: #666666;
481
   stroke-width: 1px;
482
-  stroke-dasharray:2,2,2;
483
+  stroke-dasharray: 5 5;
484
 }
485
 
486
 .xAxisLabels{
487
   text-anchor: middle;
488
   fill: #000000;
489
   font-size: #{x_label_font_size}px;
490
-  font-family: "Verdana", sans-serif;
491
+  font-family: "Arial", sans-serif;
492
   font-weight: normal;
493
 }
494
 
495
@@ -925,7 +926,7 @@
496
   text-anchor: end;
497
   fill: #000000;
498
   font-size: #{y_label_font_size}px;
499
-  font-family: "Verdana", sans-serif;
500
+  font-family: "Arial", sans-serif;
501
   font-weight: normal;
502
 }
503
 
504
@@ -933,7 +934,7 @@
505
   text-anchor: middle;
506
   fill: #ff0000;
507
   font-size: #{x_title_font_size}px;
508
-  font-family: "Verdana", sans-serif;
509
+  font-family: "Arial", sans-serif;
510
   font-weight: normal;
511
 }
512
 
513
@@ -941,7 +942,7 @@
514
   fill: #ff0000;
515
   text-anchor: middle;
516
   font-size: #{y_title_font_size}px;
517
-  font-family: "Verdana", sans-serif;
518
+  font-family: "Arial", sans-serif;
519
   font-weight: normal;
520
 }
521
 
522
@@ -949,7 +950,7 @@
523
   fill: #000000;
524
   text-anchor:middle;
525
   font-size: 10px;
526
-  font-family: "Verdana", sans-serif;
527
+  font-family: "Arial", sans-serif;
528
   font-weight: normal;
529
 }
530
 
531
@@ -965,7 +966,7 @@
532
   fill: #000000;
533
   text-anchor:start;
534
   font-size: #{key_font_size}px;
535
-  font-family: "Verdana", sans-serif;
536
+  font-family: "Arial", sans-serif;
537
   font-weight: normal;
538
 }
539
 /* End copy for external style sheet */