简体   繁体   English

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

[英]How to rotate an object around the center in d3.js

I have two simple objects in d3.js, they should be circling around the center of the viewport (like planets around the sun). 我在d3.js中有两个简单的物体,它们应绕着视口的中心盘旋(就像围绕太阳的行星一样)。

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. 我是d3.js的新手,我知道我必须使用过渡但是因为行星必须一直循环而不仅仅是进入或退出我不知道在哪里以及如何设置过渡。

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. 这是一个可以玩的小伙伴

You need to: 你需要:

  1. Place your planets in g groups in a g that is centered on your sun 请将您的行星g的群体g是在你的太阳中心
  2. Create an d3.timer in which you rotate your group. 创建一个d3.timer旋转组的d3.timer

For, example of the use of d3.timer see Mike Bostocks Epicyclic Gearing example. 有关使用d3.timer示例,请参阅Mike Bostocks Epicyclic Gearing示例。 Using that example, I put together something similar to what you asked: http://bl.ocks.org/4953593 使用这个例子,我把类似于你问的内容放在一起: 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/ 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;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM