2015-10-19 113 views
3

我正在使用D3创建一些数据的边缘分层模型。将D3 SVG旋转到特定角度

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

线采取旋转整个车轮的护理如下:

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

的数据与红线时d.x = 270对齐。在你的情况下,调用所选数据(必须在红线上)的“原点”,你需要给出一个角度dx-origin.x + 270.

要保持0和360,下面的技巧的工作原理:

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

所以,在我看来,最简单的方法是添加一个“角度”字段中的数据,然后代替DX的使用

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) + ")"; 
}) 

现在你有关系的节点角度中心为你想要的。

额外的说明,以帮助您了解如何对齐它。你的红线在角度。所以旋转图形的方法是找到r和180之间的差异。