2012-05-04 37 views
8

Tôi đang cố gắng xây dựng một mạng lưới hình chữ nhật trong d3.js.d3.js xây dựng một mạng lưới hình chữ nhật

Lưới là 7 hàng (ngày trong một tuần) và 24 cột (giờ trong một ngày).

Các mã sau chỉ thu hút (hàng: Cột): day0: hour0, day1: hour1, Ngày 2: hour2, day3: hour3, day4: hour4, day5: hour5, day6: hour6, ngày7: giờ7

Câu hỏi: Mọi ý tưởng tại sao mã sau đây sẽ không hoạt động?

/** 
* 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; 
} 

Trả lời

10

Vấn đề là databinding của bạn chỉ lặp qua thứ nguyên đầu tiên của mảng (0,1,2) và bạn đang cố gắng sử dụng nó để lặp qua thứ nguyên thứ hai (0,0) (0 , 1) (0,2) dẫn đến hành vi (0,0) (1,1) (2,2).

Để nhận được kết quả bạn muốn, chỉ cần sử dụng một lựa chọn phụ. Bắt đầu với định nghĩa hàng của bạn:

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

Sau đó sử dụng chức năng nhận dạng (như tài sản dữ liệu) để dereference các tế bào cho mỗi hàng:

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

Bạn có thể thấy một ví dụ làm việc với nguồn đầy đủ tại http://bl.ocks.org/2605010.

Các vấn đề liên quan