D3:迭代和访问数据集?

时间:2015-12-26 13:07:46

标签: d3.js

上下文

我正在制作一个散点图。对于每个位置,在我的数据集中,我想使用'lat'和'long'值在地图上绘制一个圆。将绘制两个圆圈,一个在另一个的顶部。两个圆的半径将由'total'和'pass'值定义。我制作了地图;我打算将绘制的数据看起来像这样:

enter image description here

我可以按照自己想要的方式构建数据。我在下面选择了json。

[
  {
    "year": 2006,
    "inspections": [
      {
        "location": "Cheshire",
        "total": 341,
        "passed": 26,
        "long": 5,
        "lat": 20
      },
      {
        "location": "County Durham",
        "total": 102,
        "passed": 1,
        "long": 480,
        "lat": 90
      }
    ]
  },
  {
    "year": 2007,
    ...
]

最终,我想转换我的圈子(让它们成长和收缩)多年来,但是现在我开始变得简单,只是想在我的地图上绘制一年的数据。

这是我第一次尝试绘制我的圈子的代码:

d3.json("dataset", function(error, data) {
  svg.selectAll("circle")
  .data(data)
  .enter()
  .append("circle")
  .attr("cx", function(d) {
    // return someting;
  })
  .attr("cy", function(d) {
    // return someting;
  })
  .attr("r", 5);
});

以下是d的控制台输出:

enter image description here

问题

我不太了解.data().enter()的工作原理?如何依次访问我的值,'location','total','pass','long'和'lat',这样我可以绘制2006年的所有圈子。可用的示例往往使用非常简单的数组。如何从更复杂的嵌套数组和对象结构中获取值?

2 个答案:

答案 0 :(得分:0)

如果您的json数据是这样的

  var json = [{
      "year": 2006,
      "inspections": [{
        "location": "Cheshire",
        "total": 341,
        "passed": 26,
        "long": 50,
        "lat": 0
      }, {
        "location": "County Durham",
        "total": 102,
        "passed": 10,
        "long": 52,
        "lat": 0
      }]
    }, {
      "year": 2007,
      "inspections": [{
        "location": "Cheshire",
        "total": 341,
        "passed": 26,
        "long": 51,
        "lat": 1
      }, {
        "location": "County Durham",
        "total": 102,
        "passed": 10,
        "long": 51,
        "lat": -1.8
      }]
    }
  ];

首先为第一组检查制作红圈:

  //circle1
svg.selectAll(".red")//get all the circles with class red
    .data(json).enter()//iterate over the json
    .append("circle")
    .attr("cx", function (d) { var circle1 = d.inspections[0]; return projection([circle1.lat,circle1.long])[0]; })//get x point based on projection set the x point which is 0 index
    .attr("cy", function (d) { var circle1 = d.inspections[0]; return projection([circle1.lat,circle1.long])[1]; })//get x point based on projection set the x point which is 1 index
    .attr("r", "8")
    .attr("class", "red")//to get the selection for red circles
    .attr("fill", "red")

为第二组检查制作蓝色圆圈,如下所示:

//circle 2
svg.selectAll(".blue")
    .data(json).enter()
    .append("circle")
    .attr("cx", function (d) { var circle1 = d.inspections[1]; return projection([circle1.lat,circle1.long])[0]; })
    .attr("cy", function (d) { var circle1 = d.inspections[1]; return projection([circle1.lat,circle1.long])[1]; })
    .attr("r", "8")
  .attr("class", "blue")
    .attr("fill", "blue")

工作代码here

希望这有帮助!

答案 1 :(得分:0)

如果可以的话,更容易拥有一个平面的对象数组:

[
  {
    "year": 2006,
    "location": "Cheshire",
    "total": 341,
    "passed": 26,
    "long": 5,
    "lat": 20
  },
  {
    "year": 2006,
    "location": "County Durham",
    "total": 102,
    "passed": 1,
    "long": 480,
    "lat": 90
  }
]

然后d.lat等将返回您的期望。否则你的代码乍一看看起来很好。只需执行svg.selectAll("circle").data(data).enter().append("circle")两次 - 每组一次。