2014-01-10 44 views
3

我想知道我的数学在哪里,或者是否有更好的方法来实现我试图用d3完成的任务。基本上,我有一个具有给定半径的旋转圆圈,我想旋转任意数量的较小的形状,类似于此轨道示例here。但事情是我不想使用计时器,因为我的场景涉及沿着较大圆的半径旋转小圆圈,并在每个圆圈之间以相同的旋转角度旋转。因此,例如,第一个圆将沿着半径旋转到315度,然后在270度旋转,直到每一个距离相等。这是假设我有8个小圆圈,所以它们之间的角度是45度。问题是,调用旋转角度大于180度会导致轨道发生错误的方向。d3轨道使用变换旋转

var dataset = [1, 2, 3, 4, 5, 6, 7, 8]; 

var width = 600, 
    height = 600, 
    rad = Math.PI/180, 
    layerRadius = 10, 
    radius = width/2, 
    step = 360/dataset.length, 
    svg = d3.select('#ecosystem') 
     .attr('width', width) 
     .attr('height', height); 

var layers = svg.selectAll('g') 
    .data(dataset) 
    .enter() 
    .append('g') 
    .attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 

layers.append('circle') 
    .attr('class', 'planet') 
    .attr('cx', 0) 
    .attr('cy', -height/2) 
    .attr('r', layerRadius) 
    .attr('fill', 'none') 
    .style({ 
    'stroke': 'black', 
    'stroke-width': 1 
}); 

svg.selectAll('.planet') 
    .transition() 
    .duration(600) 
    .delay(function (d, i) { 
    return i * 120; 
}) 
.ease('cubic') 
.attr("transform", function (d, i) { 
    //angle should be 360 - step * (i + 1); 
    console.log(360 - step * (i + 1)); 
    var angle = 360 - step * (i + 1); 
    return "rotate(" + angle + ")"; 
}); 

//circle of rotation  
var c = svg.append('circle') 
    .attr('cx', width/2) 
    .attr('cy', height/2) 
    .attr('r', radius) 
    .attr('fill', 'none') 
    .style({ 
    'stroke': 'black', 
    'stroke-width': 1 
}); 

//center point 
var cp = svg.append('circle') 
    .attr('cx', width/2) 
    .attr('cy', height/2) 
    .attr('r', 1) 
    .attr('fill', 'none') 
    .style({ 
    'stroke': 'black', 
    'stroke-width': 1 
}); 

这里的小提琴: fiddle

回答

3

类似动画饼图(见例如here),您需要自定义函数吐温 - 默认插值是不是真的适合任何径向。幸运的是,这是相对直接的,您只需告诉D3如何插入角度,在这种情况下,这是一个简单的数字插值。

function angleTween(d, i) { 
      var angle = 360 - ((i+1)*20); 
      var i = d3.interpolate(0, angle); 
      return function(t) { 
       return "rotate(" + i(t) + ")"; 
      }; 
     } 

然后,而不是直接指定transform,给它这个功能:

.attrTween("transform", angleTween); 

完成演示here

+0

非常感谢!所以基本上补间可以运行在给定的属性上,并且插值函数估计每个补间的x,y坐标或者给定属性的开始点和结束点。在我的情况下,开始角度或0和最终角度? – swallace

+0

是的 - 除了它是两个值之间的简单插值(例如,用0.5调用它可以给出中点)。补间函数的要点是告诉D3如何插入不明显的东西。例如。在“旋转(0)”和“旋转(180)”(作为字符串)之间插入不是。这个补间函数只设置一个值,即旋转角度。 –