Математика для создания SVG p ie диаграммы без использования CSS или JS - PullRequest
2 голосов
/ 26 января 2020

Я пытаюсь создать график ap ie в чистом SVG. Я не хочу использовать JS или CSS, которые использует большинство решений на этом сайте. Я наткнулся на эту замечательную статью, в которой объясняется, как создать диаграмму ap ie в чистом SVG: https://seesparkbox.com/foundry/how_to_code_an_SVG_pie_chart

Проблема состоит в том, что в этой статье описывается только один фрагмент. Я пытаюсь создать диаграмму ap ie, которая может содержать максимум 360 элементов (в которой каждый фрагмент p ie будет составлять 0,27% от него).

Я пытался для создания другого клина в следующем примере, повернув его на -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>

Мне было интересно, есть ли какая-нибудь математика, которую мне нужно сделать, чтобы вычислить правильный угол и перевод, чтобы синий клин появился рядом с красным.

Ответы [ 2 ]

2 голосов
/ 27 января 2020

К сожалению, calc() для вычисления атрибута stroke-dasharray работает только в Chrome

Для кросс-браузерного решения необходимо рассчитать и присвоить значения в штрих-dasharray.

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>

Для двух сегментов:

  1. красный = "35%"
  2. синий = "15%" stroke-dasharray = 31.4 * 0.15, 31.4 или stroke-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>

Мы видим, что синий сектор перекрывает красный сектор; поэтому необходимо сместить синий сектор на величину, равную длине красного сектора 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>

Четыре сектора

Решение работает во всех современных браузерах, включая 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>
1 голос
/ 26 января 2020

Один простой способ решить вашу проблему - использовать другой viewBox: "-10 -10 20 20", сделав точку 0,0 центром холста SVG. Обратите внимание, что вам больше не нужны атрибуты cx и cy, и преобразование только вращается.

Я полагаю, что вы хотите разделить круг на 100 частей. В этом случае вам нужно повернуть второй круг на -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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...