带 ruby​​ 的 SVG 饼图

发布于 2024-10-06 06:21:49 字数 1497 浏览 3 评论 0原文

我尝试生成一小段代码来为我构建一个 SVG 饼图,如下所示:

# 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>" }

问题是,如果我提供它,比如说 50% (ruby piechart-svg.rb 50),产生的楔形小于圆的一半。我不明白为什么。

I've tried to produce a small block of code which would construct for me a SVG piechart, listed below:

# 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>" }

The trouble is, if I feed it, say, 50% (ruby piechart-svg.rb 50), the produced wedge is less than half of the circle. I don't understand why.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猥︴琐丶欲为 2024-10-13 06:21:49

您已经将度数向后转换为弧度。应该是:

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

请注意,如果任何切片大于 50%,您仍然会遇到问题,但这与这个问题是分开的。 :)

You have your degrees to radians conversion backwards. Should be:

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

Note that you still have problems if any slice is greater than 50%, but that's separate from this question. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文