获取圆扇区的中心坐标

时间:2021-02-01 14:46:12

标签: javascript math svg geometry

我需要在 svg <text> 中饼图段的中心设置 <circle> 元素。现在我使用这个公式作为坐标:

x(t) = r cos(t) + j
y(t) = r sin(t) + j 

其中 t 必须是弧度。实际上,第一点效果很好。但接下来的观点是错误的(见代码片段)。问题是我使用了错误的公式吗?

这是我对 <text> 坐标的计算

var textAngle = ((data[c].value/100) *360)/2  + textAngleOffset;
var radians = degrees_to_radians(textAngle);
text.setAttribute("x", radius * Math.cos(radians) + 188.5 );
text.setAttribute("y", radius * Math.sin(radians) + 188.5);

//Pie chart plugin
function initPieChart(segmentsData) {
  
var data = [];
  
for (var i = 0; i < segmentsData.length; i++) {
  var percent = segmentsData[i].getAttribute('data-percent');
  var bgcolor = segmentsData[i].getAttribute('data-bg-color');
  var textcolor = segmentsData[i].getAttribute('data-text-color');
  data.push({"bgcolor": bgcolor, "textcolor": textcolor, "value" : Number(percent)});
}
  
var angle = -90; 
var textAngleOffset = -90; 

// Setup global variables
var svg = document.getElementById('pie-chart'),
    list = document.getElementById('pie-values'),
    totalValue = 0,
    radius = 94,
    circleLength = Math.PI * (radius * 2), // Circumference = PI * Diameter
    spaceLeft = circleLength;

// Get total value of all data.
for (var i = 0; i < data.length; i++) {
  totalValue += data[i].value;
}
  
function degrees_to_radians(degrees){
  var pi = Math.PI;
  return degrees * (pi/180);
}

function animate(circle, segmentLength, circleLength) {
 // circle.setAttribute("stroke-dasharray", spaceLeft + " " + circleLength);
  circle.setAttribute("stroke-dasharray", circleLength *segmentLength + " " + circleLength);
}
  var segmentOffset = 0;
  var animationDelay = 0;

// Loop trough data to create pie
for (var c = 0; c < data.length; c++) {
  
  var segmentLength = data[c].value/100; 
  var angleOffset = (data[c].value) *360 + angle;
  animationDelay = animationDelay + 800;
  
  if(c>0) {
    segmentOffset = segmentOffset -data[c-1].value/100*circleLength;
    textAngleOffset = (data[c].value/100) *360 + textAngleOffset;
  }
  
  
  // Create circle
  var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
  // Create group for each segment
  var group = document.createElementNS("http://www.w3.org/2000/svg", "g");
  group.classList.add("segment-group");
  //Create text
  var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
  var textAngle = ((data[c].value/100) *360)/2  + textAngleOffset;

  
    var radians = degrees_to_radians(textAngle);
  
  text.setAttribute("x", radius * Math.cos(radians) + 188.5 );
  text.setAttribute("y", radius * Math.sin(radians) + 188.5);
  text.setAttribute("text-anchor", "middle");
  text.setAttribute("fill", data[c].textcolor);
  text.innerHTML = data[c].value + '%';
  
  
  // Set attributes (self explanatory)
  circle.setAttribute("class", "pie-chart-value");
  circle.setAttribute("cx", 188.5);
  circle.setAttribute("cy", 188.5); 
  circle.setAttribute("r", radius);
  circle.setAttribute("transform", "rotate(" + angleOffset + ", 188.5, 188.5)"); 
  
  // Set dash on circle
  circle.setAttribute("stroke-dasharray", "0" + " " + circleLength);
  setTimeout(animate, animationDelay, circle, segmentLength, circleLength);
  if(c>0) {
    circle.setAttribute("stroke-dashoffset", segmentOffset);
  }
  
  // Set Stroke color
  circle.style.stroke = data[c].bgcolor;
  
  //Append circle and text to group
  group.appendChild(circle);
  group.appendChild(text);
  
  // Append group to svg.
  svg.appendChild(group);
  
}
  
}



//Pie chart call
var chartSegments = document.getElementsByClassName('pie-segment');
initPieChart(chartSegments);
/* Pie chart styles */

.pie-chart-value {
  fill: none;
  stroke-width: 188.5;
  transition: stroke-dasharray 800ms linear;
}

/* */
.time-statistics {
  padding-top: 30px;
}
.chart-value {
  position: relative;
  margin-bottom: 5px;
}
.chart-value:before {
  display: none;
}
.chart-value .dot {
  width: 8px;
  height: 8px;
  border-radius: 100%;
  margin-right: 10px;
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
}

.pie-chart-container {
  position: relative;
}

.pie-chart-bg {
    position: absolute;
    top: 0px;
    left: 0;
    z-index: -1;
}

.pie-chart-content {
    position: absolute;
    top: 0px;
    left: 0px;
}
<div class="pie-chart-container">
  <span class="pie-segment" data-percent="20" data-bg-color="#d8d8d8" data-text-color="#123431"></span>
  <span class="pie-segment" data-percent="40" data-bg-color="#345a57" data-text-color="white"></span>
  <span class="pie-segment" data-percent="40" data-bg-color="#133532" data-text-color="white"></span>
  
  
  <div class="pie-chart-content">
    <svg id="pie-chart" width="377" height="377"></svg>
  </div>
