将 D3 SVG 旋转到特定角度对齐

4
我正在使用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个回答

3
负责旋转整个轮子的代码行如下:
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })

当d.x=270时,数据与红线对齐。在您的情况下,将“原点”称为所选数据(必须位于红线上的数据),则需要给出d.x-origin.x + 270的角度。
为保持值在0和360之间,可以使用以下技巧:
(d.x - origin.x + 270 +360) % 360

我认为最简单的方法是在您的数据中添加一个“角度”字段,然后使用它代替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

我认为正确的做法是获取节点的角度(相对于中心点)

您已经有了节点的角度,也许因为您两次分配旋转而令人困惑。但可以通过以下方式将其统一为一个:

.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之间的差异。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接