8

d3.jsで長方形のグリッドを作成しようとしています。

グリッドは7行(1週間の日数)、24列(1日の時間数)です。

次のコードは(行:列)のみを描画します:day0:hour0、day1:hour1、day2:hour2、day3:hour3、day4:hour4、day5:hour5、day6:hour6、day7: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;
}
4

1 に答える 1

11

問題は、データバインディングが配列の最初の次元(0,1,2)のみを反復処理しており、それを使用して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で、完全なソースを使用した実例を見ることができます。

于 2012-05-05T19:56:37.897 に答える