</div>

1 个答案:

答案 0 :(得分:1)

您需要调整前一个值的 textoffset,而不是当前值。即:

textAngleOffset = (data[c-1].value/100) *360 + textAngleOffset;

这是工作代码:

//Pie chart plugin
function initPieChart(segmentsData) {
  
var data = [];
  
for (var i = 0; i < segmentsData.length; i++) {
  var percent = segmentsData[i].getAttribute('data-percent');
  var bgcolor = segmentsData[i].getAttribute('data-bg-color');
  var textcolor = segmentsData[i].getAttribute('data-text-color');
  data.push({"bgcolor": bgcolor, "textcolor": textcolor, "value" : Number(percent)});
}
  
var angle = -90; 
var textAngleOffset = -90; 

// Setup global variables
var svg = document.getElementById('pie-chart'),
    list = document.getElementById('pie-values'),
    totalValue = 0,
    radius = 94,
    circleLength = Math.PI * (radius * 2), // Circumference = PI * Diameter
    spaceLeft = circleLength;

// Get total value of all data.
for (var i = 0; i < data.length; i++) {
  totalValue += data[i].value;
}
  
function degrees_to_radians(degrees){
  var pi = Math.PI;
  return degrees * (pi/180);
}

function animate(circle, segmentLength, circleLength) {
 // circle.setAttribute("stroke-dasharray", spaceLeft + " " + circleLength);
  circle.setAttribute("stroke-dasharray", circleLength *segmentLength + " " + circleLength);
}
  var segmentOffset = 0;
  var animationDelay = 0;

// Loop trough data to create pie
for (var c = 0; c < data.length; c++) {
  
  var segmentLength = data[c].value/100; 
  var angleOffset = (data[c].value) *360 + angle;
  animationDelay = animationDelay + 800;
  
  if(c>0) {
    segmentOffset = segmentOffset -data[c-1].value/100*circleLength;

    textAngleOffset = (data[c-1].value/100) *360 + textAngleOffset;
  }
  
  
  // Create circle
  var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
  // Create group for each segment
  var group = document.createElementNS("http://www.w3.org/2000/svg", "g");
  group.classList.add("segment-group");
  //Create text
  var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
  var textAngle = ((data[c].value/100) *360)/2  + textAngleOffset;

  
    var radians = degrees_to_radians(textAngle);
  
  text.setAttribute("x", radius * Math.cos(radians) + 188.5 );
  text.setAttribute("y", radius * Math.sin(radians) + 188.5);
  text.setAttribute("text-anchor", "middle");
  text.setAttribute("fill", data[c].textcolor);
  text.innerHTML = data[c].value + '%';
  
  
  // Set attributes (self explanatory)
  circle.setAttribute("class", "pie-chart-value");
  circle.setAttribute("cx", 188.5);
  circle.setAttribute("cy", 188.5); 
  circle.setAttribute("r", radius);
  circle.setAttribute("transform", "rotate(" + angleOffset + ", 188.5, 188.5)"); 
  
  // Set dash on circle
  circle.setAttribute("stroke-dasharray", "0" + " " + circleLength);
  setTimeout(animate, animationDelay, circle, segmentLength, circleLength);
  if(c>0) {
    circle.setAttribute("stroke-dashoffset", segmentOffset);
  }
  
  // Set Stroke color
  circle.style.stroke = data[c].bgcolor;
  
  //Append circle and text to group
  group.appendChild(circle);
  group.appendChild(text);
  
  // Append group to svg.
  svg.appendChild(group);
  
}
  
}



//Pie chart call
var chartSegments = document.getElementsByClassName('pie-segment');
initPieChart(chartSegments);
/* Pie chart styles */

.pie-chart-value {
  fill: none;
  stroke-width: 188.5;
  transition: stroke-dasharray 800ms linear;
}

/* */
.time-statistics {
  padding-top: 30px;
}
.chart-value {
  position: relative;
  margin-bottom: 5px;
}
.chart-value:before {
  display: none;
}
.chart-value .dot {
  width: 8px;
  height: 8px;
  border-radius: 100%;
  margin-right: 10px;
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
}

.pie-chart-container {
  position: relative;
}

.pie-chart-bg {
    position: absolute;
    top: 0px;
    left: 0;
    z-index: -1;
}

.pie-chart-content {
    position: absolute;
    top: 0px;
    left: 0px;
}
<div class="pie-chart-container">
  <span class="pie-segment" data-percent="20" data-bg-color="#d8d8d8" data-text-color="#123431"></span>
  <span class="pie-segment" data-percent="40" data-bg-color="#345a57" data-text-color="white"></span>
  <span class="pie-segment" data-percent="40" data-bg-color="#133532" data-text-color="white"></span>
  
  
  <div class="pie-chart-content">
    <svg id="pie-chart" width="377" height="377"></svg>
  </div>
</div>

相关问题