d3 donut/pie 图表 - 在圆弧之间画一条线

d3 donut/pie chart - drawing a line between arcs

无法找到弧的端点以从 (0,0) 到弧的端点画一条线..附上图片

我可以找到圆弧的质心并画一条线,但在这里我想拉一条线到圆弧的末端,这样我就可以将该线延伸到左侧/右侧(然后将圆附加到线的端点)...在整个 google 中找不到任何此类解决方案。任何帮助将不胜感激。只需提示即可。

通过执行以下操作将饼图布局应用于数据集后

var pieData = myPieLayout(myDataset)

在 pieData 中,您会发现,对于数据集的每个元素,都有两个名为 startAngle 和 endAngle 的属性。使用它,您可以通过遍历 pieData 元素并执行

从饼图的中心找到所需点的位置
var x = Math.cos(d.endAngle)*radius
var y = Math.sin(d.endAngle)*radius

当您将数据数组传递给 pie generator 时,它 returns 具有以下属性的对象数组:

  • data - 输入数据;输入数据数组中的相应元素。
  • value - 圆弧的数值。
  • index - 弧的从零开始排序的索引。
  • startAngle - 圆弧的起始角度。
  • endAngle - 圆弧的结束角度。
  • padAngle - 圆弧的焊盘角度。

根据这些,您可以使用 startAngleendAngle 绘制线条,因为它们包含弧的起点(和终点)。

但有一个问题:与常规三角函数表示不同,D3 饼图生成器将 0 角放在 12 点钟方向:

The angular units are arbitrary, but if you plan to use the pie generator in conjunction with an arc generator, you should specify angles in radians, with 0 at -y (12 o’clock) and positive angles proceeding clockwise.

因此,我们必须减去 Math.PI/2 才能得到正确的角度。

在下面的演示中,坐标是使用正弦和余弦计算的:

.attr("y2", function(d) {
    return Math.sin(d.startAngle - Math.PI / 2) * (outerRadius)
})
.attr("x2", function(d) {
    return Math.cos(d.startAngle - Math.PI / 2) * (outerRadius)
}) 

查看演示:

var data = [10, ,12, 50, 15, 20, 40, 6, 32, 17];

var width = 500,
  height = 400,
  radius = Math.min(width, height) / 2;

var color = d3.scaleOrdinal(d3.schemeCategory10)

var pie = d3.pie()
  .sort(null);

var arc = d3.arc()
  .innerRadius(radius - 100)
  .outerRadius(radius - 50);

var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var path = svg.selectAll(null)
  .data(pie(data))
  .enter().append("path")
  .attr("fill", function(d, i) {
    return color(i);
  })
  .attr("d", arc);

var lines = svg.selectAll(null)
  .data(pie(data))
  .enter()
  .append("line")
  .attr("x1", 0)
  .attr("y1", 0)
  .attr("y2", function(d) {
    return Math.sin(d.startAngle - Math.PI / 2) * (radius - 50)
  })
  .attr("x2", function(d) {
    return Math.cos(d.startAngle - Math.PI / 2) * (radius - 50)
  })
  .attr("stroke", "black")
  .attr("stroke-width", 1)
<script src="https://d3js.org/d3.v4.min.js"></script>