最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to rotate an object around the center in d3.js - Stack Overflow

programmeradmin6浏览0评论

I have two simple objects in d3.js, they should be circling around the center of the viewport (like planets around the sun).

I am new to d3.js and I know that I have to use transitions but as the planets have to circle all the time and not just on enter or exit I don't know where and how to set the transition.

Here is my current code:

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

}

And here is a jsfiddle to play around.

I have two simple objects in d3.js, they should be circling around the center of the viewport (like planets around the sun).

I am new to d3.js and I know that I have to use transitions but as the planets have to circle all the time and not just on enter or exit I don't know where and how to set the transition.

Here is my current code:

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

}

And here is a jsfiddle to play around.

Share Improve this question asked Feb 14, 2013 at 10:27 MarcMarc 6,7719 gold badges50 silver badges79 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 14

You need to:

  1. Place your planets in g groups in a g that is centered on your sun
  2. Create an d3.timer in which you rotate your group.

For, example of the use of d3.timer see Mike Bostocks Epicyclic Gearing example. Using that example, I put together something similar to what you asked: http://bl.ocks.org/4953593

Core of the example:

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

I know this might come too late. But I do hope this can help future readers if they also are facing the same problem. I created fiddles and add some explanation in here, hope it can help:

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

Here is the code:

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;
    }

}
发布评论

评论列表(0)

  1. 暂无评论