具有数据值的dataLabels下如何计算X和Y坐标是动态的。
这是我的JSfiddle
https://jsfiddle.net/BlackLabel/ay5mbfew/

{
          name: 'Incorrect',
          legendColor: 'green',
          dataLabels: {
              enabled: true,
              zIndex: 3,
              y: -150,
              x: 90,
              borderWidth: 0,
              overflow: 'allow',
              style: {
                  fontSize: 60
              }
          },
          data: [{
              color: 'green',
              radius: '112%',
              innerRadius: '65%',
              y: 40
          }]
  }]


如果更改了值,则如何根据值计算x,y坐标,以使文本相应地显示在条形上

谢谢

最佳答案

可以以更简单的方式完成此类图表。我不是使用复杂的路径,而是使用带有stroke-dasharray和stroke-dashoffset的圆。

我在不使用Highcharts的情况下这样做-您可能不喜欢这样

另外,我建议删除线条的圆度,因为这会引起混淆。在我的代码中,如果要删除圆度,则需要从CSS中删除它:stroke-linecap: round;

请阅读我的代码中的注释。



var SVG_NS = 'http://www.w3.org/2000/svg';
let r = bg.getAttribute("r");//the radius of the chart

let items = [ {val:.17,color:"red"}, {val:.35,color:"hotpink"}, {val:.25,color:"gold"}, {val:.12,color:"skyblue"} ];//<--- change this

// the total length of the circle
let totalLength = bg.getTotalLength()


for(let i = items.length-1; i >=0 ; i--){
//the previous item in the array
  let prev = getPrev(i);
  // for every item in the items array calculate the value for the stroke-dasharray, stroke-dashoffset
  let o = {
  r:r,
  "stroke-dasharray":totalLength,
  "stroke-dashoffset": totalLength,
  "style":  `--sdo:${totalLength * (1 - items[i].val)}`,
  stroke:items[i].color,
  transform: `rotate(${prev * 360})`,
  class:"animatable"
}
//draw the circles
drawSVGelmt(o,"circle", circles)
 // calculate the position for the text
 // first get the angle in the middle
 let textAngle = 2*Math.PI * (prev + items[i].val/2);
 // get the position and rotate the text
 let t = {}
   t.x=r*Math.cos(textAngle);
   t.y=r*Math.sin(textAngle);
   t.transform= `rotate(${90},${t.x},${t.y})`

 //draw the text
 let _text = drawSVGelmt(t,"text", text);
 // add the text content
 _text.textContent = `${items[i].val * 100}%`;
}


// a function to draw an svg element
function drawSVGelmt(o,tag, parent) {
  var elmt = document.createElementNS(SVG_NS, tag);
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      elmt.setAttributeNS(null, name, o[name]);
    }
  }
  parent.appendChild(elmt);
  return elmt;
}

// a function to get the previous item in the array
function getPrev(i){
  let prev = 0;
  if(i > 0){
     for(let j = 0; j < i; j++){
       prev += items[j].val
     }
  }
  return prev;
}

svg {
  border: 1px solid;
  transform: rotate(-90deg);
}

circle {
  fill: none;
  stroke-width: 60;
  stroke-linecap: round;
}

circle.animatable {
  animation: dash 0.5s ease-in forwards;
}
text {
  fill: black;
  stroke: white;
  paint-order: stroke;
  stroke-width: 5;
  font-size: 50px;
  font-family: arial;
  font-weight: bold;
  text-anchor: middle;
  dominant-baseline: middle;
}

@keyframes dash {
  to {
    stroke-dashoffset: var(--sdo);
  }
}

<svg id="svg" width="400" viewBox="-200 -200 400 400">

  <circle id="bg" r="150" stroke="#d9d9d9" />
  <g id="circles"></g>

  <g id="text"></g>
</svg>

10-05 20:00