2014-03-05 212 views
0

说我有以下的JSON阵列选择:d3.js嵌套二维数组

var json = [ 
    [1,2,3], 
    [1,2,3], 
    [1,2,3] 
]; 

我怎样才能使SVG的网格,而不执行2个selectAll电话rect节点?在这fiddle我能够使网格,但我不得不渲染每个行中的g节点。有没有办法在没有第一个选择的情况下编写它?如果我尝试:

svg.data(json) 
    .selectAll('rect') 
     .data(function(data) { return data; }) 
     .enter() 
     .append('rect') 
     .attr('x', function(data, x, y) { 
      return (x * size) + (x * spacing); 
     }) 
     .attr('y', function(data, x, y) { 
      return (y * size) + (y * spacing); 
     }) 
     .attr('width', size) 
     .attr('height', size); 

它只渲染二维数组的第一行。

+1

是否有一个特别的原因,你不想两次使用'selectAll'? – Quinn

+1

您的SVG结构应该密切反映您的JSON结构。如果你想改变SVG结构不具有g元素,那么你需要改变你的JSON结构(可能是一个平面阵列)。 – dcryan22

+0

@奎因不是真的,我是新来的d3,所以我只是想更好地了解API :) – chinabuffet

回答

1

您的意思是说,您宁愿在层次结构中没有g节点,而是想让所有rects直接兄弟姐妹?

这是可行的,但您必须首先将json平铺为具有9个元素的一维数组(这里未显示;可以使用Array.reduce())。然后,你就只能选择并绑定一次:

var flatJson = [1,2,3,1,2,3,1,2,3] 
svg 
    .selectAll('rect') 
    .data(flatJson)` 

和位置,并根据i

.enter() 
    .append('rect') 
    .attr('x', function(d, i) { 
    return (i % numColumns) * (size + spacing); 
    }) 
    .attr('y', function(d, i) { 
    return Math.floor(i/numColumns) * (size + spacing); 
    }) 
    .attr('width', size) 
    .attr('height', size); 

的代价就是需要有列numColumns = 3的数感。

扁平的json可以变成一个对象数组,每个对象可以有一个列和一行。例如:

var flatJson = [ 
    { row:0, col:0, value: 1}, 
    { row:0, col:1, value: 2}, 
    { row:0, col:2, value: 3}, 
    { row:1, col:0, value: 1}, 
    ... 
]