使用 D3 JS 将饼图的每个圆弧旋转 180(如太阳)。如何计算翻译参数

Rotate every arc of pie chart 180 (like sun) with D3 JS. How to calculate translate parameters

我正在使用 d3 js 制作饼图。我想将饼图的每个弧度旋转 180。我知道我无法完全解释这里显示的是我的 fiddle link.

[fiddle]: https://jsfiddle.net/dsLonquL/ 

如何获取 translate() 函数的动态参数。

基本上你需要计算出每个圆弧边缘的中心点。我用这个例子来寻求帮助:How to get coordinates of slices along the edge of a pie chart?

这没问题,但我需要旋转点以使它们处于正确的位置。因为它是弧度的,所以旋转如下:

 var rotationInRadians = 1.5708 * 1.5;

现在使用我使用数据作为路径之前的示例,所以开始和结束角度以及中心点如下所示:

var thisAngle = (d.startAngle + rotationInRadians + (d.endAngle + rotationInRadians - d.startAngle + rotationInRadians) / 2);
    var x = centreOfPie[0] + radius * 2 * Math.cos(thisAngle)
    var y = centreOfPie[1] + radius * 2 * Math.sin(thisAngle)

我创建了一个函数来在这些点显示圆圈以澄清:

function drawCircle(points, colour) {
    svg.append('circle')
      .attr('cx', points[0])
      .attr('cy', points[1])
      .attr('r', 5)
      .attr('fill', colour);

  }

像这样在当前函数中调用它:

drawCircle([x, y], color(d.data.label))

然后进行相应的平移和旋转:

return 'translate(' + (x) + ',' + y + ') rotate(180)';

我添加了一个过渡,所以你可以看到它的工作。这是最后的 fiddle :

https://jsfiddle.net/thatOneGuy/dsLonquL/7/

编辑

在您的评论中,您说您希望最大的部分保留在中间。所以我们需要 运行 通过细分并获得最大的。我还处理了重复项,即如果两个或多个段的大小相同。

这是添加的代码:

 var biggestSegment = {
    angle: 0,
    index: []
  };

 path.each(function(d, i) {
    var thisAngle = (d.endAngle - d.startAngle).toFixed(6);//i had to round them as the numbers after around the 7th or 8th decimal point tend to differ tet theyre suppose to be the same value
    if (i == 0) {
      biggestSegment.angle = thisAngle
    } else {
      if (biggestSegment.angle < thisAngle) {
        biggestSegment.angle = thisAngle;
        biggestSegment.index = [i];
      } else if (biggestSegment.angle == thisAngle) {
      console.log('push')
        biggestSegment.index.push(i);
      }
    }
  })

现在遍历每条路径检查它是否大于当前值,如果它覆盖最大值并记下索引。如果相同,则将索引添加到索引数组。

现在在平移路径时,您需要根据上面的索引数组检查当前索引,看它是否需要旋转。像这样:

 if (biggestSegment.index.indexOf(i) > -1) {
      return 'translate(' + (centreOfPie[0]) + ',' + (centreOfPie[1]) + ')' // rotate(180)';
    } else {
      return 'translate(' + (x) + ',' + y + ') rotate(180)';
    }

已更新 fiddle:https://jsfiddle.net/thatOneGuy/dsLonquL/8/

我编辑了 3 个值以与其余值不同。继续改变这些,看看你的想法:)

这是一个纯中学几何作业。

CASE 1:每个扇形旋转的顶点都在圆的外线上

fiddle

// ... previous code there
.attr('fill', function(d, i) {
        return color(d.data.label);
      })
.attr("transform", function(d, i) {
    var a = (d.endAngle + d.startAngle) / 2, // angle of vertex
        dx = 2 * radius * Math.sin(a),       // shift/translate  is two times of the vertex coordinate
        dy = - 2 * radius * Math.cos(a);     // the same
        return ("translate(" + dx + " " + dy + ") rotate(180)"); // output
      });

CASE 2:顶点在弦的中心

fiddle

// ... previous code there
.attr('fill', function(d, i) {
        return color(d.data.label);
      })
.attr("transform", function(d, i) {
    var dx = radius * (Math.sin(d.endAngle) + Math.sin(d.startAngle)), // shift/translation as coordinate of vertex
        dy = - radius * (Math.cos(d.endAngle) + Math.cos(d.startAngle)); // the same for Y
        return ("translate(" + dx + " " + dy + ") rotate(180)"); // output
      });