### Eclipse Workspace Patch 1.0 #P Redmine Index: lib/SVG/Graph/Plot.rb =================================================================== --- lib/SVG/Graph/Plot.rb (revision 2632) +++ lib/SVG/Graph/Plot.rb (working copy) @@ -88,16 +88,18 @@ class Plot < Graph # In addition to the defaults set by Graph::initialize, sets + # [show_data_values] true # [show_data_points] true # [area_fill] false # [stacked] false def set_defaults init_with( - :show_data_points => true, - :area_fill => false, - :stacked => false - ) - self.top_align = self.right_align = self.top_font = self.right_font = 1 + :show_data_values => true, + :show_data_points => true, + :area_fill => false, + :stacked => false + ) + self.top_align = self.right_align = self.top_font = self.right_font = 1 end # Determines the scaling for the X axis divisions. @@ -128,20 +130,20 @@ # Set the minimum value of the Y axis attr_accessor :min_y_value - + # Adds data to the plot. The data must be in X,Y pairs; EG # [ 1, 2 ] # A data set with 1 point: (1,2) # [ 1,2, 5,6] # A data set with 2 points: (1,2) and (5,6) def add_data data @data = [] unless @data - + raise "No data provided by #{conf.inspect}" unless data[:data] and - data[:data].kind_of? Array + data[:data].kind_of? Array raise "Data supplied must be x,y pairs! "+ "The data provided contained an odd set of "+ "data points" unless data[:data].length % 2 == 0 return if data[:data].length == 0 - + x = [] y = [] data[:data].each_index {|i| @@ -205,7 +207,7 @@ max = @data.collect{|x| x[:data][X][-1]}.max dx = (max - values[-1]).to_f / (values[-1] - values[-2]) (@graph_width.to_f - font_size*2*right_font) / - (values.length + dx - right_align) + (values.length + dx - right_align) end @@ -238,14 +240,18 @@ def field_height values = get_y_values max = @data.collect{|x| x[:data][Y].max }.max - dx = (max - values[-1]).to_f / (values[-1] - values[-2]) + if values.length == 1 + dx = values[-1] + else + dx = (max - values[-1]).to_f / (values[-1] - values[-2]) + end (@graph_height.to_f - font_size*2*top_font) / - (values.length + dx - top_align) + (values.length + dx - top_align) end def draw_data line = 1 - + x_min, x_max, x_div = x_range y_min, y_max, y_div = y_range x_step = (@graph_width.to_f - font_size*2) / (x_max-x_min) @@ -290,7 +296,7 @@ }) add_popup(x, y, format( x_points[idx], y_points[idx] )) if add_popups end - make_datapoint_text( x, y-6, y_points[idx] ) + make_datapoint_text( x, y-6, y_points[idx] ) if show_data_values } end line += 1 Index: lib/SVG/Graph/BarHorizontal.rb =================================================================== --- lib/SVG/Graph/BarHorizontal.rb (revision 2632) +++ lib/SVG/Graph/BarHorizontal.rb (working copy) @@ -103,28 +103,41 @@ def draw_data minvalue = min_value fieldheight = field_height - fieldwidth = (@graph_width.to_f - font_size*2*right_font ) / + + unit_size = (@graph_width.to_f - font_size*2*right_font ) / (get_x_labels.max - get_x_labels.min ) bargap = bar_gap ? (fieldheight < 10 ? fieldheight / 2 : 10) : 0 - subbar_height = fieldheight - bargap - subbar_height /= @data.length if stack == :side + bar_height = fieldheight - bargap + bar_height /= @data.length if stack == :side + y_mod = (bar_height / 2) + (font_size / 2) field_count = 1 - y_mod = (subbar_height / 2) + (font_size / 2) @config[:fields].each_index { |i| dataset_count = 0 for dataset in @data - y = @graph_height - (fieldheight * field_count) - y += (subbar_height * dataset_count) if stack == :side - x = (dataset[:data][i] - minvalue) * fieldwidth + value = dataset[:data][i] + + top = @graph_height - (fieldheight * field_count) + top += (bar_height * dataset_count) if stack == :side + # cases (assume 0 = +ve): + # value min length left + # +ve +ve value.abs - min minvalue.abs + # +ve -ve value.abs - 0 minvalue.abs + # -ve -ve value.abs - 0 minvalue.abs + value + length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size + left = (minvalue.abs + (value < 0 ? value : 0)) * unit_size - @graph.add_element( "path", { - "d" => "M0 #{y} H#{x} v#{subbar_height} H0 Z", + @graph.add_element( "rect", { + "x" => left.to_s, + "y" => top.to_s, + "width" => length.to_s, + "height" => bar_height.to_s, "class" => "fill#{dataset_count+1}" }) + make_datapoint_text( - x+5, y+y_mod, dataset[:data][i], "text-anchor: start; " + left+length+5, top+y_mod, value, "text-anchor: start; " ) dataset_count += 1 end Index: lib/SVG/Graph/Pie.rb =================================================================== --- lib/SVG/Graph/Pie.rb (revision 2632) +++ lib/SVG/Graph/Pie.rb (working copy) @@ -222,6 +222,7 @@ y_start = radius-(Math.cos(radians) * radius) radians = (prev_percent+percent) * rad_mult x_end = radius+(Math.sin(radians) * radius) + x_end -= 0.00001 if @data.length == 1 y_end = radius-(Math.cos(radians) * radius) path = "M#{radius},#{radius} L#{x_start},#{y_start} "+ "A#{radius},#{radius} "+ @@ -257,7 +258,7 @@ ty = -(Math.cos(radians) * expand_gap) translate = "translate( #{tx} #{ty} )" wedge.attributes["transform"] = translate - clear.attributes["transform"] = translate + clear.attributes["transform"] = translate if clear end if show_shadow Index: lib/SVG/Graph/Bar.rb =================================================================== --- lib/SVG/Graph/Bar.rb (revision 2632) +++ lib/SVG/Graph/Bar.rb (working copy) @@ -96,37 +96,48 @@ end def draw_data - fieldwidth = field_width - maxvalue = max_value minvalue = min_value + fieldwidth = field_width - fieldheight = (@graph_height.to_f - font_size*2*top_font) / + unit_size = (@graph_height.to_f - font_size*2*top_font) / (get_y_labels.max - get_y_labels.min) bargap = bar_gap ? (fieldwidth < 10 ? fieldwidth / 2 : 10) : 0 - subbar_width = fieldwidth - bargap - subbar_width /= @data.length if stack == :side - x_mod = (@graph_width-bargap)/2 - (stack==:side ? subbar_width/2 : 0) - # Y1 - p2 = @graph_height - # to X2 + bar_width = fieldwidth - bargap + bar_width /= @data.length if stack == :side + x_mod = (@graph_width-bargap)/2 - (stack==:side ? bar_width/2 : 0) + + bottom = @graph_height + field_count = 0 @config[:fields].each_index { |i| dataset_count = 0 for dataset in @data - # X1 - p1 = (fieldwidth * field_count) - # to Y2 - p3 = @graph_height - ((dataset[:data][i] - minvalue) * fieldheight) - p1 += subbar_width * dataset_count if stack == :side - @graph.add_element( "path", { - "class" => "fill#{dataset_count+1}", - "d" => "M#{p1} #{p2} V#{p3} h#{subbar_width} V#{p2} Z" + + # cases (assume 0 = +ve): + # value min length + # +ve +ve value - min + # +ve -ve value - 0 + # -ve -ve value.abs - 0 + + value = dataset[:data][i] + + left = (fieldwidth * field_count) + + length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size + # top is 0 if value is negative + top = bottom - (((value < 0 ? 0 : value) - minvalue) * unit_size) + left += bar_width * dataset_count if stack == :side + + @graph.add_element( "rect", { + "x" => left.to_s, + "y" => top.to_s, + "width" => bar_width.to_s, + "height" => length.to_s, + "class" => "fill#{dataset_count+1}" }) - make_datapoint_text( - p1 + subbar_width/2.0, - p3 - 6, - dataset[:data][i].to_s) + + make_datapoint_text(left + bar_width/2.0, top - 6, value.to_s) dataset_count += 1 end field_count += 1 Index: lib/SVG/Graph/TimeSeries.rb =================================================================== --- lib/SVG/Graph/TimeSeries.rb (revision 2632) +++ lib/SVG/Graph/TimeSeries.rb (working copy) @@ -145,7 +145,7 @@ def add_data data @data = [] unless @data - raise "No data provided by #{conf.inspect}" unless data[:data] and + raise "No data provided by #{@data.inspect}" unless data[:data] and data[:data].kind_of? Array raise "Data supplied must be x,y pairs! "+ "The data provided contained an odd set of "+ @@ -191,13 +191,13 @@ rv = [] min, max, scale_division = x_range if timescale_divisions - timescale_divisions =~ /(\d+) ?(days|weeks|months|years|hours|minutes|seconds)?/ - division_units = $2 ? $2 : "days" + timescale_divisions =~ /(\d+) ?(day|week|month|year|hour|minute|second)?/ + division_units = $2 ? $2 : "day" amount = $1.to_i if amount step = nil case division_units - when "months" + when "month" cur = min while cur < max rv << cur @@ -209,7 +209,7 @@ end cur = Time.local(*arr).to_i end - when "years" + when "year" cur = min while cur < max rv << cur @@ -217,15 +217,15 @@ arr[5] += amount cur = Time.local(*arr).to_i end - when "weeks" + when "week" step = 7 * 24 * 60 * 60 * amount - when "days" + when "day" step = 24 * 60 * 60 * amount - when "hours" + when "hour" step = 60 * 60 * amount - when "minutes" + when "minute" step = 60 * amount - when "seconds" + when "second" step = amount end min.step( max, step ) {|v| rv << v} if step Index: lib/SVG/Graph/BarBase.rb =================================================================== --- lib/SVG/Graph/BarBase.rb (revision 2632) +++ lib/SVG/Graph/BarBase.rb (working copy) @@ -43,18 +43,17 @@ protected def max_value - return @data.collect{|x| x[:data].max}.max + @data.collect{|x| x[:data].max}.max end def min_value min = 0 - - if (min_scale_value.nil? == false) then + if min_scale_value.nil? + min = @data.collect{|x| x[:data].min}.min + min = min > 0 ? 0 : min + else min = min_scale_value - else - min = @data.collect{|x| x[:data].min}.min end - return min end Index: lib/SVG/Graph/Graph.rb =================================================================== --- lib/SVG/Graph/Graph.rb (revision 2632) +++ lib/SVG/Graph/Graph.rb (working copy) @@ -105,12 +105,12 @@ init_with({ :width => 500, - :height => 300, + :height => 300, :show_x_guidelines => false, :show_y_guidelines => true, :show_data_values => true, - :min_scale_value => 0, +# :min_scale_value => 0, :show_x_labels => true, :stagger_x_labels => false, @@ -137,14 +137,14 @@ :key => true, :key_position => :right, # bottom or right - :font_size =>10, - :title_font_size =>12, + :font_size =>12, + :title_font_size =>16, :subtitle_font_size =>14, - :x_label_font_size =>11, + :x_label_font_size =>12, :x_title_font_size =>14, - :y_label_font_size =>11, + :y_label_font_size =>12, :y_title_font_size =>14, - :key_font_size => 9, + :key_font_size =>10, :no_css =>false, :add_popups =>false, @@ -392,7 +392,7 @@ @border_right = 7 if key and key_position == :right val = keys.max { |a,b| a.length <=> b.length } - @border_right += val.length * key_font_size * 0.7 + @border_right += val.length * key_font_size * 0.6 @border_right += KEY_BOX_SIZE @border_right += 10 # Some padding around the box end @@ -421,7 +421,7 @@ t.attributes["style"] = "fill: #000; "+ (x+txt_width > width ? "text-anchor: end;" : "text-anchor: start;") t.text = label.to_s - t.attributes["id"] = t.id.to_s + t.attributes["id"] = t.object_id.to_s @foreground.add_element( "circle", { "cx" => x.to_s, @@ -429,9 +429,9 @@ "r" => "10", "style" => "opacity: 0", "onmouseover" => - "document.getElementById(#{t.id}).setAttribute('visibility', 'visible' )", + "document.getElementById(#{t.object_id}).setAttribute('visibility', 'visible' )", "onmouseout" => - "document.getElementById(#{t.id}).setAttribute('visibility', 'hidden' )", + "document.getElementById(#{t.object_id}).setAttribute('visibility', 'hidden' )", }) end @@ -446,11 +446,11 @@ @border_bottom += 10 end if show_x_labels - max_x_label_height_px = rotate_x_labels ? + max_x_label_height_px = (not rotate_x_labels) ? + x_label_font_size : get_x_labels.max{|a,b| - a.length<=>b.length - }.length * x_label_font_size * 0.6 : - x_label_font_size + a.to_s.length<=>b.to_s.length + }.to_s.length * x_label_font_size * 0.6 @border_bottom += max_x_label_height_px @border_bottom += max_x_label_height_px + 10 if stagger_x_labels end @@ -723,7 +723,7 @@ }) group.add_element( "text", { "x" => (KEY_BOX_SIZE + 5).to_s, - "y" => (y_offset + KEY_BOX_SIZE - 2).to_s, + "y" => (y_offset + KEY_BOX_SIZE).to_s, "class" => "keyText" }).text = key_name.to_s key_count += 1 @@ -737,10 +737,11 @@ x_offset = @border_left + 20 y_offset = @border_top + @graph_height + 5 if show_x_labels - max_x_label_height_px = rotate_x_labels ? - get_x_labels.max{|a,b| - a.length<=>b.length - }.length * x_label_font_size : + max_x_label_height_px = (not rotate_x_labels) ? + x_label_font_size : + get_x_labels.max{|a,b| + a.to_s.length<=>b.to_s.length + }.to_s.length * x_label_font_size * 0.6 x_label_font_size y_offset += max_x_label_height_px y_offset += max_x_label_height_px + 5 if stagger_x_labels @@ -883,41 +884,41 @@ fill:#ffffff; } .graphBackground{ - fill:#f5f5f5; + fill:#f0f0f0; } /* graphs titles */ .mainTitle{ text-anchor: middle; - fill: #555555; + fill: #000000; font-size: #{title_font_size}px; - font-family: "Verdana", sans-serif; - font-weight: bold; + font-family: "Arial", sans-serif; + font-weight: normal; } .subTitle{ text-anchor: middle; fill: #999999; font-size: #{subtitle_font_size}px; - font-family: "Verdana", sans-serif; + font-family: "Arial", sans-serif; font-weight: normal; } .axis{ - stroke: #666666; + stroke: #000000; stroke-width: 1px; } .guideLines{ stroke: #666666; stroke-width: 1px; - stroke-dasharray:2,2,2; + stroke-dasharray: 5 5; } .xAxisLabels{ text-anchor: middle; fill: #000000; font-size: #{x_label_font_size}px; - font-family: "Verdana", sans-serif; + font-family: "Arial", sans-serif; font-weight: normal; } @@ -925,7 +926,7 @@ text-anchor: end; fill: #000000; font-size: #{y_label_font_size}px; - font-family: "Verdana", sans-serif; + font-family: "Arial", sans-serif; font-weight: normal; } @@ -933,7 +934,7 @@ text-anchor: middle; fill: #ff0000; font-size: #{x_title_font_size}px; - font-family: "Verdana", sans-serif; + font-family: "Arial", sans-serif; font-weight: normal; } @@ -941,7 +942,7 @@ fill: #ff0000; text-anchor: middle; font-size: #{y_title_font_size}px; - font-family: "Verdana", sans-serif; + font-family: "Arial", sans-serif; font-weight: normal; } @@ -949,7 +950,7 @@ fill: #000000; text-anchor:middle; font-size: 10px; - font-family: "Verdana", sans-serif; + font-family: "Arial", sans-serif; font-weight: normal; } @@ -965,7 +966,7 @@ fill: #000000; text-anchor:start; font-size: #{key_font_size}px; - font-family: "Verdana", sans-serif; + font-family: "Arial", sans-serif; font-weight: normal; } /* End copy for external style sheet */