旋转D3 SVG以排列到特定角度

时间:2015-10-19 11:30:16

标签: javascript d3.js svg

我正在使用D3创建一些数据的边缘分层模型。

enter image description here

我希望能够做的是点击边缘节点,让它与红线对齐。

enter image description here

我到目前为止尝试的是尝试计算中间的(x,y)位置与边缘节点的(x,y)位置之间的角度差。这没有给我正确的结果。

我认为正确的方法是获得节点的角度(相对于中间)。虽然我在这方面遇到了很多麻烦,因为我找不到哪个属性存储这些信息。边缘层次结构基于这个:

http://bl.ocks.org/mbostock/7607999

使用以下代码生成文本:

node = node
      .data(nodes.filter(function(n) { return !n.children; }))
    .enter().append("text")
      .attr("class", "node")
      .attr("dy", ".31em")
      .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })
      .style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
      .text(function(d) { return d.key; })
      .on("mouseover", mouseovered)
      .on("mouseout", mouseouted);

任何信息都会非常有用。感谢

2 个答案:

答案 0 :(得分:2)

负责旋转整个车轮的线路如下:

.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })

当d.x = 270时,数据与红线对齐。在你的情况下,调用&#34; origin&#34;选定的数据(必须在红线上),你需要给出一个d.x的角度 - origin.x + 270。

要保持0到360之间的值,以下技巧可行:

(d.x - origin.x + 270 +360) % 360

所以我认为最简单的方法是添加一个&#34;角度&#34;数据中的字段,然后使用它代替d.x。

node = node
      .data(nodes.filter(function(n) { return !n.children; }))
    .enter().append("text")
      .attr("class", "node")
      .attr("dy", ".31em")
      .each(function(d) { d.angle =   (d.x - origin.x + 270 +360) % 360 })
      .attr("transform", function(d) { return "rotate(" + d.angle - 90 + ")translate(" + (d.y + 8) + ",0)" + (d.angle < 180 ? "" : "rotate(180)"); })
      .style("text-anchor", function(d) { return d.angle < 180 ? "start" : "end"; })
      .text(function(d) { return d.key; })
      .on("mouseover", mouseovered)
      .on("mouseout", mouseouted);

答案 1 :(得分:1)

  

我认为正确的方法是获得节点的角度(相对于中间)

您已经拥有节点的角度,可能因为您指定了两次旋转而一直困惑。但是可以通过执行以下操作将其统一为一个:

.attr("transform", function(d) {
  var r = d.x < 180 ? d.x - 90 : (d.x - 90) + 180;
  return "rotate(" + r + ")translate(" + (d.y + 8) + ",0)";
})

r将是角度,但是这个版本存在潜在的“问题”(或者只是使动画代码更麻烦)因为某些r值将为负值。

避免这种情况的更好方法是翻译Y轴而不是现在正在进行的X轴。

.attr("transform", function(d) {
  // Simpler version for assigning the r value and avoid negatives.
  var r = d.x > 180 ? d.x + 180 : d.x;
  // Notice the negative value for the Y Axis.
  return "rotate(" + r + ")translate(0, -" + (d.y + 8) + ")";
})

现在您可以根据需要获得相对于中心的节点角度。

额外注释,以帮助您了解如何对齐它。您的红线处于 180 的角度。因此,旋转图形的方法是找到r和180之间的差异。