Calculating SVG donut slice label position server side

跟風遠走 提交于 2020-01-16 09:05:12

问题


How can I calculate a slice text label to be positioned directly in the center of a slice in an svg donut chart?

I have an svg donut chart that is generated server side. I have the slices of the chart correctly implemented but I'm having some trouble figuring out the math to place each individual slice label inside the center of it's respective slice. The label will be the percentage of the slice it occupies.

This is a slimmed down version of the svg.

<svg width="100%" height="100%" viewBox="0 0 42 42">
  <circle cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#d2d3d4" stroke-width="3" />
  <circle
    cx="21"
    cy="21"
    r="15.91549430918954"
    fill="transparent"
    stroke="#b1c94e"
    stroke-width="3"
    stroke-dasharray="25 75"
    stroke-dashoffset="25"
  />
  <!-- How do I calculate x and y so the text is in the center of the above slice. -->
  <text x="80%" y="30%" font-size="6" text-anchor="middle">25%</text>
</svg>

Here's a jsfiddle of the svg. https://jsfiddle.net/xgyzvnka/


回答1:


This is how I would do it. Please change the value of the perc. Please read the comments in my code.

let r = 16;//circles radius
let perc = .15//percentage
//the angle used to draw the circle
let angle = 2*Math.PI * perc;
// the circle's circumference
let totalLength = base.getTotalLength();
//the length of the dash 
let length_perc = totalLength * perc;
//the length of the gap
let difference = totalLength * (1 - perc);

test.setAttributeNS(null,"stroke-dasharray",length_perc+", "+difference);
//rotate backwards 90degs. The center of rotation is the center of the circle; 21,21
test.setAttributeNS(null,"transform","rotate(-90,21,21)");

//the point where to draw the circle
let textPoint = {x:21 + r * Math.cos((angle - Math.PI)/2),
                 y:21 + r * Math.sin((angle - Math.PI)/2)}
text.setAttributeNS(null,"x",textPoint.x);
text.setAttributeNS(null,"y",textPoint.y);
//the text
text.textContent = perc * 100 + "%";
text{text-anchor:middle; dominant-baseline:middle;}
svg{width:90vh;}
<svg viewBox="0 0 42 42">
  <circle id="base" cx="21" cy="21" r="16" fill="transparent" stroke="#d2d3d4" stroke-width="3" />
  <circle id="test"
    cx="21"
    cy="21"
    r="16"
    fill="transparent"
    stroke="#b1c94e"
    stroke-width="3"
  />

  <text id="text"  font-size="6" text-anchor="middle"> </text>
</svg>


来源:https://stackoverflow.com/questions/56672591/calculating-svg-donut-slice-label-position-server-side

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!