martes, 10 de junio de 2014

Week 4: Moving around the reads

Now that I have scaffold to start filling the components, I can focus on rendering the actual components. One of my main concerns I have is to keep the rendered stack as short as possible, while not having to calculate all the time on which row the component is going to be.
The test page I got is getting a list of contains and you can select them to send the region to the SAM Viewer. The SAMViewer then generates an appropriate ajax quering the region to be displayed and a two step process is triggered. The first step is to render the floating divs in the container. The divs are only located in the X axis initially.
 
    render_visible: function(){
            var region = this.current_region;
            var start = region.start - this.opt.flanking_cache;
            var canvas = this._render_div;
            if(start < 0){
              start = 1;
            }
            //alert(JSON.stringify(this.alignments));
            for(i = start; i < region.end + this.opt.flanking_cache ; i++){
              if("undefined" !== typeof this.alignments[i]){
                var current_alignments = this.alignments[i];
                for (var j in current_alignments) {
                  aln = current_alignments[j];  
                  if("undefined" === typeof aln.div){ //We don't render  it again if it already exists
                    var new_div = document.createElement("div");
                    new_div.style.width = this.opt.base_width * aln.len + "px"; 
                    new_div.style.height = this.opt.fontSize ;
                    new_div.style.position = "absolute";
                    new_div.style.left = ( i - 1) * this.opt.base_width + "px"; 
                    new_div.style.backgroundColor =   this.opt.default_read_background; 
                    aln.div = new_div;
                    canvas.appendChild(new_div);
                  }
                  
                }
              }
            }
          }
In the second stage, the divs are pushed up as high as possible, without overlapping to each other. Originally I was trying to use some sort of CSS magic, but the floats can´t be customised to this level.Then, I thought on having a matrix with the occupied coordinates and keep it in the back, to know which space is free. Also, I tried to make a massive div, and use the scrollbars from the browser to move around, and just load from the current coordinate. However, the browser does render everything, displayed or not. So, for long chromosomes the solution ended up freezing the web browser.
Luckily, someone else is working in a similar problem and already queried in stack overflow (http://stackoverflow.com/questions/20048688/how-to-float-top). The answer relies on getting the global position, so I had to do a bit more of research on how to get the rectangle of my current div. So, in my case, I calculate the local rectangle.
 
    _move_to_top: function  (){
        var top = 1; // top value for next row
        var margin = 1; // space between rows
        var rows = []; // list of rows
          for (var c = 0; c < this._render_div.children.length; c++) {
              var ok = false;
              var child = this._render_div.children[c];
              var cr = {};
              cr.top = child.offsetTop;
              cr.left = child.offsetLeft;
              cr.right = cr.left + parseInt(child.style.width, 10);
              cr.bottom = cr.top + parseInt(child.style.height, 10);
             
              for (var i = 0; i < rows.length; i++) {
                  if (cr.left > rows[i].right) {
                      rows[i].right = cr.right;
                      child.style.top = rows[i].top + "px";
                      ok = true;
                      break;
                  }
                  if (cr.right < rows[i].left) {
                      rows[i].left = cr.left;
                      child.style.top = rows[i].top + "px";
                      ok = true;
                      break;
                  }
              }
              if (!ok) {
                  // add new row
                  rows.push({
                      top: top,
                      right: cr.right,
                      left: cr.left
                  }); 
                  child.style.top = top + "px";
                  top =  child.offsetTop + parseInt(child.style.height, 10) + margin;
              }
          }
      }
My next step is to enable scrolling around and testing that I don’t leak memory when moving around.

No hay comentarios:

Publicar un comentario