Charts: Heatmaps revised plugin code, now modularized and enabled for variable data

This commit is contained in:
Aysam Guerler
2014-05-01 15:25:06 -04:00
parent c5ac90301e
commit 3e64390c13
3 changed files with 523 additions and 278 deletions
@@ -4,6 +4,7 @@ return {
title : 'Heatmap',
library : '',
tag : 'div',
use_panels : true,
columns : {
col_label : {
title : 'Columns',
@@ -20,313 +20,215 @@ return Backbone.View.extend(
cellSize: 0,
// color buckets
colorBuckets: 0,
nColors: 0,
// default settings
optionsDefault: {
margin : {
pace : 1000,
margin : {
top : 50,
right : 10,
bottom : 50,
left : 100
},
colors : ['#005824','#1A693B','#347B53','#4F8D6B','#699F83','#83B09B','#9EC2B3','#B8D4CB','#D2E6E3','#EDF8FB','#FFFFFF','#F1EEF6','#E6D3E1','#DBB9CD','#D19EB9','#C684A4','#BB6990','#B14F7C','#A63467','#9B1A53','#91003F']
colors : ['#005824','#1A693B','#347B53','#4F8D6B','#699F83','#83B09B','#9EC2B3','#B8D4CB','#D2E6E3','#EDF8FB','#FFFFFF','#F1EEF6','#E6D3E1','#DBB9CD','#D19EB9','#C684A4','#BB6990','#B14F7C','#A63467','#9B1A53','#91003F']
},
// initialize
initialize: function(options) {
// link this
var self = this;
// load options
this.options = Utils.merge(options, this.optionsDefault)
// add ui elements
this.options.div.append(this._templateTooltip());
this.options.div.append(this._templateSelect());
// check requirements
if (!this.options.data || !this.options.div) {
console.debug('FAILED - HeatMapPlugin::initialize() - Parameters (container and/or data) missing.');
return;
}
// access data
var data = this.options.data;
// link data
this.data = this.options.data;
// identify unique labels
var col_hash = {};
var row_hash = {};
// set element
this.setElement(this.options.div);
// create label indices
this.colNumber = 0;
this.rowNumber = 0;
for (var i in data) {
var cell = data[i];
//
// data indexing
//
// labels in alphabetical order
this.rowLabel = [];
this.colLabel = [];
// unique keys (key indices are unique per label and indicate the labels rank in the alphabetical sorting)
this.colRank = {};
this.rowRank = {};
// identify unqiue labels
for (var i in this.data) {
var cell = this.data[i];
// add label to index list
var col_label = cell.col_label;
if (col_hash[col_label] === undefined) {
col_hash[col_label] = ++this.colNumber;
if (this.colRank[col_label] === undefined) {
this.colRank[col_label] = true;
this.colLabel.push(col_label);
}
var row_label = cell.row_label;
if (row_hash[row_label] === undefined) {
row_hash[row_label] = ++this.rowNumber;
if (this.rowRank[row_label] === undefined) {
this.rowRank[row_label] = true;
this.rowLabel.push(row_label);
}
}
// add indices to data
for (var i in data) {
var cell = data[i];
cell.col = col_hash[cell.col_label];
cell.row = row_hash[cell.row_label];
}
// set sizes
this.rowNumber = this.rowLabel.length
this.colNumber = this.colLabel.length
// add row labels
// sort labels alphabetical
this.rowLabel.sort();
this.colLabel.sort();
// generate sorted key list for rows
this.rowIndex = []
for (var key in row_hash) {
this.rowLabel.push(key);
this.rowIndex.push(row_hash[key]);
for (var i in this.rowLabel) {
var row_label = this.rowLabel[i];
var row_index = parseInt(i);
this.rowRank[row_label] = row_index;
// should contain clustering
this.rowIndex.push(row_index);
}
// add col labels
// generate sorted key list for columns
this.colIndex = []
for (var key in col_hash) {
this.colLabel.push(key);
this.colIndex.push(col_hash[key]);
for (var i in this.colLabel) {
var col_label = this.colLabel[i];
var col_index = parseInt(i);
this.colRank[col_label] = col_index;
// should contain clustering
this.colIndex.push(col_index);
}
console.log(this.rowIndex);
console.log(this.colIndex);
//
// parse indexing to cells, identify data range
//
// min/max
this.max = undefined;
this.min = undefined
// add indices to data
for (var i in this.data) {
// get cell data
var cell = this.data[i];
// add rank
cell.col_rank = this.colRank[cell.col_label];
cell.row_rank = this.rowRank[cell.row_label];
// identify max/min values
if (this.min == undefined || this.min > cell.value) {
this.min = cell.value;
}
if (this.max == undefined || this.max < cell.value) {
this.max = cell.value;
}
}
// middle
this.mid = (this.max + this.min) / 2;
//
// set colors
//
// identify buckets
this.colorBuckets = this.options.colors.length;
// draw
this._draw(this.options.div, this.options.data);
},
_draw: function(container, data) {
// get height
this.width = parseInt(container.width()) - this.options.margin.left;
this.height = parseInt(container.height()) - 2*this.options.margin.top;
// calculate cell size
this.cellSize = Math.min( this.height / (this.rowNumber),
this.width / (this.colNumber));
// set width/height for plugin
this.width = this.options.cellSize * this.colNumber;
this.height = this.options.cellSize * this.rowNumber;
// set legend width
this.legendElementWidth = this.options.cellSize * 2.5;
// configure
var margin = this.options.margin;
var cellSize = this.cellSize;
var colNumber = this.colNumber;
var rowNumber = this.rowNumber;
var colorBuckets = this.colorBuckets;
var colors = this.options.colors;
var rowIndex = this.rowIndex;
var colIndex = this.colIndex;
var colLabel = this.colLabel;
var rowLabel = this.rowLabel;
var width = this.width;
var height = this.height;
var legendElementWidth = this.legendElementWidth;
this.nColors = this.options.colors.length;
// color scale
var colorScale = d3.scale.quantile()
.domain([ -10, 0, 10])
.range(colors);
this.colorScale = d3.scale.quantile()
.domain([this.min, this.mid, this.max])
.range(this.options.colors);
// add graph
var svg = d3.select(container[0]).append('svg')
//
// add ui elements
//
// create ui elements
this.$tooltip = $(this._templateTooltip());
this.$select = $(this._templateSelect());
// append
this.$el.append(this.$tooltip);
this.$el.append(this.$select);
// add event to select field
this.$select.on('change', function(){
self._order(this.value);
});
//
// draw
//
this._draw();
},
_draw: function() {
// link this
var self = this;
// container
var container_width = this.$el.width();
var container_height = this.$el.height();
// get height
this.width = this.$el.width() - this.options.margin.left - this.options.margin.right;
this.height = this.$el.height() - this.options.margin.top - this.options.margin.bottom;
// calculate cell size
this.cellSize = Math.min(parseInt(this.height / this.rowNumber),
parseInt(this.width / this.colNumber));
// set width/height for plugin
this.width = this.cellSize * this.colNumber;
this.height = this.cellSize * this.rowNumber;
// get dimensions
var margin = this.options.margin;
var width = this.width;
var height = this.height;
// add main group and translate
this.svg = d3.select(this.$el[0]).append('svg')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("transform", "translate(" + (container_width - width) / 2 + "," + (container_height - height) / 2 + ")")
// row labels
var rowSortOrder=false;
var colSortOrder=false;
var rowLabels = svg.append("g")
.selectAll(".rowLabelg")
.data(rowLabel)
.enter()
.append("text")
.text(function (d) { return d; })
.attr("x", 0)
.attr("y", function (d, i) { return rowIndex.indexOf(i+1) * cellSize; })
.style("font-size", cellSize + "px")
.style("text-anchor", "end")
.attr("transform", "translate(-10," + cellSize / 1.5 + ")")
.attr("class", function (d,i) { return "rowLabel mono r"+i;} )
.on("mouseover", function(d) {
d3.select(this).classed("text-hover",true);
d3.select(this).style("font-size", parseInt(cellSize * 1.3) + "px");
})
.on("mouseout" , function(d) {
d3.select(this).classed("text-hover",false);
d3.select(this).style("font-size", parseInt(cellSize) + "px");
})
.on("click", function(d,i) {rowSortOrder=!rowSortOrder; sortbylabel("r",i,rowSortOrder);d3.select("#order").property("selectedIndex", 4).node().focus();;});
// column labels
var colLabels = svg.append("g")
.selectAll(".colLabelg")
.data(colLabel)
.enter()
.append("text")
.text(function (d) { return d; })
.attr("x", 0)
.attr("y", function (d, i) { return colIndex.indexOf(i+1) * cellSize; })
.style("font-size", cellSize + "px")
.style("text-anchor", "left")
.attr("transform", "translate("+cellSize/2 + ",-17) rotate (-90)")
.attr("class", function (d,i) { return "colLabel mono c"+i;} )
.on("mouseover", function(d) {
d3.select(this).classed("text-hover",true);
d3.select(this).style("font-size", parseInt(cellSize * 1.3) + "px");
})
.on("mouseout" , function(d) {
d3.select(this).classed("text-hover",false);
d3.select(this).style("font-size", parseInt(cellSize) + "px");
})
.on("click", function(d,i) {colSortOrder=!colSortOrder; sortbylabel("c",i,colSortOrder);d3.select("#order").property("selectedIndex", 4).node().focus();;});
// heat map
var heatMap = svg.append("g").attr("class","g3")
.selectAll(".cellg")
.data(data,function(d){return d.row+":"+d.col;})
.enter()
.append("rect")
.attr("x", function(d) { return colIndex.indexOf(d.col) * cellSize; })
.attr("y", function(d) { return rowIndex.indexOf(d.row) * cellSize; })
.attr("class", function(d){return "cell cell-border cr"+(d.row-1)+" cc"+(d.col-1);})
.attr("width", cellSize)
.attr("height", cellSize)
.style("fill", function(d) { return colorScale(d.value); })
// .on("click", function(d) {
// var rowtext=d3.select(".r"+(d.row-1));
// if(rowtext.classed("text-selected")==false){
// rowtext.classed("text-selected",true);
// }else{
// rowtext.classed("text-selected",false);
// }
//})
.on("mouseover", function(d){
//highlight text
d3.select(this).classed("cell-hover",true);
d3.selectAll(".rowLabel").classed("text-highlight",function(r,ri){ return ri==(d.row-1);});
d3.selectAll(".colLabel").classed("text-highlight",function(c,ci){ return ci==(d.col-1);});
//d3.selectAll(".colLabel").style("font-size", parseInt(cellSize * 1.3) + "px");
//d3.selectAll(".rowLabel").style("font-size", parseInt(cellSize * 1.3) + "px");
//Update the tooltip position and value
d3.select("#heatmap-tooltip")
.style("left", (d3.event.pageX+10) + "px")
.style("top", (d3.event.pageY-10) + "px")
.select("#value")
.text("lables:"+rowLabel[d.row-1]+","+colLabel[d.col-1]+"\ndata:"+d.value+"\nrow-col-idx:"+d.col+","+d.row+"\ncell-xy "+this.x.baseVal.value+", "+this.y.baseVal.value);
//Show the tooltip
d3.select("#heatmap-tooltip").classed("hidden", false);
})
.on("mouseout", function(){
d3.select(this).classed("cell-hover",false);
d3.selectAll(".rowLabel").classed("text-highlight",false);
d3.selectAll(".colLabel").classed("text-highlight",false);
//d3.selectAll(".colLabel").style("font-size", parseInt(cellSize) + "px");
//d3.selectAll(".rowLabel").style("font-size", parseInt(cellSize) + "px");
d3.select("#heatmap-tooltip").classed("hidden", true);
});
var legend = svg.selectAll(".legend")
.data([-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10])
.enter().append("g")
.attr("class", "legend");
legend.append("rect")
.attr("x", function(d, i) { return legendElementWidth * i; })
.attr("y", height+(cellSize*2))
.attr("width", legendElementWidth)
.attr("height", cellSize)
.style("fill", function(d, i) { return colors[i]; });
legend.append("text")
.attr("class", "mono")
.text(function(d) { return d; })
.attr("width", legendElementWidth)
.attr("x", function(d, i) { return legendElementWidth * i; })
.attr("y", height + (cellSize*4))
.style("font-size", cellSize + "px");
// change ordering of cells
function sortbylabel(rORc,i,sortOrder) {
var t = svg.transition().duration(3000);
var values=[];
var sorted; // sorted is zero-based index
d3.selectAll(".c"+rORc+i)
.filter(function(ce){
values.push(ce.value);
});
if(rORc=="r"){ // sort valuesatio of a gene
sorted=d3.range(colNumber).sort(function(a,b){ if(sortOrder){ return values[b]-values[a];}else{ return values[a]-values[b];}});
t.selectAll(".cell")
.attr("x", function(d) { return sorted.indexOf(d.col-1) * cellSize; });
t.selectAll(".colLabel")
.attr("y", function (d, i) { return sorted.indexOf(i) * cellSize; });
} else { // sort valuesatio of a contrast
sorted=d3.range(rowNumber).sort(function(a,b){if(sortOrder){ return values[b]-values[a];}else{ return values[a]-values[b];}});
t.selectAll(".cell")
.attr("y", function(d) { return sorted.indexOf(d.row-1) * cellSize; });
t.selectAll(".rowLabel")
.attr("y", function (d, i) { return sorted.indexOf(i) * cellSize; });
}
}
d3.select("#order").on("change",function(){
order(this.value);
});
function order(value) {
if(value=="hclust"){
var t = svg.transition().duration(3000);
t.selectAll(".cell")
.attr("x", function(d) { return colIndex.indexOf(d.col) * cellSize; })
.attr("y", function(d) { return rowIndex.indexOf(d.row) * cellSize; });
t.selectAll(".rowLabel")
.attr("y", function (d, i) { return rowIndex.indexOf(i+1) * cellSize; });
t.selectAll(".colLabel")
.attr("y", function (d, i) { return colIndex.indexOf(i+1) * cellSize; });
} else if (value=="probecontrast") {
var t = svg.transition().duration(3000);
t.selectAll(".cell")
.attr("x", function(d) { return (d.col - 1) * cellSize; })
.attr("y", function(d) { return (d.row - 1) * cellSize; });
t.selectAll(".rowLabel")
.attr("y", function (d, i) { return i * cellSize; });
t.selectAll(".colLabel")
.attr("y", function (d, i) { return i * cellSize; });
} else if (value=="probe") {
var t = svg.transition().duration(3000);
t.selectAll(".cell")
.attr("y", function(d) { return (d.row - 1) * cellSize; });
t.selectAll(".rowLabel")
.attr("y", function (d, i) { return i * cellSize; });
} else if (value=="contrast"){
var t = svg.transition().duration(3000);
t.selectAll(".cell")
.attr("x", function(d) { return (d.col - 1) * cellSize; });
t.selectAll(".colLabel")
.attr("y", function (d, i) { return i * cellSize; });
}
}
// reset sorting
this.rowSortOrder = false;
this.colSortOrder = false;
// build
this.rowLabels = this._buildRowLabels();
this.colLabels = this._buildColLabels();
this.heatMap = this._buildHeatMap();
this.legend = this._buildLegend();
},
// selection of cells
_addSelectionTool: function() {
//
// selection
//
var sa=d3.select(".g3")
.on("mousedown", function() {
if( !d3.event.altKey) {
d3.selectAll(".cell-selected").classed("cell-selected",false);
d3.selectAll(".rowLabel").classed("text-selected",false);
d3.selectAll(".colLabel").classed("text-selected",false);
d3.selectAll(".cell-selected").classed("cell-selected", false);
d3.selectAll(".rowLabel").classed("text-selected", false);
d3.selectAll(".colLabel").classed("text-selected", false);
}
var p = d3.mouse(this);
sa.append("rect")
@@ -374,8 +276,7 @@ return Backbone.View.extend(
// deselect all temporary selected state objects
d3.selectAll(".cell-selection.cell-selected").classed("cell-selected", false);
d3.selectAll(".text-selection.text-selected").classed("text-selected",false);
d3.selectAll('.cell').filter(function(cell_d, i) {
d3.selectAll(".cell").filter(function(cell_d, i) {
if(!d3.select(this).classed("cell-selected") &&
// inner circle inside selection frame
(this.x.baseVal.value)+cellSize >= d.x && (this.x.baseVal.value)<=d.x+d.width &&
@@ -385,11 +286,11 @@ return Backbone.View.extend(
.classed("cell-selection", true)
.classed("cell-selected", true);
d3.select(".r"+(cell_d.row-1))
d3.select(".r"+(cell_d.row_rank))
.classed("text-selection",true)
.classed("text-selected",true);
d3.select(".c"+(cell_d.col-1))
d3.select(".c"+(cell_d.col_rank))
.classed("text-selection",true)
.classed("text-selected",true);
}
@@ -417,14 +318,353 @@ return Backbone.View.extend(
});
},
// build legend
_buildLegend: function() {
// link this
var self = this;
// gather data
var cellSize = this.cellSize;
var height = this.height;
var legendCellWidth = this.width / this.nColors;
// create range labels
var dataRange = [];
for(var i = 0; i < this.nColors; i++) {
dataRange.push('');
}
// prepare indices
var dataRangeMin = 0;
var dataRangeMid = parseInt((dataRange.length - 1) / 2);
var dataRangeMax = dataRange.length - 1;
// add labels
dataRange[dataRangeMin] = this.min;
dataRange[dataRangeMid] = this.mid;
dataRange[dataRangeMax] = this.max;
// create legend
var legend = this.svg.selectAll(".legend")
.data(dataRange)
.enter().append("g")
.attr("class", "legend");
// add boxes
legend.append("rect")
.attr("x", function(d, i) {
return legendCellWidth * i;
})
.attr("y", height + cellSize)
.attr("width", legendCellWidth)
.attr("height", cellSize)
.style("fill", function(d, i) {
return self.options.colors[i];
});
// add text
legend.append("text")
.attr("class", "mono")
.text(function(d) {
return d;
})
.attr("width", legendCellWidth)
.attr("x", function(d, i) {
return legendCellWidth * i;
})
.attr("y", height + cellSize)
.style("font-size", cellSize + "px");
},
// build column labels
_buildColLabels: function() {
// link this
var self = this;
// gather data
var cellSize = this.cellSize;
var colIndex = this.colIndex;
var colLabel = this.colLabel;
// column labels
var colLabels = this.svg.append("g")
.selectAll(".colLabelg")
.data(colLabel)
.enter()
.append("text")
.text(function (d) {
return d;
})
.attr("x", 0)
.attr("y", function (d, i) {
return colIndex.indexOf(i) * cellSize;
})
.style("font-size", cellSize + "px")
.style("text-anchor", "left")
.attr("transform", "translate(" + cellSize / 2 + ", -17) rotate (-90)")
.attr("class", function (d, i) {
return "colLabel mono c" + i;
})
.on("mouseover", function(d) {
d3.select(this).classed("text-hover",true);
d3.select(this).style("font-size", parseInt(cellSize * 1.3) + "px");
})
.on("mouseout" , function(d) {
d3.select(this).classed("text-hover",false);
d3.select(this).style("font-size", parseInt(cellSize) + "px");
})
.on("click", function(d, i) {
self.colSortOrder=!self.colSortOrder;
self._sortByLabel("c", i, self.colSortOrder);
d3.select("#order").property("selectedIndex", 4).node().focus();
});
},
// build row labels
_buildRowLabels: function() {
// link this
var self = this;
// gather data
var cellSize = this.cellSize;
var rowIndex = this.rowIndex;
var rowLabel = this.rowLabel;
// draw labels
var rowLabels = this.svg.append("g")
.selectAll(".rowLabelg")
.data(rowLabel)
.enter()
.append("text")
.text(function (d) {
return d;
})
.attr("x", 0)
.attr("y", function (d, i) {
return rowIndex.indexOf(i) * cellSize;
})
.style("font-size", cellSize + "px")
.style("text-anchor", "end")
.attr("transform", "translate(-10," + cellSize / 1.5 + ")")
.attr("class", function (d, i) {
return "rowLabel mono r" + i;
} )
.on("mouseover", function(d) {
d3.select(this).classed("text-hover",true);
d3.select(this).style("font-size", parseInt(cellSize * 1.3) + "px");
})
.on("mouseout" , function(d) {
d3.select(this).classed("text-hover",false);
d3.select(this).style("font-size", parseInt(cellSize) + "px");
})
.on("click", function(d, i) {
self.rowSortOrder=!self.rowSortOrder;
self._sortByLabel("r", i, self.rowSortOrder);
d3.select("#order").property("selectedIndex", 4).node().focus();
});
},
// build heat map
_buildHeatMap: function() {
// link this
var self = this;
// gather data
var cellSize = this.cellSize;
var rowIndex = this.rowIndex;
var rowLabel = this.rowLabel;
var colIndex = this.colIndex;
var colLabel = this.colLabel;
// heat map
var heatMap = this.svg.append("g").attr("class","g3")
.selectAll(".cellg")
.data(self.data, function(d) {
return d.row_rank + ":" + d.col_rank;
})
.enter()
.append("rect")
.attr("x", function(d) {
return colIndex.indexOf(d.col_rank) * cellSize;
})
.attr("y", function(d) {
return rowIndex.indexOf(d.row_rank) * cellSize;
})
.attr("class", function(d){
return "cell cell-border cr" + d.row_rank + " cc" + d.col_rank;
})
.attr("width", cellSize)
.attr("height", cellSize)
.style("fill", function(d) {
return self.colorScale(d.value);
})
.on("mouseover", function(d){
// highlight text
d3.select(this).classed("cell-hover",true);
d3.selectAll(".rowLabel").classed("text-highlight",function(r,ri){ return ri==(d.row_rank);});
d3.selectAll(".colLabel").classed("text-highlight",function(c,ci){ return ci==(d.col_rank);});
// update the tooltip position and value
d3.select("#heatmap-tooltip")
.style("left", (d3.event.pageX+10) + "px")
.style("top", (d3.event.pageY-10) + "px")
.select("#value")
.text("Label: " + rowLabel[d.row_rank] + " | " + colLabel[d.col_rank] + ", Value: " + d.value);
// show the tooltip
d3.select("#heatmap-tooltip").classed("hidden", false);
})
.on("mouseout", function(){
d3.select(this).classed("cell-hover",false);
d3.selectAll(".rowLabel").classed("text-highlight",false);
d3.selectAll(".colLabel").classed("text-highlight",false);
d3.select("#heatmap-tooltip").classed("hidden", true);
});
},
// change ordering of cells
_sortByLabel: function(rORc, i, sortOrder) {
// get cell size
var cellSize = this.cellSize;
// define transition / prepare element
var t = this.svg.transition().duration(this.options.pace);
// collect cells
var cells=[];
t.selectAll(".c" + rORc + i)
.filter(function(ce){
cells.push(ce);
});
// sort cells
cells.sort(function(a, b) {
if (sortOrder) {
return b.value - a.value;
} else {
return a.value - b.value;
}
});
// rows or columns
if(rORc == "r") {
// get sorted key list
var sorted = [];
for (var i in cells) {
sorted.push(cells[i].col_rank);
}
// sort cells
t.selectAll(".cell")
.attr("x", function(d) {
return sorted.indexOf(d.col_rank) * cellSize;
});
// sort labels
t.selectAll(".colLabel")
.attr("y", function (d, i) {
return sorted.indexOf(i) * cellSize;
});
} else {
// get sorted key list
sorted = [];
for (var i in cells) {
sorted.push(cells[i].row_rank);
}
// sort cells
t.selectAll(".cell")
.attr("y", function(d) {
return sorted.indexOf(d.row_rank) * cellSize;
});
// sort labels
t.selectAll(".rowLabel")
.attr("y", function (d, i) {
return sorted.indexOf(i) * cellSize;
});
}
},
// sort function
_order: function (value) {
// link this
var self = this;
// gather data
var cellSize = this.cellSize;
var rowIndex = this.rowIndex;
var rowLabel = this.rowLabel;
var colIndex = this.colIndex;
var colLabel = this.colLabel;
// set duration / select element
var t = this.svg.transition().duration(this.options.pace);
if(value=="hclust"){
t.selectAll(".cell")
.attr("x", function(d) {
return colIndex.indexOf(d.col_rank) * cellSize;
})
.attr("y", function(d) {
return rowIndex.indexOf(d.row_rank) * cellSize;
});
t.selectAll(".rowLabel")
.attr("y", function(d, i) {
return rowIndex.indexOf(i) * cellSize;
});
t.selectAll(".colLabel")
.attr("y", function(d, i) {
return colIndex.indexOf(i) * cellSize;
});
} else if (value=="byboth") {
t.selectAll(".cell")
.attr("x", function(d) {
return d.col_rank * cellSize;
})
.attr("y", function(d) {
return d.row_rank * cellSize;
});
t.selectAll(".rowLabel")
.attr("y", function (d, i) {
return i * cellSize;
});
t.selectAll(".colLabel")
.attr("y", function (d, i) {
return i * cellSize;
});
} else if (value=="byrow") {
t.selectAll(".cell")
.attr("y", function(d) {
return d.row_rank * cellSize;
});
t.selectAll(".rowLabel")
.attr("y", function (d, i) {
return i * cellSize;
});
} else if (value=="bycol"){
t.selectAll(".cell")
.attr("x", function(d) {
return d.col_rank * cellSize;
});
t.selectAll(".colLabel")
.attr("y", function (d, i) {
return i * cellSize;
});
}
},
// template
_templateSelect: function() {
return '<select id="order">' +
'<option value="hclust">by cluster</option>' +
'<option value="probecontrast">by probe name and contrast name</option>' +
'<option value="probe">by probe name</option>' +
'<option value="contrast">by contrast name</option>' +
'<option value="custom">by log2 ratio</option>' +
'<option value="hclust">Cluster</option>' +
'<option value="byboth">Sort by row and column</option>' +
'<option value="byrow">Sort by row label</option>' +
'<option value="bycol">Sort by column label</option>' +
'</select>';
},
@@ -1,5 +1,5 @@
// dependencies
define(['utils/utils', 'plugin/charts/heatmap/heatmap-plugin'], function(Utils, Plugin) {
define(['utils/utils', 'plugin/charts/heatmap/heatmap-plugin'], function(Utils, HeatmapPlugin) {
// widget
return Backbone.View.extend(
@@ -17,13 +17,17 @@ return Backbone.View.extend(
var self = this;
this.app.datasets.request(request_dictionary, function() {
console.log(request_dictionary.groups);
// loop through data groups
for (var group_index in request_dictionary.groups) {
// get group
var group = request_dictionary.groups[group_index];
// draw plot
new Plugin({
'data' : request_dictionary.groups[0].values,
'div' : self.options.canvas[0]
});
// draw plot
var heatmap = new HeatmapPlugin({
'data' : group.values,
'div' : self.options.canvas[group_index]
});
}
// set chart state
chart.state('ok', 'Heat map drawn.');