没有显式存储行和列的 D3 热图

DMa*_*ack 5 javascript d3.js

我有一个二维数据数组,我想将其可视化为 D3 中的热图。

从我看到的例子中,包括:

/sf/answers/904781391/

http://bl.ocks.org/2605010

看起来您必须将行和列编码为每个数据元素的属性。有没有办法利用数据的结构(即它是一个可以用 [i][j] 符号索引的二维数组)来避免对位置信息进行冗余编码?

如果没有,是否有一种简洁和/或有效的方法来生成对位置信息进行编码的数据结构?我的意思是嵌套 for 循环以外的其他内容:

myData = [[1, 2], [3, 4]]
myDataWithPos = []

nRow = myData.length
nCol = myData[0].length

for (i = 0; i < nRow; i++){
    for(j = 0; j < nCol; j++){
        myDataWithPos.push({val: myData[i][j], row: i, col: j})
    }
}
Run Code Online (Sandbox Code Playgroud)

Bil*_*ill 5

当然,您可以使用二维数组的索引来绘制热图。我在http://jsfiddle.net/uArga/4/ 上放了一个简单的例子。

假设您的数据如下所示:

var data = [[3,5],[9,2]];
Run Code Online (Sandbox Code Playgroud)

首先,我建立了一些基本的尺度计算xy基于数据的大小和图表的大小偏移。这使得通过更改heightwidth无需手动重新计算每个单元格应该有多大来轻松调整图表大小。

var x = d3.scale.linear()
    .range([0, width])
    .domain([0,data[0].length]);

var y = d3.scale.linear()
    .range([0, height])
    .domain([0,data.length]);
Run Code Online (Sandbox Code Playgroud)

然后您可以将每一行添加到热图中

var row = svg.selectAll(".row")
             .data(data)
           .enter().append("svg:g")
             .attr("class", "row");
Run Code Online (Sandbox Code Playgroud)

然后使用子选择将每个单元格添加到行中。可能有一种更简洁的方法来做到这一点,但我基本上只是在每个单元格的数据旁边捕获行号。然后我用秤搞清楚xyheight,和width每个细胞。

var col = row.selectAll(".cell")
    .data(function (d,i) {return d.map(function(a){return {value: a, row: i};})})
  .enter().append("svg:rect")
    .attr("class", "cell")
    .attr("x", function(d, i) { return x(i); })
    .attr("y", function(d, i) { return y(d.row); })
    .attr("width", x(1))
    .attr("height", y(1))
    .style("fill", function(d) { return colorScale(d.value); });
Run Code Online (Sandbox Code Playgroud)