2012-05-04 49 views
8

我想在d3.js中构建一个矩形网格。d3.js构建一个矩形网格

网格为7行(一周中的天数)和24列(一天中的小时数)。

以下代码仅汲取(行:列): day0:hour0, DAY1:hour1, DAY2:hour2, 第3天:hour3, 第四天:hour4, DAY5:hour5, 第六天:hour6, 第7天:hour7

问:任何想法,为什么下面的代码将无法正常工作?

/** 
* calendarWeekHour Setup a week-hour grid: 
*       7 Rows (days), 24 Columns (hours) 
* @param id   div id tag starting with # 
* @param width  width of the grid in pixels 
* @param height  height of the grid in pixels 
* @param square  true/false if you want the height to 
*       match the (calculated first) width 
*/ 
function calendarWeekHour(id, width, height, square) 
{ 
    var calData = randomData(width, height, square); 
    var grid = d3.select(id).append("svg") 
        .attr("width", width) 
        .attr("height", height) 
        .attr("class", "chart"); 

     grid.selectAll("rect") 
       .data(calData) 
       .enter().append("svg:rect") 
       .attr("x", function(d, i) { return d[i].x; }) 
       .attr("y", function(d, i) { return d[i].y; }) 
       .attr("width", function(d, i) { return d[i].width; }) 
       .attr("height", function(d, i) { return d[i].height; }) 
       .on('mouseover', function() { 
        d3.select(this) 
         .style('fill', '#0F0'); 
       }) 
       .on('mouseout', function() { 
        d3.select(this) 
         .style('fill', '#FFF'); 
       }) 
       .on('click', function() { 
        console.log(d3.select(this)); 
       }) 
       .style("fill", '#FFF') 
       .style("stroke", '#555'); 
} 

//////////////////////////////////////////////////////////////////////// 

/** 
* randomData()  returns an array: [ 
              [{id:value, ...}], 
              [{id:value, ...}], 
              [...],..., 
              ]; 
         ~ [ 
          [hour1, hour2, hour3, ...], 
          [hour1, hour2, hour3, ...] 
          ] 

*/ 
function randomData(gridWidth, gridHeight, square) 
{ 
    var data = new Array(); 
    var gridItemWidth = gridWidth/24; 
    var gridItemHeight = (square) ? gridItemWidth : gridHeight/7; 
    var startX = gridItemWidth/2; 
    var startY = gridItemHeight/2; 
    var stepX = gridItemWidth; 
    var stepY = gridItemHeight; 
    var xpos = startX; 
    var ypos = startY; 
    var newValue = 0; 
    var count = 0; 

    for (var index_a = 0; index_a < 7; index_a++) 
    { 
     data.push(new Array()); 
     for (var index_b = 0; index_b < 24; index_b++) 
     { 
      newValue = Math.round(Math.random() * (100 - 1) + 1); 
      data[index_a].push({ 
           time: index_b, 
           value: newValue, 
           width: gridItemWidth, 
           height: gridItemHeight, 
           x: xpos, 
           y: ypos, 
           count: count 
          }); 
      xpos += stepX; 
      count += 1; 
     } 
     xpos = startX; 
     ypos += stepY; 
    } 
    return data; 
} 

回答

10

的问题是,你的绑定仅通过阵列(0,1,2)的第一维迭代,你要使用它通过第二个维度(0,0)迭代(0 ,1)(0,2)导致(0,0)(1,1)(2,2)行为。

要获得您想要的结果,只需使用子选择。你行定义的地方开始:

var row = chart.selectAll(".row") 
    .data(data) // each row will be bound to the array at data[i] 
    .enter().append("div") 
    .attr("class", "row") 
    … 

然后使用标识功能(如数据属性)取消引用 细胞的每一行:

var cell = row.selectAll(".cell") 
    .data(function(d) { return d; }) // then iterate through data[i] for each cell 
    .enter().append("div") 
    .attr("class", "cell") 
    … 

你可以看到完整的源代码在一个工作示例http://bl.ocks.org/2605010