# HG changeset patch -- Bitbucket.org # Project galaxy-dist # URL http://bitbucket.org/galaxy/galaxy-dist/overview # User Kanwei Li <kanwei@gmail.com> # Date 1282839152 14400 # Node ID 2ac11399c20ed6b844f563b77de089b9ddff657e # Parent 291183d3896bcedef4d632a91fe7169d07bd8154 trackster: Overview track, viz cloning, "Go-to" specific location, UI fixes - Each track now has an Overview checkbox that will set the initial chromosome-wide view of that track to become the overview - Visualizations that users own or are shared with can now be cloned - Go-to feature lets users go directly to a certain chrom (eg "chr1"), or chrom and position ("chr1:1-100,000,000") - Fix double flushing when creating converter - Line tracks display mode is now inline - Use smaller font for tracks - Fix web-kit bug where using scrollbar would also trigger viewport dragging - Fix Line tracks jumping around when changing position - Made default Line track height 80px from 100px - Fix drag-zoom overlay appearing at top of header instead of Label track - Minor grid refactoring --- a/templates/tracks/browser.mako +++ b/templates/tracks/browser.mako @@ -115,7 +115,7 @@ // To adjust the size of the viewport to fit the fixed-height footer var refresh = function() { if (view !== undefined) { - view.viewport_container.height( $("#center").height() - 110 ); + view.viewport_container.height( $("#center").height() - $(".nav-container").height() - 40 ); view.nav_container.width( $("#center").width() ); view.redraw(); } --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -204,12 +204,6 @@ class UsesVisualization( SharableItemSec latest_revision = visualization.latest_revision tracks = [] - # Set dbkey. - try: - dbkey = latest_revision.dbkey - except KeyError: - dbkey = None - # Set tracks. if 'tracks' in latest_revision.config: hda_query = trans.sa_session.query( trans.model.HistoryDatasetAssociation ) @@ -227,12 +221,9 @@ class UsesVisualization( SharableItemSec "dataset_id": dataset.id, "prefs": simplejson.dumps(prefs), } ) - if dbkey is None: dbkey = dataset.dbkey # Hack for backward compat - - ## TODO: chrom needs to be able to be set; right now it's empty. config = { "title": visualization.title, "vis_id": trans.security.encode_id( visualization.id ), - "tracks": tracks, "chrom": "", "dbkey": dbkey } + "tracks": tracks, "chrom": "", "dbkey": visualization.dbkey } return config Binary file static/images/fugue/navigation.png has changed --- a/static/scripts/packed/trackster.js +++ b/static/scripts/packed/trackster.js @@ -1,1 +1,1 @@ -var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",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=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/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=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONT EXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};var Cache=function(a){this.num_elements=a;this.clear()};$.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},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init();this.reset()};$.extend( View.prototype,{init:function(){var b=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(b);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(b);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(b);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.viewport=$("<div/>").addClass("viewport").appendTo(this.viewport_container);this.nav_container=$("<div/>").addClass("nav-container").appendTo(b);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overvi ew_viewport);this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);this.low_input=$("<input/>").addClass("low").css("width","10em").appendTo(this.chrom_form);$("<span/>").text(" - ").appendTo(this.chrom_form);this.high_input=$("<input/>").addClass("high").css("width","10em").appendTo(this.chrom_form);if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.pn g" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(c){if(c.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=c.chrom_info;var f='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var e=a.chrom_data[i]["chrom"];f+='<option value="'+e+'">'+e+"</option>"}a.chrom_select.html(f);var d=function(){if(a.chrom_select.val()===""){a.intro_div.show();a.content_div.hide()}else{a.intro_div.hide();a.content_div.show()}a.chrom=a.chrom_select.val();var h=$.grep(a.chrom_data,function(k,l){return k.chrom===a.chrom})[0];a.max_high=(h!==undefined?h.len:0);a.reset();a.redraw(true);for(var j in a.tracks){var g=a.tracks[j];if(g.init){g.init()}}a.redraw()};a.chrom_select.bind("change",d);d()},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(c){a.zoom_in(c.pageX,this.viewport_container)});thi s.overview_box.bind("dragstart",function(c){this.current_x=c.offsetX}).bind("drag",function(c){var f=c.offsetX-this.current_x;this.current_x=c.offsetX;var d=Math.round(f/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-d)});this.viewport_container.bind("dragstart",function(c){this.original_low=a.low;this.current_height=c.clientY;this.current_x=c.offsetX}).bind("drag",function(f){var c=$(this);var h=f.offsetX-this.current_x;var d=c.scrollTop()-(f.clientY-this.current_height);c.scrollTop(d);this.current_height=f.clientY;this.current_x=f.offsetX;var g=Math.round(h/a.viewport_container.width()*(a.high-a.low));a.move_delta(g)});this.top_labeltrack.bind("dragstart",function(c){this.drag_origin_x=c.clientX;this.drag_origin_pos=c.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.viewport_container.height(),top:"0px",position:"absolute","background-color":"#cfc",border:"1px solid #6a6",opacity:0.5,"z-index":1000}).app endTo($(this))}).bind("drag",function(h){var d=Math.min(h.clientX,this.drag_origin_x)-a.container.offset().left,c=Math.max(h.clientX,this.drag_origin_x)-a.container.offset().left,g=(a.high-a.low),f=a.viewport_container.width();a.low_input.val(commatize(Math.round(d/f*g)+a.low));a.high_input.val(commatize(Math.round(c/f*g)+a.low));this.drag_div.css({left:d+"px",width:(c-d)+"px"})}).bind("dragend",function(j){var d=Math.min(j.clientX,this.drag_origin_x),c=Math.max(j.clientX,this.drag_origin_x),g=(a.high-a.low),f=a.viewport_container.width(),h=a.low;a.low=Math.round(d/f*g)+h;a.high=Math.round(c/f*g)+h;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_tra ck:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];this.viewport.append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.max_high){e=this.max_high}if(this.high!==0&& d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));this.overview_box.css({left:(this.low/(this.max_high-this.max_low))*this.overview_viewport.width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())}).show();this.low_input.val(commatize(this.low));this.high_input.val(commatize(this.high));if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*( this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d ||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="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.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){this.left_offset=200};$.extend(TiledT rack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+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);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)}});var LabelTrack=functio n(a,b){Track.call(this,null,a,b);this.track_type="LabelTrack";this.hidden=true;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 ReferenceTrack=function(a){this.track_type="ReferenceTrack";Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.hidden=true;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend (ReferenceTrack.prototype,TiledTrack.prototype,{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;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("he ight","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=100;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}if(c.mode!==undefined){this.prefs.mode=c.mode}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").va l(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(a.prefs.min_value);var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(a.prefs.max_value);d.css({position:"relative",top:"25px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+55+"px",left:"10px"});e.prependTo(a.container_div)})},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;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e ){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e+this.left_offset);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px,m=this.prefs.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.ro und(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(o){var a=$("<div />").addClass("form-row");var h="track_"+o+"_minval",m=$("<label></label>").attr("for",h).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),n=$("<input></input>").attr("id",h).val(b),l="track_"+o+"_maxval",g=$("<label></label>").attr("for",l).text("Max value:"),k=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",l).val(k),e="track_"+o+"_mode",d=$("<label></label>").attr("for",e).text("Display mode:"),j=(this.prefs.mode===undefined?"Line":this.prefs.mode),c=$('<select id="'+e+'"><option value="Line" id="mode_Line">Line</option><option value="Filled" id="mode_Filled">Filled</option><option value="Intensity" id="mode_Intensity">Intensity</option></select>');c.children("#mo de_"+j).attr("selected","selected");return a.append(m).append(n).append(g).append(f).append(d).append(c)},update_options:function(d){var a=$("#track_"+d+"_minval").val(),c=$("#track_"+d+"_maxval").val(),b=$("#track_"+d+"_mode option:selected").val();if(a!==this.prefs.min_value||c!==this.prefs.max_value||b!==this.prefs.mode){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(c);this.prefs.mode=b;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+d+"_minval").text(this.prefs.min_value);$("#linetrack_"+d+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var b=this,c=b.view.max_low+"_"+b.view.max_high;if(b.mode_div===undefined){b.mode_div=$("<div class='right-float menubutton popup' />").text("Display Mode").appendTo(b.header_div);b.mode="Auto";var a=function(d){b.mode_div.text(d);b.mode=d;b.tile_cache.clear();b.draw()};make_popupmenu(b.mode_div,{Auto:function(){a("Auto")},Dense:function(){a("Dense")},Squish:function(){a("Squish")},Pack:function(){a("Pack")}})}else{b.mode_div.hide()}this.init_each({low:b.view.max_low,high :b.view.max_high,dataset_id:b.dataset_id,chrom:b.view.chrom,resolution:this.view.resolution},function(d){b.mode_div.show();b.data_cache.set(c,d);b.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,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(thi s.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u++){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_ color;n.fillRect(k,h+4,e,3)}},draw_tile:function(X,h,n,ak){var E=h*DENSITY*X,ad=(h+1)*DENSITY*X,D=DENSITY*X;var ae=E+"_"+ad;var z=this.data_cache.get(ae);if(z===undefined){this.data_queue[[E,ad]]=true;this.get_data(E,ad);return}var a=Math.ceil(D*ak),L=$("<canvas class='tile'></canvas>"),Z=this.prefs.label_color,f=this.prefs.block_color,m=this.mode,V=(m==="Squish")||(m==="Dense")&&(m!=="Pack")||(m==="Auto"&&(z.extra_info==="no_detail")),P=this.left_offset,aj,s,al;if(z.dataset_type==="summary_tree"){s=30}else{if(m==="Dense"){s=15;al=10}else{al=(V?this.vertical_nodetail_px:this.vertical_detail_px);s=this.incremental_slots(this.view.zoom_res,z.data,V,m)*al+15;aj=this.inc_slots[this.view.zoom_res]}}L.css({position:"absolute",top:0,left:(E-this.view.low)*ak-P});L.get(0).width=a+P;L.get(0).height=s;n.parent().css("height",Math.max(this.height_px,s)+"px");var A=L.get(0).getContext("2d");A.fillStyle=f;A.font=this.default_font;A.textAlign="right";if(z.dataset_type=="summary_tree"){var K,H=55,ac=255-H,g=ac*2/3,R=z.data,C=z.max,l=z.avg,b=Math.ceil(z.delta*ak);for(var ag=0,w=R.length;ag<w;ag++){var T=Math.floor((R[ag][0]-E)*ak);var S=R[ag][1];if(!S){continue}K=Math.floor(ac-(S/C)*ac);A.fillStyle="rgb("+K+","+K+","+K+")";A.fillRect(T+P,0,b,20);if(this.prefs.show_counts&&A.measureText(S).width<b){if(K>g){A.fillStyle="black"}else{A.fillStyle="#ddd"}A.textAlign="center";A.fillText(S,T+P+(b/2),12)}}n.append(L);return L}var ai=z.data;var af=0;for(var ag=0,w=ai.length;ag<w;ag++){var M=ai[ag],J=M[0],ah=M[1],U=M[2],F=M[3];if(ah<=ad&&U>=E){var W=Math.floor(Math.max(0,(ah-E)*ak)),B=Math.ceil(Math.min(a,Math.max(0,(U-E)*ak))),Q=(m==="Dense"?0:aj[J]*al);if(z.dataset_type==="bai"){A.fillStyle=f;if(M[4] instanceof Array){var t=Math.floor(Math.max(0,(M[4][0]-E)*ak)),I=Math.ceil(Math.min(a,Math.max(0,(M[4][1]-E)*ak))),r=Math.floor(Math.max(0,(M[5][0]-E)*ak)),p=Math.ceil(Math.min(a,Math.max(0,(M[5][1]-E)*ak)));if(M[4][1]>=E&&M[4][0]<=ad){this.rect_or_text(A,ak,E,ad,M[4][0],M [4][2],t+P,I-t,Q)}if(M[5][1]>=E&&M[5][0]<=ad){this.rect_or_text(A,ak,E,ad,M[5][0],M[5][2],r+P,p-r,Q)}if(r>I){A.fillStyle="#999";A.fillRect(I+P,Q+5,r-I,1)}}else{A.fillStyle=f;this.rect_or_text(A,ak,E,ad,ah,F,W+P,B-W,Q)}if(m!=="Dense"&&!V&&ah>E){A.fillStyle=this.prefs.label_color;if(h===0&&W-A.measureText(F).width<0){A.textAlign="left";A.fillText(J,B+2+P,Q+8)}else{A.textAlign="right";A.fillText(J,W-2+P,Q+8)}A.fillStyle=f}}else{if(z.dataset_type==="interval_index"){if(V){A.fillRect(W+P,Q+5,B-W,1)}else{var v=M[4],O=M[5],Y=M[6],e=M[7];var u,aa,G=null,am=null;if(O&&Y){G=Math.floor(Math.max(0,(O-E)*ak));am=Math.ceil(Math.min(a,Math.max(0,(Y-E)*ak)))}if(m!=="Dense"&&F!==undefined&&ah>E){A.fillStyle=Z;if(h===0&&W-A.measureText(F).width<0){A.textAlign="left";A.fillText(F,B+2+P,Q+8)}else{A.textAlign="right";A.fillText(F,W-2+P,Q+8)}A.fillStyle=f}if(e){if(v){if(v=="+"){A.fillStyle=RIGHT_STRAND}else{if(v=="-"){A.fillStyle=LEFT_STRAND}}A.fillRect(W+P,Q,B-W,10);A.fillStyle=f}for(var ae=0,d= e.length;ae<d;ae++){var o=e[ae],c=Math.floor(Math.max(0,(o[0]-E)*ak)),N=Math.ceil(Math.min(a,Math.max((o[1]-E)*ak)));if(c>N){continue}u=5;aa=3;A.fillRect(c+P,Q+aa,N-c,u);if(G!==undefined&&!(c>am||N<G)){u=9;aa=1;var ab=Math.max(c,G),q=Math.min(N,am);A.fillRect(ab+P,Q+aa,q-ab,u)}}}else{u=9;aa=1;A.fillRect(W+P,Q+aa,B-W,u);if(M.strand){if(M.strand=="+"){A.fillStyle=RIGHT_STRAND_INV}else{if(M.strand=="-"){A.fillStyle=LEFT_STRAND_INV}}A.fillRect(W+P,Q,B-W,10);A.fillStyle=prefs.block_color}}}}}af++}}n.append(L);return L},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<inpu t type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e+"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{}); +var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",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=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),PX_PER_CHAR=CONTEXT.measureText("A").width,RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/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=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONT EXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.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},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,c,e,d,b){this.container=a;this.vis_id=d;this.dbkey=b;this.title=e;this.chrom=c;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this .has_changes=false;this.init();this.reset()};$.extend(View.prototype,{init:function(){var b=this.container,a=this;this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(b);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(b);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(b);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.nav_container=$("<div/>").addClass("nav-container").appendTo(b);this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.nav);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_o verview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){void (0)}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress",function(c){if((c.keyCode||c.which)===13){a.go_to($(this).val());$(this).hide();return false}}).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.goto_link=$("<a/>").click(function(){a.nav_input.toggle();a.nav_input.focus()}).html('<img src="'+image_path+'/fugue/navigation.png" />').appendTo(this.chrom_form);this.zo_link=$("<a/>").click(function() {a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(function(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(c){if(c.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=c.chrom_info;var e='<option value="">Select Chrom/Contig</option>';for(i in a.chrom_data){var d=a.chrom_data[i]["chrom"];e+='<option value="'+d+'">'+d+"</option>"}a.chrom_select.html(e);a.intro_div.show();a.content_div.hide();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())})},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(c){a.zoom_in(c.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(c){ this.current_x=c.offsetX}).bind("drag",function(c){var f=c.offsetX-this.current_x;this.current_x=c.offsetX;var d=Math.round(f/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-d)});this.viewport_container.bind("dragstart",function(c){this.original_low=a.low;this.current_height=c.clientY;this.current_x=c.offsetX;this.active=(c.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(f){if(!this.active){return}var c=$(this);var h=f.offsetX-this.current_x;var d=c.scrollTop()-(f.clientY-this.current_height);c.scrollTop(d);this.current_height=f.clientY;this.current_x=f.offsetX;var g=Math.round(h/a.viewport_container.width()*(a.high-a.low));a.move_delta(g)});this.top_labeltrack.bind("dragstart",function(c){this.drag_origin_x=c.clientX;this.drag_origin_pos=c.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height(),top:"0px",position:"absolute","background-color":"#cfc",border:"1px soli d #6a6",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(h){var d=Math.min(h.clientX,this.drag_origin_x)-a.container.offset().left,c=Math.max(h.clientX,this.drag_origin_x)-a.container.offset().left,g=(a.high-a.low),f=a.viewport_container.width();a.update_location(Math.round(d/f*g)+a.low,Math.round(c/f*g)+a.low);this.drag_div.css({left:d+"px",width:(c-d)+"px"})}).bind("dragend",function(j){var d=Math.min(j.clientX,this.drag_origin_x),c=Math.max(j.clientX,this.drag_origin_x),g=(a.high-a.low),f=a.viewport_container.width(),h=a.low;a.low=Math.round(d/f*g)+h;a.high=Math.round(c/f*g)+h;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack))},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(d,a,f){var c=this;var e=$.grep(c.chrom_data ,function(h,j){return h.chrom===d})[0];if(e===undefined){return}c.chrom=d;if(c.chrom===""){c.intro_div.show();c.content_div.hide()}else{c.intro_div.hide();c.content_div.show()}c.chrom_select.val(c.chrom);c.max_high=e.len;c.reset();c.redraw(true);for(var g in c.tracks){var b=c.tracks[g];if(b.init){b.init()}}if(a!==undefined&&f!==undefined){c.low=Math.max(a,0);c.high=Math.min(f,c.max_high)}c.overview_viewport.find("canvas").remove();c.redraw()},go_to:function(f){var k=this,b=f.split(":"),h=b[0],j=b[1];if(j!==undefined){try{var g=j.split("-"),a=parseInt(g[0].replace(/,/g,"")),d=parseInt(g[1].replace(/,/g,""))}catch(c){return false}}k.change_chrom(h,a,d)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.contain er_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},update_options:function(){this.has_changes=true;var b=$("ul#sortable-ul").sortable("toArray");for(var c in b){var e=b[c].split("_li")[0].split("track_")[1];this.viewport.append($("#track_"+e))}for(var d in view.tracks){var a=view.tracks[d];if(a&&a.update_options){a.update_options(d)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(f){var d=this.high-this.low,b=this.low,e=this.high;if(b<this.max_low){b=this.max_low}if(e>this.max_high){e=this.max_high}if(this.high!==0&&d<this.min_separation){e=b+this.min_separation}this.low=Math.floor(b);this.high=Math.ceil(e);this.resolution= Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));this.overview_box.css({left:(this.low/(this.max_high-this.max_low))*this.overview_viewport.width(),width:Math.max(12,(this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())}).show();this.update_location(this.low,this.high);if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b= this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()}});var Track=function(b,a,c){this.name=b;this.parent_element=c;this.view=a;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div />").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.vie w.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="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.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var c=this,b=c.view;if(c.display_modes!==undefined){if(c.mode_div===undefined){c.mode_div=$("<div class='right-float menubutton popup' />").appendTo(c.header_di v);var g=c.display_modes[0];c.mode=g;c.mode_div.text(g);var a=function(h){c.mode_div.text(h);c.mode=h;c.tile_cache.clear();c.draw()};var e={};for(var d in c.display_modes){var f=c.display_modes[d];e[f]=function(h){return function(){a(h)}}(f)}make_popupmenu(c.mode_div,e)}else{c.mode_div.hide()}}if(c.overview_check_div===undefined){c.overview_check_div=$("<div class='right-float' />").css("margin-top","-3px").appendTo(c.header_div);c.overview_check=$("<input type='checkbox' class='overview_check' />").appendTo(c.overview_check_div);c.overview_check.bind("click",function(){var h=this;b.overview_viewport.find("canvas").remove();c.set_overview();$(".overview_check").each(function(){if(this!==h){$(this).attr("checked",false)}})});c.overview_check_div.append($("<label />").text("Overview"))}};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var j=this.view.low,e=this.view.high,f=e-j,d=this.view.resolution;var l=$("<div style='position: relative;'></div>"),m=this.conte nt_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(l),this.max_height=0;var a=Math.floor(j/d/DENSITY);while((a*DENSITY*d)<e){var k=this.content_div.width()+"_"+m+"_"+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);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,k,j,e,a,d,l,m)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){if(!c.initial_canvas){c.initial_canvas=$(tile_element).clone();var l=tile_element.get(0).getContext("2d");var j=c.initial_canvas.get(0).getContext("2d");var k=l.getImageData(0,0,l.canvas.width,l.canvas.height);j.putImageData(k,0,0);c.set_overview()}c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.cont ent_div.css("height",c.max_height+"px")}}},50)},set_overview:function(){var a=this.view;a.overview_viewport.height(a.default_overview_height);a.overview_box.height(a.default_overview_height);if(this.overview_check.is(":checked")){a.overview_viewport.append(this.initial_canvas);a.overview_viewport.height(this.initial_canvas.height());a.overview_box.height(this.initial_canvas.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){Track.call(this,null,a,b);this.track_type="LabelTrack";this.hidden=true;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.chil dren(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.hidden=true;this.height_px=12;this.container_div.addClass("reference-track");this.dummy_canvas=$("<canvas></canvas>").get(0).getContext("2d");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{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;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,e=$("<canvas class='tile'></canvas>"),n=e.get(0).getContext("2d"),j=f+"_"+b;if(o>PX_PER_CHAR){if(t his.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o);n.fillText(m[h],a+this.left_offset,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Line","Filled","Intensity"];this.mode="Line";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(c.min_value!==undefined){this.prefs.min_value=c.min_value}if(c.max_value!==undefined){this.prefs.max_value=c.max_value}};$.extend(LineTrack.prototype,Tiled Track.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"relative",top:"32px",left:"10px"});d.prependTo(a.container_div);e.css({position:"relative",top:a .height_px+32+"px",left:"10px"});e.prependTo(a.container_div)})},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;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,j){console.log(h,g,j)}})}},draw_tile:function(p,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*p,a=DENSITY*p,b=$("<canvas class='tile'></canvas>"),v=p+"_"+r;if(this.data_cache.get(v)===undefined){this.get_data(p,r);return}var j=this.data_cache.get(v);if(j===null){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var o=b.get(0).getContext("2d"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,n=this.vertical_range,t=this.total_frequency,d=this.height_px, m=this.mode;o.beginPath();if(data.length>1){var f=Math.ceil((data[1][0]-data[0][0])*e)}else{var f=10}var u,h;for(var q=0;q<data.length;q++){u=(data[q][0]-s)*e;h=data[q][1];if(m=="Intensity"){if(h===null){continue}if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/n*255);o.fillStyle="rgb("+h+","+h+","+h+")";o.fillRect(u,0,f,this.height_px)}else{if(h===null){if(k&&m==="Filled"){o.lineTo(u,d)}k=false;continue}else{if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/n*d);if(k){o.lineTo(u,h)}else{k=true;if(m==="Filled"){o.moveTo(u,d);o.lineTo(u,h)}else{o.moveTo(u,h)}}}}}if(m==="Filled"){if(k){o.lineTo(u,d)}o.fill()}else{o.stroke()}c.append(b);return b},gen_options:function(k){var a=$("<div />").addClass("form-row");var e="track_"+k+"_minval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),j=$("<input></input>").attr("id",e).val(b),g="track_"+k+"_maxval",d=$("<label></label>").attr("for",g).text("Max value:" ),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(j).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=2;this.su mmary_draw_height=20;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"black",label_color:"black",show_counts:true};if(c.block_color!==undefined){this.prefs.block_color=c.block_color}if(c.label_color!==undefined){this.prefs.label_color=c.label_color}if(c.show_counts!==undefined){this.prefs.show_counts=c.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(c){a.mode_div.show();a.data_cache.set(b,c);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,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolutio n,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,c,r){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.inc_slots[a].mode=r;this.s_e_by_tile[a]={}}var n=this.inc_slots[a].w_scale,z=[],l=0,b=$("<canvas></canvas>").get(0).getContext("2d"),o=this.view.max_low;var B=[];if(this.inc_slots[a].mode!==r){delete this.inc_slots[a];this.inc_slots[a]={mode:r,w_scale:n};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var w=0,x=h.length;w<x;w++){var g=h[w],m=g[0];if(this.inc_slots[a][m]!==undefined){l=Math.max(l,this.inc_slots[a][m]);B.push(this.inc_slots[a][m])}else{z.push(w)}}for(var w=0,x=z.length;w<x;w++){var g=h[z[w]],m=g[0],s=g[1],d=g[2],q=g[3],e=Math.floor((s-o)*n),f=Math.ceil((d-o)*n);if(q!==undefined&&!c){var t=b.measureText(q).width;if(e-t<0){f+=t}else{e-=t}}var v=0;while(true){var p=true;if(this.s_e_by_tile[a][v]!==undefined){for(var u=0,A=this.s_e_by_tile[a][v].length;u<A;u+ +){var y=this.s_e_by_tile[a][v][u];if(f>y[0]&&e<y[1]){p=false;break}}}if(p){if(this.s_e_by_tile[a][v]===undefined){this.s_e_by_tile[a][v]=[]}this.s_e_by_tile[a][v].push([e,f]);this.inc_slots[a][m]=v;l=Math.max(l,v);break}v++}}return l},rect_or_text:function(n,o,f,m,b,d,k,e,h){n.textAlign="center";var j=Math.round(o/2);if((this.mode==="Pack"||this.mode==="Auto")&&d!==undefined&&o>PX_PER_CHAR){n.fillStyle=this.prefs.block_color;n.fillRect(k,h+1,e,9);n.fillStyle="#eee";for(var g=0,l=d.length;g<l;g++){if(b+g>=f&&b+g<=m){var a=Math.floor(Math.max(0,(b+g-f)*o));n.fillText(d[g],a+this.left_offset+j,h+9)}}}else{n.fillStyle=this.prefs.block_color;n.fillRect(k,h+4,e,3)}},draw_tile:function(Y,l,o,al){var F=l*DENSITY*Y,ae=(l+1)*DENSITY*Y,E=ae-F;var af=(!this.initial_canvas?"initial":F+"_"+ae);var A=this.data_cache.get(af);var d;if(A===undefined){this.data_queue[[F,ae]]=true;this.get_data(F,ae);return}var a=Math.ceil(E*al),M=$("<canvas class='tile'></canvas>"),aa=this.prefs.label_color,g =this.prefs.block_color,n=this.mode,W=(n==="Squish")||(n==="Dense")&&(n!=="Pack")||(n==="Auto"&&(A.extra_info==="no_detail")),Q=this.left_offset,ak,t,am;if(A.dataset_type==="summary_tree"){t=this.summary_draw_height}else{if(n==="Dense"){t=15;am=10}else{am=(W?this.vertical_nodetail_px:this.vertical_detail_px);t=this.incremental_slots(this.view.zoom_res,A.data,W,n)*am+15;ak=this.inc_slots[this.view.zoom_res]}}M.css({position:"absolute",top:0,left:(F-this.view.low)*al-Q});M.get(0).width=a+Q;M.get(0).height=t;o.parent().css("height",Math.max(this.height_px,t)+"px");var B=M.get(0).getContext("2d");B.fillStyle=g;B.font=this.default_font;B.textAlign="right";if(A.dataset_type=="summary_tree"){var L,I=55,ad=255-I,h=ad*2/3,S=A.data,D=A.max,m=A.avg,b=Math.ceil(A.delta*al);for(var ah=0,z=S.length;ah<z;ah++){var U=Math.floor((S[ah][0]-F)*al);var T=S[ah][1];if(!T){continue}L=Math.floor(ad-(T/D)*ad);B.fillStyle="rgb("+L+","+L+","+L+")";B.fillRect(U+Q,0,b,this.summary_draw_height);if(this.p refs.show_counts&&B.measureText(T).width<b){if(L>h){B.fillStyle="black"}else{B.fillStyle="#ddd"}B.textAlign="center";B.fillText(T,U+Q+(b/2),12)}}d="Summary";o.append(M);return M}var aj=A.data;var ag=0;for(var ah=0,z=aj.length;ah<z;ah++){var N=aj[ah],K=N[0],ai=N[1],V=N[2],G=N[3];if(ai<=ae&&V>=F){var X=Math.floor(Math.max(0,(ai-F)*al)),C=Math.ceil(Math.min(a,Math.max(0,(V-F)*al))),R=(n==="Dense"?0:ak[K]*am);if(A.dataset_type==="bai"){B.fillStyle=g;if(N[4] instanceof Array){var u=Math.floor(Math.max(0,(N[4][0]-F)*al)),J=Math.ceil(Math.min(a,Math.max(0,(N[4][1]-F)*al))),s=Math.floor(Math.max(0,(N[5][0]-F)*al)),q=Math.ceil(Math.min(a,Math.max(0,(N[5][1]-F)*al)));if(N[4][1]>=F&&N[4][0]<=ae){this.rect_or_text(B,al,F,ae,N[4][0],N[4][2],u+Q,J-u,R)}if(N[5][1]>=F&&N[5][0]<=ae){this.rect_or_text(B,al,F,ae,N[5][0],N[5][2],s+Q,q-s,R)}if(s>J){B.fillStyle="#999";B.fillRect(J+Q,R+5,s-J,1)}}else{B.fillStyle=g;this.rect_or_text(B,al,F,ae,ai,G,X+Q,C-X,R)}if(n!=="Dense"&&!W&&ai>F){B.fillStyle=th is.prefs.label_color;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(K,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(K,X-2+Q,R+8)}B.fillStyle=g}}else{if(A.dataset_type==="interval_index"){if(W){B.fillRect(X+Q,R+5,C-X,1)}else{var w=N[4],P=N[5],Z=N[6],f=N[7];var v,ab,H=null,an=null;if(P&&Z){H=Math.floor(Math.max(0,(P-F)*al));an=Math.ceil(Math.min(a,Math.max(0,(Z-F)*al)))}if(n!=="Dense"&&G!==undefined&&ai>F){B.fillStyle=aa;if(l===0&&X-B.measureText(G).width<0){B.textAlign="left";B.fillText(G,C+2+Q,R+8)}else{B.textAlign="right";B.fillText(G,X-2+Q,R+8)}B.fillStyle=g}if(f){if(w){if(w=="+"){B.fillStyle=RIGHT_STRAND}else{if(w=="-"){B.fillStyle=LEFT_STRAND}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=g}for(var af=0,e=f.length;af<e;af++){var p=f[af],c=Math.floor(Math.max(0,(p[0]-F)*al)),O=Math.ceil(Math.min(a,Math.max((p[1]-F)*al)));if(c>O){continue}v=5;ab=3;B.fillRect(c+Q,R+ab,O-c,v);if(H!==undefined&&!(c>an||O<H)){v=9;ab=1;var ac=Math.max(c,H),r=Math.min(O,an);B.fillRe ct(ac+Q,R+ab,r-ac,v)}}}else{v=9;ab=1;B.fillRect(X+Q,R+ab,C-X,v);if(N.strand){if(N.strand=="+"){B.fillStyle=RIGHT_STRAND_INV}else{if(N.strand=="-"){B.fillStyle=LEFT_STRAND_INV}}B.fillRect(X+Q,R,C-X,10);B.fillStyle=prefs.block_color}}}}}ag++}}o.append(M);return M},gen_options:function(j){var a=$("<div />").addClass("form-row");var e="track_"+j+"_block_color",l=$("<label />").attr("for",e).text("Block color:"),m=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),k="track_"+j+"_label_color",g=$("<label />").attr("for",k).text("Text color:"),h=$("<input />").attr("id",k).attr("name",k).val(this.prefs.label_color),f="track_"+j+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(l).append(m).append(g).append(h).append(d)},update_options:function(e){var b=$("#track_"+e +"_block_color").val(),d=$("#track_"+e+"_label_color").val(),c=$("#track_"+e+"_mode option:selected").val(),a=$("#track_"+e+"_show_count").attr("checked");if(b!==this.prefs.block_color||d!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=d;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c){FeatureTrack.call(this,d,b,a,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{}); --- a/static/scripts/trackster.js +++ b/static/scripts/trackster.js @@ -37,6 +37,10 @@ left_img_inv.onload = function() { LEFT_STRAND_INV = CONTEXT.createPattern(left_img_inv, "repeat"); }; +function round_1000(num) { + return Math.round(num * 1000) / 1000; +} + var Cache = function( num_elements ) { this.num_elements = num_elements; this.clear(); @@ -96,7 +100,6 @@ var View = function( container, chrom, t this.content_div = $("<div/>").addClass("content").css("position", "relative").appendTo(parent_element); this.intro_div = $("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide().appendTo(parent_element); this.viewport_container = $("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div); - this.viewport = $("<div/>").addClass("viewport").appendTo(this.viewport_container); this.nav_container = $("<div/>").addClass("nav-container").appendTo(parent_element); this.nav_labeltrack = $("<div/>").addClass("nav-labeltrack").appendTo(this.nav_container); @@ -104,18 +107,26 @@ var View = function( container, chrom, t this.overview = $("<div/>").addClass("overview").appendTo(this.nav); this.overview_viewport = $("<div/>").addClass("overview-viewport").appendTo(this.overview); this.overview_box = $("<div/>").addClass("overview-box").appendTo(this.overview_viewport); + this.default_overview_height = this.overview_box.height(); this.nav_controls = $("<div/>").addClass("nav-controls").appendTo(this.nav); this.chrom_form = $("<form/>").attr("action", function() { void(0); } ).appendTo(this.nav_controls); this.chrom_select = $("<select/>").attr({ "name": "chrom"}).css("width", "15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form); - this.low_input = $("<input/>").addClass("low").css("width", "10em").appendTo(this.chrom_form); - $("<span/>").text(" - ").appendTo(this.chrom_form); - this.high_input = $("<input/>").addClass("high").css("width", "10em").appendTo(this.chrom_form); + this.nav_input = $("<input/>").addClass("nav-input").hide().bind("keypress", function(e) { + if ((e.keyCode || e.which) === 13) { + view.go_to( $(this).val() ); + $(this).hide(); + return false; + } + + }).appendTo(this.chrom_form); + this.location_span = $("<span/>").addClass("location").appendTo(this.chrom_form); if (this.vis_id !== undefined) { this.hidden_input = $("<input/>").attr("type", "hidden").val(this.vis_id).appendTo(this.chrom_form); } - this.zi_link = $("<a/>").click(function() { view.zoom_in(); view.redraw() }).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form); - this.zo_link = $("<a/>").click(function() { view.zoom_out(); view.redraw() }).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);; + this.goto_link = $("<a/>").click(function() { view.nav_input.toggle(); view.nav_input.focus(); }).html('<img src="'+image_path+'/fugue/navigation.png" />').appendTo(this.chrom_form); + this.zo_link = $("<a/>").click(function() { view.zoom_out(); view.redraw() }).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form); + this.zi_link = $("<a/>").click(function() { view.zoom_in(); view.redraw() }).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form); $.ajax({ url: chrom_url, @@ -132,34 +143,11 @@ var View = function( container, chrom, t chrom_options += '<option value="' + chrom + '">' + chrom + '</option>'; } view.chrom_select.html(chrom_options); - - var change_chrom = function () { - if (view.chrom_select.val() === "") { - // No chrom selected - view.intro_div.show(); - view.content_div.hide(); - } else { - view.intro_div.hide(); - view.content_div.show(); - } - view.chrom = view.chrom_select.val(); - var found = $.grep(view.chrom_data, function(v, i) { - return v.chrom === view.chrom; - })[0]; - view.max_high = (found !== undefined ? found.len : 0); - view.reset(); - view.redraw(true); - - for (var track_id in view.tracks) { - var track = view.tracks[track_id]; - if (track.init) { - track.init(); - } - } - view.redraw(); - }; - view.chrom_select.bind( "change", change_chrom ); - change_chrom(); + view.intro_div.show(); + view.content_div.hide(); + view.chrom_select.bind("change", function() { + view.change_chrom(view.chrom_select.val()); + }); }, error: function() { alert( "Could not load chroms for this dbkey:", view.dbkey ); @@ -199,13 +187,13 @@ var View = function( container, chrom, t this.original_low = view.low; this.current_height = e.clientY; this.current_x = e.offsetX; + this.active = (e.clientX < view.viewport_container.width() - 16) ? true : false; // Fix webkit scrollbar }).bind( "drag", function( e ) { + if (!this.active) { return; } var container = $(this); var delta = e.offsetX - this.current_x; var new_scroll = container.scrollTop() - (e.clientY - this.current_height); - // if ( new_scroll < container.get(0).scrollHeight - container.height() ) { - container.scrollTop(new_scroll); - // } + container.scrollTop(new_scroll); this.current_height = e.clientY; this.current_x = e.offsetX; @@ -217,7 +205,7 @@ var View = function( container, chrom, t this.drag_origin_x = e.clientX; this.drag_origin_pos = e.clientX / view.viewport_container.width() * (view.high - view.low) + view.low; this.drag_div = $("<div />").css( { - "height": view.viewport_container.height(), "top": "0px", "position": "absolute", + "height": view.content_div.height(), "top": "0px", "position": "absolute", "background-color": "#cfc", "border": "1px solid #6a6", "opacity": 0.5, "z-index": 1000 } ).appendTo( $(this) ); }).bind( "drag", function(e) { @@ -226,8 +214,7 @@ var View = function( container, chrom, t span = (view.high - view.low), width = view.viewport_container.width(); - view.low_input.val(commatize(Math.round(min / width * span) + view.low)); - view.high_input.val(commatize(Math.round(max / width * span) + view.low)); + view.update_location(Math.round(min / width * span) + view.low, Math.round(max / width * span) + view.low); this.drag_div.css( { "left": min + "px", "width": (max - min) + "px" } ); }).bind( "dragend", function(e) { var min = Math.min(e.clientX, this.drag_origin_x), @@ -245,6 +232,64 @@ var View = function( container, chrom, t this.add_label_track( new LabelTrack( this, this.top_labeltrack ) ); this.add_label_track( new LabelTrack( this, this.nav_labeltrack ) ); }, + update_location: function(low, high) { + this.location_span.text( commatize(low) + ' - ' + commatize(high) ); + this.nav_input.val( this.chrom + ':' + commatize(low) + '-' + commatize(high) ); + }, + change_chrom: function(chrom, low, high) { + var view = this; + var found = $.grep(view.chrom_data, function(v, i) { + return v.chrom === chrom; + })[0]; + if (found === undefined) { + // Invalid chrom + return; + } + view.chrom = chrom; + if (view.chrom === "") { + // No chrom selected + view.intro_div.show(); + view.content_div.hide(); + } else { + view.intro_div.hide(); + view.content_div.show(); + } + view.chrom_select.val(view.chrom); + view.max_high = found.len; + view.reset(); + view.redraw(true); + + for (var track_id in view.tracks) { + var track = view.tracks[track_id]; + if (track.init) { + track.init(); + } + } + if (low !== undefined && high !== undefined) { + view.low = Math.max(low, 0); + view.high = Math.min(high, view.max_high); + } + view.overview_viewport.find("canvas").remove(); + view.redraw(); + + }, + go_to: function(str) { + var view = this, + chrom_pos = str.split(":"), + chrom = chrom_pos[0], + pos = chrom_pos[1]; + + if (pos !== undefined) { + try { + var pos_split = pos.split("-"), + new_low = parseInt(pos_split[0].replace(/,/g, "")), + new_high = parseInt(pos_split[1].replace(/,/g, "")); + } catch (e) { + return false; + } + } + view.change_chrom(chrom, new_low, new_high); + }, move_delta: function(delta_chrom) { var view = this; var current_chrom_span = view.high - view.low; @@ -327,8 +372,7 @@ var View = function( container, chrom, t // Minimum width for usability width: Math.max( 12, (this.high - this.low)/(this.max_high - this.max_low) * this.overview_viewport.width() ) }).show(); - this.low_input.val( commatize(this.low) ); - this.high_input.val( commatize(this.high) ); + this.update_location(this.low, this.high); if (!nodraw) { for (var i = 0, len = this.tracks.length; i < len; i++) { if (this.tracks[i] && this.tracks[i].enabled) { @@ -386,6 +430,7 @@ var Track = function (name, view, parent track.data_queue = {}; track.tile_cache.clear(); track.data_cache.clear(); + track.initial_canvas = undefined; track.content_div.css( "height", "auto" ); if (!track.content_div.text()) { track.content_div.text(DATA_LOADING); @@ -432,7 +477,49 @@ var Track = function (name, view, parent }); var TiledTrack = function() { - this.left_offset = 200; + var track = this, + view = track.view; + + if (track.display_modes !== undefined) { + if (track.mode_div === undefined) { + track.mode_div = $("<div class='right-float menubutton popup' />").appendTo(track.header_div); + var init_mode = track.display_modes[0]; + track.mode = init_mode; + track.mode_div.text(init_mode); + + var change_mode = function(name) { + track.mode_div.text(name); + track.mode = name; + track.tile_cache.clear(); + track.draw(); + }; + var mode_mapping = {}; + for (var i in track.display_modes) { + var mode = track.display_modes[i]; + mode_mapping[mode] = function(mode) { + return function() { change_mode(mode); } + }(mode); + } + make_popupmenu(track.mode_div, mode_mapping); + } else { + track.mode_div.hide(); + } + } + if (track.overview_check_div === undefined) { + track.overview_check_div = $("<div class='right-float' />").css("margin-top", "-3px").appendTo(track.header_div); + track.overview_check = $("<input type='checkbox' class='overview_check' />").appendTo(track.overview_check_div); + track.overview_check.bind("click", function() { + var curr = this; + view.overview_viewport.find("canvas").remove(); + track.set_overview(); + $(".overview_check").each(function() { + if (this !== curr) { + $(this).attr("checked", false); + } + }); + }); + track.overview_check_div.append( $("<label />").text("Overview") ); + } }; $.extend( TiledTrack.prototype, Track.prototype, { draw: function() { @@ -476,13 +563,33 @@ var TiledTrack = function() { setTimeout(function() { if ( !(low > track.view.high || high < track.view.low) ) { tile_element = track.draw_tile( resolution, tile_index, parent_element, w_scale ); - if ( tile_element ) { + if (tile_element) { + // Store initial canvas in we need to use it for overview + if (!track.initial_canvas) { + track.initial_canvas = $(tile_element).clone(); + var src_ctx = tile_element.get(0).getContext("2d"); + var tgt_ctx = track.initial_canvas.get(0).getContext("2d"); + var data = src_ctx.getImageData(0, 0, src_ctx.canvas.width, src_ctx.canvas.height); + tgt_ctx.putImageData(data, 0, 0); + track.set_overview(); + } track.tile_cache.set(key, tile_element); track.max_height = Math.max( track.max_height, tile_element.height() ); track.content_div.css("height", track.max_height + "px"); } } }, 50); + }, set_overview: function() { + var view = this.view; + view.overview_viewport.height(view.default_overview_height); + view.overview_box.height(view.default_overview_height); + + if (this.initial_canvas && this.overview_check.is(":checked")) { + view.overview_viewport.append(this.initial_canvas); + view.overview_viewport.height(this.initial_canvas.height()); + view.overview_box.height(this.initial_canvas.height()); + } + $(window).trigger("resize"); } }); @@ -580,7 +687,7 @@ var ReferenceTrack = function (view) { var c_start = Math.round(c * w_scale); ctx.fillText(seq[c], c_start + this.left_offset, 10); } - parent_element.append( canvas ); + parent_element.append(canvas); return canvas; } this.content_div.css("height", "0px"); @@ -589,17 +696,18 @@ var ReferenceTrack = function (view) { var LineTrack = function ( name, view, dataset_id, prefs ) { this.track_type = "LineTrack"; + this.display_modes = ["Line", "Filled", "Intensity"]; + this.mode = "Line"; Track.call( this, name, view, view.viewport_container ); TiledTrack.call( this ); - this.height_px = 100; + this.height_px = 80; this.dataset_id = dataset_id; this.data_cache = new Cache(CACHED_DATA); this.tile_cache = new Cache(CACHED_TILES_LINE); this.prefs = { 'min_value': undefined, 'max_value': undefined, 'mode': 'Line' }; if (prefs.min_value !== undefined) { this.prefs.min_value = prefs.min_value; } if (prefs.max_value !== undefined) { this.prefs.max_value = prefs.max_value; } - if (prefs.mode !== undefined) { this.prefs.mode = prefs.mode; } }; $.extend( LineTrack.prototype, TiledTrack.prototype, { init: function() { @@ -626,13 +734,13 @@ var LineTrack = function ( name, view, d $('#linetrack_' + track_id + '_minval').remove(); $('#linetrack_' + track_id + '_maxval').remove(); - var min_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_minval').text(track.prefs.min_value); - var max_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_maxval').text(track.prefs.max_value); + var min_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_minval').text(round_1000(track.prefs.min_value)); + var max_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_maxval').text(round_1000(track.prefs.max_value)); - max_label.css({ position: "relative", top: "25px", left: "10px" }); + max_label.css({ position: "relative", top: "32px", left: "10px" }); max_label.prependTo(track.container_div); - min_label.css({ position: "relative", top: track.height_px + 55 + "px", left: "10px" }); + min_label.css({ position: "relative", top: track.height_px + 32 + "px", left: "10px" }); min_label.prependTo(track.container_div); }); }, @@ -689,7 +797,7 @@ var LineTrack = function ( name, view, d left: ( tile_low - this.view.low ) * w_scale }); - canvas.get(0).width = Math.ceil( tile_length * w_scale + this.left_offset); + canvas.get(0).width = Math.ceil( tile_length * w_scale ); canvas.get(0).height = this.height_px; var ctx = canvas.get(0).getContext("2d"), in_path = false, @@ -698,7 +806,7 @@ var LineTrack = function ( name, view, d vertical_range = this.vertical_range, total_frequency = this.total_frequency, height_px = this.height_px, - mode = this.prefs.mode; + mode = this.mode; ctx.beginPath(); @@ -768,7 +876,7 @@ var LineTrack = function ( name, view, d } else { ctx.stroke(); } - parent_element.append( canvas ); + parent_element.append(canvas); return canvas; }, gen_options: function(track_id) { var container = $("<div />").addClass("form-row"); @@ -780,23 +888,15 @@ var LineTrack = function ( name, view, d maxval = 'track_' + track_id + '_maxval', max_label = $('<label></label>').attr("for", maxval).text("Max value:"), max_val = (this.prefs.max_value === undefined ? "" : this.prefs.max_value), - max_input = $('<input></input>').attr("id", maxval).val(max_val), - mode = 'track_' + track_id + '_mode', - mode_label = $('<label></label>').attr("for", mode).text("Display mode:"), - mode_val = (this.prefs.mode === undefined ? "Line" : this.prefs.mode), - mode_input = $('<select id="' +mode+ '"><option value="Line" id="mode_Line">Line</option><option value="Filled" id="mode_Filled">Filled</option><option value="Intensity" id="mode_Intensity">Intensity</option></select>'); - - mode_input.children("#mode_"+mode_val).attr('selected', 'selected'); - - return container.append(min_label).append(min_input).append(max_label).append(max_input).append(mode_label).append(mode_input); + max_input = $('<input></input>').attr("id", maxval).val(max_val); + + return container.append(min_label).append(min_input).append(max_label).append(max_input); }, update_options: function(track_id) { var min_value = $('#track_' + track_id + '_minval').val(), - max_value = $('#track_' + track_id + '_maxval').val(), - mode = $('#track_' + track_id + '_mode option:selected').val(); - if ( min_value !== this.prefs.min_value || max_value !== this.prefs.max_value || mode !== this.prefs.mode ) { + max_value = $('#track_' + track_id + '_maxval').val(); + if ( min_value !== this.prefs.min_value || max_value !== this.prefs.max_value ) { this.prefs.min_value = parseFloat(min_value); this.prefs.max_value = parseFloat(max_value); - this.prefs.mode = mode; this.vertical_range = this.prefs.max_value - this.prefs.min_value; // Update the y-axis $('#linetrack_' + track_id + '_minval').text(this.prefs.min_value); @@ -809,6 +909,7 @@ var LineTrack = function ( name, view, d var FeatureTrack = function ( name, view, dataset_id, prefs ) { this.track_type = "FeatureTrack"; + this.display_modes = ["Auto", "Dense", "Squish", "Pack"]; Track.call( this, name, view, view.viewport_container ); TiledTrack.call( this ); @@ -819,13 +920,15 @@ var FeatureTrack = function ( name, view this.show_labels_scale = 0.001; this.showing_details = false; this.vertical_detail_px = 10; - this.vertical_nodetail_px = 3; + this.vertical_nodetail_px = 2; + this.summary_draw_height = 20; this.default_font = "9px Monaco, Lucida Console, monospace"; this.inc_slots = {}; this.data_queue = {}; this.s_e_by_tile = {}; this.tile_cache = new Cache(CACHED_TILES_FEATURE); this.data_cache = new Cache(20); + this.left_offset = 200; this.prefs = { 'block_color': 'black', 'label_color': 'black', 'show_counts': true }; if (prefs.block_color !== undefined) { this.prefs.block_color = prefs.block_color; } @@ -835,39 +938,11 @@ var FeatureTrack = function ( name, view $.extend( FeatureTrack.prototype, TiledTrack.prototype, { init: function() { var track = this, - key = track.view.max_low + '_' + track.view.max_high; - if (track.mode_div === undefined) { - track.mode_div = $("<div class='right-float menubutton popup' />").text("Display Mode").appendTo(track.header_div); - track.mode = "Auto"; - - var change_mode = function(name) { - track.mode_div.text(name); - track.mode = name; - track.tile_cache.clear(); - track.draw(); - }; - make_popupmenu(track.mode_div, { - "Auto": function() { - change_mode("Auto"); - }, - "Dense": function() { - change_mode("Dense"); - }, - "Squish": function() { - change_mode("Squish"); - }, - "Pack": function() { - change_mode("Pack"); - } - }); - } else { - track.mode_div.hide(); - } + key = "initial"; - this.init_each({ low: track.view.max_low, - high: track.view.max_high, dataset_id: track.dataset_id, - chrom: track.view.chrom, resolution: this.view.resolution }, function (result) { - + this.init_each({ low: track.view.max_low, + high: track.view.max_high, dataset_id: track.dataset_id, + chrom: track.view.chrom, resolution: this.view.resolution }, function (result) { track.mode_div.show(); track.data_cache.set(key, result); track.draw(); @@ -993,8 +1068,8 @@ var FeatureTrack = function ( name, view draw_tile: function( resolution, tile_index, parent_element, w_scale ) { var tile_low = tile_index * DENSITY * resolution, tile_high = ( tile_index + 1 ) * DENSITY * resolution, - tile_span = DENSITY * resolution; - // console.log("drawing " + tile_index); + tile_span = tile_high - tile_low; + // console.log("drawing " + tile_low + " to " + tile_high); /*for (var k in this.data_cache.obj_cache) { var k_split = k.split("_"), k_low = k_split[0], k_high = k_split[1]; @@ -1004,9 +1079,9 @@ var FeatureTrack = function ( name, view } }*/ - // var k = this.view.low + '_' + this.view.high; - var k = tile_low + '_' + tile_high; + var k = (!this.initial_canvas ? "initial" : tile_low + '_' + tile_high); var result = this.data_cache.get(k); + var cur_mode; if (result === undefined) { this.data_queue[ [tile_low, tile_high] ] = true; @@ -1024,7 +1099,7 @@ var FeatureTrack = function ( name, view slots, required_height, y_scale; if (result.dataset_type === "summary_tree") { - required_height = 30; + required_height = this.summary_draw_height; } else if (mode === "Dense") { required_height = 15; y_scale = 10; @@ -1066,7 +1141,7 @@ var FeatureTrack = function ( name, view if (!y) { continue; } color = Math.floor( color_span - (y / max) * color_span ); ctx.fillStyle = "rgb(" +color+ "," +color+ "," +color+ ")"; - ctx.fillRect(x + left_offset, 0, delta_x_px, 20); + ctx.fillRect(x + left_offset, 0, delta_x_px, this.summary_draw_height); if (this.prefs.show_counts && ctx.measureText(y).width < delta_x_px) { if (color > color_cutoff) { @@ -1078,7 +1153,7 @@ var FeatureTrack = function ( name, view ctx.fillText(y, x + left_offset + (delta_x_px/2), 12); } } - + cur_mode = "Summary"; parent_element.append( new_canvas ); return new_canvas; } --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -661,11 +661,11 @@ class DatasetInstance( object ): new_dataset = self.datatype.convert_dataset( trans, self, target_ext, return_output=True, visible=False, deps=deps ).values()[0] new_dataset.hid = self.hid new_dataset.name = self.name - trans.sa_session.add( new_dataset ) - trans.sa_session.flush() + session = trans.sa_session + session.add( new_dataset ) assoc.dataset = new_dataset - trans.sa_session.add( assoc ) - trans.sa_session.flush() + session.add( assoc ) + session.flush() return None def clear_associated_files( self, metadata_safe = False, purge = False ): raise 'Unimplemented' --- a/lib/galaxy/web/controllers/visualization.py +++ b/lib/galaxy/web/controllers/visualization.py @@ -30,8 +30,9 @@ class VisualizationListGrid( grids.Grid grids.GridAction( "Create new visualization", dict( action='create' ) ) ] operations = [ - grids.GridOperation( "View", allow_multiple=False, url_args=dict( controller='tracks', action='browser' ) ), + grids.GridOperation( "View/Edit", allow_multiple=False, url_args=dict( controller='tracks', action='browser' ) ), grids.GridOperation( "Edit Attributes", allow_multiple=False, url_args=dict( action='edit') ), + grids.GridOperation( "Clone", allow_multiple=False, condition=( lambda item: not item.deleted ), async_compatible=False, url_args=dict( action='clone') ), grids.GridOperation( "Share or Publish", allow_multiple=False, condition=( lambda item: not item.deleted ), async_compatible=False ), grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), async_compatible=True, confirm="Are you sure you want to delete this visualization?" ), ] @@ -86,6 +87,34 @@ class VisualizationController( BaseContr return self.list( trans, args, kwargs ) @web.expose + @web.require_login() + def clone(self, trans, id, *args, **kwargs): + viz = self.get_visualization( trans, id, check_ownership=False ) + user = trans.get_user() + if viz.user == user: + owner = True + else: + if trans.sa_session.query( model.VisualizationUserShareAssociation ) \ + .filter_by( user=user, visualization=viz ).count() == 0: + error( "Visualization is not owned by or shared with current user" ) + owner = False + new_viz = model.Visualization() + new_viz.title = "Clone of '%s'" % viz.title + new_viz.dbkey = viz.dbkey + new_viz.type = viz.type + new_viz.latest_revision = viz.latest_revision + if not owner: + new_viz.title += " shared by '%s'" % viz.user.email + new_viz.user = user + # Persist + session = trans.sa_session + session.add( new_viz ) + session.flush() + # Display the management page + trans.set_message( 'Clone created with name "%s"' % new_viz.title ) + return self.list( trans ) + + @web.expose @web.require_login( "use Galaxy visualizations", use_panels=True ) def list( self, trans, *args, **kwargs ): # Handle operation --- a/static/june_2007_style/blue/trackster.css +++ b/static/june_2007_style/blue/trackster.css @@ -1,13 +1,15 @@ .viewport-container{overflow-x:hidden;overflow-y:auto;} .nav{padding:0 0;color:#333;font-weight:bold;} -.nav-controls{text-align:center;background:#cccccc;background-image:url(panel_header_bg.png);background-position:top center;background-repeat:repeat-x;padding:2px 0;} +.content{font:9px verdana;} +.nav-controls{text-align:center;position:relative;background:#cccccc;background-image:url(panel_header_bg.png);background-position:top center;background-repeat:repeat-x;padding:2px 0;} .nav-controls input{margin:0 5px;} .nav-controls a{padding:0 0.4em;} +.nav-input{font-size:12px;position:absolute;right:0px;bottom:25px;width:20em;z-index:1000;} +.location{display:inline-block;width:15em;margin:0px 10px;} .intro{position:absolute;top:50%;left:30%;color:#555;font-size:16px;} .overview{width:100%;margin:0px;color:white;} .overview-viewport{position:relative;height:14px;background:white;border-bottom:solid gray 1px;margin:0;} -.overview-box{position:absolute;margin-top:0px;height:14px;background:#ddd url(../images/visualization/draggable_horizontal.png) center center no-repeat;} -.viewport{background-color:#fff;} +.overview-box{opacity:0.5;z-index:100;position:absolute;margin-top:0px;height:14px;background:#cfc url(../images/visualization/draggable_horizontal.png) center center no-repeat;border-style:solid;border-color:#6a6;border-width:0px 2px;} .viewport-canvas{width:100%;height:100px;} .yaxislabel{color:#777;} .line-track .track-content{border-top:1px solid #ddd;border-bottom:1px solid #ddd;} @@ -20,5 +22,5 @@ .label-track{} .label-track .label{border-left:solid #999 1px;padding:1px;display:inline-block;} .right-float{float:right;margin-left:5px;} -.top-labeltrack{border-bottom:solid #999 1px;} +.top-labeltrack{position:relative;border-bottom:solid #999 1px;} .nav-labeltrack{border-top:solid #999 1px;border-bottom:solid #999 1px;} --- a/static/june_2007_style/trackster.css.tmpl +++ b/static/june_2007_style/trackster.css.tmpl @@ -2,17 +2,16 @@ overflow-x: hidden; overflow-y: auto; } - -/*canvas{ - border-left: 1px solid green; - border-right: 1px solid red; } /* debugging */ .nav { padding: 0 0; color:#333;font-weight:bold; } - +.content { + font: 9px verdana; +} .nav-controls { text-align: center; + position: relative; background:#cccccc; background-image:url(panel_header_bg.png); background-position:top center; @@ -25,7 +24,20 @@ .nav-controls a { padding: 0 0.4em; } -.intro{ +.nav-input { + font-size: 12px; + position: absolute; + right: 0px; + bottom: 25px; + width: 20em; + z-index: 1000; +} +.location { + display: inline-block; + width: 15em; + margin: 0px 10px; +} +.intro { position: absolute; top: 50%; left: 30%; @@ -37,7 +49,6 @@ margin: 0px; color: white; } - .overview-viewport { position: relative; height: 14px; @@ -48,20 +59,16 @@ margin: 0; } .overview-box { + opacity: 0.5; + z-index: 100; position: absolute; margin-top: 0px; height: 14px; - background: #ddd url(../images/visualization/draggable_horizontal.png) center center no-repeat; - /*border-style: outset;*/ + background: #cfc url(../images/visualization/draggable_horizontal.png) center center no-repeat; + border-style: solid; + border-color: #6a6; + border-width: 0px 2px; } - -.viewport { -/* overflow-x: hidden;*/ - background-color: #fff; -/* overflow: scroll;*/ -/* border-bottom: 2px solid black;*/ -} - .viewport-canvas { width: 100%; height: 100px; @@ -121,6 +128,7 @@ } .top-labeltrack { + position: relative; border-bottom: solid #999 1px; } --- a/templates/visualization/display.mako +++ b/templates/visualization/display.mako @@ -10,7 +10,7 @@ // To adjust the size of the viewport to fit the fixed-height footer var refresh = function( e ) { if (view !== undefined) { - view.viewport_container.height( $(window).height() - 100 ); + view.viewport_container.height( $("#center").height() - $(".nav-container").height() - 40 ); view.nav_container.width( $("#center").width() ); view.redraw(); } --- a/static/june_2007_style/process_css.py +++ b/static/june_2007_style/process_css.py @@ -84,7 +84,7 @@ def build_stylesheet_parser(): # Just match anything that looks like a selector, including element, class, # id, attribute, and pseudoclass. Attributes are not handled properly (spaces, # and even newlines in the quoted string are legal). - simple_selector = Word( alphanums + ".#*:()[]|=\"'_-" ) + simple_selector = Word( alphanums + "@.#*:()[]|=\"'_-" ) combinator = Literal( ">" ) | Literal( "+" ) selector = Group( simple_selector + ZeroOrMore( Optional( combinator ) + simple_selector ) ) selectors = Group( delimitedList( selector ) ) --- a/tools/regVariation/compute_q_values.xml +++ b/tools/regVariation/compute_q_values.xml @@ -46,7 +46,7 @@ **What it does** -This program computes the q-values based on the p-values of multiple simultaneous tests. The q-valules are computed using a specific R package, created by John Storey and Alan Dabney, called "qvalue". The program takes five inputs: +This program computes the q-values based on the p-values of multiple simultaneous tests. The q-values are computed using a specific R package, created by John Storey and Alan Dabney, called "qvalue". The program takes five inputs: - The first input is a TABULAR format file consisting of one column only that represents the p-values of multiple simultaneous tests, one line for every p-value. - The second input is the lambda parameter. The user can choose either the default: seq(0, 0.95, 0.05) or a decimal number between 0.0 and 1.0. @@ -103,7 +103,7 @@ Let us have the first input file of p-va 0.904129283 0.031152635 -Runnig the program will give the following output:: +Running the program will give the following output:: pi0: 0.140311054 --- a/templates/grid_base.mako +++ b/templates/grid_base.mako @@ -97,10 +97,8 @@ // Operations that are async (AJAX) compatible. var async_ops = {}; - %for operation in grid.operations: - %if operation.async_compatible: - async_ops['${operation.label.lower()}'] = "True"; - %endif + %for operation in [op for op in grid.operations if op.async_compatible]: + async_ops['${operation.label.lower()}'] = "True"; %endfor // Initialize grid controls @@ -108,15 +106,13 @@ // Initialize operation buttons. $('input[name=operation]:submit').each(function() { $(this).click( function() { - // Get the webapp var webapp = $("input[name=webapp]").attr("value"); - // Get operation name. - var operation_name = $(this).attr("value"); + var operation_name = $(this).val(); // For some reason, $('input[name=id]:checked').val() does not return all ids for checked boxes. // The code below performs this function. var item_ids = []; $('input[name=id]:checked').each(function() { - item_ids[item_ids.length] = $(this).val(); + item_ids.push( $(this).val() ); }); do_operation(webapp, operation_name, item_ids); }); @@ -133,28 +129,24 @@ $(this).mouseup( function() { $(this).removeClass('gray-background'); }); - }); // Initialize sort links. $('.sort-link').each( function() { - var sort_key = $(this).attr('sort_key'); $(this).click( function() { - set_sort_condition(sort_key); - return false; + set_sort_condition( $(this).attr('sort_key') ); + return false; }); - }); // Initialize page links. $('.page-link > a').each( function() { - var page_num = $(this).attr('page_num'); $(this).click( function() { - set_page(page_num); - return false; + set_page( $(this).attr('page_num') ); + return false; }); - }); + $('#show-all-link').click( function() { set_page('all'); return false; @@ -163,9 +155,7 @@ // Initialize categorical filters. $('.categorical-filter > a').each( function() { $(this).click( function() { - var filter_key = $(this).attr('filter_key'); - var filter_val = $(this).attr('filter_val'); - set_categorical_filter(filter_key, filter_val); + set_categorical_filter( $(this).attr('filter_key'), $(this).attr('filter_val') ); return false; }); }); @@ -179,15 +169,15 @@ text_input_obj.val(''); add_filter_condition(column_key, text_input, true); return false; - }); + }); }); - + // Initialize autocomplete for text inputs in search UI. var t = $("#input-tags-filter"); if (t.length) { t.autocomplete( "${h.url_for( controller='tag', action='tag_autocomplete_data', item_class='History' )}", { selectFirst: false, autoFill: false, highlight: false, mustMatch: false }); - } + } var t2 = $("#input-name-filter"); if (t2.length) { @@ -209,14 +199,15 @@ // Initialize grid selection checkboxes. $(".grid").each( function() { var checkboxes = $(this).find("input.grid-row-select-checkbox"); - var update = $(this).find( "span.grid-selected-count" ); - update.text(""); + var check_count = $(this).find("span.grid-selected-count"); + var update_checked = function() { + check_count.text( $(checkboxes).filter(":checked").length ); + }; + $(checkboxes).each( function() { - $(this).change( function() { - var n = $(checkboxes).filter("[checked]").size(); - update.text( n ); - }); + $(this).change(update_checked); }); + update_checked(); }); // Initialize item labels.