d3.selectAll进入嵌套键值对的退出 - 又名:数组选择如何工作?

时间:2018-03-16 05:03:57

标签: arrays d3.js

我有一个嵌套的数据数组,我用它来创建一个分组的条形图。我无法为嵌套数组的datajoin分配密钥。

下面是输入数据,顶层的工作数据连接,以及我想要完成的两个部分实现。我很亲密!

// input data    

var data = [
      {"key":"cat1","value":[{"key":"subcatA","value":100},{"key":"subcatB","value":200}]},
      {"key":"cat2","value":[{"key":"subcatA","value":150},{"key":"subcatB","value":250}]}
    ];

要访问顶级并构建主要类别,请执行以下操作:

// top level (all good)
var plot = d3.select('#plot');

plot.selectAll(".category")
    .data(data,function(d) {return d.key;}) // <-- return key on datajoin
    .enter().append("g")
    .attr("class", "category")

在datajoin上返回d.key会跟踪每个类别,使得enter()和exit()不是一大堆动画。有关向数据连接添加密钥的参考信息,请参阅Mike Bostock的General Update Pattern, II

要绘制第二级,我会这样做:

// second level (plots but no key is assigned)

plot.selectAll(".category").selectAll(".bar")
    .data(function (d) {return d.value; }) // <-- is this right?
    .enter().append("rect")
    .attr("class","bar")

没有分配密钥,因此d3相当随机地处理更新。如果我这样做,我可以得到我想要的第一次迭代:

 // second level (key is assigned but first iteration only)

 plot.selectAll(".g-category").selectAll(".bar")
    .data(data[0].value, function (d) {return d.key; }) // <-- first category only
    .enter().append("rect")
    .attr("class","bar")

完美除了我需要迭代data,而不只是data[0]。我的问题是,一旦我尝试,我就会与d3.selectAll发生利益冲突并使事情陷入混乱。

这个问题的答案可能很简单,但我错过了:如何在d3中正确选择和分配嵌套数组的键?

1 个答案:

答案 0 :(得分:2)

第二级中的数据方法只有一个参数:

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

要分配键功能,您必须传递第二个参数。例如:

.data(function(d) {
    return d.value
}, function(d) {
    return d.key
});

你可以在一行中更好地看到它:

.data(function(d) { return d.value }, function(d) { return d.key });
//2nd arg after the comma ----------^

但是,为了方便人类阅读,我建议你为1级和2级使用不同的属性名称。现在一切都是valuekey,这很难理解(但不是为了机器。例如,在上面的代码片段中,value指的是第一级数组,而key指的是第二级数组,而不是第一级数组......你看到这个混乱吗?

以下是您的数据演示:

var data = [{
    "key": "cat1",
    "value": [{
      "key": "subcatA",
      "value": 100
    }, {
      "key": "subcatB",
      "value": 200
    }]
  },
  {
    "key": "cat2",
    "value": [{
      "key": "subcatA",
      "value": 150
    }, {
      "key": "subcatB",
      "value": 250
    }]
  }
];

var body = d3.select("body");
var outer = body.selectAll(null)
  .data(data, function(d) {
    return d.key
  })
  .enter()
  .append("div")
  .attr("class", "outer");

var inner = outer.selectAll(null)
  .data(function(d) {
    return d.value
  }, function(d) {
    console.log("the key is: " + d.key)
    return d.key
  })
  .enter()
  .append("div")
  .html(function(d) {
    return d.key + " - " + d.value
  });
<script src="https://d3js.org/d3.v4.min.js"></script>

相关问题