@@ -96,37 +96,48 module SVG | |||
|
96 | 96 | end |
|
97 | 97 | |
|
98 | 98 | def draw_data |
|
99 | fieldwidth = field_width | |
|
100 | maxvalue = max_value | |
|
101 | 99 | minvalue = min_value |
|
100 | fieldwidth = field_width | |
|
102 | 101 | |
|
103 |
|
|
|
102 | unit_size = (@graph_height.to_f - font_size*2*top_font) / | |
|
104 | 103 | (get_y_labels.max - get_y_labels.min) |
|
105 | 104 | bargap = bar_gap ? (fieldwidth < 10 ? fieldwidth / 2 : 10) : 0 |
|
106 | 105 | |
|
107 |
|
|
|
108 |
|
|
|
109 |
x_mod = (@graph_width-bargap)/2 - (stack==:side ? |
|
|
110 | # Y1 | |
|
111 |
|
|
|
112 | # to X2 | |
|
106 | bar_width = fieldwidth - bargap | |
|
107 | bar_width /= @data.length if stack == :side | |
|
108 | x_mod = (@graph_width-bargap)/2 - (stack==:side ? bar_width/2 : 0) | |
|
109 | ||
|
110 | bottom = @graph_height | |
|
111 | ||
|
113 | 112 | field_count = 0 |
|
114 | 113 | @config[:fields].each_index { |i| |
|
115 | 114 | dataset_count = 0 |
|
116 | 115 | for dataset in @data |
|
117 |
|
|
|
118 | p1 = (fieldwidth * field_count) | |
|
119 | # to Y2 | |
|
120 | p3 = @graph_height - ((dataset[:data][i] - minvalue) * fieldheight) | |
|
121 | p1 += subbar_width * dataset_count if stack == :side | |
|
122 | @graph.add_element( "path", { | |
|
123 | "class" => "fill#{dataset_count+1}", | |
|
124 | "d" => "M#{p1} #{p2} V#{p3} h#{subbar_width} V#{p2} Z" | |
|
116 | ||
|
117 | # cases (assume 0 = +ve): | |
|
118 | # value min length | |
|
119 | # +ve +ve value - min | |
|
120 | # +ve -ve value - 0 | |
|
121 | # -ve -ve value.abs - 0 | |
|
122 | ||
|
123 | value = dataset[:data][i] | |
|
124 | ||
|
125 | left = (fieldwidth * field_count) | |
|
126 | ||
|
127 | length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size | |
|
128 | # top is 0 if value is negative | |
|
129 | top = bottom - (((value < 0 ? 0 : value) - minvalue) * unit_size) | |
|
130 | left += bar_width * dataset_count if stack == :side | |
|
131 | ||
|
132 | @graph.add_element( "rect", { | |
|
133 | "x" => left.to_s, | |
|
134 | "y" => top.to_s, | |
|
135 | "width" => bar_width.to_s, | |
|
136 | "height" => length.to_s, | |
|
137 | "class" => "fill#{dataset_count+1}" | |
|
125 | 138 | }) |
|
126 | make_datapoint_text( | |
|
127 | p1 + subbar_width/2.0, | |
|
128 | p3 - 6, | |
|
129 | dataset[:data][i].to_s) | |
|
139 | ||
|
140 | make_datapoint_text(left + bar_width/2.0, top - 6, value.to_s) | |
|
130 | 141 | dataset_count += 1 |
|
131 | 142 | end |
|
132 | 143 | field_count += 1 |
@@ -43,18 +43,17 module SVG | |||
|
43 | 43 | protected |
|
44 | 44 | |
|
45 | 45 | def max_value |
|
46 |
|
|
|
46 | @data.collect{|x| x[:data].max}.max | |
|
47 | 47 | end |
|
48 | 48 | |
|
49 | 49 | def min_value |
|
50 | 50 | min = 0 |
|
51 | ||
|
52 | if (min_scale_value.nil? == false) then | |
|
53 | min = min_scale_value | |
|
54 | else | |
|
51 | if min_scale_value.nil? | |
|
55 | 52 | min = @data.collect{|x| x[:data].min}.min |
|
53 | min = min > 0 ? 0 : min | |
|
54 | else | |
|
55 | min = min_scale_value | |
|
56 | 56 | end |
|
57 | ||
|
58 | 57 | return min |
|
59 | 58 | end |
|
60 | 59 |
@@ -103,28 +103,41 module SVG | |||
|
103 | 103 | def draw_data |
|
104 | 104 | minvalue = min_value |
|
105 | 105 | fieldheight = field_height |
|
106 | fieldwidth = (@graph_width.to_f - font_size*2*right_font ) / | |
|
106 | ||
|
107 | unit_size = (@graph_width.to_f - font_size*2*right_font ) / | |
|
107 | 108 | (get_x_labels.max - get_x_labels.min ) |
|
108 | 109 | bargap = bar_gap ? (fieldheight < 10 ? fieldheight / 2 : 10) : 0 |
|
109 | 110 | |
|
110 |
|
|
|
111 |
|
|
|
111 | bar_height = fieldheight - bargap | |
|
112 | bar_height /= @data.length if stack == :side | |
|
113 | y_mod = (bar_height / 2) + (font_size / 2) | |
|
112 | 114 | |
|
113 | 115 | field_count = 1 |
|
114 | y_mod = (subbar_height / 2) + (font_size / 2) | |
|
115 | 116 | @config[:fields].each_index { |i| |
|
116 | 117 | dataset_count = 0 |
|
117 | 118 | for dataset in @data |
|
118 | y = @graph_height - (fieldheight * field_count) | |
|
119 | y += (subbar_height * dataset_count) if stack == :side | |
|
120 | x = (dataset[:data][i] - minvalue) * fieldwidth | |
|
119 | value = dataset[:data][i] | |
|
120 | ||
|
121 | top = @graph_height - (fieldheight * field_count) | |
|
122 | top += (bar_height * dataset_count) if stack == :side | |
|
123 | # cases (assume 0 = +ve): | |
|
124 | # value min length left | |
|
125 | # +ve +ve value.abs - min minvalue.abs | |
|
126 | # +ve -ve value.abs - 0 minvalue.abs | |
|
127 | # -ve -ve value.abs - 0 minvalue.abs + value | |
|
128 | length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size | |
|
129 | left = (minvalue.abs + (value < 0 ? value : 0)) * unit_size | |
|
121 | 130 | |
|
122 |
@graph.add_element( " |
|
|
123 | "d" => "M0 #{y} H#{x} v#{subbar_height} H0 Z", | |
|
131 | @graph.add_element( "rect", { | |
|
132 | "x" => left.to_s, | |
|
133 | "y" => top.to_s, | |
|
134 | "width" => length.to_s, | |
|
135 | "height" => bar_height.to_s, | |
|
124 | 136 | "class" => "fill#{dataset_count+1}" |
|
125 | 137 | }) |
|
138 | ||
|
126 | 139 | make_datapoint_text( |
|
127 |
|
|
|
140 | left+length+5, top+y_mod, value, "text-anchor: start; " | |
|
128 | 141 | ) |
|
129 | 142 | dataset_count += 1 |
|
130 | 143 | end |
@@ -110,7 +110,7 module SVG | |||
|
110 | 110 | :show_y_guidelines => true, |
|
111 | 111 | :show_data_values => true, |
|
112 | 112 | |
|
113 |
|
|
|
113 | # :min_scale_value => 0, | |
|
114 | 114 | |
|
115 | 115 | :show_x_labels => true, |
|
116 | 116 | :stagger_x_labels => false, |
@@ -137,14 +137,14 module SVG | |||
|
137 | 137 | :key => true, |
|
138 | 138 | :key_position => :right, # bottom or right |
|
139 | 139 | |
|
140 |
:font_size =>1 |
|
|
141 |
:title_font_size =>1 |
|
|
140 | :font_size =>12, | |
|
141 | :title_font_size =>16, | |
|
142 | 142 | :subtitle_font_size =>14, |
|
143 |
:x_label_font_size =>1 |
|
|
143 | :x_label_font_size =>12, | |
|
144 | 144 | :x_title_font_size =>14, |
|
145 |
:y_label_font_size =>1 |
|
|
145 | :y_label_font_size =>12, | |
|
146 | 146 | :y_title_font_size =>14, |
|
147 |
:key_font_size => |
|
|
147 | :key_font_size =>10, | |
|
148 | 148 | |
|
149 | 149 | :no_css =>false, |
|
150 | 150 | :add_popups =>false, |
@@ -392,7 +392,7 module SVG | |||
|
392 | 392 | @border_right = 7 |
|
393 | 393 | if key and key_position == :right |
|
394 | 394 | val = keys.max { |a,b| a.length <=> b.length } |
|
395 |
@border_right += val.length * key_font_size * 0. |
|
|
395 | @border_right += val.length * key_font_size * 0.6 | |
|
396 | 396 | @border_right += KEY_BOX_SIZE |
|
397 | 397 | @border_right += 10 # Some padding around the box |
|
398 | 398 | end |
@@ -421,7 +421,7 module SVG | |||
|
421 | 421 | t.attributes["style"] = "fill: #000; "+ |
|
422 | 422 | (x+txt_width > width ? "text-anchor: end;" : "text-anchor: start;") |
|
423 | 423 | t.text = label.to_s |
|
424 | t.attributes["id"] = t.id.to_s | |
|
424 | t.attributes["id"] = t.object_id.to_s | |
|
425 | 425 | |
|
426 | 426 | @foreground.add_element( "circle", { |
|
427 | 427 | "cx" => x.to_s, |
@@ -429,9 +429,9 module SVG | |||
|
429 | 429 | "r" => "10", |
|
430 | 430 | "style" => "opacity: 0", |
|
431 | 431 | "onmouseover" => |
|
432 | "document.getElementById(#{t.id}).setAttribute('visibility', 'visible' )", | |
|
432 | "document.getElementById(#{t.object_id}).setAttribute('visibility', 'visible' )", | |
|
433 | 433 | "onmouseout" => |
|
434 | "document.getElementById(#{t.id}).setAttribute('visibility', 'hidden' )", | |
|
434 | "document.getElementById(#{t.object_id}).setAttribute('visibility', 'hidden' )", | |
|
435 | 435 | }) |
|
436 | 436 | |
|
437 | 437 | end |
@@ -446,11 +446,11 module SVG | |||
|
446 | 446 | @border_bottom += 10 |
|
447 | 447 | end |
|
448 | 448 | if show_x_labels |
|
449 |
|
|
|
449 | max_x_label_height_px = (not rotate_x_labels) ? | |
|
450 | x_label_font_size : | |
|
450 | 451 | get_x_labels.max{|a,b| |
|
451 | a.length<=>b.length | |
|
452 |
}.length * x_label_font_size * 0.6 |
|
|
453 | x_label_font_size | |
|
452 | a.to_s.length<=>b.to_s.length | |
|
453 | }.to_s.length * x_label_font_size * 0.6 | |
|
454 | 454 | @border_bottom += max_x_label_height_px |
|
455 | 455 | @border_bottom += max_x_label_height_px + 10 if stagger_x_labels |
|
456 | 456 | end |
@@ -723,7 +723,7 module SVG | |||
|
723 | 723 | }) |
|
724 | 724 | group.add_element( "text", { |
|
725 | 725 | "x" => (KEY_BOX_SIZE + 5).to_s, |
|
726 |
"y" => (y_offset + KEY_BOX_SIZE |
|
|
726 | "y" => (y_offset + KEY_BOX_SIZE).to_s, | |
|
727 | 727 | "class" => "keyText" |
|
728 | 728 | }).text = key_name.to_s |
|
729 | 729 | key_count += 1 |
@@ -737,10 +737,11 module SVG | |||
|
737 | 737 | x_offset = @border_left + 20 |
|
738 | 738 | y_offset = @border_top + @graph_height + 5 |
|
739 | 739 | if show_x_labels |
|
740 |
|
|
|
740 | max_x_label_height_px = (not rotate_x_labels) ? | |
|
741 | x_label_font_size : | |
|
741 | 742 |
|
|
742 | a.length<=>b.length | |
|
743 |
|
|
|
743 | a.to_s.length<=>b.to_s.length | |
|
744 | }.to_s.length * x_label_font_size * 0.6 | |
|
744 | 745 | x_label_font_size |
|
745 | 746 | y_offset += max_x_label_height_px |
|
746 | 747 | y_offset += max_x_label_height_px + 5 if stagger_x_labels |
@@ -883,41 +884,41 module SVG | |||
|
883 | 884 | fill:#ffffff; |
|
884 | 885 | } |
|
885 | 886 | .graphBackground{ |
|
886 |
fill:#f |
|
|
887 | fill:#f0f0f0; | |
|
887 | 888 | } |
|
888 | 889 | |
|
889 | 890 | /* graphs titles */ |
|
890 | 891 | .mainTitle{ |
|
891 | 892 | text-anchor: middle; |
|
892 |
fill: # |
|
|
893 | fill: #000000; | |
|
893 | 894 | font-size: #{title_font_size}px; |
|
894 |
font-family: " |
|
|
895 |
font-weight: |
|
|
895 | font-family: "Arial", sans-serif; | |
|
896 | font-weight: normal; | |
|
896 | 897 | } |
|
897 | 898 | .subTitle{ |
|
898 | 899 | text-anchor: middle; |
|
899 | 900 | fill: #999999; |
|
900 | 901 | font-size: #{subtitle_font_size}px; |
|
901 |
font-family: " |
|
|
902 | font-family: "Arial", sans-serif; | |
|
902 | 903 | font-weight: normal; |
|
903 | 904 | } |
|
904 | 905 | |
|
905 | 906 | .axis{ |
|
906 |
stroke: # |
|
|
907 | stroke: #000000; | |
|
907 | 908 | stroke-width: 1px; |
|
908 | 909 | } |
|
909 | 910 | |
|
910 | 911 | .guideLines{ |
|
911 | 912 | stroke: #666666; |
|
912 | 913 | stroke-width: 1px; |
|
913 |
stroke-dasharray: |
|
|
914 | stroke-dasharray: 5 5; | |
|
914 | 915 | } |
|
915 | 916 | |
|
916 | 917 | .xAxisLabels{ |
|
917 | 918 | text-anchor: middle; |
|
918 | 919 | fill: #000000; |
|
919 | 920 | font-size: #{x_label_font_size}px; |
|
920 |
font-family: " |
|
|
921 | font-family: "Arial", sans-serif; | |
|
921 | 922 | font-weight: normal; |
|
922 | 923 | } |
|
923 | 924 | |
@@ -925,7 +926,7 module SVG | |||
|
925 | 926 | text-anchor: end; |
|
926 | 927 | fill: #000000; |
|
927 | 928 | font-size: #{y_label_font_size}px; |
|
928 |
font-family: " |
|
|
929 | font-family: "Arial", sans-serif; | |
|
929 | 930 | font-weight: normal; |
|
930 | 931 | } |
|
931 | 932 | |
@@ -933,7 +934,7 module SVG | |||
|
933 | 934 | text-anchor: middle; |
|
934 | 935 | fill: #ff0000; |
|
935 | 936 | font-size: #{x_title_font_size}px; |
|
936 |
font-family: " |
|
|
937 | font-family: "Arial", sans-serif; | |
|
937 | 938 | font-weight: normal; |
|
938 | 939 | } |
|
939 | 940 | |
@@ -941,7 +942,7 module SVG | |||
|
941 | 942 | fill: #ff0000; |
|
942 | 943 | text-anchor: middle; |
|
943 | 944 | font-size: #{y_title_font_size}px; |
|
944 |
font-family: " |
|
|
945 | font-family: "Arial", sans-serif; | |
|
945 | 946 | font-weight: normal; |
|
946 | 947 | } |
|
947 | 948 | |
@@ -949,7 +950,7 module SVG | |||
|
949 | 950 | fill: #000000; |
|
950 | 951 | text-anchor:middle; |
|
951 | 952 | font-size: 10px; |
|
952 |
font-family: " |
|
|
953 | font-family: "Arial", sans-serif; | |
|
953 | 954 | font-weight: normal; |
|
954 | 955 | } |
|
955 | 956 | |
@@ -965,7 +966,7 module SVG | |||
|
965 | 966 | fill: #000000; |
|
966 | 967 | text-anchor:start; |
|
967 | 968 | font-size: #{key_font_size}px; |
|
968 |
font-family: " |
|
|
969 | font-family: "Arial", sans-serif; | |
|
969 | 970 | font-weight: normal; |
|
970 | 971 | } |
|
971 | 972 | /* End copy for external style sheet */ |
@@ -222,6 +222,7 module SVG | |||
|
222 | 222 | y_start = radius-(Math.cos(radians) * radius) |
|
223 | 223 | radians = (prev_percent+percent) * rad_mult |
|
224 | 224 | x_end = radius+(Math.sin(radians) * radius) |
|
225 | x_end -= 0.00001 if @data.length == 1 | |
|
225 | 226 | y_end = radius-(Math.cos(radians) * radius) |
|
226 | 227 | path = "M#{radius},#{radius} L#{x_start},#{y_start} "+ |
|
227 | 228 | "A#{radius},#{radius} "+ |
@@ -257,7 +258,7 module SVG | |||
|
257 | 258 | ty = -(Math.cos(radians) * expand_gap) |
|
258 | 259 | translate = "translate( #{tx} #{ty} )" |
|
259 | 260 | wedge.attributes["transform"] = translate |
|
260 | clear.attributes["transform"] = translate | |
|
261 | clear.attributes["transform"] = translate if clear | |
|
261 | 262 | end |
|
262 | 263 | |
|
263 | 264 | if show_shadow |
@@ -88,11 +88,13 module SVG | |||
|
88 | 88 | class Plot < Graph |
|
89 | 89 | |
|
90 | 90 | # In addition to the defaults set by Graph::initialize, sets |
|
91 | # [show_data_values] true | |
|
91 | 92 | # [show_data_points] true |
|
92 | 93 | # [area_fill] false |
|
93 | 94 | # [stacked] false |
|
94 | 95 | def set_defaults |
|
95 | 96 | init_with( |
|
97 | :show_data_values => true, | |
|
96 | 98 | :show_data_points => true, |
|
97 | 99 | :area_fill => false, |
|
98 | 100 | :stacked => false |
@@ -238,7 +240,11 module SVG | |||
|
238 | 240 | def field_height |
|
239 | 241 | values = get_y_values |
|
240 | 242 | max = @data.collect{|x| x[:data][Y].max }.max |
|
243 | if values.length == 1 | |
|
244 | dx = values[-1] | |
|
245 | else | |
|
241 | 246 | dx = (max - values[-1]).to_f / (values[-1] - values[-2]) |
|
247 | end | |
|
242 | 248 | (@graph_height.to_f - font_size*2*top_font) / |
|
243 | 249 |
|
|
244 | 250 | end |
@@ -290,7 +296,7 module SVG | |||
|
290 | 296 | }) |
|
291 | 297 | add_popup(x, y, format( x_points[idx], y_points[idx] )) if add_popups |
|
292 | 298 | end |
|
293 | make_datapoint_text( x, y-6, y_points[idx] ) | |
|
299 | make_datapoint_text( x, y-6, y_points[idx] ) if show_data_values | |
|
294 | 300 | } |
|
295 | 301 | end |
|
296 | 302 | line += 1 |
@@ -145,7 +145,7 module SVG | |||
|
145 | 145 | def add_data data |
|
146 | 146 | @data = [] unless @data |
|
147 | 147 | |
|
148 |
raise "No data provided by #{ |
|
|
148 | raise "No data provided by #{@data.inspect}" unless data[:data] and | |
|
149 | 149 | data[:data].kind_of? Array |
|
150 | 150 | raise "Data supplied must be x,y pairs! "+ |
|
151 | 151 | "The data provided contained an odd set of "+ |
@@ -191,13 +191,13 module SVG | |||
|
191 | 191 | rv = [] |
|
192 | 192 | min, max, scale_division = x_range |
|
193 | 193 | if timescale_divisions |
|
194 |
timescale_divisions =~ /(\d+) ?(day |
|
|
195 |
division_units = $2 ? $2 : "day |
|
|
194 | timescale_divisions =~ /(\d+) ?(day|week|month|year|hour|minute|second)?/ | |
|
195 | division_units = $2 ? $2 : "day" | |
|
196 | 196 | amount = $1.to_i |
|
197 | 197 | if amount |
|
198 | 198 | step = nil |
|
199 | 199 | case division_units |
|
200 |
when "month |
|
|
200 | when "month" | |
|
201 | 201 | cur = min |
|
202 | 202 | while cur < max |
|
203 | 203 | rv << cur |
@@ -209,7 +209,7 module SVG | |||
|
209 | 209 | end |
|
210 | 210 | cur = Time.local(*arr).to_i |
|
211 | 211 | end |
|
212 |
when "year |
|
|
212 | when "year" | |
|
213 | 213 | cur = min |
|
214 | 214 | while cur < max |
|
215 | 215 | rv << cur |
@@ -217,15 +217,15 module SVG | |||
|
217 | 217 | arr[5] += amount |
|
218 | 218 | cur = Time.local(*arr).to_i |
|
219 | 219 | end |
|
220 |
when "week |
|
|
220 | when "week" | |
|
221 | 221 | step = 7 * 24 * 60 * 60 * amount |
|
222 |
when "day |
|
|
222 | when "day" | |
|
223 | 223 | step = 24 * 60 * 60 * amount |
|
224 |
when "hour |
|
|
224 | when "hour" | |
|
225 | 225 | step = 60 * 60 * amount |
|
226 |
when "minute |
|
|
226 | when "minute" | |
|
227 | 227 | step = 60 * amount |
|
228 |
when "second |
|
|
228 | when "second" | |
|
229 | 229 | step = amount |
|
230 | 230 | end |
|
231 | 231 | min.step( max, step ) {|v| rv << v} if step |
General Comments 0
You need to be logged in to leave comments.
Login now