d3热图 - 放大选定区域

时间:2015-05-11 17:54:43

标签: javascript d3.js zoom heatmap

现在我重新计算我在热图上选择的所有点。我是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();
                    });
            });

0 个答案:

没有答案