如何在d3.js中围绕中心旋转对象

时间:2013-02-14 10:27:54

标签: javascript d3.js

我在d3.js中有两个简单的物体,它们应绕着视口的中心盘旋(就像围绕太阳的行星一样)。

我是d3.js的新手,我知道我必须使用过渡但是因为行星必须一直循环而不仅仅是进入或退出我不知道在何处以及如何设置过渡。 / p>

这是我目前的代码:

var planets = [
    {d:100,r:2},
    {d:150,r:4}
];

var w = 500, h = 400, svg, circle;

function init(){

    svg = d3.select("#drawArea").append("svg").attr({width: w, height: h});

    var center = {
        x: Math.floor(w/2),
        y: Math.floor(h/2)
    };

    svg.append('circle').attr({
        'cx': center.x,
        'cy': center.y,
        'r': 10,
        'class': 'sun'
    });

    circle = svg.selectAll(".planet")
        .data(planets)
        .enter()
            .append("circle")
                .attr("class", "planet")
                .attr("r", function(s){return s.r});

    circle.attr({
        // distance from the center
        'cx': function(s){ return center.x - s.d; },
        // center of the screen
        'cy': function(s){ return center.y; }
    });

}

这是一个 jsfiddle 来玩。

2 个答案:

答案 0 :(得分:13)

你需要:

  1. 将行星放置在以g为中心的g组中
  2. 创建一个用于轮换组的d3.timer
  3. 有关使用d3.timer的示例,请参阅Mike Bostocks Epicyclic Gearing示例。使用该示例,我将类似于您所问的内容放在一起:http://bl.ocks.org/4953593

    示例的核心:

      var w = 800, h = 800;
      var t0 = Date.now();
    
      var planets = [
        { R: 300, r:  5, speed: 5, phi0: 90},
        { R: 150, r: 10, speed: 2, phi0: 190}
      ];
    
    
      var svg = d3.select("#planetarium").insert("svg")
        .attr("width", w).attr("height", h);
    
      svg.append("circle").attr("r", 20).attr("cx", w/2)
        .attr("cy", h/2).attr("class", "sun")
    
      var container = svg.append("g")
        .attr("transform", "translate(" + w/2 + "," + h/2 + ")")
    
      container.selectAll("g.planet").data(planets).enter().append("g")
        .attr("class", "planet").each(function(d, i) {
          d3.select(this).append("circle").attr("class", "orbit")
            .attr("r", d.R);
          d3.select(this).append("circle").attr("r", d.r).attr("cx",d.R)
            .attr("cy", 0).attr("class", "planet");
        });
    
      d3.timer(function() {
        var delta = (Date.now() - t0);
        svg.selectAll(".planet").attr("transform", function(d) {
          return "rotate(" + d.phi0 + delta * d.speed/200 + ")";
        });
      });
    

答案 1 :(得分:2)

我知道这可能来得太晚了。但我希望如果他们也面临同样的问题,这可以帮助未来的读者。 我在这里创建了小提琴并添加了一些解释,希望它可以提供帮助:

http://www.zestyrock.com/data-visualization/d3-rotate-object-around-the-center-object-part-2/

以下是代码:

var start = Date.now();

var mode = 0;

var svg = d3.select("#canvas")
    .append("svg")
    .attr("width", 500)
    .attr("height", 500);

svg.append("circle")
    .attr("r", 50)
    .attr("cx", 250)
    .attr("cy", 250)
    .attr("fill", "#e05038");

var rotateElements = svg.append("g");

rotateElements.append("circle")
    .attr("r", 25)
    .attr("cx", 250)
    .attr("cy", 50)
    .attr("fill", "#f2b632")
    .attr("class", "orangeNode");

rotateElements.append("line")
    .attr("x1", 250)
    .attr("y1", 75)
    .attr("x2", 250)
    .attr("y2", 200)
    .attr("class", "edge")
    .attr("stroke", "grey");


d3.select("#start")
    .on("click", startAnimation);

function startAnimation() {
    if (mode === 0) {
        d3.timer(function() {
            var angle = (Date.now() - start);
            var transform = function() {
                return "rotate(" + angle + ", 250, 250)";
            };
            d3.selectAll(".orangeNode, .edge")
                .attr("transform", transform);

            if (mode === 0) {
                return true;
            } else {
                return false;
            }
        });
        mode = 1;
    } else {
        mode = 0;
    }

}