2010-12-05 42 views
0

j'ai essayé de produire un petit bloc de code qui construirait pour moi une piechart SVG, ci-dessous:SVG piechart avec Ruby

# piechart-svg.rb: 
BEGIN { 
    @colors = [] 
    both = %w(coral grey green salmon blue seagreen slategrey cyan) 
    darks = %w(magenta red olivegreen orange turquoise goldenrod khaki orchid slateblue violet) 
    lights = %w(steelblue yellow skyblue pink goldenrodyellow) 
    @colors << both.map {|c| [c, "light#{c}", "dark#{c}"] } 
    @colors << darks.map {|c| [c, "dark#{c}"] } 
    @colors << lights.map {|c| [c, "light#{c}"] } 
    @colors.flatten! 

    @radius = 100.0 
    @prevcoord = "#{@radius},0" 
    puts <<-EOF 
<?xml version="1.0" standalone="no" ?> 
<svg xmlns="http://www.w3.org/2000/svg" 
    preserveAspectRatio="xMinYMin" 
    viewBox="-#{@radius},-#{@radius} #{@radius*2},#{@radius*2}"> 
    <defs> 
    <style> 
     .wedge { stroke: darkgrey; stroke-linejoin: round; fill-opacity: .2; } 
    </style> 
    </defs> 
    EOF 
} 

ARGV.each_with_index do |percent,index| 
    print " <path class=\"wedge\" fill=\"#{@colors[index]}\" d=\"" 
    angle_as_degrees = percent.to_f/100 * 360 
    x = Math::cos(angle_as_degrees * 180/Math::PI) * @radius 
    y = Math::sin(angle_as_degrees * 180/Math::PI) * @radius 
    print "M#{@prevcoord} A#{@radius},#{@radius} 0 0,1 #{x},#{y} L0,0 Z\" />\n" 
    @prevcoord = "#{x},#{y}" 
end 

END { puts " <circle fill=\"none\" stroke=\"black\" r=\"#{@radius}\" /> 
</svg>" } 

Le problème est, si je le nourrir, disons, 50% (ruby piechart-svg.rb 50), la cale produite est inférieure à la moitié du cercle. Je ne comprends pas pourquoi.

+0

Pour une prochaine question, vous pourriez réduire légèrement votre code de test. Les couleurs et les styles, par exemple, ne servent pas à illustrer le problème. – Phrogz

Répondre

1

Vous faites reculer vos degrés en radians. Devrait être:

x = Math::cos(angle_as_degrees * Math::PI/180) * @radius 
y = Math::sin(angle_as_degrees * Math::PI/180) * @radius 

Notez que vous avez encore des problèmes si une tranche est supérieure à 50%, mais c'est séparé de cette question. :)