在D3中循环遍历数组的数组

9

我有一个包含x个对象的数组,每个对象都有一个包含y个对象的数组,就像这样:

var data = [
    { name: '1', data: [1,2,3] },
    { name: '2', data: [1,2,3] }
]

有没有一种方法可以链接d3函数,以便迭代每个data[x]和每个data[x][y]?
我认为这样的做法可能会有所帮助,但显然并不是这样:
var svg = d3.selectAll('g')
    .data(data)
    .enter()
    .append('g')
    .selectAll('rect') /* This might be made up, but it makes sense to me :)*/
    .data(data, function (d, i) {
        return data[i].data;
    })
    .enter()
    .append('rect')

谢谢


我现在唯一的另一个选择是使用for循环,这个方法可以正常工作,只是希望有更聪明的方法。 - Ade
3个回答

10
这个大概是这样的://未测试
var svg = d3.selectAll('g')
    .data(data)
    .enter()
    .append('g')
    .selectAll('rect') /* This might be made up, but it makes sense to me :)*/
    //.data(data, function (d, i) {
    //   return data[i].data;
    //})
    //.enter()
    //.append('rect')
    .each(function(d){
    d3.select(this).selectAll('rect').data(d.data).append('rect')//and so on
    })

编辑:

工作的fiddle: http://jsfiddle.net/reko91/58WJE/34/

var data = [
    { name: '1', data: [1,2,3] },
    { name: '2', data: [1,2,3] }
]

var colourScale = ['red','blue','yellow']
var svg = d3.select('body').append('svg').attr('width', 1000).attr('height', 1000);
svg.selectAll('rect')
    .data(data)
  .enter().append('g')
    .each(function(d,i){
        d3.select(this).selectAll('rect')
        .data(d.data)
      .enter().append('rect')
        .attr('x', function(d,j) { return j*100; })
        .attr('y', function() { return i*100; })
        .attr('width', function() { return 90; })
        .attr('height', function() { return 90; })
        .attr('fill', function(d,j) { console.log(d); return colourScale[j]; })
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>


是的,谢谢。each函数可以解决问题,尽管它必须移动到... append('g').each,因为rect还不可用。 - Ade
修改答案,现在可以正常工作了,这样可以吗? - thatOneGuy
1
嗯 :) 我认为第一次翻译得很好 - Ade
是的,矩形第一次添加得很好,但你看不到它们,所以我必须正确地定位它们 :) - thatOneGuy

8

虽然使用显式的.each循环可以工作,但是使用d3推荐的方法是使用嵌套选择器

var data = [
    { name: '1', data: [1,2,3] },
    { name: '2', data: [1,2,3] }
]

var colourScale = ['red','blue','yellow']
var colourScale2 = ['yellow','pink','black']
var svg = d3.select('body').append('svg').attr('width', 1000).attr('height', 1000);
svg.selectAll('rect')
    .data(data)
  .enter().append('g')
  .selectAll('rect')
  .data(function(d){
    return d.data;
  })
  .enter()
  .append('rect')
  .attr('x', function(d,i) { return i*100; })
  .attr('y', function(d,i,j) { return j*100; })
  .attr('width', function() { return 90; })
  .attr('height', function() { return 90; })
  .attr('fill', function(d,i) { return colourScale2[i]; })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>


1
这是一个关于如何在d3.js中嵌套数据的好问题,我最近也遇到了这个问题。(也在思考一种强大的处理方式)
以下是Mike Bostock撰写的相关文章: 1. 选择器的工作原理 - 让你了解数据绑定到选择器上的方式 2. 嵌套选择器 - 了解选择器链接函数在底层的真正发生方式
下面是我使用svg时处理此问题的方法。(canvas可能有其他方法)
首先,D3的思想是“数据驱动文档”。要处理嵌套数据,您必须在SVG中创建嵌套元素。(您会发现,数据结构设计确实很重要,它反映了可视化结果) SVG中的

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接