Reputation: 66123
I have managed to generate a heatmap based on some sample gene expression data, and I am assigning a fill to each cell depending on the level of gene expression. I am mapping the fill against a colorbrewer scale, i.e.:
var z = d3.scale.log().base(2).domain([min, max]).range([0,1]),
fills = colorbrewer.RdBu[6];
heatmapFill = d3.scale.linear().domain(d3.range(0, 1, 1.0 / (fills.length - 1))).range(fills);
…which works totally fine for me. However, I am facing a problem with assigning these fills to the accompanying legend, which have a #NaNNaNNaN
fill.
// Get data
svg.selectAll('.tile')
.data(data.melted)
.enter()
.append('rect')
.attr({
'x': function(d) { return x(d.condition); },
'y': function(d) { return y(d.geneID); },
'fill': function(d) { return heatmapFill(z(d.value)); },
'width': x.rangeBand(),
'height': y.rangeBand()
});
// Add a legend for the color values.
var legend = svg.selectAll(".legend")
.data(z.ticks())
.enter()
.append("g")
.attr({
'class': 'legend',
'transform': function(d, i) {
return "translate(" + (i * 40) + "," + (height + margin.bottom - 40) + ")";
}
});
legend.append("rect")
.attr({
'width': 40,
'height': 20,
'fill': z // Problem likely to be arising from here
});
Based on my understanding, it seems that I am unable to fetch the value of the fill, based on the value of z.
Here's the complete fiddle: http://jsfiddle.net/teddyrised/jLxbawhz/2/
If I choose not to map my expression level against a colorbrewer scale but simply a start and an end color, the script works fine (http://jsfiddle.net/teddyrised/jLxbawhz/3/):
// Scale
var z = d3.scale.log().base(2).domain([min, max]).range(['white','steelblue']);
// Get data
svg.selectAll('.tile')
.data(data.melted)
.enter()
.append('rect')
.attr({
'x': function(d) { return x(d.condition); },
'y': function(d) { return y(d.geneID); },
'fill': function(d) { return z(d.value); },
'width': x.rangeBand(),
'height': y.rangeBand()
});
// Add a legend for the color values.
var legend = svg.selectAll(".legend")
.data(z.ticks())
.enter()
.append("g")
.attr({
'class': 'legend',
'transform': function(d, i) {
return "translate(" + (i * 40) + "," + (height + margin.bottom - 40) + ")";
}
});
legend.append("rect")
.attr({
'width': 40,
'height': 20,
'fill': z
});
Upvotes: 1
Views: 4405