我有一个二维数据数组,我想将其可视化为 D3 中的热图。
从我看到的例子中,包括:
看起来您必须将行和列编码为每个数据元素的属性。有没有办法利用数据的结构(即它是一个可以用 [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)
当然,您可以使用二维数组的索引来绘制热图。我在http://jsfiddle.net/uArga/4/ 上放了一个简单的例子。
假设您的数据如下所示:
var data = [[3,5],[9,2]];
Run Code Online (Sandbox Code Playgroud)
首先,我建立了一些基本的尺度计算x和y基于数据的大小和图表的大小偏移。这使得通过更改height和width无需手动重新计算每个单元格应该有多大来轻松调整图表大小。
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)
然后使用子选择将每个单元格添加到行中。可能有一种更简洁的方法来做到这一点,但我基本上只是在每个单元格的数据旁边捕获行号。然后我用秤搞清楚x,y,height,和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)