details: http://www.bx.psu.edu/hg/galaxy/rev/fa318a093bf2 changeset: 3245:fa318a093bf2 user: Kanwei Li <kanwei@gmail.com> date: Thu Jan 14 17:49:20 2010 -0500 description: trackster: fix thick region display bug, stacking bugs, enable right-panel diffstat: lib/galaxy/web/controllers/tracks.py | 1 - lib/galaxy/web/controllers/visualization.py | 15 +-- static/scripts/packed/galaxy.panels.js | 2 +- static/scripts/packed/trackster.js | 2 +- static/scripts/trackster.js | 110 ++++++++++++++++----------- static/trackster.css | 6 +- templates/base_panels.mako | 2 +- templates/panels.mako | 2 +- templates/tracks/browser.mako | 35 ++++++-- 9 files changed, 105 insertions(+), 70 deletions(-) diffs (447 lines): diff -r 44526498cd00 -r fa318a093bf2 lib/galaxy/web/controllers/tracks.py --- a/lib/galaxy/web/controllers/tracks.py Thu Jan 14 15:22:10 2010 -0500 +++ b/lib/galaxy/web/controllers/tracks.py Thu Jan 14 17:49:20 2010 -0500 @@ -221,7 +221,6 @@ converted dataset (possibly new) is returned, if it cannot be converted, None is returned. """ - log.debug("Inside dataset as type") # Already of correct type if dataset.extension == type: return dataset diff -r 44526498cd00 -r fa318a093bf2 lib/galaxy/web/controllers/visualization.py --- a/lib/galaxy/web/controllers/visualization.py Thu Jan 14 15:22:10 2010 -0500 +++ b/lib/galaxy/web/controllers/visualization.py Thu Jan 14 17:49:20 2010 -0500 @@ -25,17 +25,16 @@ return query.filter_by( user=trans.user ) class VisualizationController( BaseController ): - + list_grid = VisualizationListGrid() @web.expose @web.require_login() - def index( self, trans ): - return trans.fill_template( "panels.mako", active_view='visualization', main_url=url_for( action='list' ) ) + def index( self, trans, *args, **kwargs ): + return trans.fill_template( "panels.mako", grid=self.list_grid( trans, *args, **kwargs ), active_view='visualization', main_url=url_for( action='list' ) ) - list_grid = VisualizationListGrid() - @web.expose - @web.require_login() - def list( self, trans, *args, **kwargs ): - return self.list_grid( trans, *args, **kwargs ) + # @web.expose + # @web.require_login() + # def list( self, trans, *args, **kwargs ): + # return self.list_grid( trans, *args, **kwargs ) #@web.expose #@web.require_admin diff -r 44526498cd00 -r fa318a093bf2 static/scripts/packed/galaxy.panels.js --- a/static/scripts/packed/galaxy.panels.js Thu Jan 14 15:22:10 2010 -0500 +++ b/static/scripts/packed/galaxy.panels.js Thu Jan 14 17:49:20 2010 -0500 @@ -1,1 +1,1 @@ -function ensure_dd_helper(){if($("#DD-helper").length==0){$("<div id='DD-helper'/>").css({background:"white",opacity:0,zIndex:9000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function make_left_panel(h,c,e){var g=false;var f=null;var d=function(i){var j=i;if(i<0){i=0}$(h).css("width",i);$(e).css("left",j);$(c).css("left",i+7);if(document.recalc){document.recalc()}};var a=function(){if(g){$(e).removeClass("hover");$(e).animate({left:f},"fast");$(h).css("left",-f).show().animate({left:0},"fast",function(){d(f);$(e).removeClass("hidden")});g=false}else{f=$(e).position().left;$(c).css("left",$(e).innerWidth());if(document.recalc){document.recalc()}$(e).removeClass("hover");$(h).animate({left:-f},"fast");$(e).animate({left:-1},"fast",function(){$(this).addClass("hidden")});g=true}};$(e).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(i){$("#DD-helper").show()}).bind("dragend ",function(i){$("#DD-helper").hide()}).bind("drag",function(i){x=i.offsetX;x=Math.min(400,Math.max(100,x));if(g){$(h).css("left",0);$(e).removeClass("hidden");g=false}d(x)}).bind("dragclickonly",function(i){a()}).find("div").show();var b=function(i){if((g&&i=="show")||(!g&&i=="hide")){a()}};return{force_panel:b}}function make_right_panel(a,e,h){var j=false;var g=false;var c=null;var d=function(k){$(a).css("width",k);$(e).css("right",k+9);$(h).css("right",k).css("left","");if(document.recalc){document.recalc()}};var i=function(){if(j){$(h).removeClass("hover");$(h).animate({right:c},"fast");$(a).css("right",-c).show().animate({right:0},"fast",function(){d(c);$(h).removeClass("hidden")});j=false}else{c=$(document).width()-$(h).position().left-$(h).outerWidth();$(e).css("right",$(h).innerWidth()+1);if(document.recalc){document.recalc()}$(h).removeClass("hover");$(a).animate({right:-c},"fast");$(h).animate({right:-1},"fast",function(){$(this).addClass("hidden")});j=true}g=false} ;var b=function(k){var l=$(e).width()-(j?c:0);if(l<k){if(!j){i();g=true}}else{if(g){i();g=false}}};$(h).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(k){$("#DD-helper").show()}).bind("dragend",function(k){$("#DD-helper").hide()}).bind("drag",function(k){x=k.offsetX;w=$(window).width();x=Math.min(w-100,x);x=Math.max(w-400,x);if(j){$(a).css("right",0);$(h).removeClass("hidden");j=false}d(w-x-$(this).outerWidth())}).bind("dragclickonly",function(k){i()}).find("div").show();var f=function(k){if((j&&k=="show")||(!j&&k=="hide")){i()}};return{handle_minwidth_hint:b,force_panel:f}}function hide_modal(){$(".dialog-box-container").fadeOut(function(){$("#overlay").hide();$(".dialog-box").find(".body").children().remove()})}function show_modal(f,c,e,d){if(f){$(".dialog-box").find(".title").html(f);$(".dialog-box").find(".unified-panel-header").show()}else{$(".dialog-box").find(".unified-panel-header").hide()}var a=$(".dia log-box").find(".buttons").html("");if(e){$.each(e,function(b,g){a.append($("<button/>").text(b).click(g));a.append(" ")});a.show()}else{a.hide()}var a=$(".dialog-box").find(".extra_buttons").html("");if(d){$.each(d,function(b,g){a.append($("<button/>").text(b).click(g));a.append(" ")});a.show()}else{a.hide()}if(c=="progress"){c=$("<img src='../images/yui/rel_interstitial_loading.gif')' />")}$(".dialog-box").find(".body").html(c);if(!$(".dialog-box-container").is(":visible")){$("#overlay").show();$(".dialog-box-container").fadeIn()}}function show_in_overlay(c){var d=c.width||"600";var b=c.height||"400";var a=c.scroll||"auto";$("#overlay-background").bind("click.overlay",function(){hide_modal();$("#overlay-background").unbind("click.overlay")});show_modal(null,$("<div style='margin: -5px;'><img id='close_button' style='position:absolute;right:3px;top:3px;' src='../images/icon_error_sml.gif'><iframe style='margin: 0; padding: 0;' src='"+c.url+"' width='"+d+"' height='"+b+"' sc rolling='"+a+"' frameborder='0'></iframe></div>"));$("#close_button").bind("click",function(){hide_modal()})}$(function(){$(".tab").each(function(){var a=$(this).children(".submenu");if(a.length>0){if($.browser.msie){a.prepend("<iframe style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; filter:Alpha(Opacity='0');\"></iframe>")}$(this).hover(function(){a.show()},function(){a.hide()});a.click(function(){a.hide()})}})});function user_changed(a,b){if(a){$(".loggedin-only").show();$(".loggedout-only").hide();$("#user-email").text(a);if(b){$(".admin-only").show()}}else{$(".loggedin-only").hide();$(".loggedout-only").show();$(".admin-only").hide()}}; \ No newline at end of file +function ensure_dd_helper(){if($("#DD-helper").length==0){$("<div id='DD-helper'/>").css({background:"white",opacity:0,zIndex:9000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}function make_left_panel(h,c,e){var g=false;var f=null;var d=function(i){var j=i;if(i<0){i=0}$(h).css("width",i);$(e).css("left",j);$(c).css("left",i+7);if(document.recalc){document.recalc()}};var a=function(){if(g){$(e).removeClass("hover");$(e).animate({left:f},"fast");$(h).css("left",-f).show().animate({left:0},"fast",function(){d(f);$(e).removeClass("hidden")});g=false}else{f=$(e).position().left;$(c).css("left",$(e).innerWidth());if(document.recalc){document.recalc()}$(e).removeClass("hover");$(h).animate({left:-f},"fast");$(e).animate({left:-1},"fast",function(){$(this).addClass("hidden")});g=true}};$(e).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(i){$("#DD-helper").show()}).bind("dragend ",function(i){$("#DD-helper").hide()}).bind("drag",function(i){x=i.offsetX;x=Math.min(400,Math.max(100,x));if(g){$(h).css("left",0);$(e).removeClass("hidden");g=false}d(x)}).bind("dragclickonly",function(i){a()}).find("div").show();var b=function(i){if((g&&i=="show")||(!g&&i=="hide")){a()}};return{force_panel:b}}function make_right_panel(a,e,h){var j=false;var g=false;var c=null;var d=function(k){$(a).css("width",k);$(e).css("right",k+9);$(h).css("right",k).css("left","");if(document.recalc){document.recalc()}};var i=function(){if(j){$(h).removeClass("hover");$(h).animate({right:c},"fast");$(a).css("right",-c).show().animate({right:0},"fast",function(){d(c);$(h).removeClass("hidden")});j=false}else{c=$(document).width()-$(h).position().left-$(h).outerWidth();$(e).css("right",$(h).innerWidth()+1);if(document.recalc){document.recalc()}$(h).removeClass("hover");$(a).animate({right:-c},"fast");$(h).animate({right:-1},"fast",function(){$(this).addClass("hidden")});j=true}g=false} ;var b=function(k){var l=$(e).width()-(j?c:0);if(l<k){if(!j){i();g=true}}else{if(g){i();g=false}}};$(h).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(k){$("#DD-helper").show()}).bind("dragend",function(k){$("#DD-helper").hide()}).bind("drag",function(k){x=k.offsetX;w=$(window).width();x=Math.min(w-100,x);x=Math.max(w-400,x);if(j){$(a).css("right",0);$(h).removeClass("hidden");j=false}d(w-x-$(this).outerWidth())}).bind("dragclickonly",function(k){i()}).find("div").show();var f=function(k){if((j&&k=="show")||(!j&&k=="hide")){i()}};return{handle_minwidth_hint:b,force_panel:f}}function hide_modal(){$(".dialog-box-container").fadeOut(function(){$("#overlay").hide();$(".dialog-box").find(".body").children().remove()})}function show_modal(f,c,e,d){if(f){$(".dialog-box").find(".title").html(f);$(".dialog-box").find(".unified-panel-header").show()}else{$(".dialog-box").find(".unified-panel-header").hide()}var a=$(".dia log-box").find(".buttons").html("");if(e){$.each(e,function(b,g){a.append($("<button/>").text(b).click(g));a.append(" ")});a.show()}else{a.hide()}var a=$(".dialog-box").find(".extra_buttons").html("");if(d){$.each(d,function(b,g){a.append($("<button/>").text(b).click(g));a.append(" ")});a.show()}else{a.hide()}if(c=="progress"){c=$("<img src='../images/yui/rel_interstitial_loading.gif')' />")}$(".dialog-box").find(".body").html(c);if(!$(".dialog-box-container").is(":visible")){$("#overlay").show();$(".dialog-box-container").fadeIn()}}function show_in_overlay(c){var d=c.width||"600";var b=c.height||"400";var a=c.scroll||"auto";$("#overlay-background").bind("click.overlay",function(){hide_modal();$("#overlay-background").unbind("click.overlay")});show_modal(null,$("<div style='margin: -5px;'><img id='close_button' style='position:absolute;right:-12px;top:-12px;' src='../images/delete_icon.png'><iframe style='margin: 0; padding: 0;' src='"+c.url+"' width='"+d+"' height='"+b+"' s crolling='"+a+"' frameborder='0'></iframe></div>"));$("#close_button").bind("click",function(){hide_modal()})}$(function(){$(".tab").each(function(){var a=$(this).children(".submenu");if(a.length>0){if($.browser.msie){a.prepend("<iframe style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; filter:Alpha(Opacity='0');\"></iframe>")}$(this).hover(function(){a.show()},function(){a.hide()});a.click(function(){a.hide()})}})});function user_changed(a,b){if(a){$(".loggedin-only").show();$(".loggedout-only").hide();$("#user-email").text(a);if(b){$(".admin-only").show()}}else{$(".loggedin-only").hide();$(".loggedout-only").show();$(".admin-only").hide()}}; \ No newline at end of file diff -r 44526498cd00 -r fa318a093bf2 static/scripts/packed/trackster.js --- a/static/scripts/packed/trackster.js Thu Jan 14 15:22:10 2010 -0500 +++ b/static/scripts/packed/trackster.js Thu Jan 14 17:49:20 2010 -0500 @@ -1,1 +1,1 @@ -var DEBUG=false;var DENSITY=1000,FEATURE_LEVELS=100,DATA_ERROR="There was an error in indexing this dataset.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=20,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src="../images/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src="../images/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src="../images/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src="../images/visualization/strand_left_inv.png";left_ img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}var Cache=function(a){this.num_elements=a;this.obj_cache={};this.key_ary=[]};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c}});var View=function(b,a){this.chrom=b;this.tracks=[];this.max_low=0;this.max_high=a;this.center=(this.max_high-this.max_low)/2;this.span=this.max_high-this.max_low;this.zoom_factor=3;this.zoom_level=0};$.extend(View.prototype,{add_track:function(a){a.view=this;this.tracks.push(a);if(a.init){a.init()}},redraw:function(){var d=this.span/Math.pow(this.zoom_factor,this.zoom_level),b=thi s.center-(d/2),e=b+d;if(b<0){b=0;e=b+d}else{if(e>this.max_high){e=this.max_high;b=e-d}}this.low=Math.floor(b);this.high=Math.ceil(e);this.center=Math.round(this.low+(this.high-this.low)/2);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/DENSITY)/Math.LN10));this.zoom_res=Math.max(1,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS)));$("#overview-box").css({left:(this.low/this.span)*$("#overview-viewport").width(),width:Math.max(12,((this.high-this.low)/this.span)*$("#overview-viewport").width())}).show();$("#low").val(commatize(this.low));$("#high").val(commatize(this.high));for(var c=0,a=this.tracks.length;c<a;c++){this.tracks[c].draw()}},zoom_in:function(a){if(this.max_high===0||this.high-this.low<30){return}if(a){this.center=a/$(document).width()*(this.high-this.low)+this.low}this.zoom_level+=1;this.redraw()},zoom_out:function(){if(this.max_high===0){return}if(this.zoom_level<=0){this.zoom_level=0;return}this.zoom_level-=1;thi s.redraw()}});var Track=function(a,b){this.name=a;this.parent_element=b;this.make_container()};$.extend(Track.prototype,{make_container:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div class='track'></div>").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)}});var TiledTrack=function(){};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;if(DEBUG){$("#debug").text(d+" "+this.view.zoom_res)}var l=$("<div style='position: relative;'></div>");this.content_div.children(":first").remove();this.content_div.append(l);var m=this.content_div.width()/f;var i=20;var h;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+this.view.zoom_level+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b=(g-j)*m;if(this.left_off set){b-=this.left_offset}c.css({left:b});l.append(c);i=Math.max(i,c.height())}else{h=this.draw_tile(d,a,l,m);if(h){this.tile_cache.set(k,h);i=Math.max(i,h.height())}}this.content_div.css("height",i);a+=1}}});var LabelTrack=function(a){Track.call(this,null,a);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var LineTrack=function(c,b,d,a){this.tile_cache=new Cache(CACHED_TILES_LINE);Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.indexer=d;this.height_px=(a?a:100);this.container_div.addClass("line -track");this.dataset_id=b;this.data_queue={};this.cache=new Cache(CACHED_DATA)};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this;a.content_div.text(DATA_LOADING);$.getJSON(data_url,{stats:true,indexer:a.indexer,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){if(!c||c=="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR)}else{if(c=="no data"){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(c=="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.min_value=c.min;a.max_value=c.max;a.vertical_range=a.max_value-a.min_value;var d=$("<div class='yaxislabel'>"+a.min_value+"</div>");var b=$("<div class='yaxislabel'>"+a.max_value+"</div>");b.css({position:"relative",top:"35px"});b.prependTo(a.container_div);d.css({position:"relative",top:a.height_ px+32+"px"});d.prependTo(a.container_div);a.draw()}}}})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.getJSON(data_url,{indexer:this.indexer,chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},function(g){c.cache.set(e,g);delete c.data_queue[e];c.draw()})}},draw_tile:function(d,a,m,o){if(!this.vertical_range){return}var h=a*DENSITY*d,b=DENSITY*d,c=$("<canvas class='tile'></canvas>"),l=d+"_"+a;if(!this.cache.get(l)){this.get_data(d,a);return}var g=this.cache.get(l);c.css({position:"absolute",top:0,left:(h-this.view.low)*o});c.get(0).width=Math.ceil(b*o);c.get(0).height=this.height_px;var n=c.get(0).getContext("2d");var e=false;n.beginPath();for(var f=0;f<g.length-1;f++){var k=g[f][0]-h;var j=g[f][1];if(isNaN(j)){e=false}else{k=k*o;j=(j-this.min_value)/this.vertical_range*this.height_px;if(e){n.lineTo(k,j)}else{n.moveTo(k,j);e=true}}}n.stroke();m.append(c);retu rn c}});var FeatureTrack=function(c,b,d,a){this.tile_cache=new Cache(CACHED_TILES_FEATURE);Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.indexer=d;this.height_px=(a?a:100);this.container_div.addClass("feature-track");this.dataset_id=b;this.zo_slots={};this.show_labels_scale=0.001;this.showing_labels=false;this.vertical_gap=10;this.base_color="#2C3143";this.default_font="9px Monaco, Lucida Console, monospace";this.left_offset=200;this.inc_slots={};this.data_queue={};this.data_cache=new Cache(20)};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this;a.content_div.text(DATA_LOADING);$.getJSON(data_url,{indexer:a.indexer,low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom},function(b){if(b=="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR)}else{if(b.length===0||b=="no data"){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(b=="pending"){a.container_div.addCla ss("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.values=b;a.calc_slots();a.slots=a.zo_slots;a.draw()}}}})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{indexer:b.indexer,chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,include_blocks:true},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},calc_slots:function(){var c=[],b=this.content_div.width()/(this.view.high-this.view.low),a=this.view.max_high,e=this.view.max_low;for(var f=0,g=this.values.length;f<g;f++){var h,k,l=this.values[f];h=Math.floor((l.start-e)*b);k=Math.ceil((l.end-e)*b);var d=0;while(true){if(c[d]===undefined||c[d]<h){c[d]=k;this.zo_slots[l.uid]=d;break}d++}}this.height_px=c.length*this.vertical_gap+15;this.content_div.css("height",this.height_px+"px")},incremental_slots:function(a,b){if(!this.inc_slots[a]){this.inc _slots[a]={};this.inc_slots[a].w_scale=DENSITY/Math.pow(FEATURE_LEVELS,a+1)}var k=this.inc_slots[a];var d=[],l=[],c=0,m=$("<canvas></canvas>").get(0).getContext("2d"),f=this.view.max_low;for(var g=0,h=b.length;g<h;g++){var n=b[g];if(k[n.uid]){c=Math.max(c,k[n.uid]);d[k[n.uid]]=Math.ceil((n.end-f)*k.w_scale)}else{l.push(n)}}for(var g=0,h=l.length;g<h;g++){var n=l[g];f_start=Math.floor((n.start-f)*k.w_scale);f_start-=m.measureText(n.name).width;f_end=Math.ceil((n.end-f)*k.w_scale);var e=0;while(true){if(d[e]===undefined||d[e]<f_start){d[e]=f_end;k[n.uid]=e;c=Math.max(c,e);break}e++}}return c},draw_tile:function(A,F,n,r){if(!this.values){return}var G=F*DENSITY*A,c=(F+1)*DENSITY*A,v=DENSITY*A;var K,u,h;if(r>this.show_labels_scale){if(!this.showing_labels){this.showing_labels=true}for(var B in this.data_cache.obj_cache){var p=B.split("_"),e=p[0],d=p[1];if(e<=G&&d>=c){K=this.data_cache.get(B);break}}if(!K){this.data_queue[[G,c]]=true;this.get_data(G,c);return}h=this.incremental_sl ots(this.view.zoom_res,K)*this.vertical_gap+15;u=this.inc_slots[this.view.zoom_res]}else{if(this.showing_labels){this.showing_labels=false}h=this.height_px;u=this.zo_slots;K=this.values}var y=Math.ceil(v*r),x=$("<canvas class='tile'></canvas>");x.css({position:"absolute",top:0,left:(G-this.view.low)*r-this.left_offset});x.get(0).width=y+this.left_offset;x.get(0).height=h;var z=x.get(0).getContext("2d");z.fillStyle=this.base_color;z.font=this.default_font;z.textAlign="right";var C=0;for(var D=0,E=K.length;D<E;D++){var m=K[D];if(m.start<=c&&m.end>=G){var g=Math.floor(Math.max(0,(m.start-G)*r)),l=Math.ceil(Math.min(y,(m.end-G)*r)),f=u[m.uid]*this.vertical_gap;var a,L,b=null,s=null;if(m.thick_start&&m.thick_end){b=Math.floor(Math.max(0,(m.thick_start-G)*r));s=Math.ceil(Math.min(y,(m.thick_end-G)*r))}if(!this.showing_labels){z.fillRect(g+this.left_offset,f+5,l-g,1)}else{if(z.fillText&&m.start>G){z.fillText(m.name,g-1+this.left_offset,f+8)}var I=m.blocks;if(I){if(m.strand){if(m.st rand=="+"){z.fillStyle=RIGHT_STRAND}else{if(m.strand=="-"){z.fillStyle=LEFT_STRAND}}z.fillRect(g+this.left_offset,f,l-g,10);z.fillStyle=this.base_color}for(var B=0,J=I.length;B<J;B++){var q=I[B],o=Math.floor(Math.max(0,(q[0]-G)*r)),H=Math.ceil(Math.min(y,(q[1]-G)*r));if(o>H){continue}a=5;L=3;z.fillRect(o+this.left_offset,f+L,H-o,a);if(b&&(o<s||H>b)){a=9;L=1;var w=Math.max(o,b),t=Math.min(H,s);z.fillRect(w+this.left_offset,f+L,t-w,a)}}}else{a=9;L=1;z.fillRect(g+this.left_offset,f+L,l-g,a);if(m.strand){if(m.strand=="+"){z.fillStyle=RIGHT_STRAND_INV}else{if(m.strand=="-"){z.fillStyle=LEFT_STRAND_INV}}z.fillRect(g+this.left_offset,f,l-g,10);z.fillStyle=this.base_color}}}C++}}n.append(x);return x}});var ReadTrack=function(c,b,d,a){this.tile_cache=new Cache(CACHED_TILES_FEATURE);Track.call(this,c,$("#viewport"));TiledTrack.call(this);FeatureTrack.call(this,c,b,d,a);this.default_font="9px Monaco, Lucida Console, monospace"};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureT rack.prototype,{draw_tile:function(w,A,n,o){if(!this.values){return}var B=A*DENSITY*w,f=(A+1)*DENSITY*w,r=DENSITY*w;var E,q,k;k=this.height_px;q=this.zo_slots;E=this.values;var u=Math.ceil(r*o),s=$("<canvas class='tile'></canvas>");var b=$("<canvas></canvas>").get(0).getContext("2d");s.css({position:"absolute",top:0,left:(B-this.view.low)*o-this.left_offset});s.get(0).width=u+this.left_offset;s.get(0).height=k;var v=s.get(0).getContext("2d");v.fillStyle=this.base_color;v.font=this.default_font;v.textAlign="right";var t=v.measureText("A").width;var x=0;for(var y=0,z=E.length;y<z;y++){var m=E[y];if(m.start<=f&&m.end>=B){var h=Math.floor(Math.max(0,(m.start-B)*o)),l=Math.ceil(Math.min(u,(m.end-B)*o)),g=q[m.uid]*this.vertical_gap;var a,F,e=null,p=null;if(o>t){for(var C=0,d=m.name.length;C<d;C++){var D=Math.floor(Math.max(0,(m.start+C-B)*o));v.fillText(m.name[C],D+this.left_offset,g+8)}}else{v.fillRect(h+this.left_offset,g+4,l-h,3)}}}n.append(s);return s}}); \ No newline at end of file +var DEBUG=false;var DENSITY=1000,FEATURE_LEVELS=100,DATA_ERROR="There was an error in indexing this dataset.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=20,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src="../images/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src="../images/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src="../images/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src="../images/visualization/strand_left_inv.png";left_ img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}var Cache=function(a){this.num_elements=a;this.obj_cache={};this.key_ary=[]};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c}});var View=function(b,a){this.chrom=b;this.tracks=[];this.max_low=0;this.max_high=a;this.center=(this.max_high-this.max_low)/2;this.span=this.max_high-this.max_low;this.zoom_factor=3;this.zoom_level=0};$.extend(View.prototype,{add_track:function(a){a.view=this;this.tracks.push(a);if(a.init){a.init()}},redraw:function(){var d=this.span/Math.pow(this.zoom_factor,this.zoom_level),b=thi s.center-(d/2),e=b+d;if(b<0){b=0;e=b+d}else{if(e>this.max_high){e=this.max_high;b=e-d}}this.low=Math.floor(b);this.high=Math.ceil(e);this.center=Math.round(this.low+(this.high-this.low)/2);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/DENSITY)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));$("#overview-box").css({left:(this.low/this.span)*$("#overview-viewport").width(),width:Math.max(12,((this.high-this.low)/this.span)*$("#overview-viewport").width())}).show();$("#low").val(commatize(this.low));$("#high").val(commatize(this.high));for(var c=0,a=this.tracks.length;c<a;c++){this.tracks[c].draw()}},zoom_in:function(a){if(this.max_high===0||this.high-this.low<30){return}if(a){this.center=a/$(document).width()*(this.high-this.low)+this.low}this.zoom_level+=1;this.redraw()},zoom_out:function(){if(this.max_high===0){return}if(this.zoom_level<=0){this.zoom_level=0;retu rn}this.zoom_level-=1;this.redraw()}});var Track=function(a,b){this.name=a;this.parent_element=b;this.make_container()};$.extend(Track.prototype,{make_container:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div class='track'></div>").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)}});var TiledTrack=function(){};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;if(DEBUG){$("#debug").text(d+" "+this.view.zoom_res)}var l=$("<div style='position: relative;'></div>");this.content_div.children(":first").remove();this.content_div.append(l);var m=this.content_div.width()/f;var i=20;var h;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+this.view.zoom_level+"_"+a;var c=this.tile_cache.get(k);if(c){var g=a*DENSITY*d;var b =(g-j)*m;if(this.left_offset){b-=this.left_offset}c.css({left:b});l.append(c);i=Math.max(i,c.height())}else{h=this.draw_tile(d,a,l,m);if(h){this.tile_cache.set(k,h);i=Math.max(i,h.height())}}this.content_div.css("height",i);a+=1}}});var LabelTrack=function(a){Track.call(this,null,a);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var LineTrack=function(c,b,d,a){this.tile_cache=new Cache(CACHED_TILES_LINE);Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.indexer=d;this.height_px=(a?a:100);this.con tainer_div.addClass("line-track");this.dataset_id=b;this.data_queue={};this.cache=new Cache(CACHED_DATA)};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this;a.content_div.text(DATA_LOADING);$.getJSON(data_url,{stats:true,indexer:a.indexer,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){if(!c||c=="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR)}else{if(c=="no data"){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(c=="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.min_value=c.min;a.max_value=c.max;a.vertical_range=a.max_value-a.min_value;var d=$("<div class='yaxislabel'>"+a.min_value+"</div>");var b=$("<div class='yaxislabel'>"+a.max_value+"</div>");b.css({position:"relative",top:"25px"});b.prependTo(a.container_div);d.css({position :"relative",top:a.height_px+55+"px"});d.prependTo(a.container_div);a.draw()}}}})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.getJSON(data_url,{indexer:this.indexer,chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},function(g){c.cache.set(e,g);delete c.data_queue[e];c.draw()})}},draw_tile:function(d,a,m,o){if(!this.vertical_range){return}var h=a*DENSITY*d,b=DENSITY*d,c=$("<canvas class='tile'></canvas>"),l=d+"_"+a;if(!this.cache.get(l)){this.get_data(d,a);return}var g=this.cache.get(l);c.css({position:"absolute",top:0,left:(h-this.view.low)*o});c.get(0).width=Math.ceil(b*o);c.get(0).height=this.height_px;var n=c.get(0).getContext("2d");var e=false;n.beginPath();for(var f=0;f<g.length-1;f++){var k=g[f][0]-h;var j=g[f][1];if(isNaN(j)){e=false}else{k=k*o;j=(j-this.min_value)/this.vertical_range*this.height_px;if(e){n.lineTo(k,j)}else{n.moveTo(k,j);e=true}}}n. stroke();m.append(c);return c}});var FeatureTrack=function(c,b,d,a){this.tile_cache=new Cache(CACHED_TILES_FEATURE);Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.indexer=d;this.height_px=(a?a:100);this.container_div.addClass("feature-track");this.dataset_id=b;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.base_color="#2C3143";this.default_font="9px Monaco, Lucida Console, monospace";this.left_offset=200;this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.data_cache=new Cache(20)};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this;a.content_div.text(DATA_LOADING);$.getJSON(data_url,{indexer:a.indexer,low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom},function(b){if(b=="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR)}else{if(b.length===0||b=="no data"){a.container_div.addClass("nod ata");a.content_div.text(DATA_NONE)}else{if(b=="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.values=b;a.calc_slots();a.slots=a.zo_slots;a.draw()}}}})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{indexer:b.indexer,chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,include_blocks:true},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},calc_slots:function(){var b=[],a=this.content_div.width()/(this.view.high-this.view.low),d=this.view.max_low;for(var e=0,f=this.values.length;e<f;e++){var g,h,k=this.values[e];g=Math.floor((k.start-d)*a);h=Math.ceil((k.end-d)*a);var c=0;while(true){if(b[c]===undefined||b[c]<g){b[c]=h;this.zo_slots[k.uid]=c;break}c++}}this.height_px=b.length*this.vertical_nodetail_px+15;this.content_div.css("height",this.height_px+"px ")},incremental_slots:function(a,f){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.s_e_by_tile[a]={}}var h=this.inc_slots[a].w_scale,s=[],g=0,b=$("<canvas></canvas>").get(0).getContext("2d"),l=this.view.max_low;var c,e,u=[];for(var p=0,q=f.length;p<q;p++){var d=f[p];if(this.inc_slots[a][d.uid]!==undefined){g=Math.max(g,this.inc_slots[a][d.uid]);u.push(this.inc_slots[a][d.uid])}else{s.push(p)}}for(var p=0,q=s.length;p<q;p++){var d=f[s[p]];c=Math.floor((d.start-l)*h);c-=b.measureText(d.name).width;e=Math.ceil((d.end-l)*h);var o=0;while(true){var m=true;if(this.s_e_by_tile[a][o]!==undefined){for(var n=0,t=this.s_e_by_tile[a][o].length;n<t;n++){var r=this.s_e_by_tile[a][o][n];if(e>r[0]&&c<r[1]){m=false;break}}}if(m){if(this.s_e_by_tile[a][o]===undefined){this.s_e_by_tile[a][o]=[]}this.s_e_by_tile[a][o].push([c,e]);this.inc_slots[a][d.uid]=o;g=Math.max(g,o);break}o++}}return g},draw_tile:function(A,F,n,r){if(!this.values){return}var G=F*DENSITY*A,c =(F+1)*DENSITY*A,v=DENSITY*A;var K,u,h;if(r>this.show_labels_scale){if(!this.showing_details){this.showing_details=true}for(var B in this.data_cache.obj_cache){var p=B.split("_"),e=p[0],d=p[1];if(e<=G&&d>=c){K=this.data_cache.get(B);break}}if(!K){this.data_queue[[G,c]]=true;this.get_data(G,c);return}h=this.incremental_slots(this.view.zoom_res,K)*this.vertical_detail_px+15;u=this.inc_slots[this.view.zoom_res]}else{if(this.showing_details){this.showing_details=false}h=this.height_px;u=this.zo_slots;K=this.values}var y=Math.ceil(v*r),x=$("<canvas class='tile'></canvas>");x.css({position:"absolute",top:0,left:(G-this.view.low)*r-this.left_offset});x.get(0).width=y+this.left_offset;x.get(0).height=h;var z=x.get(0).getContext("2d");z.fillStyle=this.base_color;z.font=this.default_font;z.textAlign="right";var C=0;for(var D=0,E=K.length;D<E;D++){var m=K[D];if(m.start<=c&&m.end>=G){var g=Math.floor(Math.max(0,(m.start-G)*r)),l=Math.ceil(Math.min(y,(m.end-G)*r)),f=u[m.uid]*(this.showin g_details?this.vertical_detail_px:this.vertical_nodetail_px);var a,L,b=null,s=null;if(m.thick_start&&m.thick_end){b=Math.floor(Math.max(0,(m.thick_start-G)*r));s=Math.ceil(Math.min(y,(m.thick_end-G)*r))}if(!this.showing_details){z.fillRect(g+this.left_offset,f+5,l-g,1)}else{if(z.fillText&&m.start>G){z.fillText(m.name,g-1+this.left_offset,f+8)}var I=m.blocks;if(I){if(m.strand){if(m.strand=="+"){z.fillStyle=RIGHT_STRAND}else{if(m.strand=="-"){z.fillStyle=LEFT_STRAND}}z.fillRect(g+this.left_offset,f,l-g,10);z.fillStyle=this.base_color}for(var B=0,J=I.length;B<J;B++){var q=I[B],o=Math.floor(Math.max(0,(q[0]-G)*r)),H=Math.ceil(Math.min(y,(q[1]-G)*r));if(o>H){continue}a=5;L=3;z.fillRect(o+this.left_offset,f+L,H-o,a);if(b!==undefined&&(o<=s||H>=b)){a=9;L=1;var w=Math.max(o,b),t=Math.min(H,s);z.fillRect(w+this.left_offset,f+L,t-w,a)}}}else{a=9;L=1;z.fillRect(g+this.left_offset,f+L,l-g,a);if(m.strand){if(m.strand=="+"){z.fillStyle=RIGHT_STRAND_INV}else{if(m.strand=="-"){z.fillStyle=L EFT_STRAND_INV}}z.fillRect(g+this.left_offset,f,l-g,10);z.fillStyle=this.base_color}}}C++}}n.append(x);return x}});var ReadTrack=function(c,b,d,a){this.tile_cache=new Cache(CACHED_TILES_FEATURE);Track.call(this,c,$("#viewport"));TiledTrack.call(this);FeatureTrack.call(this,c,b,d,a);this.default_font="9px Monaco, Lucida Console, monospace"};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{draw_tile:function(v,z,m,n){if(!this.values){return}var A=z*DENSITY*v,e=(z+1)*DENSITY*v,q=DENSITY*v;var D,p,h;h=this.height_px;p=this.zo_slots;D=this.values;var t=Math.ceil(q*n),r=$("<canvas class='tile'></canvas>");r.css({position:"absolute",top:0,left:(A-this.view.low)*n-this.left_offset});r.get(0).width=t+this.left_offset;r.get(0).height=h;var u=r.get(0).getContext("2d");u.fillStyle=this.base_color;u.font=this.default_font;u.textAlign="right";var s=u.measureText("A").width;var w=0;for(var x=0,y=D.length;x<y;x++){var l=D[x];if(l.start<=e&&l.end>=A){var g=Math.floor (Math.max(0,(l.start-A)*n)),k=Math.ceil(Math.min(t,(l.end-A)*n)),f=p[l.uid]*this.vertical_detail_px;var a,E,d=null,o=null;if(n>s){for(var B=0,b=l.name.length;B<b;B++){var C=Math.floor(Math.max(0,(l.start+B-A)*n));u.fillText(l.name[B],C+this.left_offset,f+8)}}else{u.fillRect(g+this.left_offset,f+4,k-g,3)}}}m.append(r);return r}}); \ No newline at end of file diff -r 44526498cd00 -r fa318a093bf2 static/scripts/trackster.js --- a/static/scripts/trackster.js Thu Jan 14 15:22:10 2010 -0500 +++ b/static/scripts/trackster.js Thu Jan 14 17:49:20 2010 -0500 @@ -1,5 +1,5 @@ /* Trackster - 2009, James Taylor, Kanwei Li + 2010, James Taylor, Kanwei Li */ var DEBUG = false; @@ -19,22 +19,22 @@ right_img.src = "../images/visualization/strand_right.png"; right_img.onload = function() { RIGHT_STRAND = CONTEXT.createPattern(right_img, "repeat"); -} +}; var left_img = new Image(); left_img.src = "../images/visualization/strand_left.png"; left_img.onload = function() { LEFT_STRAND = CONTEXT.createPattern(left_img, "repeat"); -} +}; var right_img_inv = new Image(); right_img_inv.src = "../images/visualization/strand_right_inv.png"; right_img_inv.onload = function() { RIGHT_STRAND_INV = CONTEXT.createPattern(right_img_inv, "repeat"); -} +}; var left_img_inv = new Image(); left_img_inv.src = "../images/visualization/strand_left_inv.png"; left_img_inv.onload = function() { LEFT_STRAND_INV = CONTEXT.createPattern(left_img_inv, "repeat"); -} +}; function commatize( number ) { number += ''; // Convert to string @@ -49,7 +49,7 @@ this.num_elements = num_elements; this.obj_cache = {}; this.key_ary = []; -} +}; $.extend( Cache.prototype, { get: function( key ) { var index = this.key_ary.indexOf(key); @@ -109,7 +109,7 @@ // 10^log10(range / DENSITY) Close approximation for browser window, assuming DENSITY = window width this.resolution = Math.pow( 10, Math.ceil( Math.log( (this.high - this.low) / DENSITY ) / Math.LN10 ) ); - this.zoom_res = Math.max(1,Math.ceil( Math.log( this.resolution, FEATURE_LEVELS ) / Math.log(FEATURE_LEVELS) )); + this.zoom_res = Math.pow( FEATURE_LEVELS, Math.max(0,Math.ceil( Math.log( this.resolution, FEATURE_LEVELS ) / Math.log(FEATURE_LEVELS) ))); // Overview $("#overview-box").css( { @@ -282,10 +282,10 @@ var min_label = $("<div class='yaxislabel'>" + track.min_value + "</div>"); var max_label = $("<div class='yaxislabel'>" + track.max_value + "</div>"); - max_label.css({ position: "relative", top: "35px" }); - max_label.prependTo(track.container_div) + max_label.css({ position: "relative", top: "25px" }); + max_label.prependTo(track.container_div); - min_label.css({ position: "relative", top: track.height_px + 32 + "px" }); + min_label.css({ position: "relative", top: track.height_px + 55 + "px" }); min_label.prependTo(track.container_div); track.draw(); @@ -371,13 +371,15 @@ this.dataset_id = dataset_id; this.zo_slots = {}; this.show_labels_scale = 0.001; - this.showing_labels = false; - this.vertical_gap = 10; + this.showing_details = false; + this.vertical_detail_px = 10; + this.vertical_nodetail_px = 3; this.base_color = "#2C3143"; this.default_font = "9px Monaco, Lucida Console, monospace"; this.left_offset = 200; this.inc_slots = {}; this.data_queue = {}; + this.s_e_by_tile = {}; this.data_cache = new Cache(20); }; $.extend( FeatureTrack.prototype, TiledTrack.prototype, { @@ -425,10 +427,8 @@ } }, calc_slots: function() { - // console.log("num vals: " + this.values.length); var end_ary = [], scale = this.content_div.width() / (this.view.high - this.view.low), - max_high = this.view.max_high, max_low = this.view.max_low; // console.log(scale, this.view.high, this.view.low); for (var i = 0, len = this.values.length; i < len; i++) { @@ -447,43 +447,62 @@ j++; } } - this.height_px = end_ary.length * this.vertical_gap + 15; + this.height_px = end_ary.length * this.vertical_nodetail_px + 15; this.content_div.css( "height", this.height_px + "px" ); }, incremental_slots: function( level, features ) { if (!this.inc_slots[level]) { this.inc_slots[level] = {}; - this.inc_slots[level].w_scale = DENSITY / Math.pow(FEATURE_LEVELS, level+1); + this.inc_slots[level].w_scale = 1 / level; + this.s_e_by_tile[level] = {}; } - var slots = this.inc_slots[level]; - // console.log(level, slots.w_scale, slots); - var end_ary = [], + // TODO: Should calculate zoom tile index, which will improve performance + // by only having to look at a smaller subset + // if (this.s_e_by_tile[0] === undefined) { this.s_e_by_tile[0] = []; } + var w_scale = this.inc_slots[level].w_scale, undone = [], highest_slot = 0, // To measure how big to draw canvas dummy_canvas = $("<canvas></canvas>").get(0).getContext("2d"), max_low = this.view.max_low; + var f_start, f_end, slotted = []; + + // If feature already exists in slots (from previously seen tiles), use the same slot, + // otherwise if not seen, add to "undone" list for slot calculation for (var i = 0, len = features.length; i < len; i++) { var feature = features[i]; - // console.log(feature.name, feature.uid, slots[feature.uid]); - if (slots[feature.uid]) { - highest_slot = Math.max(highest_slot, slots[feature.uid]); - end_ary[ slots[feature.uid] ] = Math.ceil( (feature.end - max_low) * slots.w_scale ); + if (this.inc_slots[level][feature.uid] !== undefined) { + highest_slot = Math.max(highest_slot, this.inc_slots[level][feature.uid]); + slotted.push(this.inc_slots[level][feature.uid]); } else { - undone.push(feature); - } + undone.push(i); + } } + + // console.log("Slotted: ", features.length - undone.length, "/", features.length, slotted); for (var i = 0, len = undone.length; i < len; i++) { - var feature = undone[i]; - f_start = Math.floor( (feature.start - max_low) * slots.w_scale ); + var feature = features[undone[i]]; + f_start = Math.floor( (feature.start - max_low) * w_scale ); f_start -= dummy_canvas.measureText(feature.name).width; - f_end = Math.ceil( (feature.end - max_low) * slots.w_scale ); - // console.log(f_start, f_end, feature.name); + f_end = Math.ceil( (feature.end - max_low) * w_scale ); + var j = 0; + // Try to fit the feature to the first slot that doesn't overlap any other features in that slot while (true) { - if (end_ary[j] === undefined || end_ary[j] < f_start) { - end_ary[j] = f_end; - slots[feature.uid] = j; + var found = true; + if (this.s_e_by_tile[level][j] !== undefined) { + for (var k = 0, k_len = this.s_e_by_tile[level][j].length; k < k_len; k++) { + var s_e = this.s_e_by_tile[level][j][k]; + if (f_end > s_e[0] && f_start < s_e[1]) { + found = false; + break; + } + } + } + if (found) { + if (this.s_e_by_tile[level][j] === undefined) { this.s_e_by_tile[level][j] = []; } + this.s_e_by_tile[level][j].push([f_start, f_end]); + this.inc_slots[level][feature.uid] = j; highest_slot = Math.max(highest_slot, j); break; } @@ -504,8 +523,8 @@ // Once we zoom in enough, show name labels var data, slots, required_height; if (w_scale > this.show_labels_scale) { - if (!this.showing_labels) { - this.showing_labels = true; + if (!this.showing_details) { + this.showing_details = true; } for (var k in this.data_cache.obj_cache) { var k_split = k.split("_"), k_low = k_split[0], k_high = k_split[1]; @@ -519,12 +538,13 @@ this.get_data(tile_low, tile_high); return; } - required_height = this.incremental_slots( this.view.zoom_res, data ) * this.vertical_gap + 15; + // Calculate new slots incrementally for this new chunk of data and update height if necessary + required_height = this.incremental_slots( this.view.zoom_res, data ) * this.vertical_detail_px + 15; // console.log(required_height); slots = this.inc_slots[this.view.zoom_res]; } else { - if (this.showing_labels) { - this.showing_labels = false; + if (this.showing_details) { + this.showing_details = false; } required_height = this.height_px; slots = this.zo_slots; @@ -554,14 +574,14 @@ if (feature.start <= tile_high && feature.end >= tile_low) { var f_start = Math.floor( Math.max(0, (feature.start - tile_low) * w_scale) ), f_end = Math.ceil( Math.min(width, (feature.end - tile_low) * w_scale) ), - y_center = slots[feature.uid] * this.vertical_gap; + y_center = slots[feature.uid] * (this.showing_details ? this.vertical_detail_px : this.vertical_nodetail_px); var thickness, y_start, thick_start = null, thick_end = null; if (feature.thick_start && feature.thick_end) { thick_start = Math.floor( Math.max(0, (feature.thick_start - tile_low) * w_scale) ); thick_end = Math.ceil( Math.min(width, (feature.thick_end - tile_low) * w_scale) ); } - if (!this.showing_labels) { + if (!this.showing_details) { // Non-detail levels ctx.fillRect(f_start + this.left_offset, y_center + 5, f_end - f_start, 1); } else { @@ -569,6 +589,7 @@ if (ctx.fillText && feature.start > tile_low) { ctx.fillText(feature.name, f_start - 1 + this.left_offset, y_center + 8); // ctx.fillText(commatize(feature.start), f_start - 1 + this.left_offset, y_center + 8); + // ctx.fillText(slots[feature.uid], f_start - 1 + this.left_offset, y_center + 8); } var blocks = feature.blocks; if (blocks) { @@ -592,13 +613,12 @@ thickness = 5; y_start = 3; ctx.fillRect(block_start + this.left_offset, y_center + y_start, block_end - block_start, thickness); - - if (thick_start && (block_start < thick_end || block_end > thick_start) ) { + + if (thick_start !== undefined && (block_start <= thick_end || block_end >= thick_start) ) { thickness = 9; y_start = 1; var block_thick_start = Math.max(block_start, thick_start), block_thick_end = Math.min(block_end, thick_end); - ctx.fillRect(block_thick_start + this.left_offset, y_center + y_start, block_thick_end - block_thick_start, thickness); } @@ -654,9 +674,7 @@ // console.log(tile_low, tile_high, tile_length, w_scale); var width = Math.ceil( tile_span * w_scale ), new_canvas = $("<canvas class='tile'></canvas>"); - - var dummy_canvas = $("<canvas></canvas>").get(0).getContext("2d"); - + new_canvas.css({ position: "absolute", top: 0, @@ -677,7 +695,7 @@ if (feature.start <= tile_high && feature.end >= tile_low) { var f_start = Math.floor( Math.max(0, (feature.start - tile_low) * w_scale) ), f_end = Math.ceil( Math.min(width, (feature.end - tile_low) * w_scale) ), - y_center = slots[feature.uid] * this.vertical_gap; + y_center = slots[feature.uid] * this.vertical_detail_px; var thickness, y_start, thick_start = null, thick_end = null; if (w_scale > px_per_char) { diff -r 44526498cd00 -r fa318a093bf2 static/trackster.css --- a/static/trackster.css Thu Jan 14 15:22:10 2010 -0500 +++ b/static/trackster.css Thu Jan 14 17:49:20 2010 -0500 @@ -22,7 +22,6 @@ #nav-container { position: fixed; bottom: 0; - width: 100%; } input { @@ -60,7 +59,8 @@ width: 100%; margin: 0px; color: white; - margin-top: 10px; + margin-top: -6px; + margin-bottom: -3px; } #overview-viewport { @@ -82,7 +82,7 @@ } #viewport { - overflow-x: hidden; +/* overflow-x: hidden;*/ background-color: #fff; /* overflow: scroll;*/ /* border-bottom: 2px solid black;*/ diff -r 44526498cd00 -r fa318a093bf2 templates/base_panels.mako --- a/templates/base_panels.mako Thu Jan 14 15:22:10 2010 -0500 +++ b/templates/base_panels.mako Thu Jan 14 17:49:20 2010 -0500 @@ -318,8 +318,8 @@ <head> <title>${self.title()}</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + ${self.stylesheets()} ${self.javascripts()} - ${self.stylesheets()} </head> <body scroll="no" class="${self.body_class}"> diff -r 44526498cd00 -r fa318a093bf2 templates/panels.mako --- a/templates/panels.mako Thu Jan 14 15:22:10 2010 -0500 +++ b/templates/panels.mako Thu Jan 14 17:49:20 2010 -0500 @@ -11,6 +11,6 @@ <%def name="center_panel()"> - <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${main_url}"> </iframe> + ${grid} </%def> diff -r 44526498cd00 -r fa318a093bf2 templates/tracks/browser.mako --- a/templates/tracks/browser.mako Thu Jan 14 15:22:10 2010 -0500 +++ b/templates/tracks/browser.mako Thu Jan 14 17:49:20 2010 -0500 @@ -1,4 +1,13 @@ -<%inherit file="/base.mako"/> +<%inherit file="/base_panels.mako"/> + +<%def name="init()"> +<% + self.has_left_panel=False + self.has_right_panel=True + self.active_view="visualization" + self.message_box_visible=False +%> +</%def> <%def name="stylesheets()"> ${parent.stylesheets()} @@ -53,13 +62,16 @@ }); // To adjust the size of the viewport to fit the fixed-height footer - $(window).resize( function( e ) { - $("#content").height( $(window).height() - $("#nav-container").height() ); + var refresh = function( e ) { + $("#content").height( $(window).height() - $("#nav-container").height() - $("#masthead").height()); $("#viewport-container").height( $("#content").height() - $("#top-labeltrack").height() - $("#nav-labeltrack").height() ); + $("#nav-container").width( $("#center").width() ); view.redraw(); - }); - - $(window).resize(); + }; + $(window).bind( "resize", function(e) { refresh(e); } ); + $("#right-border").bind( "click", function(e) { refresh(e); } ); + $("#right-border").bind( "dragend", function(e) { refresh(e); } ); + $(window).trigger( "resize" ); $("#viewport").bind( "dragstart", function( e ) { this.original_low = view.low; @@ -103,15 +115,16 @@ </script> </%def> +<%def name="center_panel()"> <div id="content"> <div id="top-labeltrack"></div> <div id="viewport-container" style="overflow-x: hidden; overflow-y: auto;"> <div id="viewport"></div> </div> - <div id="nav-labeltrack"></div> + </div> <div id="nav-container"> - ## <div style="height: 5px; border-top: solid #ccc 1px"></div> + <div id="nav-labeltrack"></div> <div id="nav"> <div id="overview"> <div id="overview-viewport"> @@ -133,3 +146,9 @@ </div> </div> </div> +</%def> + +<%def name="right_panel()"> + <div>Configs</div> + +</%def> \ No newline at end of file