module Rubyvis module SvgScene def self.area(scenes) e = scenes._g.elements[1] return e if scenes.size==0 s=scenes[0] # segmented */ return self.area_segment(scenes) if (s.segmented) # visible # return e if (!s.visible) fill = s.fill_style stroke = s.stroke_style return e if (fill.opacity==0 and stroke.opacity==0) # /** @private Computes the straight path for the range [i, j]. */ path=lambda {|i,j| p1 = [] p2 = []; k=j (i..k).each {|i| si = scenes[i] sj = scenes[j] pi = "#{si.left},#{si.top}" pj = "#{(sj.left + sj.width)},#{(sj.top + sj.height)}" #/* interpolate */ if (i < k) sk = scenes[i + 1] sl = scenes[j - 1] case (s.interpolate) when "step-before" pi = pi+"V#{sk.top}" pj = pj+"H#{sl.left + sl.width}" when "step-after" pi = pi+"H#{sk.left}" pj = pj+"V#{sl.top + sl.height}" end end p1.push(pi); p2.push(pj); j=j-1 } (p1+p2).join("L"); } # @private Computes the curved path for the range [i, j]. */ path_curve=lambda {|i, j| pointsT = [] pointsB = [] pathT=nil pathB=nil k=j (i..k).each {|i| sj = scenes[j]; pointsT.push(scenes[i]) pointsB.push(OpenStruct.new({:left=> sj.left + sj.width, :top=> sj.top + sj.height})) j=j-1 } if (s.interpolate == "basis") pathT = pv.SvgScene.curve_basis(pointsT); pathB = pv.SvgScene.curve_basis(pointsB); elsif (s.interpolate == "cardinal") pathT = pv.SvgScene.curve_cardinal(pointsT, s.tension); pathB = pv.SvgScene.curve_cardinal(pointsB, s.tension); elsif # monotone pathT = pv.SvgScene.curve_monotone(pointsT); pathB = pv.SvgScene.curve_monotone(pointsB); end "#{pointsT[0].left },#{ pointsT[0].top }#{ pathT }L#{ pointsB[0].left},#{pointsB[0].top}#{pathB}" } #/* points */ d = [] si=nil sj=nil i=0 while(i 2 and (s.interpolate == "basis" or s.interpolate == "cardinal" or s.interpolate == "monotone")) ? path_curve : path).call(i, j - 1)) i = j - 1 i+=1 end return e if d.size==0 e = self.expect(e, "path", { "shape-rendering"=> s.antialias ? nil : "crispEdges", "pointer-events"=> s.events, "cursor"=> s.cursor, "d"=> "M" + d.join("ZM") + "Z", "fill"=> fill.color, "fill-opacity"=> fill.opacity==0 ? nil : fill.opacity, "stroke"=> stroke.color, "stroke-opacity"=> stroke.opacity==0 ? nil : stroke.opacity, "stroke-width"=> stroke.opacity!=0 ? s.line_width / self.scale : nil }); return self.append(e, scenes, 0); end def self.area_segment(scenes) e = scenes._g.elements[1] s = scenes[0] pathsT=[] pathsB=[] if (s.interpolate == "basis" or s.interpolate == "cardinal" or s.interpolate == "monotone") pointsT = [] pointsB = [] n=scenes.size n.times {|i| sj = scenes[n - i - 1] pointsT.push(scenes[i]) pointsB.push(OpenStruct.new({:left=> sj.left + sj.width, :top=> sj.top + sj.height})); } if (s.interpolate == "basis") pathT = pv.SvgScene.curve_basis_segments(pointsT); pathB = pv.SvgScene.curve_basis_segments(pointsB); elsif (s.interpolate == "cardinal") pathT = pv.SvgScene.curve_cardinal_segments(pointsT, s.tension); pathB = pv.SvgScene.curve_cardinal_segments(pointsB, s.tension); elsif # monotone pathT = pv.SvgScene.curve_monotone_segments(pointsT); pathB = pv.SvgScene.curve_monotone_segments(pointsB); end end n=scenes.size-1 n.times {|i| s1 = scenes[i] s2 = scenes[i + 1] # /* visible */ next if (!s1.visible or !s2.visible) fill = s.fill_style stroke = s.stroke_style next e if (fill.opacity==0 and stroke.opacity==0) d=nil if (pathsT) pathT = pathsT[i] pb=pathsB[n - i - 1] pathB = "L" + pb[1,pb.size-1] d = pathT + pathB + "Z"; else #/* interpolate */ si = s1 sj = s2 case (s1.interpolate) when "step-before" si = s2 when "step-after" sj = s1 end #/* path */ d = "M#{s1.left},#{si.top}L#{s2.left},#{sj.top }L#{s2.left + s2.width},#{sj.top + sj.height}L#{s1.left + s1.width},#{si.top + si.height}Z" end e = self.expect(e, "path", { "shape-rendering"=> s1.antialias ? null : "crispEdges", "pointer-events"=> s1.events, "cursor"=> s1.cursor, "d"=> d, "fill"=> fill.color, "fill-opacity"=> fill.opacity==0 ? nil : fill.opacity, "stroke"=> stroke.color, "stroke-opacity"=> stroke.opacity==0 ? nil : stroke.opacity, "stroke-width"=> stroke.opacity!=0 ? s1.line_width / self.scale : nil }); e = self.append(e, scenes, i); } return e; end end end