简体   繁体   English

无需使用 CSS 或 JS 即可创建 SVG 饼图的数学运算

[英]Math to create SVG pie chart without using CSS or JS

I am seeking to create a pie chart in pure SVG.我正在寻求在纯 SVG 中创建饼图。 I do not want to use JS or CSS, which most of the solutions on this site utilize.我不想使用 JS 或 CSS,本网站上的大多数解决方案都使用了它们。 I came across this great article that explains how to create a pie chart in pure SVG: https://seesparkbox.com/foundry/how_to_code_an_SVG_pie_chart我看到了这篇很棒的文章,它解释了如何在纯 SVG 中创建饼图: https : //seesparkbox.com/foundry/how_to_code_an_SVG_pie_chart

The problem is that this article only describes how to make only one slice.问题是这篇文章只介绍了如何只制作一个切片。 I am seeking to create a pie chart that can contain up to a maximum of 360 elements (in which each slice of the pie will be ‭0.27‬% of it).我正在寻求创建一个最多可包含 360 个元素的饼图(其中饼图的每个切片将是其中的 0.27%)。

I have attempted to create another wedge in the following example by rotating it to -89 instead of the -90, but I'm not getting the results I'm looking for: https://codepen.io/HexylCinnamal/pen/KKwEjpK我试图在以下示例中创建另一个楔形,方法是将其旋转到 -89 而不是 -90,但我没有得到我正在寻找的结果: https : //codepen.io/HexylCinnamal/pen/KKwEjpK

<svg xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" viewBox="0 0 20 20">
<circle r="10" cx="10" cy="10" fill="transparent"/>
<circle r="5" cx="10" cy="10" fill="transparent" stroke="tomato" stroke-width="10"
    stroke-dasharray="calc(1 * 31.4 / 100) 31.4" transform="rotate(-90) translate(-20)"/>
<circle r="5" cx="10" cy="10" fill="transparent" stroke="blue" stroke-width="10"
    stroke-dasharray="calc(1 * 31.4 / 100) 31.4" transform="rotate(-89) translate(-20)"/>
</svg>

I was wondering if there is any math I need to do to calculate the proper angle and translation to make the blue wedge appear next to the red one.我想知道是否需要做任何数学计算来计算正确的角度和平移,以使蓝色楔形出现在红色楔形旁边。

Unfortunately, calc() to calculate the attribute stroke-dasharray only works in Chrome不幸的是, calc()计算属性stroke-dasharray只适用于Chrome

For a cross-browser solution, it is necessary to calculate and assign values in the stroke-dasharray.对于跨浏览器的解决方案,需要在stroke-dasharray 中计算和赋值。

stroke-dasharray ="Circumference * 0.35, Circumference" or stroke-dasharray = "31.4 * 0.35, 31.4" or stroke-dasharray="10.99 31.4" stroke-dasharray ="Circumference * 0.35, Circumference"stroke-dasharray = "31.4 * 0.35, 31.4"stroke-dasharray="10.99 31.4"

 <svg height="20%" width="20%" viewBox="0 0 20 20" style="border:1px solid gray; "> <circle r="10" cx="10" cy="10" fill="white" /> <circle r="5" cx="10" cy="10" fill="bisque" stroke="tomato" stroke-width="10" stroke-dasharray="10.99 31.4" /> </svg>

For two segments:对于两个段:

  1. red="35%"红色="35%"
  2. blue="15%" stroke-dasharray = 31.4 * 0.15, 31.4 or stroke-dasharray ="4.71, 31.4" blue="15%" stroke-dasharray = 31.4 * 0.15, 31.4stroke-dasharray ="4.71, 31.4"

 <svg height="20%" width="20%" viewBox="0 0 20 20" style="border:1px solid; "> <circle r="10" cx="10" cy="10" fill="white" /> <circle r="5" cx="10" cy="10" fill="bisque" stroke="tomato" stroke-width="10" stroke-dasharray="10.99 31.4" /> <circle r="5" cx="10" cy="10" fill="bisque" stroke="dodgerblue" stroke-width="10" stroke-dasharray="4.71 31.4" /> </svg>

We see that the blue sector overlaps the red sector;我们看到蓝色部分与红色部分重叠; therefore, it is necessary to shift the blue sector by an amount equal to the length of the red sector 10.99因此,需要将蓝色扇区移动等于红色扇区长度10.99

Add to shift the blue sector stroke-dashoffset="-10.99"添加移动蓝色扇区stroke-dashoffset="-10.99"

 <svg height="20%" width="20%" viewBox="0 0 20 20" style="border:1px solid; "> <circle r="5" cx="10" cy="10" fill="bisque" /> <circle r="5" cx="10" cy="10" fill="transparent" stroke="tomato" stroke-width="10" stroke-dasharray="10.99 31.4" /> <circle r="5" cx="10" cy="10" fill="transparent" stroke="dodgerblue" stroke-width="10" stroke-dasharray="4.71 31.4" stroke-dashoffset="-10.99" /> </svg>

Four sectors四大板块

The solution works in all modern browsers including MS Edge该解决方案适用于所有现代浏览器,包括MS Edge

 <!-- https://seesparkbox.com/foundry/how_to_code_an_SVG_pie_chart --> <svg height="20%" width="20%" viewBox="0 0 20 20" style="border:1px solid; "> <circle r="5" cx="10" cy="10" fill="bisque" /> <circle r="5" cx="10" cy="10" fill="transparent" stroke="tomato" stroke-width="10" stroke-dasharray="10.99 31.4" /> <circle r="5" cx="10" cy="10" fill="transparent" stroke="dodgerblue" stroke-width="10" stroke-dasharray="4.71 31.4" stroke-dashoffset="-10.99" /> <circle r="5" cx="10" cy="10" fill="transparent" stroke="gold" stroke-width="10" stroke-dasharray="9.42 31.4" stroke-dashoffset="-15.7" /> <circle r="5" cx="10" cy="10" fill="transparent" stroke="yellowgreen" stroke-width="10" stroke-dasharray="6.28 31.4" stroke-dashoffset="-25.12" /> <text x="10" y="15" font-size="3px" fill="black" >35%</text> <text x="1" y="14" font-size="3px" fill="black" >15%</text> <text x="4" y="6" font-size="3px" fill="black" >30%</text> <text x="12" y="8" font-size="3px" fill="black" >20%</text> </svg>

One easy way to fix your problem is using a different viewBox : "-10 -10 20 20" making the point 0,0 the center of the svg canvas.解决问题的一种简单方法是使用不同的viewBox"-10 -10 20 20"使点0,0成为 svg 画布的中心。 Please observe that you don't need the cx and cy attributes anymore and the transformation is only rotating.请注意,您不再需要cxcy属性,并且变换只是旋转。

I'm supposing that you want to divide the circle in 100 parts.我假设你想把圆分成 100 份。 In this case you'll need to rotate the second circle -90 + 360/100 or -90 - 360/100 degs.在这种情况下,您需要将第二个圆旋转 -90 + 360/100 或 -90 - 360/100 度。

 circle{stroke-dasharray:calc(31.4 / 100) 31.4;}
 <svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 20 20"> <circle r="10" fill="transparent"/> <circle r="5" fill="transparent" stroke="tomato" stroke-width="10" transform="rotate(-90)"/> <circle r="5" fill="transparent" stroke="blue" stroke-width="10" transform="rotate(-86.4)"/> </svg>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM