3

我的帖子在某种程度上是对这个问题的跟进:D3 - 如何处理 JSON 数据结构?

简而言之,我在处理复杂的嵌套 JSON 结构时遇到了麻烦。让我举一个简单的例子(反映上面的链接)来说明:

var regularData = [[40,20,30,24,18,40],
                    [24,20,30,41,12,34]];

var myTable = d3.select("body").append("table")
  .selectAll("tr")
  .data(regularData, function(d) {
    return d;
  })
  .enter()
  .append("tr")
  .selectAll("td")
  .data(function(d) {
    return d;
  })
  .enter()
  .append("td") 
  .text(function(d) {
    return d;
  });

正如 D3 的文档已经显示的那样,这会产生两行数字,正如预期的那样。

但是如果我用这个替换regularData:

var newData = [{"user":"jim","scores":[40,20,30,24,18,40]},
            {"user":"ray","scores":[24,20,30,41,12,34]}];

并将 myTable 的构造线 3 到 5 调整为:

  .data(newData, function(d) {
    return d.scores;
  })

我本来希望循环输入每个用户的分数。相反,第二个数据子句仍然绑定到顶级对象(即具有属性“user”和“scores”)。

一种蛮力方法是将我的数据转换为适合每个目的的普通“数组数组”。但也许我错过了一些东西,更优雅的方式是可能的?

预先感谢您的帮助,P。

4

1 回答 1

3

您稍微误解了第二个参数d3.data的含义。

该参数通过为数据提供id而不是作为访问器函数用于对象恒定性,就像在 d3 API 中的大多数其他函数中一样。

但是,当函数作为第一个参数传递时,如下所示:

.data(function(d) {
  return d;
})

那么它确实表现为一个访问器函数。

在您的情况下,您想要的是以下方面的内容:

var newData = [{"user":"jim","scores":[40,20,30,24,18,40]},
            {"user":"ray","scores":[24,20,30,41,12,34]}];

var myTable = d3.select("body").append("table")
  .selectAll("tr")
  .data(regularData, function(d) {
    return d.user;
  })
  .enter()
  .append("tr")
  .selectAll("td")
  .data(function(d) {
    return d.scores;
  })
  .enter()
  .append("td") 
  .text(function(d) {
    return d;
  });

我已将该user字段用作id数据的,并scores在第二次调用中返回了data以创建td元素。

于 2013-11-11T14:39:15.643 回答