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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14872687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 22:49:17  来源:igfitidea点击:

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

javascriptd3.js

提问by Marc

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 jsfiddleto play around.

这是一个可以玩的jsfiddle

回答by Jan van der Laan

You need to:

你需要:

  1. Place your planets in ggroups in a gthat is centered on your sun
  2. Create an d3.timerin which you rotate your group.
  1. 将您的行星g分组放置在g以您的太阳为中心的一组中
  2. 创建一个d3.timer在其中轮换您的小组。

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

例如,使用示例d3.timer参见 Mike Bostocks Epicyclic Gearing示例。使用那个例子,我把类似于你问的东西放在一起: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 + ")";
    });
  });

回答by catlovespurple

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

}