2015-05-29 209 views
1

我設法根據一些樣本基因表達數據生成熱圖,並根據基因表達水平爲每個細胞分配填充。我將填充映射到colorbrewer刻度,例如:d3.js熱圖圖例

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); 

…它對我來說工作得很好。不過,我將這些填充分配給附帶的圖例遇到了問題,該圖例填充了#NaNNaNNaN

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

根據我的理解,似乎我無法取出填充物的價值,基於z的值。

下面是完整的小提琴:http://jsfiddle.net/teddyrised/jLxbawhz/2/


如果我選擇不映射我的表達水平對一個在ColorBrewer規模,而只是一個開始和結束的顏色,腳本工作正常(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 
}); 

回答

1

不確定我完全遵循你的代碼,但不應該你的圖例填充與你的熱圖填充相同的功能?

legend.append("rect") 
    .attr({ 
    'width': 40, 
    'height': 20, 
    'fill': function(d) { 
     return heatmapFill(z(d)); 
    } 
}); 

更新fiddle

+0

因爲忽略了這個非常簡單的解決方案,所以我在嘲笑我自己。 d3確實有一個非常陡峭的學習曲線,仍然很難理解它 - 而且你有很大的幫助。謝謝 :) – Terry