0

您好,我做了一个旭日形图或双层图,它位于饼图和甜甜圈图的中间^^ 当我附加所有路径时,它工作正常:

this.path = this.svg.selectAll("path")
.data(this.partition.nodes(rootData).slice(1))
.enter().append("path")
.attr("d", this.arc)
.style("fill", function(d) { return d.fill; })
.each(function(d){ this._current = thiss.updateArc(d);});

但问题是当我试图在我的所有路径的中间添加一个圆圈所以它不起作用时,这段代码在我所有路径的中间添加圆圈很好

var indicator =  this.svg.selectAll('circle')
.data(this.partition.nodes(rootData))
.enter().append("circle")
.attr("cx", function(d){return thiss.arc.centroid(d)[0]})
.attr("cx", function(d){return thiss.arc.centroid(d)[1]})
.attr("r", 5).style('fill','#ff0000');

但我需要在中间但在路径的外部边界上添加这个小圆圈。我不知道如何获得正确的 cx 和 cy 属性,请帮忙?

这是我的目标的截图(黑点是我所拥有的)和(红点是我想要做的)

http://i.stack.imgur.com/GXPYM.jpg

在此处输入图像描述

4

2 回答 2

0

作为三角函数的替代方法,您可以使用变换来定位圆。如果转换的第一步是旋转,然后您应用平移,则平移将应用在旋转坐标系中。

不过,有点额外的复杂性是 d3 饼图以弧度表示角度(因为这是三角函数使用的),但旋转需要以度为单位的角度。

  var degreesPerRadian = 180/Math.PI;
  g.append("circle") //circles inherit pie chart data from the <g>
      .attr("r", 5)
      .attr("transform", function(d) { 
          return "rotate(" +  degreesPerRadian*((d.startAngle + d.endAngle)/2) 
          + ")" +
              //rotate by the average of the start and end angle
              //Note that d3 specifies angles in radians, but the rotate
              //function needs them in degrees
              "translate(0," + -radius + ")";
              //then translate "up" the distance of the radius;
              //"up" is interpretted according to the rotated coordinates,
              //but for zero rotation it will position the dot at the top
              //of the circle, which is the zero angle for d3
      });

现场示例: http: //fiddle.jshell.net/4x9ap/

(基于这个简单的饼图代码

于 2014-02-15T00:58:17.077 回答
0

这在一定程度上是对 Lars 评论中方程的重复,但我认为值得一次重述一遍,因为从角度转换为 x/y 坐标的三角恒等式与您的三角教科书不匹配。

大多数教科书假定角度从右侧水平轴开始并逆时针增加,并且垂直轴在页面上方具有较大的值。

在 SVG 中,较大的 y 值在页面上较低,并且由饼图布局创建的角度(以及 OP 用于旭日形布局的示例代码)将零角度绘制为圆顶部的垂直线,角度顺时针增加。

使用该信息,您可以使用以下三角方程转换为 x 和 y 值:

  g.append("circle") //circles inherit pie chart data from the <g>
      .attr("r", 5) 
      .attr("cx", function(d) { 
          return Math.sin((d.startAngle + d.endAngle)/2) *radius;
      })
      .attr("cy", function(d) { 
          return -Math.cos((d.startAngle + d.endAngle)/2) *radius;
      });

现场示例: http: //fiddle.jshell.net/4x9ap/1/

同样,这个简单的示例使用饼图布局,因此数据具有startAngleendAngle值,并且半径是恒定的。对于使用分区布局制作的旭日形图,您将替换(d.startAngle + d.endAngle)/2d.x + d.dx/2,并且您将替换radius为基于 的函数d.depth

于 2014-02-15T01:38:27.747 回答