现在我重新计算我在热图上选择的所有点。我是D3的新手,并不特别了解缩放行为的工作原理。有人可以帮忙吗?这是一大块代码,允许我使用自选区域放大热图:
function selectArea(area,svg,dataset,num,oldxStart,oldyStart) {
svg
.attr("width",width)
.attr("height",height)
var cols = dataset.dim[1]; //x
var rows = dataset.dim[0]; //y
var zoomDat = [];
var newxLab=[];
var newyLab = [];
//Makes the selection rectangles
area
.on("mousedown", function() {
var e = this,
origin = d3.mouse(e),
rect = svg
.append("rect")
.attr("class", "zoom");
origin[0] = Math.max(0, Math.min(width, origin[0]));
origin[1] = Math.max(0, Math.min(height, origin[1]));
d3.select('body')
.on("mousemove.zoomRect", function() {
var m = d3.mouse(e);
m[0] = Math.max(0, Math.min(width, m[0]));
m[1] = Math.max(0, Math.min(height, m[1]));
rect.attr("x", Math.min(origin[0], m[0]))
.attr("y", Math.min(origin[1], m[1]))
.attr("width", Math.abs(m[0] - origin[0]))
.attr("height", Math.abs(m[1] - origin[1]));
})
.on("mouseup.zoomRect", function() {
var m = d3.mouse(e);
m[0] = Math.max(0, Math.min(width, m[0]));
m[1] = Math.max(0, Math.min(height, m[1]));
//x,y Start/Finish for the selection of data => Can draw box the other way, and still work.
var xStart = Math.min(Math.floor(origin[0]/xScale(1)), Math.floor(m[0]/xScale(1)))
var xFinish = Math.max(Math.floor(m[0]/xScale(1)), Math.floor(origin[0]/xScale(1)))+1
var yStart = Math.min(Math.floor(origin[1]/yScale(1)), Math.floor(m[1]/yScale(1)))
var yFinish =Math.max(Math.floor(m[1]/yScale(1)), Math.floor(origin[1]/yScale(1)))+1
var newcolMeta = [];
var newrowMeta = [];
var newyDend = [];
var newxDend = [];
//If the Y dendrogram is selected, make the X dendrogram undefined
//because I dont want the x dendrogram to change
if (num==1) {
xStart = 0;
xFinish = cols
//If the X dendrogram is selected, make the y dendrogram undefined
//because I dont want the y dendrogram to change
} else if (num==2) {
yStart = 0;
yFinish = rows
}
//Get the data selected and send it back to heatmapgrid
for (i = xStart; i<xFinish; i++) {
newxLab.push(dataset.cols[i]);
if (data.cols!=null) { //If there is no column clustering
newxDend.push(d3.select(".ends_X"+i).attr("id"))
}
}
for (i=yStart;i<yFinish; i++) {
newyLab.push(dataset.rows[i]);
if (data.rows !=null) { //If there is no row clustering
newyDend.push(d3.select(".ends_Y"+i).attr("id"))
}
for (j=xStart; j<xFinish; j++) {
zoomDat.push(dataset.data[i*cols+j]);
}
}
//Get the Metadata -> If there is more than one line of annotations, the data is in different places, just like the grid
if (colMeta !=null) {
for (i = 0; i<colHead.length; i++) {
for (j = xStart; j<xFinish; j++) {
newcolMeta.push(colMeta[i*cols+j])
}
}
colMeta = newcolMeta
}
if (rowMeta != null) {
for (i =0; i<rowHead.length; i++) {
for (j =yStart; j<yFinish; j++) {
newrowMeta.push(rowMeta[i*rows+j])
}
}
rowMeta = newrowMeta
}
//Set new parameters based on selected data
dataset.dim[1] = newxLab.length;
dataset.dim[0] = newyLab.length;
dataset.rows = newyLab;
dataset.cols = newxLab;
dataset.data = zoomDat;
colAnnote.data = colMeta;
rowAnnote.data = rowMeta;
//Changes the margin, if the dimensions are small enough
if (dataset.dim[0] <=100) {
marginleft=100;
}
if (dataset.dim[1] <=300) {
margintop = 130;
}
xGlobal.range([0,width-marginleft])
yGlobal.range([0,height-margintop])
var x = xGlobal(1);
var y = yGlobal(1);
//This slows down the program (Remove())
d3.selectAll('.rootDend').remove();
oldxStart += xStart
oldyStart += yStart
//olsxStart + xStart because the dendrogram is translated
heatmapGrid(el.select('svg.colormap'),dataset,oldxStart,oldyStart);
//New Vertical dendrogram
dendrogram(el.select('svg.rowDend'), data.rows, false, 250, height-margintop,newyDend,oldyStart,y);
//New Horizontal dendrogram
dendrogram(el.select('svg.colDend'), data.cols, true, width-marginleft, 250,newxDend,oldxStart,x);
//New annotation bar, if no annotations, don't do this
drawAnnotate(el.select('svg.colAnnote'), colAnnote,false, width-marginleft,10);
drawAnnotate(el.select('svg.rowAnnote'),rowAnnote,true,10,height-margintop);
//zoomDat = [];
//remove blue select rectangle
rect.remove();
});
});