d3.js径向定位物体周围的元素

时间:2018-02-05 10:20:02

标签: d3.js data-visualization

我目前遇到d3.js关于定位的问题。

这是我现在的代码

 var center = {name: "sun", count: 20 }; //Will have more complex data in the future

 var planets = [
    {name: "Mercury", count: 2},
    {name: "Venus", count: 3} ,
    {name: "Earth", count: 5},
    {name: "Mars", count: 4},
    {name: "Jupiter", count: 11},
    {name: "Saturn", count: 10},
    {name: "Uranus", count: 7},
    {name: "Neptune", count: 8} ];

 var svg = d3.select("#planet-chart").append("svg")
    .attr("width", 800)
    .attr("height", 800);


 var circleContainer = svg.selectAll("g mySolarText")
     .data(planets);


 var circleContainerEnter = circleContainer.enter()
     .append("g")
     .attr("transform", function(d,i){
         return "translate("+ i*10 +",80)"
     });

 var circle = circleContainerEnter.append("circle")
      .attr("r", function(d){return d.count * 5} )
      .attr("cx", function(d,i){return (i+1) * 30} )
      .attr("cy", function(d,i){return (i+1) * 30} )
      .attr("stroke","black")
      .attr("fill", "white");


  circleContainerEnter.append("text")
       .attr("dx", function(d){return -20})
       .text(function(d){
          return d.name}
        );

output solar system current vs desired

我现在遇到的问题是:

  1. 目前,我只能将行星变量传递到圆形容器中,但我希望还将sun变量包含在其中,但我不知道如何。我不能简单地将sun变量包含在行星数组变量中,因为我将来需要将更多数据放入其中。
  2. 我很难弄清楚如何径向定位 围绕太阳的行星,并为我们希望做的连接线添加。我试过看着弧线,但我被卡住了。
  3. 目前,行星的大小正在调整其计数值,我只是乘以半径。请原谅我,我只是一名学生,希望了解更多有关d3 js的信息。如果你们能帮助我,我会非常感激。或者如果你能引导我参考,我会非常感激。

    提前非常感谢你。

1 个答案:

答案 0 :(得分:0)

@tomshanley通过d3官方帮助论坛帮助了我。他发布了这个代码来修复我遇到的问题。

http://blockbuilder.org/tomshanley/840d381a9ca87ab404f63adda1ba8452

const radians = 0.0174532925

var center = {name: "sun", count: 20 };

var planets = [
      {name: "Mercury", count: 2},
      {name: "Venus", count: 3} ,
      {name: "Earth", count: 5},
      {name: "Mars", count: 4},
      {name: "Jupiter", count: 11},
      {name: "Saturn", count: 10},
      {name: "Uranus", count: 7},
      {name: "Neptune", count: 8} ];

 var w = 800, h = 800;

 var svg = d3.select("body").append("svg")
      .attr("width", w)
      .attr("height", h);

let orbitRadius = d3.scaleLinear()
    .domain([0,8]) //number of planets
    .range([90,w/2]) //you may need adjust this later

let angle = d3.scaleLinear()
    .domain([0,9]) //number of planets + 1
    .range([0,360]) //you may need adjust this later



svg.selectAll("line")
    .data(planets)
    .enter()
    .append("line")
    .attr("x1", function(d,i){

    let a = angle(i);
    let r = orbitRadius(i);

    return xCoord = x(a, r) + (w/2)

 })
    .attr("y1", function(d,i){

    let a = angle(i);
    let r = orbitRadius(i);

    return yCoord = y(a, r) + (h/2)

 })
    .attr("x2", (w/2))
    .attr("y2", (h/2))
    .style("stroke", "black")
    .style("stroke-width", 2)



 var circleContainer = svg.selectAll("g mySolarText")
     .data(planets);

 var circleContainerEnter = circleContainer.enter()
     .append("g")
     .attr("transform", function(d,i){

    let a = angle(i);
    let r = orbitRadius(i);

    let xCoord = x(a, r) + (w/2)
    let yCoord = y(a, r) + (h/2)

    return "translate("+ xCoord +"," + yCoord + ")"
 });

var circle = circleContainerEnter.append("circle")
  .attr("r", function(d){return d.count * 5} )
  .attr("cx", 0)
  .attr("cy", 0)
  .attr("stroke","black")
  .attr("fill", "white");

circleContainerEnter.append("text")
   .attr("dx", function(d){return -20})
   .text(function(d){
      return d.name}
    );

function x (angle, radius) {
  // change to clockwise
  let a = 360 - angle
  // start from 12 o'clock
  return radius * Math.sin(a * radians)
}

function y (angle, radius) {
  // change to clockwise
  let a = 360 - angle
  // start from 12 o'clock
  return radius * Math.cos(a * radians)
}

再次,非常感谢! :)