';return i})})();
\ No newline at end of file
+(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.panel_section=b(function(e,l,d,k,j){d=d||e.helpers;var h="",c,g,f="function",i=this.escapeExpression;h+='
";return k})})();
\ No newline at end of file
+(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_form=b(function(f,m,e,l,k){e=e||f.helpers;var i="",c,h,g="function",j=this.escapeExpression,n=this;function d(s,r){var p="",q,o;p+='\n
";return i})})();
\ No newline at end of file
diff --git a/static/scripts/packed/templates/compiled/tool_link.js b/static/scripts/packed/templates/compiled/tool_link.js
index 69e5e91e842..1dba3d05bc5 100644
--- a/static/scripts/packed/templates/compiled/tool_link.js
+++ b/static/scripts/packed/templates/compiled/tool_link.js
@@ -1 +1 @@
-(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_link=b(function(e,n,d,l,k){d=d||e.helpers;var i="",c,h,o=this,f="function",m=d.helperMissing,g=void 0,j=this.escapeExpression;i+='';h=d.name;c=h||n.name;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"name",{hash:{}})}}i+=j(c)+" ";h=d.description;c=h||n.description;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"description",{hash:{}})}}i+=j(c);return i})})();
\ No newline at end of file
+(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_link=b(function(e,l,d,k,j){d=d||e.helpers;var h="",c,g,f="function",i=this.escapeExpression;h+='';g=d.name;if(g){c=g.call(l,{hash:{}})}else{c=l.name;c=typeof c===f?c():c}h+=i(c)+" ";g=d.description;if(g){c=g.call(l,{hash:{}})}else{c=l.description;c=typeof c===f?c():c}h+=i(c);return h})})();
\ No newline at end of file
diff --git a/static/scripts/packed/templates/compiled/tool_search.js b/static/scripts/packed/templates/compiled/tool_search.js
index f23b6bcfcbf..eb34e20ace6 100644
--- a/static/scripts/packed/templates/compiled/tool_search.js
+++ b/static/scripts/packed/templates/compiled/tool_search.js
@@ -1 +1 @@
-(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_search=b(function(e,n,d,l,k){d=d||e.helpers;var i="",c,h,o=this,f="function",m=d.helperMissing,g=void 0,j=this.escapeExpression;i+='\n\n';return i})})();
\ No newline at end of file
+(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_search=b(function(e,l,d,k,j){d=d||e.helpers;var h="",c,g,f="function",i=this.escapeExpression;h+='\n\n';return h})})();
\ No newline at end of file
diff --git a/static/scripts/packed/viz/trackster.js b/static/scripts/packed/viz/trackster.js
index 0c352c0760b..9a755b313b7 100644
--- a/static/scripts/packed/viz/trackster.js
+++ b/static/scripts/packed/viz/trackster.js
@@ -1 +1 @@
-var class_module=function(b,a){var c=function(){var g=arguments[0];for(var f=1;fc){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var is_deferred=function(a){return("isResolved" in a)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j>16;f=(g&65280)>>8;k=g&255;d=n(o,f,k);m=true;for(j=0;j>16;r=(q&65280)>>8;c=q&255;b=n(h,r,c);p=e(o,f,k,h,r,c);if((Math.abs(d-b)<40)||(p<200)){m=false;break}}l++}while(!m&&l<=10);return"#"+(16777216+g).toString(16).substr(1,6)};var create_action_icon=function(c,b,a){return $("").attr("href","javascript:void(0);").attr("title",c).addClass("icon-button").addClass(b).tooltip().click(a)};var trackster_module=function(d,S){var o=d("class").extend,s=d("slotting"),I=d("painters");var m={};var k=function(Z,aa){m[Z.attr("id")]=aa};var l=function(Z,ab,ad,ac){ad=".group";var aa={};m[Z.attr("id")]=ac;Z.bind("drag",{handle:"."+ab,relative:true},function(al,am){var ak=$(this),ap=$(this).parent(),ah=ap.children(),aj=m[$(this).attr("id")],ag,af,an,ae,ai;af=$(this).parents(ad);if(af.length!==0){an=af.position().top;ae=an+af.outerHeight();if(am.offsetYae){$(this).insertAfter(af);var ao=m[af.attr("id")];ao.remove_drawable(aj);ao.container.add_drawable(aj);return}}}af=null;for(ai=0;ai=an&&am.offsetY<=ae){if(am.offsetY-an0?ai-1:ai))}}}).bind("dragstart",function(){aa["border-top"]=Z.css("border-top");aa["border-bottom"]=Z.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(aa)})};S.moveable=l;var Y=16,D=9,A=20,x=100,F=12000,P=400,H=5000,u=100,n="There was an error in indexing this dataset. ",G="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",t="Preparing data. This can take a while for a large dataset. If the visualization is saved and closed, preparation will continue in the background.",v="Tool cannot be rerun: ",a="Loading data...",T="Ready for display",N=10,E=20;function U(aa,Z){if(!Z){Z=0}var ab=Math.pow(10,Z);return Math.round(aa*ab)/ab}var p=function(aa,Z,ac){if(!p.id_counter){p.id_counter=0}this.id=p.id_counter++;this.name=ac.name;this.view=aa;this.container=Z;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name}],saved_values:ac.prefs,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=ac.drag_handle_class;this.is_overview=false;this.action_icons={};this.content_visible=true;this.container_div=this.build_container_div();this.header_div=this.build_header_div();if(this.header_div){this.container_div.append(this.header_div);this.icons_div=$("").css("float","left").hide().appendTo(this.header_div);this.build_action_icons(this.action_icons_def);this.header_div.append($(""));this.header_div.dblclick(function(ad){ad.stopPropagation()});var ab=this;this.container_div.hover(function(){ab.icons_div.show()},function(){ab.icons_div.hide()});$("").appendTo(this.container_div)}};p.prototype.action_icons_def=[{name:"toggle_icon",title:"Hide/show content",css_class:"toggle",on_click_fn:function(Z){if(Z.content_visible){Z.action_icons.toggle_icon.addClass("toggle-expand").removeClass("toggle");Z.hide_contents();Z.content_visible=false}else{Z.action_icons.toggle_icon.addClass("toggle").removeClass("toggle-expand");Z.content_visible=true;Z.show_contents()}}},{name:"settings_icon",title:"Edit settings",css_class:"settings-icon",on_click_fn:function(aa){var ac=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},Z=function(){aa.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ab=function(ad){if((ad.keyCode||ad.which)===27){ac()}else{if((ad.keyCode||ad.which)===13){Z()}}};$(window).bind("keypress.check_enter_esc",ab);show_modal("Configure",aa.config.build_form(),{Cancel:ac,OK:Z})}},{name:"remove_icon",title:"Remove",css_class:"remove-icon",on_click_fn:function(Z){$(".bs-tooltip").remove();Z.remove()}}];o(p.prototype,{init:function(){},changed:function(){this.view.changed()},can_draw:function(){if(this.enabled&&this.content_visible){return true}return false},request_draw:function(){},_draw:function(){},to_dict:function(){},set_name:function(Z){this.old_name=this.name;this.name=Z;this.name_div.text(this.name)},revert_name:function(){if(this.old_name){this.name=this.old_name;this.name_div.text(this.name)}},remove:function(){this.changed();this.container.remove_drawable(this);var Z=this.view;this.container_div.hide(0,function(){$(this).remove();Z.update_intro_div()})},build_container_div:function(){},build_header_div:function(){},add_action_icon:function(aa,af,ae,ad,Z,ac){var ab=this;this.action_icons[aa]=$("").attr("href","javascript:void(0);").attr("title",af).addClass("icon-button").addClass(ae).tooltip().click(function(){ad(ab)}).appendTo(this.icons_div);if(ac){this.action_icons[aa].hide()}},build_action_icons:function(Z){var ab;for(var aa=0;aa").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);k(this.container_div,this);k(this.content_div,this);l(this.container_div,this.drag_handle_class,".group",this);this.filters_manager=new V(this);this.header_div.after(this.filters_manager.parent_div);this.saved_filters_managers=[];if("drawables" in ac){this.unpack_drawables(ac.drawables)}if("filters" in ac){var ab=this.filters_manager;this.filters_manager=new V(this,ac.filters);ab.parent_div.replaceWith(this.filters_manager.parent_div);if(ac.filters.visible){this.setup_multitrack_filtering()}}};o(M.prototype,p.prototype,w.prototype,{action_icons_def:[p.prototype.action_icons_def[0],p.prototype.action_icons_def[1],{name:"composite_icon",title:"Show composite track",css_class:"layers-stack",on_click_fn:function(Z){$(".bs-tooltip").remove();Z.show_composite_track()}},{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(Z){if(Z.filters_manager.visible()){Z.filters_manager.clear_filters();Z._restore_filter_managers()}else{Z.setup_multitrack_filtering();Z.request_draw(true)}Z.filters_manager.toggle()}},p.prototype.action_icons_def[2]],build_container_div:function(){var Z=$("").addClass("group").attr("id","group_"+this.id);if(this.container){this.container.content_div.append(Z)}return Z},build_header_div:function(){var Z=$("").addClass("track-header");Z.append($("").addClass(this.drag_handle_class));this.name_div=$("").addClass("track-name").text(this.name).appendTo(Z);return Z},hide_contents:function(){this.tiles_div.hide()},show_contents:function(){this.tiles_div.show();this.request_draw()},update_icons:function(){var ab=this.drawables.length;if(ab===0){this.action_icons.composite_icon.hide();this.action_icons.filters_icon.hide()}else{if(ab===1){if(this.drawables[0] instanceof g){this.action_icons.composite_icon.show()}this.action_icons.filters_icon.hide()}else{var ai,ah,af,al=true,ad=this.drawables[0].get_type(),Z=0;for(ai=0;ai1&&Z===this.drawables.length){var am={},aa;af=this.drawables[0];for(ah=0;ah0){this.action_icons.filters_icon.show()}else{this.action_icons.filters_icon.hide()}}else{this.action_icons.filters_icon.hide()}}}},_restore_filter_managers:function(){for(var Z=0;Z0){this.saved_filters_managers=[];for(var Z=0;Z").addClass("top-container").appendTo(ab);this.browser_content_div=$("").addClass("content").css("position","relative").appendTo(ab);this.bottom_container=$("").addClass("bottom-container").appendTo(ab);this.top_labeltrack=$("").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;k(this.viewport_container,Z);this.intro_div=$("").addClass("intro").appendTo(this.viewport_container).hide();var ac=$("").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_datasets(add_datasets_url,add_track_async_url,function(ad){_.each(ad,function(ae){Z.add_drawable(object_from_template(ae,Z,Z))})})});this.nav_labeltrack=$("").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("").addClass("trackster-nav-container").prependTo(this.top_container);this.nav=$("").addClass("trackster-nav").appendTo(this.nav_container);this.overview=$("").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("").appendTo(this.nav_controls);var aa=function(ad){if(ad.type==="focusout"||(ad.keyCode||ad.which)===13||(ad.keyCode||ad.which)===27){if((ad.keyCode||ad.which)!==27){Z.go_to($(this).val())}$(this).hide();$(this).val("");Z.location_span.show();Z.chrom_select.show()}};this.nav_input=$("").addClass("nav-input").hide().bind("keyup focusout",aa).appendTo(this.nav_controls);this.location_span=$("").addClass("location").attr("original-title","Click to change location").tooltip({placement:"bottom"}).appendTo(this.nav_controls);this.location_span.click(function(){Z.location_span.hide();Z.chrom_select.hide();Z.nav_input.val(Z.chrom+":"+Z.low+"-"+Z.high);Z.nav_input.css("display","inline-block");Z.nav_input.select();Z.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("").attr("id","zoom-out").attr("title","Zoom out").tooltip({placement:"bottom"}).click(function(){Z.zoom_out();Z.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("").attr("id","zoom-in").attr("title","Zoom in").tooltip({placement:"bottom"}).click(function(){Z.zoom_in();Z.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){Z.change_chrom(Z.chrom_select.val())});this.browser_content_div.click(function(ad){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(ad){Z.zoom_in(ad.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ad,ae){this.current_x=ae.offsetX}).bind("drag",function(ad,af){var ag=af.offsetX-this.current_x;this.current_x=af.offsetX;var ae=Math.round(ag/Z.viewport_container.width()*(Z.max_high-Z.max_low));Z.move_delta(-ae)});this.overview_close.click(function(){Z.reset_overview()});this.viewport_container.bind("draginit",function(ad,ae){if(ad.clientX>Z.viewport_container.width()-16){return false}}).bind("dragstart",function(ad,ae){ae.original_low=Z.low;ae.current_height=ad.clientY;ae.current_x=ae.offsetX}).bind("drag",function(af,ah){var ad=$(this);var ai=ah.offsetX-ah.current_x;var ae=ad.scrollTop()-(af.clientY-ah.current_height);ad.scrollTop(ae);ah.current_height=af.clientY;ah.current_x=ah.offsetX;var ag=Math.round(ai/Z.viewport_container.width()*(Z.high-Z.low));Z.move_delta(ag)}).bind("mousewheel",function(af,ah,ae,ad){if(ae){ae*=50;var ag=Math.round(-ae/Z.viewport_container.width()*(Z.high-Z.low));Z.move_delta(ag)}});this.top_labeltrack.bind("dragstart",function(ad,ae){return $("").css({height:Z.browser_content_div.height()+Z.top_labeltrack.height()+Z.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ah,ai){$(ai.proxy).css({left:Math.min(ah.pageX,ai.startX)-Z.container.offset().left,width:Math.abs(ah.pageX-ai.startX)});var ae=Math.min(ah.pageX,ai.startX)-Z.container.offset().left,ad=Math.max(ah.pageX,ai.startX)-Z.container.offset().left,ag=(Z.high-Z.low),af=Z.viewport_container.width();Z.update_location(Math.round(ae/af*ag)+Z.low,Math.round(ad/af*ag)+Z.low)}).bind("dragend",function(ai,aj){var ae=Math.min(ai.pageX,aj.startX),ad=Math.max(ai.pageX,aj.startX),ag=(Z.high-Z.low),af=Z.viewport_container.width(),ah=Z.low;Z.low=Math.round(ae/af*ag)+ah;Z.high=Math.round(ad/af*ag)+ah;$(aj.proxy).remove();Z.request_redraw()});this.add_label_track(new W(this,{content_div:this.top_labeltrack}));this.add_label_track(new W(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){if(this.resize_timer){clearTimeout(this.resize_timer)}this.resize_timer=setTimeout(function(){Z.resize_window()},500)});$(document).bind("redraw",function(){Z.redraw()});this.reset();$(window).trigger("resize")},changed:function(){this.has_changes=true},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.show()}else{this.intro_div.hide()}},trigger_navigate:function(aa,ac,Z,ad){if(this.timer){clearTimeout(this.timer)}if(ad){var ab=this;this.timer=setTimeout(function(){ab.trigger("navigate",aa+":"+ac+"-"+Z)},500)}else{view.trigger("navigate",aa+":"+ac+"-"+Z)}},update_location:function(Z,ab){this.location_span.text(commatize(Z)+" - "+commatize(ab));this.nav_input.val(this.chrom+":"+commatize(Z)+"-"+commatize(ab));var aa=view.chrom_select.val();if(aa!==""){this.trigger_navigate(aa,view.low,view.high,true)}},load_chroms:function(ab){ab.num=u;ab.dbkey=this.dbkey;var Z=this,aa=$.Deferred();$.ajax({url:chrom_url,data:ab,dataType:"json",success:function(ad){if(ad.chrom_info.length===0){alert("Invalid chromosome: "+ab.chrom);return}if(ad.reference){Z.add_label_track(new y(Z))}Z.chrom_data=ad.chrom_info;var ag='';for(var af=0,ac=Z.chrom_data.length;af'+ae+""}if(ad.prev_chroms){ag+='"}if(ad.next_chroms){ag+='"}Z.chrom_select.html(ag);Z.chrom_start_index=ad.start_index;aa.resolve(ad)},error:function(){alert("Could not load chroms for this dbkey:",Z.dbkey)}});return aa},change_chrom:function(ae,aa,ag){var ab=this;if(!ab.chrom_data){ab.load_chroms_deferred.then(function(){ab.change_chrom(ae,aa,ag)});return}if(!ae||ae==="None"){return}if(ae==="previous"){ab.load_chroms({low:this.chrom_start_index-u});return}if(ae==="next"){ab.load_chroms({low:this.chrom_start_index+u});return}var af=$.grep(ab.chrom_data,function(ah,ai){return ah.chrom===ae})[0];if(af===undefined){ab.load_chroms({chrom:ae},function(){ab.change_chrom(ae,aa,ag)});return}else{if(ae!==ab.chrom){ab.chrom=ae;ab.chrom_select.val(ab.chrom);ab.max_high=af.len-1;ab.reset();ab.request_redraw(true);for(var ad=0,Z=ab.drawables.length;adZ.max_high){Z.high=Z.max_high;Z.low=Z.max_high-ab}else{Z.high-=ac;Z.low-=ac}}Z.request_redraw();var aa=Z.chrom_select.val();this.trigger_navigate(aa,Z.low,Z.high,true)},add_drawable:function(Z){w.prototype.add_drawable.call(this,Z);Z.init();this.changed();this.update_intro_div()},add_label_track:function(Z){Z.view=this;Z.init();this.label_tracks.push(Z)},remove_drawable:function(ab,aa){w.prototype.remove_drawable.call(this,ab);if(aa){var Z=this;ab.container_div.hide(0,function(){$(this).remove();Z.update_intro_div()})}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ah,Z,ag,ai){var af=this,ae=(ai?[ai]:af.drawables),ab;var aa;for(var ad=0;adthis.max_high){ac=this.max_high}var ai=this.high-this.low;if(this.high!==0&&ai").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aq){aq.stopPropagation()}).click(function(aq){aq.stopPropagation()}).bind("dblclick",function(aq){aq.stopPropagation()});var al=$("
").addClass("param-row").appendTo(this.parent_div);var af=$("").attr("value","Run on complete dataset").appendTo(ap);var Z=$("").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);Z.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()});if("visible" in ac&&ac.visible){this.parent_div.show()}};o(q.prototype,{update_params:function(){for(var Z=0;Z").attr("size",am).attr("maxlength",am).attr("value",ap).appendTo(aj).focus().select().click(function(aq){aq.stopPropagation()}).blur(function(){$(this).remove();aj.text(ap);al.removeClass("input")}).keyup(function(av){if(av.keyCode===27){$(this).trigger("blur")}else{if(av.keyCode===13){var at=ak.slider("option","min"),aq=ak.slider("option","max"),au=function(aw){return(isNaN(aw)||aw>aq||aw").addClass("filter-row slider-row");var Z=$("").addClass("elt-label").appendTo(aa.parent_div),af=$("").addClass("slider-name").text(aa.name+" ").appendTo(Z),ab=$("").text(this.low+"-"+this.high),ac=$("").addClass("slider-value").appendTo(Z).append("[").append(ab).append("]");aa.values_span=ab;var ae=$("").addClass("slider").appendTo(aa.parent_div);aa.control_element=$("").attr("id",aa.name+"-filter-control").appendTo(ae);aa.control_element.slider({range:true,min:this.min,max:this.max,step:this.get_slider_step(this.min,this.max),values:[this.low,this.high],slide:function(ai,aj){aa.slide(ai,aj)},change:function(ai,aj){aa.control_element.slider("option","slide").call(aa.control_element,ai,aj)}});aa.slider=aa.control_element;aa.slider_label=ab;ad(ac,ab,aa.control_element);var ag=$("").addClass("display-controls").appendTo(aa.parent_div);this.transparency_icon=create_action_icon("Use filter for data transparency","layer-transparent",function(){if(aa.manager.alpha_filter!==aa){aa.manager.alpha_filter=aa;aa.manager.parent_div.find(".layer-transparent").removeClass("active").hide();aa.transparency_icon.addClass("active").show()}else{aa.manager.alpha_filter=null;aa.transparency_icon.removeClass("active")}aa.manager.track.request_draw(true,true)}).appendTo(ag).hide();this.height_icon=create_action_icon("Use filter for data height","arrow-resize-090",function(){if(aa.manager.height_filter!==aa){aa.manager.height_filter=aa;aa.manager.parent_div.find(".arrow-resize-090").removeClass("active").hide();aa.height_icon.addClass("active").show()}else{aa.manager.height_filter=null;aa.height_icon.removeClass("active")}aa.manager.track.request_draw(true,true)}).appendTo(ag).hide();aa.parent_div.hover(function(){aa.transparency_icon.show();aa.height_icon.show()},function(){if(aa.manager.alpha_filter!==aa){aa.transparency_icon.hide()}if(aa.manager.height_filter!==aa){aa.height_icon.hide()}});$("").appendTo(aa.parent_div)};o(Q.prototype,{to_dict:function(){var Z=f.prototype.to_dict.call(this);return o(Z,{type:"number",min:this.min,max:this.max,low:this.low,high:this.high})},copy:function(){return new Q({name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name})},get_slider_step:function(ab,Z){var aa=Z-ab;return(aa<=2?0.01:1)},slide:function(ab,ac){var aa=ac.values;this.values_span.text(aa[0]+"-"+aa[1]);this.low=aa[0];this.high=aa[1];var Z=this;setTimeout(function(){if(aa[0]===Z.low&&aa[1]===Z.high){Z.manager.track.request_draw(true,true)}},25)},applies_to:function(Z){if(Z.length>this.index){return true}return false},_keep_val:function(Z){return(isNaN(Z)||(Z>=this.low&&Z<=this.high))},keep:function(aa){if(!this.applies_to(aa)){return true}var ac=this;var ad=aa[this.index];if(ad instanceof Array){var ab=true;for(var Z=0;Zthis.max){this.max=Math.ceil(ad);Z=true}}return Z},update_ui_elt:function(){if(this.minZ){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",this.get_slider_step(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var V=function(ab,ah){this.track=ab;this.alpha_filter=null;this.height_filter=null;this.filters=[];this.parent_div=$("").addClass("filters").hide();this.parent_div.bind("drag",function(aj){aj.stopPropagation()}).click(function(aj){aj.stopPropagation()}).bind("dblclick",function(aj){aj.stopPropagation()}).bind("keydown",function(aj){aj.stopPropagation()});if(ah&&"filters" in ah){var Z=("alpha_filter" in ah?ah.alpha_filter:null),ac=("height_filter" in ah?ah.height_filter:null),ae=ah.filters,aa;for(var af=0;af").addClass("param-row").appendTo(this.parent_div);var ag=$("").attr("value","Run on complete dataset").appendTo(ai);var ad=this;ag.click(function(){ad.run_on_dataset()})}};o(V.prototype,{show:function(){this.parent_div.show()},hide:function(){this.parent_div.hide()},toggle:function(){this.parent_div.toggle()},visible:function(){return this.parent_div.is(":visible")},to_dict:function(){var ac={},ab=[],aa;for(var Z=0;Z= "+ag.low}if(ag.max!==ag.high){Z=af(ae,ag.tool_id,[]);Z[Z.length]=ag.tool_exp_name+" <= "+ag.high}}}var aa=[];for(var ac in ae){aa[aa.length]=[ac,ae[ac]]}(function ab(an,ak){var ai=ak[0],aj=ai[0],am=ai[1],al="("+am.join(") and (")+")",ah={cond:al,input:an,target_dataset_id:an,tool_id:aj},ak=ak.slice(1);$.getJSON(run_tool_url,ah,function(ao){if(ao.error){show_modal("Filter Dataset","Error running tool "+aj,{Close:hide_modal})}else{if(ak.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ab(ao.dataset_id,ak)}}})})(this.track.dataset_id,aa)}});var z=function(Z,aa){I.Scaler.call(this,aa);this.filter=Z};z.prototype.gen_val=function(Z){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(Z[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var C=function(Z){this.track=Z.track;this.params=Z.params;this.values={};this.restore_values((Z.saved_values?Z.saved_values:{}));this.onchange=Z.onchange};o(C.prototype,{restore_values:function(Z){var aa=this;$.each(this.params,function(ab,ac){if(Z[ac.key]!==undefined){aa.values[ac.key]=Z[ac.key]}else{aa.values[ac.key]=ac.default_value}})},build_form:function(){var ac=this;var Z=$("");var ab;function aa(ah,ad){for(var al=0;al").appendTo(ad);ar.append($("").attr("for",af).text(ab.label+":"));if(ab.type==="bool"){ar.append($('').attr("id",af).attr("name",af).attr("checked",ap))}else{if(ab.type==="text"){ar.append($('').attr("id",af).val(ap).click(function(){$(this).select()}))}else{if(ab.type==="select"){var an=$("").attr("id",af);for(var aj=0;aj").text(ab.options[aj].label).attr("value",ab.options[aj].value).appendTo(an)}an.val(ap);ar.append(an)}else{if(ab.type==="color"){var aq=$("").appendTo(ar),am=$("").attr("id",af).attr("name",af).val(ap).css("float","left").appendTo(aq).click(function(au){$(".bs-tooltip").removeClass("in");var at=$(this).siblings(".bs-tooltip").addClass("in");at.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-($(at).height()/2)+($(this).height()/2)}).show();at.click(function(av){av.stopPropagation()});$(document).bind("click.color-picker",function(){at.hide();$(document).unbind("click.color-picker")});au.stopPropagation()}),ak=$("").addClass("icon-button arrow-circle").appendTo(aq).attr("title","Set new random color").tooltip(),ao=$("").appendTo(aq).hide(),ag=$("").appendTo(ao),ae=$("").appendTo(ao),ai=$.farbtastic(ag,{width:100,height:100,callback:am,color:ap});aq.append($("").css("clear","both"));(function(at){ak.click(function(){at.setColor(get_random_color())})})(ai)}else{ar.append($("").attr("id",af).attr("name",af).val(ap))}}}}if(ab.help){ar.append($("").text(ab.help))}}}aa(this.params,Z);return Z},update_from_form:function(Z){var ab=this;var aa=false;$.each(this.params,function(ac,ae){if(!ae.hidden){var af="param_"+ac;var ad=Z.find("#"+af).val();if(ae.type==="float"){ad=parseFloat(ad)}else{if(ae.type==="int"){ad=parseInt(ad)}else{if(ae.type==="bool"){ad=Z.find("#"+af).is(":checked")}}}if(ad!==ab.values[ae.key]){ab.values[ae.key]=ad;aa=true}}});if(aa){this.onchange();this.track.changed()}}});var b=function(Z,ad,ab,aa,ac){this.track=Z;this.region=ad;this.low=ad.get("start");this.high=ad.get("end");this.resolution=ab;this.html_elt=$("").append(aa).height($(aa).attr("height"));this.data=ac;this.stale=false};b.prototype.predisplay_actions=function(){};var j=function(Z,ae,ab,aa,ac,ad){b.call(this,Z,ae,ab,aa,ac);this.max_val=ad};o(j.prototype,b.prototype);var L=function(ac,ak,ad,ab,af,am,ag,an,aa,aj){b.call(this,ac,ak,ad,ab,af);this.mode=ag;this.all_slotted=aa;this.feature_mapper=aj;this.has_icons=false;if(an){this.has_icons=true;var ah=this;ab=this.html_elt.children()[0],message_div=$("").addClass("tile-message").css({height:A-1,width:ab.width}).prependTo(this.html_elt);var ai=new GenomeRegion({chrom:ac.view.chrom,start:this.low,end:this.high}),al=af.length,ae=$("").addClass("icon more-down").attr("title","For speed, only the first "+al+" features in this region were obtained from server. Click to get more data including depth").tooltip().appendTo(message_div),Z=$("").addClass("icon more-across").attr("title","For speed, only the first "+al+" features in this region were obtained from server. Click to get more data excluding depth").tooltip().appendTo(message_div);ae.click(function(){ah.stale=true;ac.data_manager.get_more_data(ai,ac.mode,ah.resolution,{},ac.data_manager.DEEP_DATA_REQ);$(".bs-tooltip").hide();ac.request_draw(true)}).dblclick(function(ao){ao.stopPropagation()});Z.click(function(){ah.stale=true;ac.data_manager.get_more_data(ai,ac.mode,ah.resolution,{},ac.data_manager.BROAD_DATA_REQ);$(".bs-tooltip").hide();ac.request_draw(true)}).dblclick(function(ao){ao.stopPropagation()})}};o(L.prototype,b.prototype);L.prototype.predisplay_actions=function(){var aa=this,Z={};if(aa.mode!=="Pack"){return}$(this.html_elt).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()}).mousemove(function(al){if(!this.hovered){return}var ag=$(this).offset(),ak=al.pageX-ag.left,aj=al.pageY-ag.top,ap=aa.feature_mapper.get_feature_data(ak,aj),ah=(ap?ap[0]:null);$(this).parents(".track-content").children(".overlay").children(".feature-popup").each(function(){if(!ah||$(this).attr("id")!==ah.toString()){$(this).remove()}});if(ap){var ac=Z[ah];if(!ac){var ah=ap[0],am={name:ap[3],start:ap[1],end:ap[2],strand:ap[4]},af=aa.track.filters_manager.filters,ae;for(var ai=0;ai").attr("id",ah).addClass("feature-popup"),aq=$("
").append(aq));Z[ah]=ac}ac.appendTo($(this).parents(".track-content").children(".overlay"));var ad=ak+parseInt(aa.html_elt.css("left"))-ac.width()/2,ab=aj+parseInt(aa.html_elt.css("top"))+7;ac.css("left",ad+"px").css("top",ab+"px")}else{if(!al.isPropagationStopped()){al.stopPropagation();$(this).siblings().each(function(){$(this).trigger(al)})}}}).mouseleave(function(){$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()})};var h=function(ab,aa,ad){o(ad,{drag_handle_class:"draghandle"});p.call(this,ab,aa,ad);this.data_url=("data_url" in ad?ad.data_url:default_data_url);this.data_url_extra_params={};this.data_query_wait=("data_query_wait" in ad?ad.data_query_wait:H);this.dataset_check_url=("converted_datasets_state_url" in ad?ad.converted_datasets_state_url:converted_datasets_state_url);var Z=this,ac=new Dataset({id:ad.dataset_id,hda_ldda:ad.hda_ldda});this.data_manager=("data_manager" in ad?ad.data_manager:new GenomeDataManager({dataset:ac,data_url:Z.data_url,dataset_state_url:Z.dataset_check_url,data_mode_compatible:this.data_and_mode_compatible,can_subset:this.can_subset}));this.min_height_px=16;this.max_height_px=800;this.visible_height_px=0;this.content_div=$("
").appendTo(this.container_div);if(this.container){this.container.content_div.append(this.container_div);if(!("resize" in ad)||ad.resize){this.add_resize_handle()}}};o(h.prototype,p.prototype,{action_icons_def:[{name:"mode_icon",title:"Set display mode",css_class:"chevron-expand",on_click_fn:function(){}},p.prototype.action_icons_def[0],{name:"overview_icon",title:"Set as overview",css_class:"overview-icon",on_click_fn:function(Z){Z.view.set_overview(Z)}},p.prototype.action_icons_def[1],{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(Z){if(Z.filters_manager.visible()){Z.filters_manager.clear_filters()}else{Z.filters_manager.init_filters()}Z.filters_manager.toggle()}},{name:"tools_icon",title:"Tool",css_class:"hammer",on_click_fn:function(Z){Z.dynamic_tool_div.toggle();if(Z.dynamic_tool_div.is(":visible")){Z.set_name(Z.name+Z.tool_region_and_parameters_str())}else{Z.revert_name()}$(".bs-tooltip").remove()}},{name:"param_space_viz_icon",title:"Tool parameter space visualization",css_class:"arrow-split",on_click_fn:function(Z){var ac='Tool: <%= track.tool.name %> Dataset: <%= track.name %> Region(s): ',ab=_.template(ac,{track:Z});var ae=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},aa=function(){var ag=$('select[name="regions"] option:selected').val(),ai,af=new GenomeRegion({chrom:view.chrom,start:view.low,end:view.high}),ah=_.map($(".bookmark"),function(aj){return new GenomeRegion({from_str:$(aj).children(".position").text()})});if(ag==="cur"){ai=[af]}else{if(ag==="bookmarks"){ai=ah}else{ai=[af].concat(ah)}}hide_modal();window.location.href=galaxy_paths.get("sweepster_url")+"?"+$.param({dataset_id:Z.dataset_id,hda_ldda:Z.hda_ldda,regions:JSON.stringify(new Backbone.Collection(ai).toJSON())})},ad=function(af){if((af.keyCode||af.which)===27){ae()}else{if((af.keyCode||af.which)===13){aa()}}};show_modal("Visualize tool parameter space and output from different parameter settings?",ab,{No:ae,Yes:aa})}},p.prototype.action_icons_def[2]],can_draw:function(){if(this.dataset_id&&p.prototype.can_draw.call(this)){return true}return false},build_container_div:function(){return $("").addClass("track").attr("id","track_"+this.id).css("position","relative")},build_header_div:function(){var Z=$("");if(this.view.editor){this.drag_div=$("").addClass(this.drag_handle_class).appendTo(Z)}this.name_div=$("").addClass("track-name").appendTo(Z).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());return Z},on_resize:function(){},add_resize_handle:function(){var Z=this;var ac=false;var ab=false;var aa=$("
").addClass("param-row").appendTo(this.parent_div);var af=$("").attr("value","Run on complete dataset").appendTo(ap);var Z=$("").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);Z.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()});if("visible" in ac&&ac.visible){this.parent_div.show()}};o(q.prototype,{update_params:function(){for(var Z=0;Z").attr("size",am).attr("maxlength",am).attr("value",ap).appendTo(aj).focus().select().click(function(aq){aq.stopPropagation()}).blur(function(){$(this).remove();aj.text(ap);al.removeClass("input")}).keyup(function(av){if(av.keyCode===27){$(this).trigger("blur")}else{if(av.keyCode===13){var at=ak.slider("option","min"),aq=ak.slider("option","max"),au=function(aw){return(isNaN(aw)||aw>aq||aw").addClass("filter-row slider-row");var Z=$("").addClass("elt-label").appendTo(aa.parent_div),af=$("").addClass("slider-name").text(aa.name+" ").appendTo(Z),ab=$("").text(this.low+"-"+this.high),ac=$("").addClass("slider-value").appendTo(Z).append("[").append(ab).append("]");aa.values_span=ab;var ae=$("").addClass("slider").appendTo(aa.parent_div);aa.control_element=$("").attr("id",aa.name+"-filter-control").appendTo(ae);aa.control_element.slider({range:true,min:this.min,max:this.max,step:this.get_slider_step(this.min,this.max),values:[this.low,this.high],slide:function(ai,aj){aa.slide(ai,aj)},change:function(ai,aj){aa.control_element.slider("option","slide").call(aa.control_element,ai,aj)}});aa.slider=aa.control_element;aa.slider_label=ab;ad(ac,ab,aa.control_element);var ag=$("").addClass("display-controls").appendTo(aa.parent_div);this.transparency_icon=create_action_icon("Use filter for data transparency","layer-transparent",function(){if(aa.manager.alpha_filter!==aa){aa.manager.alpha_filter=aa;aa.manager.parent_div.find(".layer-transparent").removeClass("active").hide();aa.transparency_icon.addClass("active").show()}else{aa.manager.alpha_filter=null;aa.transparency_icon.removeClass("active")}aa.manager.track.request_draw(true,true)}).appendTo(ag).hide();this.height_icon=create_action_icon("Use filter for data height","arrow-resize-090",function(){if(aa.manager.height_filter!==aa){aa.manager.height_filter=aa;aa.manager.parent_div.find(".arrow-resize-090").removeClass("active").hide();aa.height_icon.addClass("active").show()}else{aa.manager.height_filter=null;aa.height_icon.removeClass("active")}aa.manager.track.request_draw(true,true)}).appendTo(ag).hide();aa.parent_div.hover(function(){aa.transparency_icon.show();aa.height_icon.show()},function(){if(aa.manager.alpha_filter!==aa){aa.transparency_icon.hide()}if(aa.manager.height_filter!==aa){aa.height_icon.hide()}});$("").appendTo(aa.parent_div)};o(Q.prototype,{to_dict:function(){var Z=f.prototype.to_dict.call(this);return o(Z,{type:"number",min:this.min,max:this.max,low:this.low,high:this.high})},copy:function(){return new Q({name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name})},get_slider_step:function(ab,Z){var aa=Z-ab;return(aa<=2?0.01:1)},slide:function(ab,ac){var aa=ac.values;this.values_span.text(aa[0]+"-"+aa[1]);this.low=aa[0];this.high=aa[1];var Z=this;setTimeout(function(){if(aa[0]===Z.low&&aa[1]===Z.high){Z.manager.track.request_draw(true,true)}},25)},applies_to:function(Z){if(Z.length>this.index){return true}return false},_keep_val:function(Z){return(isNaN(Z)||(Z>=this.low&&Z<=this.high))},keep:function(aa){if(!this.applies_to(aa)){return true}var ac=this;var ad=aa[this.index];if(ad instanceof Array){var ab=true;for(var Z=0;Zthis.max){this.max=Math.ceil(ad);Z=true}}return Z},update_ui_elt:function(){if(this.minZ){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",this.get_slider_step(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var V=function(ab,ah){this.track=ab;this.alpha_filter=null;this.height_filter=null;this.filters=[];this.parent_div=$("").addClass("filters").hide();this.parent_div.bind("drag",function(aj){aj.stopPropagation()}).click(function(aj){aj.stopPropagation()}).bind("dblclick",function(aj){aj.stopPropagation()}).bind("keydown",function(aj){aj.stopPropagation()});if(ah&&"filters" in ah){var Z=("alpha_filter" in ah?ah.alpha_filter:null),ac=("height_filter" in ah?ah.height_filter:null),ae=ah.filters,aa;for(var af=0;af").addClass("param-row").appendTo(this.parent_div);var ag=$("").attr("value","Run on complete dataset").appendTo(ai);var ad=this;ag.click(function(){ad.run_on_dataset()})}};o(V.prototype,{show:function(){this.parent_div.show()},hide:function(){this.parent_div.hide()},toggle:function(){this.parent_div.toggle()},visible:function(){return this.parent_div.is(":visible")},to_dict:function(){var ac={},ab=[],aa;for(var Z=0;Z= "+ag.low}if(ag.max!==ag.high){Z=af(ae,ag.tool_id,[]);Z[Z.length]=ag.tool_exp_name+" <= "+ag.high}}}var aa=[];for(var ac in ae){aa[aa.length]=[ac,ae[ac]]}(function ab(an,ak){var ai=ak[0],aj=ai[0],am=ai[1],al="("+am.join(") and (")+")",ah={cond:al,input:an,target_dataset_id:an,tool_id:aj},ak=ak.slice(1);$.getJSON(run_tool_url,ah,function(ao){if(ao.error){show_modal("Filter Dataset","Error running tool "+aj,{Close:hide_modal})}else{if(ak.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ab(ao.dataset_id,ak)}}})})(this.track.dataset_id,aa)}});var z=function(Z,aa){I.Scaler.call(this,aa);this.filter=Z};z.prototype.gen_val=function(Z){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(Z[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var C=function(Z){this.track=Z.track;this.params=Z.params;this.values={};this.restore_values((Z.saved_values?Z.saved_values:{}));this.onchange=Z.onchange};o(C.prototype,{restore_values:function(Z){var aa=this;$.each(this.params,function(ab,ac){if(Z[ac.key]!==undefined){aa.values[ac.key]=Z[ac.key]}else{aa.values[ac.key]=ac.default_value}})},build_form:function(){var ac=this;var Z=$("");var ab;function aa(ah,ad){for(var al=0;al").appendTo(ad);ar.append($("").attr("for",af).text(ab.label+":"));if(ab.type==="bool"){ar.append($('').attr("id",af).attr("name",af).attr("checked",ap))}else{if(ab.type==="text"){ar.append($('').attr("id",af).val(ap).click(function(){$(this).select()}))}else{if(ab.type==="select"){var an=$("").attr("id",af);for(var aj=0;aj").text(ab.options[aj].label).attr("value",ab.options[aj].value).appendTo(an)}an.val(ap);ar.append(an)}else{if(ab.type==="color"){var aq=$("").appendTo(ar),am=$("").attr("id",af).attr("name",af).val(ap).css("float","left").appendTo(aq).click(function(au){$(".bs-tooltip").removeClass("in");var at=$(this).siblings(".bs-tooltip").addClass("in");at.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-($(at).height()/2)+($(this).height()/2)}).show();at.click(function(av){av.stopPropagation()});$(document).bind("click.color-picker",function(){at.hide();$(document).unbind("click.color-picker")});au.stopPropagation()}),ak=$("").addClass("icon-button arrow-circle").appendTo(aq).attr("title","Set new random color").tooltip(),ao=$("").appendTo(aq).hide(),ag=$("").appendTo(ao),ae=$("").appendTo(ao),ai=$.farbtastic(ag,{width:100,height:100,callback:am,color:ap});aq.append($("").css("clear","both"));(function(at){ak.click(function(){at.setColor(get_random_color())})})(ai)}else{ar.append($("").attr("id",af).attr("name",af).val(ap))}}}}if(ab.help){ar.append($("").text(ab.help))}}}aa(this.params,Z);return Z},update_from_form:function(Z){var ab=this;var aa=false;$.each(this.params,function(ac,ae){if(!ae.hidden){var af="param_"+ac;var ad=Z.find("#"+af).val();if(ae.type==="float"){ad=parseFloat(ad)}else{if(ae.type==="int"){ad=parseInt(ad)}else{if(ae.type==="bool"){ad=Z.find("#"+af).is(":checked")}}}if(ad!==ab.values[ae.key]){ab.values[ae.key]=ad;aa=true}}});if(aa){this.onchange();this.track.changed()}}});var b=function(Z,ad,ab,aa,ac){this.track=Z;this.region=ad;this.low=ad.get("start");this.high=ad.get("end");this.resolution=ab;this.html_elt=$("").append(aa).height($(aa).attr("height"));this.data=ac;this.stale=false};b.prototype.predisplay_actions=function(){};var j=function(Z,ae,ab,aa,ac,ad){b.call(this,Z,ae,ab,aa,ac);this.max_val=ad};o(j.prototype,b.prototype);var L=function(ac,ak,ad,ab,af,am,ag,an,aa,aj){b.call(this,ac,ak,ad,ab,af);this.mode=ag;this.all_slotted=aa;this.feature_mapper=aj;this.has_icons=false;if(an){this.has_icons=true;var ah=this;ab=this.html_elt.children()[0],message_div=$("").addClass("tile-message").css({height:A-1,width:ab.width}).prependTo(this.html_elt);var ai=new GenomeRegion({chrom:ac.view.chrom,start:this.low,end:this.high}),al=af.length,ae=$("").addClass("icon more-down").attr("title","For speed, only the first "+al+" features in this region were obtained from server. Click to get more data including depth").tooltip().appendTo(message_div),Z=$("").addClass("icon more-across").attr("title","For speed, only the first "+al+" features in this region were obtained from server. Click to get more data excluding depth").tooltip().appendTo(message_div);ae.click(function(){ah.stale=true;ac.data_manager.get_more_data(ai,ac.mode,ah.resolution,{},ac.data_manager.DEEP_DATA_REQ);$(".bs-tooltip").hide();ac.request_draw(true)}).dblclick(function(ao){ao.stopPropagation()});Z.click(function(){ah.stale=true;ac.data_manager.get_more_data(ai,ac.mode,ah.resolution,{},ac.data_manager.BROAD_DATA_REQ);$(".bs-tooltip").hide();ac.request_draw(true)}).dblclick(function(ao){ao.stopPropagation()})}};o(L.prototype,b.prototype);L.prototype.predisplay_actions=function(){var aa=this,Z={};if(aa.mode!=="Pack"){return}$(this.html_elt).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()}).mousemove(function(al){if(!this.hovered){return}var ag=$(this).offset(),ak=al.pageX-ag.left,aj=al.pageY-ag.top,ap=aa.feature_mapper.get_feature_data(ak,aj),ah=(ap?ap[0]:null);$(this).parents(".track-content").children(".overlay").children(".feature-popup").each(function(){if(!ah||$(this).attr("id")!==ah.toString()){$(this).remove()}});if(ap){var ac=Z[ah];if(!ac){var ah=ap[0],am={name:ap[3],start:ap[1],end:ap[2],strand:ap[4]},af=aa.track.filters_manager.filters,ae;for(var ai=0;ai").attr("id",ah).addClass("feature-popup"),aq=$("
").append(aq));Z[ah]=ac}ac.appendTo($(this).parents(".track-content").children(".overlay"));var ad=ak+parseInt(aa.html_elt.css("left"))-ac.width()/2,ab=aj+parseInt(aa.html_elt.css("top"))+7;ac.css("left",ad+"px").css("top",ab+"px")}else{if(!al.isPropagationStopped()){al.stopPropagation();$(this).siblings().each(function(){$(this).trigger(al)})}}}).mouseleave(function(){$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()})};var h=function(ab,aa,ad){o(ad,{drag_handle_class:"draghandle"});p.call(this,ab,aa,ad);this.data_url=("data_url" in ad?ad.data_url:default_data_url);this.data_url_extra_params={};this.data_query_wait=("data_query_wait" in ad?ad.data_query_wait:H);this.dataset_check_url=("converted_datasets_state_url" in ad?ad.converted_datasets_state_url:converted_datasets_state_url);var Z=this,ac=new Dataset({id:ad.dataset_id,hda_ldda:ad.hda_ldda});this.data_manager=("data_manager" in ad?ad.data_manager:new GenomeDataManager({dataset:ac,data_url:Z.data_url,dataset_state_url:Z.dataset_check_url,data_mode_compatible:this.data_and_mode_compatible,can_subset:this.can_subset}));this.min_height_px=16;this.max_height_px=800;this.visible_height_px=0;this.content_div=$("
").appendTo(this.container_div);if(this.container){this.container.content_div.append(this.container_div);if(!("resize" in ad)||ad.resize){this.add_resize_handle()}}};o(h.prototype,p.prototype,{action_icons_def:[{name:"mode_icon",title:"Set display mode",css_class:"chevron-expand",on_click_fn:function(){}},p.prototype.action_icons_def[0],{name:"overview_icon",title:"Set as overview",css_class:"overview-icon",on_click_fn:function(Z){Z.view.set_overview(Z)}},p.prototype.action_icons_def[1],{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(Z){if(Z.filters_manager.visible()){Z.filters_manager.clear_filters()}else{Z.filters_manager.init_filters()}Z.filters_manager.toggle()}},{name:"tools_icon",title:"Tool",css_class:"hammer",on_click_fn:function(Z){Z.dynamic_tool_div.toggle();if(Z.dynamic_tool_div.is(":visible")){Z.set_name(Z.name+Z.tool_region_and_parameters_str())}else{Z.revert_name()}$(".bs-tooltip").remove()}},{name:"param_space_viz_icon",title:"Tool parameter space visualization",css_class:"arrow-split",on_click_fn:function(Z){var ac='Tool: <%= track.tool.name %> Dataset: <%= track.name %> Region(s): ',ab=_.template(ac,{track:Z});var ae=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},aa=function(){var ag=$('select[name="regions"] option:selected').val(),ai,af=new GenomeRegion({chrom:view.chrom,start:view.low,end:view.high}),ah=_.map($(".bookmark"),function(aj){return new GenomeRegion({from_str:$(aj).children(".position").text()})});if(ag==="cur"){ai=[af]}else{if(ag==="bookmarks"){ai=ah}else{ai=[af].concat(ah)}}hide_modal();window.location.href=galaxy_paths.get("sweepster_url")+"?"+$.param({dataset_id:Z.dataset_id,hda_ldda:Z.hda_ldda,regions:JSON.stringify(new Backbone.Collection(ai).toJSON())})},ad=function(af){if((af.keyCode||af.which)===27){ae()}else{if((af.keyCode||af.which)===13){aa()}}};show_modal("Visualize tool parameter space and output from different parameter settings?",ab,{No:ae,Yes:aa})}},p.prototype.action_icons_def[2]],can_draw:function(){if(this.dataset_id&&p.prototype.can_draw.call(this)){return true}return false},build_container_div:function(){return $("").addClass("track").attr("id","track_"+this.id).css("position","relative")},build_header_div:function(){var Z=$("");if(this.view.editor){this.drag_div=$("").addClass(this.drag_handle_class).appendTo(Z)}this.name_div=$("").addClass("track-name").appendTo(Z).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());return Z},on_resize:function(){},add_resize_handle:function(){var Z=this;var ac=false;var ab=false;var aa=$("
",{Close:hide_modal})});aa.tiles_div.append(ac)}}else{if(ab==="no converter"){aa.container_div.addClass("error");aa.tiles_div.text(G)}else{if(ab==="no data"||(ab.data!==undefined&&(ab.data===null||ab.data.length===0))){aa.container_div.addClass("nodata");aa.tiles_div.text(B)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.tiles_div.html(t);setTimeout(function(){aa.init()},aa.data_query_wait)}else{if(ab==="data"||ab.status==="data"){if(ab.valid_chroms){aa.valid_chroms=ab.valid_chroms;aa.update_icons()}aa.tiles_div.text(T);if(aa.view.chrom){aa.tiles_div.text("");aa.tiles_div.css("height",aa.visible_height_px+"px");aa.enabled=true;$.when(aa.predraw_init()).done(function(){Z.resolve();aa.container_div.removeClass("nodata error pending");aa.request_draw()})}else{Z.resolve()}}}}}}});this.update_icons();return Z},predraw_init:function(){}});var J=function(ab,aa,ac){h.call(this,ab,aa,ac);var Z=this;l(Z.container_div,Z.drag_handle_class,".group",Z);this.filters_manager=new V(this,("filters" in ac?ac.filters:null));this.data_manager.set("filters_manager",this.filters_manager);this.filters_available=false;this.tool=("tool" in ac&&ac.tool?new q(this,ac.tool,ac.tool_state):null);this.tile_cache=new Cache(N);if(this.header_div){this.set_filters_manager(this.filters_manager);if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}this.tiles_div=$("").addClass("tiles").appendTo(this.content_div);this.overlay_div=$("").addClass("overlay").appendTo(this.content_div);if(ac.mode){this.change_mode(ac.mode)}};o(J.prototype,p.prototype,h.prototype,{action_icons_def:h.prototype.action_icons_def.concat([{name:"show_more_rows_icon",title:"To minimize track height, not all feature rows are displayed. Click to display more rows.",css_class:"exclamation",on_click_fn:function(Z){$(".bs-tooltip").remove();Z.slotters[Z.view.resolution_px_b].max_rows*=2;Z.request_draw(true)},hide:true}]),copy:function(Z){var aa=this.to_dict();o(aa,{data_manager:this.data_manager});var ab=new this.constructor(this.view,Z,aa);ab.change_mode(this.mode);ab.enabled=this.enabled;return ab},set_filters_manager:function(Z){this.filters_manager=Z;this.header_div.after(this.filters_manager.parent_div)},to_dict:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,filters:this.filters_manager.to_dict(),tool_state:(this.tool?this.tool.state_dict():{})}},change_mode:function(aa){var Z=this;Z.mode=aa;Z.config.values.mode=aa;Z.tile_cache.clear();Z.request_draw();this.action_icons.mode_icon.attr("title","Set display mode (now: "+Z.mode+")");return Z},update_icons:function(){var Z=this;if(Z.filters_available){Z.action_icons.filters_icon.show()}else{Z.action_icons.filters_icon.hide()}if(Z.tool){Z.action_icons.tools_icon.show();Z.action_icons.param_space_viz_icon.show()}else{Z.action_icons.tools_icon.hide();Z.action_icons.param_space_viz_icon.hide()}},_gen_tile_cache_key:function(aa,ab,Z){return aa+"_"+ab+"_"+Z},request_draw:function(aa,Z){this.view.request_redraw(false,aa,Z,this)},before_draw:function(){},_draw:function(aa,ak){if(!this.can_draw()){return}var ai=this.view.low,ae=this.view.high,ag=ae-ai,ab=this.view.container.width(),am=this.view.resolution_px_b,ad=this.view.resolution_b_px;if(this.is_overview){ai=this.view.max_low;ae=this.view.max_high;ad=(view.max_high-view.max_low)/ab;am=1/ad}this.before_draw();this.tiles_div.children().addClass("remove");var Z=Math.floor(ai/(ad*P)),ah=true,al=[],af=function(an){return(an&&"track" in an)};while((Z*P*ad)view.canvas_manager.char_width_px){ag=view.reference_track.data_manager.get_data(ac,ak.mode,ao,view.reference_track.data_url_extra_params);if(is_deferred(ag)){ai=false}}if(ai){o(ap,am.more_tile_data);var ah=ak.mode;if(ah==="Auto"){ah=ak.get_mode(ap);ak.update_auto_mode(ah)}var ab=ak.view.canvas_manager.new_canvas(),ar=ac.get("start"),aa=ac.get("end"),al=Math.ceil((aa-ar)*af)+ak.left_offset,aj=ak.get_canvas_height(ap,ah,af,al);ab.width=al;ab.height=aj;var an=ab.getContext("2d");an.translate(this.left_offset,0);var at=ak.draw_tile(ap,an,ah,ao,ac,af,ag);if(at!==undefined){ak.tile_cache.set_elt(au,at);ak.show_tile(at,ae,af)}return at}var ad=$.Deferred();$.when(ap,ag).then(function(){view.request_redraw(false,false,false,ak);ad.resolve()});return ad},get_canvas_height:function(Z,ab,ac,aa){return this.visible_height_px},draw_tile:function(Z,aa,ae,ac,ad,af,ab){console.log("Warning: TiledTrack.draw_tile() not implemented.")},show_tile:function(ab,ad,ae){var aa=this,Z=ab.html_elt;ab.predisplay_actions();var ac=(ab.low-(this.is_overview?this.view.max_low:this.view.low))*ae;if(this.left_offset){ac-=this.left_offset}Z.css({position:"absolute",top:0,left:ac});if(Z.hasClass("remove")){Z.removeClass("remove")}else{ad.append(Z)}aa.after_show_tile(ab)},after_show_tile:function(Z){this.max_height_px=Math.max(this.max_height_px,Z.html_elt.height());Z.html_elt.parent().children().css("height",this.max_height_px+"px");var aa=this.max_height_px;if(this.visible_height_px!==0){aa=Math.min(this.max_height_px,this.visible_height_px)}this.tiles_div.css("height",aa+"px")},_get_tile_bounds:function(Z,aa){var ac=Math.floor(Z*P*aa),ad=Math.ceil(P*aa),ab=(ac+ad<=this.view.max_high?ac+ad:this.view.max_high);return new GenomeRegion({chrom:this.view.chrom,start:ac,end:ab})},tool_region_and_parameters_str:function(ab,Z,ac){var aa=this,ad=(ab!==undefined&&Z!==undefined&&ac!==undefined?ab+":"+Z+"-"+ac:"all");return" - region=["+ad+"], parameters=["+aa.tool.get_param_values().join(", ")+"]"},data_and_mode_compatible:function(Z,aa){return true},can_subset:function(Z){return false},init_for_tool_data:function(){this.data_manager.set("data_url",raw_data_url);this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.normal_postdraw_actions=this.postdraw_actions;this.postdraw_actions=function(ab,ac,ae,Z){var aa=this;aa.normal_postdraw_actions(ab,ac,ae,Z);aa.dataset_state_url=converted_datasets_state_url;aa.data_query_wait=H;var ad=new ServerStateDeferred({url:aa.dataset_state_url,url_params:{dataset_id:aa.dataset_id,hda_ldda:aa.hda_ldda},interval:aa.data_query_wait,success_fn:function(af){return af!=="pending"}});$.when(ad.go()).then(function(){aa.data_manager.set("data_url",default_data_url)});aa.postdraw_actions=aa.normal_postdraw_actions}}});var W=function(aa,Z){var ab={resize:false};h.call(this,aa,Z,ab);this.container_div.addClass("label-track")};o(W.prototype,h.prototype,{build_header_div:function(){},init:function(){this.enabled=true},_draw:function(){var ab=this.view,ac=ab.high-ab.low,af=Math.floor(Math.pow(10,Math.floor(Math.log(ac)/Math.log(10)))),Z=Math.floor(ab.low/af)*af,ad=this.view.container.width(),aa=$("");while(Z"+commatize(Z)+"
").css({position:"absolute",left:ae-1}));Z+=af}this.content_div.children(":first").remove();this.content_div.append(aa)}});var g=function(aa,Z,ad){J.call(this,aa,Z,ad);this.drawables=[];this.left_offset=0;if("drawables" in ad){var ac;for(var ab=0;abthis.left_offset){this.left_offset=ac.left_offset}}this.enabled=true}if(this.drawables.length!==0){this.set_display_modes(this.drawables[0].display_modes,this.drawables[0].mode)}this.update_icons();this.obj_type="CompositeTrack"};o(g.prototype,J.prototype,{action_icons_def:[{name:"composite_icon",title:"Show individual tracks",css_class:"layers-stack",on_click_fn:function(Z){$(".bs-tooltip").remove();Z.show_group()}}].concat(J.prototype.action_icons_def),to_dict:w.prototype.to_dict,add_drawable:w.prototype.add_drawable,unpack_drawables:w.prototype.unpack_drawables,change_mode:function(Z){J.prototype.change_mode.call(this,Z);for(var aa=0;aaview.canvas_manager.char_width_px){ak=view.reference_track.data_manager.get_data(ae,ao.mode,at,view.reference_track.data_url_extra_params);if(is_deferred(ak)){am=false}}ai.push(ak)}if(am){o(au,aq.more_tile_data);this.tile_predraw_init();var ad=ao.view.canvas_manager.new_canvas(),af=ao._get_tile_bounds(aw,at),ax=ae.get("start"),ab=ae.get("end"),ay=0,ap=Math.ceil((ab-ax)*aj)+this.left_offset,an=0,ac=[],av;var Z=0;for(av=0;avan){an=Z}}ad.width=ap;ad.height=(aq.height?aq.height:an);ay=0;var ar=ad.getContext("2d");ar.translate(this.left_offset,0);ar.globalAlpha=0.5;ar.globalCompositeOperation="source-over";for(av=0;avZ){Z=aa.prefs.max_value}}}for(var ab=0;abad){ad=Z}}for(var ac=0;acthis.view.canvas_manager.char_width_px){return J.prototype.draw_helper.call(this,ad,ab,Z,aa,ae,af,ac)}else{this.hide_contents();return null}},draw_tile:function(ah,ai,ad,ac,af,aj){var ab=this;if(aj>this.view.canvas_manager.char_width_px){if(ah.data===null){this.hide_contents();return}var aa=ai.canvas;ai.font=ai.canvas.manager.default_font;ai.textAlign="center";ah=ah.data;for(var ae=0,ag=ah.length;ae").text(U(Z.prefs.min_value,3)).make_text_editable({num_cols:6,on_finish:function(ag){$(".bs-tooltip").remove();var ag=parseFloat(ag);if(!isNaN(ag)){Z.set_min_value(ag)}},help_text:"Set min value"}).addClass("yaxislabel bottom").attr("id","linetrack_"+Z.dataset_id+"_minval").prependTo(Z.container_div),ac=$("").text(U(Z.prefs.max_value,3)).make_text_editable({num_cols:6,on_finish:function(ag){$(".bs-tooltip").remove();var ag=parseFloat(ag);if(!isNaN(ag)){Z.set_max_value(ag)}},help_text:"Set max value"}).addClass("yaxislabel top").attr("id","linetrack_"+Z.dataset_id+"_maxval").prependTo(Z.container_div)})},draw_tile:function(ai,ag,ab,aa,ad,ah){var Z=ag.canvas,ac=ad.get("start"),af=ad.get("end"),ae=new I.LinePainter(ai.data,ac,af,this.prefs,ab);ae.draw(ag,Z.width,Z.height,ah);return new b(this,ad,aa,Z,ai.data)},can_subset:function(Z){return false}});var r=function(ab,aa,ac){var Z=this;this.display_modes=["Heatmap"];this.mode="Heatmap";J.call(this,ab,aa,ac);this.hda_ldda=ac.hda_ldda;this.dataset_id=ac.dataset_id;this.original_dataset_id=this.dataset_id;this.left_offset=0;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"pos_color",label:"Positive Color",type:"color",default_value:"4169E1"},{key:"negative_color",label:"Negative Color",type:"color",default_value:"FF8C00"},{key:"min_value",label:"Min Value",type:"float",default_value:0},{key:"max_value",label:"Max Value",type:"float",default_value:1},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:500,hidden:true}],saved_values:ac.prefs,onchange:function(){Z.set_name(Z.prefs.name);Z.vertical_range=Z.prefs.max_value-Z.prefs.min_value;Z.set_min_value(Z.prefs.min_value);Z.set_max_value(Z.prefs.max_value)}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value};o(r.prototype,p.prototype,J.prototype,{on_resize:function(){this.request_draw(true)},set_min_value:function(Z){this.prefs.min_value=Z;this.tile_cache.clear();this.request_draw()},set_max_value:function(Z){this.prefs.max_value=Z;this.tile_cache.clear();this.request_draw()},draw_tile:function(aj,ah,ae,ac,aa,ai){var ab=ah.canvas,Z=this._get_tile_bounds(aa,ac),ad=Z[0],ag=Z[1],af=new I.DiagonalHeatmapPainter(aj.data,ad,ag,this.prefs,ae);af.draw(ah,ab.width,ab.height,ai);return new b(this,aa,ac,ab,aj.data)}});var c=function(ac,ab,ae){var aa=this;this.display_modes=["Auto","Coverage","Dense","Squish","Pack"];J.call(this,ac,ab,ae);var ad=get_random_color(),Z=get_random_color([ad,"#ffffff"]);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:ad},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:Z},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.visible_height_px,hidden:true}],saved_values:ae.prefs,onchange:function(){aa.set_name(aa.prefs.name);aa.tile_cache.clear();aa.set_painter_from_config();aa.request_draw()}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.container_div.addClass("feature-track");this.hda_ldda=ae.hda_ldda;this.dataset_id=ae.dataset_id;this.original_dataset_id=ae.dataset_id;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.slotters={};this.start_end_dct={};this.left_offset=200;this.set_painter_from_config()};o(c.prototype,p.prototype,J.prototype,{set_dataset:function(Z){this.dataset_id=Z.get("id");this.hda_ldda=Z.get("hda_ldda");this.data_manager.set("dataset",Z)},set_painter_from_config:function(){if(this.config.values.connector_style==="arcs"){this.painter=I.ArcLinkedFeaturePainter}else{this.painter=I.LinkedFeaturePainter}},before_draw:function(){this.max_height_px=0},postdraw_actions:function(ao,aj,ae,ad){J.prototype.postdraw_actions.call(this,ao,ad);var ai=this,al;if(ai.mode==="Coverage"){var aa=-1;for(al=0;alaa){aa=ak}}for(al=0;al").text(ah).make_text_editable({num_cols:12,on_finish:function(ar){$(".bs-tooltip").remove();var ar=parseFloat(ar);ai.prefs.histogram_max=(!isNaN(ar)?ar:null);ai.tile_cache.clear();ai.request_draw()},help_text:"Set max value; leave blank to use default"}).addClass("yaxislabel top").css("color",this.prefs.label_color);this.container_div.prepend(ab)}if(ac instanceof L){var am=true;for(al=0;alF){mode="Squish"}else{mode="Pack"}}}return mode},get_canvas_height:function(Z,ad,ae,aa){if(ad==="summary_tree"||ad==="Coverage"){return this.summary_draw_height}else{var ac=this.incremental_slots(ae,Z.data,ad);var ab=new (this.painter)(null,null,null,this.prefs,ad);return Math.max(Y,ab.get_required_height(ac,aa))}},draw_tile:function(aj,an,al,ao,ac,ag,ab){var am=this,aa=an.canvas,av=ac.get("start"),Z=ac.get("end"),ad=this.left_offset;if(al==="summary_tree"||al==="Coverage"){var ax=new I.SummaryTreePainter(aj,av,Z,this.prefs);ax.draw(an,aa.width,aa.height,ag);return new j(am,ac,ao,aa,aj.data,aj.max)}var af=[],ak=this.slotters[ag].slots;all_slotted=true;if(aj.data){var ah=this.filters_manager.filters;for(var ap=0,ar=aj.data.length;api[0]&&E=0){g-=u;j="left"}else{l+=u;j="right"}}var s=q(g,l);if(s>=0){if(h[s]===undefined){h[s]=[]}h[s].push([g,l]);this.slots[o]=s;n=Math.max(n,s)}}return n+1}})};var painters_module=function(require,exports){var extend=require("class").extend;var dashedLine=function(ctx,x1,y1,x2,y2,dashLen){if(dashLen===undefined){dashLen=4}var dX=x2-x1;var dY=y2-y1;var dashes=Math.floor(Math.sqrt(dX*dX+dY*dY)/dashLen);var dashX=dX/dashes;var dashY=dY/dashes;var q;for(q=0;q1){delta_x_px=Math.ceil((data[1][0]-data[0][0])*w_scale)}else{delta_x_px=10}var pref_color=parseInt(this.prefs.color.slice(1),16),pref_r=(pref_color&16711680)>>16,pref_g=(pref_color&65280)>>8,pref_b=pref_color&255;for(var i=0,len=data.length;imax_value){top_overflow=true;y=max_value}}if(mode==="Histogram"){y=Math.round(y/vertical_range*height_px);ctx.fillRect(x_scaled,y_zero,delta_x_px,-y)}else{if(mode==="Intensity"){var saturation=(y-min_value)/vertical_range,new_r=Math.round(pref_r+(255-pref_r)*(1-saturation)),new_g=Math.round(pref_g+(255-pref_g)*(1-saturation)),new_b=Math.round(pref_b+(255-pref_b)*(1-saturation));ctx.fillStyle="rgb("+new_r+","+new_g+","+new_b+")";ctx.fillRect(x_scaled,0,delta_x_px,height_px)}else{y=Math.round(height_px-(y-min_value)/vertical_range*height_px);if(in_path){ctx.lineTo(x_scaled,y)}else{in_path=true;if(mode==="Filled"){ctx.moveTo(x_scaled,height_px);ctx.lineTo(x_scaled,y)}else{ctx.moveTo(x_scaled,y)}}}}ctx.fillStyle=this.prefs.overflow_color;if(top_overflow||bot_overflow){var overflow_x;if(mode==="Histogram"||mode==="Intensity"){overflow_x=delta_x_px}else{x_scaled-=2;overflow_x=4}if(top_overflow){ctx.fillRect(x_scaled,0,overflow_x,3)}if(bot_overflow){ctx.fillRect(x_scaled,height_px-3,overflow_x,3)}}ctx.fillStyle=this.prefs.color}if(mode==="Filled"){if(in_path){ctx.lineTo(x_scaled,y_zero);ctx.lineTo(0,y_zero)}ctx.fill()}else{ctx.stroke()}ctx.restore()};var FeaturePositionMapper=function(slot_height){this.feature_positions={};this.slot_height=slot_height;this.translation=0;this.y_translation=0};FeaturePositionMapper.prototype.map_feature_data=function(feature_data,slot,x_start,x_end){if(!this.feature_positions[slot]){this.feature_positions[slot]=[]}this.feature_positions[slot].push({data:feature_data,x_start:x_start,x_end:x_end})};FeaturePositionMapper.prototype.get_feature_data=function(x,y){var slot=Math.floor((y-this.y_translation)/this.slot_height),feature_dict;if(!this.feature_positions[slot]){return null}x+=this.translation;for(var i=0;i=feature_dict.x_start&&x<=feature_dict.x_end){return feature_dict.data}}};var FeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){Painter.call(this,data,view_start,view_end,prefs,mode);this.alpha_scaler=(alpha_scaler?alpha_scaler:new Scaler());this.height_scaler=(height_scaler?height_scaler:new Scaler())};FeaturePainter.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};extend(FeaturePainter.prototype,{get_required_height:function(rows_required,width){var required_height=this.get_row_height(),y_scale=required_height,mode=this.mode;if(mode==="no_detail"||mode==="Squish"||mode==="Pack"){required_height=rows_required*y_scale}return required_height+this.get_top_padding(width)+this.get_bottom_padding(width)},get_top_padding:function(width){return 0},get_bottom_padding:function(width){return Math.max(Math.round(this.get_row_height()/2),5)},draw:function(ctx,width,height,w_scale,slots){var data=this.data,view_start=this.view_start,view_end=this.view_end;ctx.save();ctx.fillStyle=this.prefs.block_color;ctx.textAlign="right";var y_scale=this.get_row_height(),feature_mapper=new FeaturePositionMapper(y_scale),x_draw_coords;for(var i=0,len=data.length;iview_start)&&(this.mode==="Dense"||slot!==null)){x_draw_coords=this.draw_element(ctx,this.mode,feature,slot,view_start,view_end,w_scale,y_scale,width);feature_mapper.map_feature_data(feature,slot,x_draw_coords[0],x_draw_coords[1])}}ctx.restore();feature_mapper.y_translation=this.get_top_padding(width);return feature_mapper},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){console.log("WARNING: Unimplemented function.");return[0,0]}});var DENSE_TRACK_HEIGHT=10,NO_DETAIL_TRACK_HEIGHT=3,SQUISH_TRACK_HEIGHT=5,PACK_TRACK_HEIGHT=10,NO_DETAIL_FEATURE_HEIGHT=1,DENSE_FEATURE_HEIGHT=9,SQUISH_FEATURE_HEIGHT=3,PACK_FEATURE_HEIGHT=9,LABEL_SPACING=2,CONNECTOR_COLOR="#ccc";var LinkedFeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){FeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.draw_background_connector=true;this.draw_individual_connectors=false};extend(LinkedFeaturePainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var mode=this.mode,height;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="no_detail"){height=NO_DETAIL_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT}}}return height},draw_element:function(ctx,mode,feature,slot,tile_low,tile_high,w_scale,y_scale,width){var feature_uid=feature[0],feature_start=feature[1],feature_end=feature[2]-1,feature_name=feature[3],feature_strand=feature[4],f_start=Math.floor(Math.max(0,(feature_start-tile_low)*w_scale)),f_end=Math.ceil(Math.min(width,Math.max(0,(feature_end-tile_low)*w_scale))),draw_start=f_start,draw_end=f_end,y_center=(mode==="Dense"?0:(0+slot))*y_scale+this.get_top_padding(width),thickness,y_start,thick_start=null,thick_end=null,block_color=(!feature_strand||feature_strand==="+"||feature_strand==="."?this.prefs.block_color:this.prefs.reverse_strand_color);label_color=this.prefs.label_color;ctx.globalAlpha=this.alpha_scaler.gen_val(feature);if(mode==="Dense"){slot=1}if(mode==="no_detail"){ctx.fillStyle=block_color;ctx.fillRect(f_start,y_center+5,f_end-f_start,NO_DETAIL_FEATURE_HEIGHT)}else{var feature_ts=feature[5],feature_te=feature[6],feature_blocks=feature[7],full_height=true;if(feature_ts&&feature_te){thick_start=Math.floor(Math.max(0,(feature_ts-tile_low)*w_scale));thick_end=Math.ceil(Math.min(width,Math.max(0,(feature_te-tile_low)*w_scale)))}var thin_height,thick_height;if(mode==="Squish"){thin_height=1;thick_height=SQUISH_FEATURE_HEIGHT;full_height=false}else{if(mode==="Dense"){thin_height=5;thick_height=DENSE_FEATURE_HEIGHT}else{thin_height=5;thick_height=PACK_FEATURE_HEIGHT}}if(!feature_blocks){ctx.fillStyle=block_color;ctx.fillRect(f_start,y_center+1,f_end-f_start,thick_height);if(feature_strand&&full_height){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand_inv")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand_inv")}}ctx.fillRect(f_start,y_center+1,f_end-f_start,thick_height)}}else{var cur_y_center,cur_height;if(mode==="Squish"||mode==="Dense"){cur_y_center=y_center+Math.floor(SQUISH_FEATURE_HEIGHT/2)+1;cur_height=1}else{if(feature_strand){cur_y_center=y_center;cur_height=thick_height}else{cur_y_center+=(SQUISH_FEATURE_HEIGHT/2)+1;cur_height=1}}if(this.draw_background_connector){if(mode==="Squish"||mode==="Dense"){ctx.fillStyle=CONNECTOR_COLOR}else{if(feature_strand){if(feature_strand==="+"){ctx.fillStyle=ctx.canvas.manager.get_pattern("right_strand")}else{if(feature_strand==="-"){ctx.fillStyle=ctx.canvas.manager.get_pattern("left_strand")}}}else{ctx.fillStyle=CONNECTOR_COLOR}}ctx.fillRect(f_start,cur_y_center,f_end-f_start,cur_height)}var start_and_height;for(var k=0,k_len=feature_blocks.length;kblock_end){continue}ctx.fillStyle=block_color;ctx.fillRect(block_start,y_center+(thick_height-thin_height)/2+1,block_end-block_start,thin_height);if(thick_start!==undefined&&feature_te>feature_ts&&!(block_start>thick_end||block_endtile_low){ctx.fillStyle=label_color;if(tile_low===0&&f_start-ctx.measureText(feature_name).width<0){ctx.textAlign="left";ctx.fillText(feature_name,f_end+LABEL_SPACING,y_center+8);draw_end+=ctx.measureText(feature_name).width+LABEL_SPACING}else{ctx.textAlign="right";ctx.fillText(feature_name,f_start-LABEL_SPACING,y_center+8);draw_start-=ctx.measureText(feature_name).width+LABEL_SPACING}}}ctx.globalAlpha=1;return[draw_start,draw_end]}});var ReadPainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler,ref_seq){FeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.ref_seq=(ref_seq?ref_seq.data:null)};extend(ReadPainter.prototype,FeaturePainter.prototype,{get_row_height:function(){var height,mode=this.mode;if(mode==="Dense"){height=DENSE_TRACK_HEIGHT}else{if(mode==="Squish"){height=SQUISH_TRACK_HEIGHT}else{height=PACK_TRACK_HEIGHT;if(this.prefs.show_insertions){height*=2}}}return height},draw_read:function(ctx,mode,w_scale,y_center,tile_low,tile_high,feature_start,cigar,strand,orig_seq){ctx.textAlign="center";var tile_region=[tile_low,tile_high],base_offset=0,seq_offset=0,gap=0,char_width_px=ctx.canvas.manager.char_width_px,block_color=(strand==="+"?this.prefs.block_color:this.prefs.reverse_strand_color);var draw_last=[];if((mode==="Pack"||this.mode==="Auto")&&orig_seq!==undefined&&w_scale>char_width_px){gap=Math.round(w_scale/2)}if(!cigar){cigar=[[0,orig_seq.length]]}for(var cig_id=0,len=cigar.length;cig_id0){ctx.fillStyle=block_color;ctx.fillRect(s_start-gap,y_center+1,s_end-s_start,9);ctx.fillStyle=CONNECTOR_COLOR;for(var c=0,str_len=seq.length;c=tile_low&&seq_start+c<=tile_high){var c_start=Math.floor(Math.max(0,(seq_start+c-tile_low)*w_scale));ctx.fillText(seq[c],c_start,y_center+9)}}}else{ctx.fillStyle=block_color;ctx.fillRect(s_start,y_center+4,s_end-s_start,SQUISH_FEATURE_HEIGHT)}}seq_offset+=cig_len;base_offset+=cig_len;break;case"N":ctx.fillStyle=CONNECTOR_COLOR;ctx.fillRect(s_start-gap,y_center+5,s_end-s_start,1);base_offset+=cig_len;break;case"D":ctx.fillStyle="red";ctx.fillRect(s_start-gap,y_center+4,s_end-s_start,3);base_offset+=cig_len;break;case"P":break;case"I":var insert_x_coord=s_start-gap;if(is_overlap([seq_start,seq_start+cig_len],tile_region)){var seq=orig_seq.slice(seq_offset,seq_offset+cig_len);if(this.prefs.show_insertions){var x_center=s_start-(s_end-s_start)/2;if((mode==="Pack"||this.mode==="Auto")&&orig_seq!==undefined&&w_scale>char_width_px){ctx.fillStyle="yellow";ctx.fillRect(x_center-gap,y_center-9,s_end-s_start,9);draw_last[draw_last.length]={type:"triangle",data:[insert_x_coord,y_center+4,5]};ctx.fillStyle=CONNECTOR_COLOR;switch(compute_overlap([seq_start,seq_start+cig_len],tile_region)){case (OVERLAP_START):seq=seq.slice(tile_low-seq_start);break;case (OVERLAP_END):seq=seq.slice(0,seq_start-tile_high);break;case (CONTAINED_BY):break;case (CONTAINS):seq=seq.slice(tile_low-seq_start,seq_start-tile_high);break}for(var c=0,str_len=seq.length;cchar_width_px){draw_last.push({type:"text",data:[seq.length,insert_x_coord,y_center+9]})}else{}}}seq_offset+=cig_len;break;case"X":seq_offset+=cig_len;break}}ctx.fillStyle="yellow";var item,type,data;for(var i=0;ictx.canvas.manager.char_width_px){var gap=Math.round(w_scale/2)}if(feature[5] instanceof Array){var b1_start=Math.floor(Math.max(0,(feature[4][0]-tile_low)*w_scale)),b1_end=Math.ceil(Math.min(width,Math.max(0,(feature[4][1]-tile_low)*w_scale))),b2_start=Math.floor(Math.max(0,(feature[5][0]-tile_low)*w_scale)),b2_end=Math.ceil(Math.min(width,Math.max(0,(feature[5][1]-tile_low)*w_scale))),connector=true;if(feature[4][1]>=tile_low&&feature[4][0]<=tile_high&&feature[4][2]){this.draw_read(ctx,mode,w_scale,y_center,tile_low,tile_high,feature[4][0],feature[4][2],feature[4][3],feature[4][4])}else{connector=false}if(feature[5][1]>=tile_low&&feature[5][0]<=tile_high&&feature[5][2]){this.draw_read(ctx,mode,w_scale,y_center,tile_low,tile_high,feature[5][0],feature[5][2],feature[5][3],feature[5][4])}else{connector=false}if(connector&&b2_start>b1_end){ctx.fillStyle=CONNECTOR_COLOR;dashedLine(ctx,b1_end-gap,y_center+5,b2_start-gap,y_center+5)}}else{this.draw_read(ctx,mode,w_scale,y_center,tile_low,tile_high,feature_start,feature[4],feature[5],feature[6])}if(mode==="Pack"&&feature_start>tile_low&&feature_name!=="."){ctx.fillStyle=this.prefs.label_color;var tile_index=1;if(tile_index===0&&f_start-ctx.measureText(feature_name).width<0){ctx.textAlign="left";ctx.fillText(feature_name,f_end+LABEL_SPACING-gap,y_center+8)}else{ctx.textAlign="right";ctx.fillText(feature_name,f_start-LABEL_SPACING-gap,y_center+8)}}return[0,0]}});var ArcLinkedFeaturePainter=function(data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler){LinkedFeaturePainter.call(this,data,view_start,view_end,prefs,mode,alpha_scaler,height_scaler);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};extend(ArcLinkedFeaturePainter.prototype,FeaturePainter.prototype,LinkedFeaturePainter.prototype,{calculate_longest_feature_length:function(){var longest_feature_length=0;for(var i=0,len=this.data.length;i0){ctx.beginPath();ctx.arc(x_center,y_center,block2_start-x_center,Math.PI,0);ctx.stroke()}}});var Color=function(rgb,a){if(Array.isArray(rgb)){this.rgb=rgb}else{if(rgb.length==6){this.rgb=rgb.match(/.{2}/g).map(function(c){return parseInt(c,16)})}else{this.rgb=rgb.split("").map(function(c){return parseInt(c+c,16)})}}this.alpha=typeof(a)==="number"?a:1};Color.prototype={eval:function(){return this},toCSS:function(){if(this.alpha<1){return"rgba("+this.rgb.map(function(c){return Math.round(c)}).concat(this.alpha).join(", ")+")"}else{return"#"+this.rgb.map(function(i){i=Math.round(i);i=(i>255?255:(i<0?0:i)).toString(16);return i.length===1?"0"+i:i}).join("")}},toHSL:function(){var r=this.rgb[0]/255,g=this.rgb[1]/255,b=this.rgb[2]/255,a=this.alpha;var max=Math.max(r,g,b),min=Math.min(r,g,b);var h,s,l=(max+min)/2,d=max-min;if(max===min){h=s=0}else{s=l>0.5?d/(2-max-min):d/(max+min);switch(max){case r:h=(g-b)/d+(g255?255:(i<0?0:i)).toString(16);return i.length===1?"0"+i:i}).join("")},mix:function(color2,weight){color1=this;var p=weight;var w=p*2-1;var a=color1.toHSL().a-color2.toHSL().a;var w1=(((w*a==-1)?w:(w+a)/(1+w*a))+1)/2;var w2=1-w1;var rgb=[color1.rgb[0]*w1+color2.rgb[0]*w2,color1.rgb[1]*w1+color2.rgb[1]*w2,color1.rgb[2]*w1+color2.rgb[2]*w2];var alpha=color1.alpha*p+color2.alpha*(1-p);return new Color(rgb,alpha)}};var LinearRamp=function(start_color,end_color,start_value,end_value){this.start_color=new Color(start_color);this.end_color=new Color(end_color);this.start_value=start_value;this.end_value=end_value;this.value_range=end_value-start_value};LinearRamp.prototype.map_value=function(value){value=Math.max(value,this.start_value);value=Math.min(value,this.end_value);value=(value-this.start_value)/this.value_range;return this.start_color.mix(this.end_color,1-value).toCSS()};var SplitRamp=function(start_color,middle_color,end_color,start_value,end_value){this.positive_ramp=new LinearRamp(middle_color,end_color,0,end_value);this.negative_ramp=new LinearRamp(middle_color,start_color,0,-start_value);this.start_value=start_value;this.end_value=end_value};SplitRamp.prototype.map_value=function(value){value=Math.max(value,this.start_value);value=Math.min(value,this.end_value);if(value>=0){return this.positive_ramp.map_value(value)}else{return this.negative_ramp.map_value(-value)}};var DiagonalHeatmapPainter=function(data,view_start,view_end,prefs,mode){Painter.call(this,data,view_start,view_end,prefs,mode);var i,len;if(this.prefs.min_value===undefined){var min_value=Infinity;for(i=0,len=this.data.length;i max){
+ alert(fieldName + " is too large.");
+ return false;
+ } else if ( value < min) {
+ alert(fieldName + " is too small.");
+ return false;
+ }
+ return true;
+ },
+
+ hasIllegalJsonCharacters : function($inputKey) {
+ /**
+ * Check if any user string inputs has illegal characters that json cannot accept
+ */
+ if ($inputKey.val().search(/"|'|\\/) !== -1){
+ alert("Named fields cannot contain these illegal characters: double quote(\"), single guote(\'), or back slash(\\). ");
+ return true;
+ }
+ return false;
+ }
+});
+
+
+function PhyloTreeLayout() {
+ /**
+ * -- Custom Layout call for phyloViz to suit the needs of a phylogenetic tree.
+ * -- Specifically: 1) Nodes have a display display of (= evo dist X depth separation) from their parent
+ * 2) Nodes must appear in other after they have expand and contracted
+ */
+
+ var self = this,
+ hierarchy = d3.layout.hierarchy().sort(null).value(null),
+ height = 360, // ! represents both the layout angle and the height of the layout, in px
+ layoutMode = "Linear",
+ leafHeight = 18, // height of each individual leaf node
+ depthSeparation = 200, // separation between nodes of different depth, in px
+ leafIndex = 0, // change to recurssive call
+ defaultDist = 0.5, // tree defaults to 0.5 dist if no dist is specified
+ maxTextWidth = 50; // maximum length of the text labels
+
+
+ self.leafHeight = function(inputLeafHeight){
+ if (typeof inputLeafHeight === "undefined"){ return leafHeight; }
+ else { leafHeight = inputLeafHeight; return self;}
+ };
+
+ self.layoutMode = function(mode){
+ if (typeof mode === "undefined"){ return layoutMode; }
+ else { layoutMode = mode; return self;}
+ };
+
+ self.layoutAngle = function(angle) { // changes the layout angle of the display, which is really changing the height
+ if (typeof angle === "undefined"){ return height; }
+ if (isNaN(angle) || angle < 0 || angle > 360) { return self; } // to use default if the user puts in strange values
+ else { height = angle; return self;}
+ };
+
+ self.separation = function(dist){ // changes the dist between the nodes of different depth
+ if (typeof dist === "undefined"){ return depthSeparation; }
+ else { depthSeparation = dist; return self;}
+ };
+
+ self.links = function (nodes) { // uses d3 native method to generate links. Done.
+ return d3.layout.tree().links(nodes);
+ };
+
+ // -- Custom method for laying out phylogeny tree in a linear fashion
+ self.nodes = function (d, i) {
+ var _nodes = hierarchy.call(self, d, i), // self is to find the depth of all the nodes, assumes root is passed in
+ nodes = [],
+ maxDepth = 0,
+ numLeaves = 0;
+
+ // changing from hierarchy's custom format for data to usable format
+ _nodes.forEach(function (_node){
+ var node = _node.data;
+ node.depth = _node.depth;
+ maxDepth = node.depth > maxDepth ? node.depth : maxDepth; //finding max depth of tree
+ nodes.push(node);
+ });
+ // counting the number of leaf nodes and assigning max depth to nodes that do not have children to flush all the leave nodes
+ nodes.forEach(function(node){
+ if ( !node.children ) { //&& !node._children
+ numLeaves += 1;
+ node.depth = maxDepth; // if a leaf has no child it would be assigned max depth
+ }
+ });
+
+ leafHeight = layoutMode === "Circular" ? height / numLeaves : leafHeight;
+ leafIndex = 0;
+ layout(nodes[0], maxDepth, leafHeight, null);
+
+ return nodes;
+ };
+
+
+ function layout (node, maxDepth, vertSeparation, parent) {
+ /**
+ * -- Function with side effect of adding x0, y0 to all child; take in the root as starting point
+ * assuming that the leave nodes would be sorted in presented order
+ * horizontal(y0) is calculated according to (= evo dist X depth separation) from their parent
+ * vertical (x0) - if leave node: find its order in all of the leave node === node.id, then multiply by verticalSeparation
+ * - if parent node: is place in the mid point all of its children nodes
+ * -- The layout will first calculate the y0 field going towards the leaves, and x0 when returning
+ */
+ var children = node.children,
+ sumChildVertSeparation = 0;
+
+ // calculation of node's dist from parents, going down.
+ var dist = node.dist || defaultDist;
+ dist = dist > 1 ? 1 : dist; // We constrain all dist to be less than one
+ node.dist = dist;
+ if (parent !== null){
+ node.y0 = parent.y0 + dist * depthSeparation;
+ } else { //root node
+ node.y0 = maxTextWidth;
+ }
+
+
+ // if a node have no children, we will treat it as a leaf and start laying it out first
+ if (!children) {
+ node.x0 = leafIndex++ * vertSeparation;
+ } else {
+ // if it has children, we will visit all its children and calculate its position from its children
+ children.forEach( function (child) {
+ child.parent = node;
+ sumChildVertSeparation += layout(child, maxDepth, vertSeparation, node);
+ });
+ node.x0 = sumChildVertSeparation / children.length;
+ }
+
+ // adding properties to the newly created node
+ node.x = node.x0;
+ node.y = node.y0;
+ return node.x0;
+ }
+ return self;
+}
+
+
+/**
+ * -- PhyloTree Model --
+ */
+var PhyloTree = Visualization.extend({
+ defaults : {
+ layout: "Linear",
+ separation : 250, // px dist between nodes of different depth to represent 1 evolutionary until
+ leafHeight: 18,
+ type : "phyloviz", // visualization type
+ title : "Title",
+ scaleFactor: 1,
+ translate: [0,0],
+ fontSize: 12, //fontSize of node label
+ selectedNode : null,
+ nodeAttrChangedTime : 0
+ },
+
+ root : {}, // Root has to be its own independent object because it is not part of the viz_config
+
+ toggle : function (d) {
+ /**
+ * Mechanism to expand or contract a single node. Expanded nodes have a children list, while for
+ * contracted nodes the list is stored in _children. Nodes with their children data stored in _children will not have their
+ * children rendered.
+ */
+ if(typeof d === "undefined") {return ;}
+ if (d.children ) {
+ d._children = d.children;
+ d.children = null;
+ } else {
+ d.children = d._children;
+ d._children = null;
+ }
+ },
+
+ toggleAll : function(d) {
+ /**
+ * Contracts the phylotree to a single node by repeatedly calling itself to place all the list
+ * of children under _children.
+ */
+ if (d.children && d.children.length !== 0) {
+ d.children.forEach(this.toggleAll);
+ toggle(d);
+ }
+ },
+
+ getData : function (){
+ /**
+ * Return the data of the tree. Used for preserving state.
+ */
+ return this.root;
+ },
+
+ save: function() {
+ /**
+ * Overriding the default save mechanism to do some clean of circular reference of the
+ * phyloTree and to include phyloTree in the saved json
+ */
+ var root = this.root;
+ cleanTree(root);
+ this.set("root", root);
+
+ function cleanTree(node){
+ // we need to remove parent to delete circular reference
+ delete node.parent;
+
+ // removing unnecessary attributes
+ if (node._selected){ delete node._selected;}
+
+ node.children ? node.children.forEach(cleanTree) : 0;
+ node._children ? node._children.forEach(cleanTree) : 0;
+ }
+
+ var config = jQuery.extend(true, {}, this.attributes);
+ config["selectedNode"] = null;
+
+ show_message("Saving to Galaxy", "progress");
+
+ return $.ajax({
+ url: this.url(),
+ type: "POST",
+ dataType: "json",
+ data: {
+ vis_json: JSON.stringify(config)
+ },
+ success: function(res){
+ var viz_id = res.url.split("id=")[1].split("&")[0],
+ viz_url = "/phyloviz/visualization?id=" + viz_id;
+ window.history.pushState({}, "", viz_url + window.location.hash);
+ hide_modal();
+ }
+ });
+ }
+});
+
+
+
+/**
+ * -- Views --
+ */
+var PhylovizLayoutBase = Backbone.View.extend({
+ /**
+ * Stores the default variable for setting up the visualization
+ */
+ defaults : {
+ nodeRadius : 4.5 // radius of each node in the diagram
+ },
+
+
+ stdInit : function (options) {
+ /**
+ * Common initialization in layouts
+ */
+
+ var self = this;
+ self.model.on("change:separation change:leafHeight change:fontSize change:nodeAttrChangedTime", self.updateAndRender, self);
+
+ self.vis = options.vis;
+ self.i = 0;
+ self.maxDepth = -1; // stores the max depth of the tree
+
+ self.width = options.width;
+ self.height = options.height;
+ },
+
+
+ updateAndRender : function(source) {
+ /**
+ * Updates the visualization whenever there are changes in the expansion and contraction of nodes
+ * AND possibly when the tree is edited.
+ */
+ var vis = d3.select(".vis"),
+ self = this;
+ source = source || self.model.root;
+
+ self.renderNodes(source);
+ self.renderLinks(source);
+ self.addTooltips();
+ },
+
+
+ renderLinks : function(source) {
+ /**
+ * Renders the links for the visualization.
+ */
+ var self = this;
+ var diagonal = self.diagonal;
+ var duration = self.duration;
+ var layoutMode = self.layoutMode;
+ var link = self.vis.selectAll("g.completeLink")
+ .data(self.tree.links(self.nodes), function(d) { return d.target.id; });
+
+ var calcalateLinePos = function(d) {
+ d.pos0 = d.source.y0 + " " + d.source.x0; // position of the source node <=> starting location of the line drawn
+ d.pos1 = d.source.y0 + " " + d.target.x0; // position where the line makes a right angle bend
+ d.pos2 = d.target.y0 + " " + d.target.x0; // point where the horizontal line becomes a dotted line
+ };
+
+ var linkEnter = link.enter().insert("svg:g","g.node")
+ .attr("class", "completeLink");
+
+
+ linkEnter.append("svg:path")
+ .attr("class", "link")
+ .attr("d", function(d) {
+ calcalateLinePos(d);
+ return "M " + d.pos0 + " L " + d.pos1;
+ });
+
+ var linkUpdate = link.transition().duration(500);
+
+ linkUpdate.select("path.link")
+ .attr("d", function(d) {
+ calcalateLinePos(d);
+ return "M " + d.pos0 + " L " + d.pos1 + " L " + d.pos2;
+ });
+
+ var linkExit = link.exit().remove();
+
+ },
+
+ // User Interaction methods below
+
+ selectNode : function(node){
+ /**
+ * Displays the information for editting
+ */
+ var self = this;
+ d3.selectAll("g.node")
+ .classed("selectedHighlight", function(d){
+ if (node.id === d.id){
+ if(node._selected) { // for de=selecting node.
+ delete node._selected;
+ return false;
+ } else {
+ node._selected = true;
+ return true;
+ }
+ }
+ return false;
+ });
+
+ self.model.set("selectedNode", node);
+ $("#phyloVizSelectedNodeName").val(node.name);
+ $("#phyloVizSelectedNodeDist").val(node.dist);
+ $("#phyloVizSelectedNodeAnnotation").val(node.annotation || "");
+ },
+
+ addTooltips : function (){
+ /**
+ * Creates bootstrap tooltip for the visualization. Has to be called repeatedly due to newly generated
+ * enterNodes
+ */
+ $(".bs-tooltip").remove(); //clean up tooltip, just in case its listeners are removed by d3
+ $(".node")
+ .attr("data-original-title", function(){
+ var d = this.__data__,
+ annotation = d.annotation || "None" ;
+ return d ? (d.name ? d.name + " " : "") + "Dist: " + d.dist + " Annotation: " + annotation: "";
+ })
+ .tooltip({'placement':'top', 'trigger' : 'hover'});
+
+ }
+});
+
+
+
+
+var PhylovizLinearView = PhylovizLayoutBase.extend({
+ /**
+ * Linea layout class of Phyloviz, is responsible for rendering the nodes
+ * calls PhyloTreeLayout to determine the positions of the nodes
+ */
+ initialize : function(options){
+ // Default values of linear layout
+ var self = this;
+ self.margins = options.margins;
+ self.layoutMode = "Linear";
+
+ self.stdInit(options);
+
+ self.layout();
+ self.updateAndRender(self.model.root);
+ },
+
+ layout : function() {
+ /**
+ * Creates the basic layout of a linear tree by precalculating fixed values.
+ * One of calculations are also made here
+ */
+
+ var self = this;
+
+ self.tree = new PhyloTreeLayout().layoutMode("Linear");
+ self.diagonal = d3.svg.diagonal()
+ .projection(function(d) { return [d.y, d.x ]; });
+ },
+
+ renderNodes : function (source) {
+ /**
+ * Renders the nodes base on Linear layout.
+ */
+ var self = this,
+ fontSize = self.model.get("fontSize") + "px";
+
+ // assigning properties from models
+ self.tree.separation(self.model.get("separation")).leafHeight(self.model.get("leafHeight"));
+
+ var duration = 500,
+ nodes = self.tree.separation(self.model.get("separation")).nodes(self.model.root);
+
+ var node = self.vis.selectAll("g.node")
+ .data(nodes, function(d) { return d.name + d.id || (d.id = ++self.i); });
+
+ // These variables has to be passed into update links which are in the base methods
+ self.nodes = nodes;
+ self.duration = duration;
+
+ // ------- D3 ENTRY --------
+ // Enter any new nodes at the parent's previous position.
+ var nodeEnter = node.enter().append("svg:g")
+ .attr("class", "node")
+ .on("dblclick", function(){ d3.event.stopPropagation(); })
+ .on("click", function(d) {
+ if (d3.event.altKey) {
+ self.selectNode(d); // display info if alt is pressed
+ } else {
+ if(d.children && d.children.length === 0){ return;} // there is no need to toggle leaves
+ self.model.toggle(d); // contract/expand nodes at data level
+ self.updateAndRender(d); // re-render the tree
+ }
+ });
+
+ nodeEnter.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; });
+
+ nodeEnter.append("svg:circle")
+ .attr("r", 1e-6)
+ .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
+
+ nodeEnter.append("svg:text")
+ .attr("class", "nodeLabel")
+ .attr("x", function(d) { return d.children || d._children ? -10 : 10; })
+ .attr("dy", ".35em")
+ .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
+ .style("fill-opacity", 1e-6);
+
+ // ------- D3 TRANSITION --------
+ // Transition nodes to their new position.
+ var nodeUpdate = node.transition()
+ .duration(duration);
+
+ nodeUpdate.attr("transform", function(d) {
+ return "translate(" + d.y + "," + d.x + ")"; });
+
+ nodeUpdate.select("circle")
+ .attr("r", self.defaults.nodeRadius)
+ .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
+
+ nodeUpdate.select("text")
+ .style("fill-opacity", 1)
+ .style("font-size", fontSize)
+ .text(function(d) { return d.name; });
+
+ // ------- D3 EXIT --------
+ // Transition exiting nodes to the parent's new position.
+ var nodeExit =node.exit().transition()
+ .duration(duration)
+ .remove();
+
+ nodeExit.select("circle")
+ .attr("r", 1e-6);
+
+ nodeExit.select("text")
+ .style("fill-opacity", 1e-6);
+
+ // Stash the old positions for transition.
+ nodes.forEach(function(d) {
+ d.x0 = d.x; // we need the x0, y0 for parents with children
+ d.y0 = d.y;
+ });
+ }
+
+});
+
+var PhylovizView = Backbone.View.extend({
+
+ className: 'phyloviz',
+
+ initialize: function(options) {
+ var self = this;
+ // -- Default values of the vis
+ self.MIN_SCALE = 0.05; //for zooming
+ self.MAX_SCALE = 5;
+ self.MAX_DISPLACEMENT = 500;
+ self.margins = [10, 60, 10, 80];
+
+ self.width = $("#PhyloViz").width();
+ self.height = $("#PhyloViz").height();
+ self.radius = self.width;
+ self.data = options.data;
+
+ // -- Events Phyloviz view responses to
+ $(window).resize(function(){
+ self.width = $("#PhyloViz").width();
+ self.height = $("#PhyloViz").height();
+ self.render();
+ });
+
+ // -- Create phyloTree model
+ self.phyloTree = new PhyloTree(options.config);
+ self.phyloTree.root = self.data;
+
+ // -- Set up UI functions of main view
+ self.zoomFunc = d3.behavior.zoom().scaleExtent([self.MIN_SCALE, self.MAX_SCALE]);
+ self.zoomFunc.translate(self.phyloTree.get("translate"));
+ self.zoomFunc.scale(self.phyloTree.get("scaleFactor"));
+
+ // -- set up header buttons, search and settings menu
+ self.navMenu = new HeaderButtons(self);
+ self.settingsMenu = new SettingsMenu({phyloTree : self.phyloTree});
+ self.nodeSelectionView = new NodeSelectionView({phyloTree : self.phyloTree});
+ self.search = new PhyloVizSearch();
+
+
+ setTimeout(function(){ // using settimeout to call the zoomAndPan function according to the stored attributes in viz_config
+ self.zoomAndPan();
+ }, 1000);
+ },
+
+ render: function(){
+ // -- Creating helper function for vis. --
+ var self = this;
+ $("#PhyloViz").empty();
+
+ // -- Layout viz. --
+ self.mainSVG = d3.select("#PhyloViz").append("svg:svg")
+ .attr("width", self.width)
+ .attr("height", self.height)
+ .attr("pointer-events", "all")
+ .call(self.zoomFunc.on("zoom", function(){
+ self.zoomAndPan();
+ }));
+
+ self.boundingRect = self.mainSVG.append("svg:rect")
+ .attr("class", "boundingRect")
+ .attr("width", self.width)
+ .attr("height", self.height)
+ .attr("stroke", "black")
+ .attr("fill", "white");
+
+ self.vis = self.mainSVG
+ .append("svg:g")
+ .attr("class", "vis");
+
+ self.layoutOptions = {
+ model : self.phyloTree,
+ width : self.width,
+ height : self.height,
+ vis: self.vis,
+ margins: self.margins
+ };
+
+ // -- Creating Title
+ $("#title").text("Phylogenetic Tree from " + self.phyloTree.get("title") + ":");
+
+ // -- Create Linear view instance --
+ var linearView = new PhylovizLinearView(self.layoutOptions)
+ },
+
+ zoomAndPan : function(event){
+ /**
+ * Function to zoom and pan the svg element which the entire tree is contained within
+ * Uses d3.zoom events, and extend them to allow manual updates and keeping states in model
+ */
+ if (typeof event !== "undefined") {
+ var zoomParams = event.zoom,
+ translateParams = event.translate;
+ }
+
+ var self = this,
+ scaleFactor = self.zoomFunc.scale(),
+ translationCoor = self.zoomFunc.translate(),
+ zoomStatement = "",
+ translateStatement = "";
+
+ // Do manual scaling.
+ switch (zoomParams) {
+ case "reset":
+ scaleFactor = 1.0;
+ translationCoor = [0,0]; break;
+ case "+":
+ scaleFactor *= 1.1; break;
+ case "-":
+ scaleFactor *= 0.9; break;
+ default:
+ if (typeof zoomParams === "number") {
+ scaleFactor = zoomParams;
+ } else if (d3.event !== null) {
+ scaleFactor = d3.event.scale;
+ }
+ }
+ if (scaleFactor < self.MIN_SCALE || scaleFactor > self.MAX_SCALE) { return;}
+ self.zoomFunc.scale(scaleFactor); //update scale Factor
+ zoomStatement = "translate(" + self.margins[3] + "," + self.margins[0] + ")" +
+ " scale(" + scaleFactor + ")";
+
+ // Do manual translation.
+ if( d3.event !== null) {
+ translateStatement = "translate(" + d3.event.translate + ")";
+ } else {
+ if(typeof translateParams !== "undefined") {
+ var x = translateParams.split(",")[0];
+ var y = translateParams.split(",")[1];
+ if (!isNaN(x) && !isNaN(y)){
+ translationCoor = [translationCoor[0] + parseFloat(x), translationCoor[1] + parseFloat(y)];
+ }
+ }
+ self.zoomFunc.translate(translationCoor); // update zoomFunc
+ translateStatement = "translate(" + translationCoor + ")";
+ }
+
+ self.phyloTree.set("scaleFactor", scaleFactor);
+ self.phyloTree.set("translate", translationCoor);
+ self.vis.attr("transform", translateStatement + zoomStatement); //refers to the view that we are actually zooming
+ },
+
+
+ reloadViz : function() {
+ /**
+ * Primes the Ajax URL to load another Nexus tree
+ */
+ var self = this,
+ treeIndex = $("#phylovizNexSelector :selected").val(),
+ dataset_id = self.phyloTree.get("dataset_id"),
+ url = "phyloviz/getJsonData?dataset_id=" + dataset_id + "&treeIndex=" + String(treeIndex);
+ $.getJSON(url, function(packedJson){
+ window.initPhyloViz(packedJson.data, packedJson.config);
+ });
+ }
+});
+
+
+var HeaderButtons = Backbone.View.extend({
+
+ initialize : function(phylovizView){
+ var self = this;
+ self.phylovizView = phylovizView;
+
+ // Clean up code - if the class initialized more than once
+ $("#panelHeaderRightBtns").empty();
+ $("#phyloVizNavBtns").empty();
+ $("#phylovizNexSelector").off();
+
+ self.initNavBtns();
+ self.initRightHeaderBtns();
+
+ // Initial a tree selector in the case of nexus
+ $("#phylovizNexSelector").off().on("change", function() {self.phylovizView.reloadViz();} );
+
+ },
+
+ initRightHeaderBtns : function(){
+ var self = this;
+
+ rightMenu = create_icon_buttons_menu([
+ { icon_class: 'gear', title: 'PhyloViz Settings', on_click: function(){
+ $("#SettingsMenu").show();
+ self.settingsMenu.updateUI();
+ } },
+ { icon_class: 'disk', title: 'Save visualization', on_click: function() {
+ var nexSelected = $("#phylovizNexSelector option:selected").text();
+ if(nexSelected) {
+ self.phylovizView.phyloTree.set("title", nexSelected);
+ }
+ self.phylovizView.phyloTree.save();
+ } },
+ { icon_class: 'chevron-expand', title: 'Search / Edit Nodes', on_click: function() {
+ $("#nodeSelectionView").show();
+ } },
+ { icon_class: 'information', title: 'Phyloviz Help', on_click: function() {
+ window.open('http://wiki.g2.bx.psu.edu/Learn/Visualization/PhylogeneticTree');
+ // https://docs.google.com/document/d/1AXFoJgEpxr21H3LICRs3EyMe1B1X_KFPouzIgrCz3zk/edit
+ } }
+ ],
+ {
+ tooltip_config: { placement: 'bottom' }
+ });
+ $("#panelHeaderRightBtns").append(rightMenu.$el);
+ },
+
+ initNavBtns: function() {
+ var self = this,
+ navMenu = create_icon_buttons_menu([
+ { icon_class: 'zoom-in', title: 'Zoom in', on_click: function() {
+ self.phylovizView.zoomAndPan({ zoom : "+"});
+ } },
+ { icon_class: 'zoom-out', title: 'Zoom out', on_click: function() {
+ self.phylovizView.zoomAndPan({ zoom : "-"});
+ } },
+ { icon_class: 'arrow-circle', title: 'Reset Zoom/Pan', on_click: function() {
+ self.phylovizView.zoomAndPan({ zoom : "reset"});
+ } }
+ ],
+ {
+ tooltip_config: { placement: 'bottom' }
+ });
+ $("#phyloVizNavBtns").append(navMenu.$el);
+ }
+});
+
+
+var SettingsMenu = UserMenuBase.extend({
+
+ className: 'Settings',
+
+ initialize: function(options){
+ // settings needs to directly interact with the phyloviz model so it will get access to it.
+ var self = this;
+ self.phyloTree = options.phyloTree;
+ self.el = $("#SettingsMenu");
+ self.inputs = {
+ separation : $("#phyloVizTreeSeparation"),
+ leafHeight : $("#phyloVizTreeLeafHeight"),
+ fontSize : $("#phyloVizTreeFontSize")
+ };
+
+ //init all buttons of settings
+ $("#settingsCloseBtn").off().on("click", function() { self.el.hide(); });
+ $("#phylovizResetSettingsBtn").off().on("click", function() { self.resetToDefaults(); });
+ $("#phylovizApplySettingsBtn").off().on("click", function() { self.apply(); });
+ },
+
+ apply : function(){
+ /**
+ * Applying user values to phylotree model.
+ */
+ var self = this;
+ if (!self.isAcceptableValue(self.inputs["separation"], 50, 2500) ||
+ !self.isAcceptableValue(self.inputs["leafHeight"], 5, 30) ||
+ !self.isAcceptableValue(self.inputs["fontSize"], 5, 20)){
+ return;
+ }
+ $.each(self.inputs, function(key, $input){
+ self.phyloTree.set(key, $input.val());
+ });
+ },
+ updateUI : function(){
+ /**
+ * Called to update the values input to that stored in the model
+ */
+ var self = this;
+ $.each(self.inputs, function(key, $input){
+ $input.val(self.phyloTree.get(key));
+ });
+ },
+ resetToDefaults : function(){
+ /**
+ * Resets the value of the phyloTree model to its default
+ */
+ $(".bs-tooltip").remove(); // just in case the tool tip was not removed
+ var self = this;
+ $.each(self.phyloTree.defaults, function(key, value) {
+ self.phyloTree.set(key, value);
+ });
+ self.updateUI();
+ },
+
+ render: function(){
+
+ }
+
+});
+
+
+var NodeSelectionView = UserMenuBase.extend({
+ /**
+ * View for inspecting node properties and editing them
+ */
+ className: 'Settings',
+
+ initialize : function (options){
+ var self = this;
+ self.el = $("#nodeSelectionView");
+ self.phyloTree = options.phyloTree;
+
+ self.UI = {
+ enableEdit : $('#phylovizEditNodesCheck'),
+ saveChanges : $('#phylovizNodeSaveChanges'),
+ cancelChanges : $("#phylovizNodeCancelChanges"),
+ name : $("#phyloVizSelectedNodeName"),
+ dist : $("#phyloVizSelectedNodeDist"),
+ annotation : $("#phyloVizSelectedNodeAnnotation")
+ };
+
+ self.valuesOfConcern = {
+ name : null,
+ dist : null,
+ annotation : null
+ }; // temporarily stores the values in case user change their mind
+
+ //init UI buttons
+ $("#nodeSelCloseBtn").off().on("click", function() { self.el.hide(); });
+ self.UI.saveChanges.off().on("click", function(){ self.updateNodes(); });
+ self.UI.cancelChanges.off().on("click", function(){ self.cancelChanges(); });
+
+ (function ($) {
+ // extending jquery fxn for enabling and disabling nodes.
+ $.fn.enable = function (isEnabled) {
+ return $(this).each(function () {
+ if(isEnabled){
+ $(this).removeAttr('disabled');
+ } else {
+ $(this).attr('disabled', 'disabled');
+ }
+ });
+ };
+ })(jQuery);
+
+ self.UI.enableEdit.off().on("click", function () {
+ self.toggleUI();
+ });
+ },
+
+ toggleUI : function(){
+ /**
+ * For turning on and off the child elements
+ */
+ var self = this,
+ checked = self.UI.enableEdit.is(':checked');
+
+ !checked ? self.cancelChanges() : "";
+
+ $.each(self.valuesOfConcern, function(key, value) {
+ self.UI[key].enable(checked);
+ });
+ if(checked){
+ self.UI.saveChanges.show();
+ self.UI.cancelChanges.show();
+ } else {
+ self.UI.saveChanges.hide();
+ self.UI.cancelChanges.hide();
+ }
+
+ },
+
+ cancelChanges : function() {
+ /**
+ * Reverting to previous values in case user change their minds
+ */
+ var self = this,
+ node = self.phyloTree.get("selectedNode");
+ if (node){
+ $.each(self.valuesOfConcern, function(key, value) {
+ self.UI[key].val(node[key]);
+ });
+ }
+ },
+
+ updateNodes : function (){
+ /**
+ * Changing the data in the underlying tree with user-specified values
+ */
+ var self = this,
+ node = self.phyloTree.get("selectedNode");
+ if (node){
+ if (!self.isAcceptableValue(self.UI.dist, 0, 1) ||
+ self.hasIllegalJsonCharacters(self.UI.name) ||
+ self.hasIllegalJsonCharacters(self.UI.annotation) ) {
+ return;
+ }
+ $.each(self.valuesOfConcern, function(key, value) {
+ (node[key]) = self.UI[key].val();
+ });
+ self.phyloTree.set("nodeAttrChangedTime", new Date());
+ } else {
+ alert("No node selected");
+ }
+ }
+
+
+});
+
+
+
+var PhyloVizSearch = UserMenuBase.extend({
+ /**
+ * Initializes the search panel on phyloviz and handles its user interaction
+ * It allows user to search the entire free based on some qualifer, like dist <= val.
+ */
+ initialize : function () {
+ var self = this;
+
+ $("#phyloVizSearchBtn").on("click", function(){
+ var searchTerm = $("#phyloVizSearchTerm"),
+ searchConditionVal = $("#phyloVizSearchCondition").val().split("-"),
+ attr = searchConditionVal[0],
+ condition = searchConditionVal[1];
+ self.hasIllegalJsonCharacters(searchTerm);
+
+ if (attr === "dist"){
+ self.isAcceptableValue(searchTerm, 0, 1);
+ }
+ self.searchTree(attr, condition, searchTerm.val());
+ });
+ },
+
+ searchTree : function (attr, condition, val){
+ /**
+ * Searches the entire tree and will highlight the nodes that match the condition in green
+ */
+ d3.selectAll("g.node")
+ .classed("searchHighlight", function(d){
+ var attrVal = d[attr];
+ if (typeof attrVal !== "undefined" && attrVal !== null){
+ if (attr === "dist"){
+ switch (condition) {
+ case "greaterEqual":
+ return attrVal >= +val;
+ case "lesserEqual":
+ return attrVal <= +val;
+ default:
+ return;
+ }
+
+ } else if (attr === "name" || attr === "annotation") {
+ return attrVal.toLowerCase().indexOf(val.toLowerCase()) !== -1;
+ }
+ }
+ });
+ }
+});
\ No newline at end of file
diff --git a/static/scripts/viz/trackster.js b/static/scripts/viz/trackster.js
index 7f8acacc6d0..9c1c512235a 100644
--- a/static/scripts/viz/trackster.js
+++ b/static/scripts/viz/trackster.js
@@ -4433,7 +4433,7 @@ var FeatureTrack = function(view, container, obj_dict) {
// initialization code.
//
var track = this;
- this.display_modes = ["Auto", "Histogram", "Dense", "Squish", "Pack"];
+ this.display_modes = ["Auto", "Coverage", "Dense", "Squish", "Pack"];
//
// Initialization.
@@ -4516,8 +4516,8 @@ extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
var track = this,
i;
- // If mode is Histogram and tiles do not share max, redraw tiles as necessary using new max.
- if (track.mode === "Histogram") {
+ // If mode is Coverage and tiles do not share max, redraw tiles as necessary using new max.
+ if (track.mode === "Coverage") {
// Get global max.
var global_max = -1;
for (i = 0; i < tiles.length; i++) {
@@ -4534,7 +4534,7 @@ extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
track.draw_helper(true, width, tile.index, tile.resolution, tile.html_elt.parent(), w_scale, { more_tile_data: { max: global_max } } );
}
}
- }
+ }
//
// Update filter attributes, UI.
@@ -4649,86 +4649,6 @@ extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
return slotter.slot_features( features );
},
- /**
- * Given feature data, returns summary tree data. Feature data must be sorted by start
- * position. Return value is a dict with keys 'data', 'delta' (bin size) and 'max.' Data
- * is a two-item list; first item is bin start, second is bin's count.
- */
- get_summary_tree_data: function(data, low, high, num_bins) {
- if (num_bins > high - low) {
- num_bins = high - low;
- }
- var bin_size = Math.floor((high - low)/num_bins),
- bins = [],
- max_count = 0;
-
- /*
- // For debugging:
- for (var i = 0; i < data.length; i++)
- console.log("\t", data[i][1], data[i][2], data[i][3]);
- */
-
- //
- // Loop through bins, counting data for each interval.
- //
- var data_index_start = 0,
- data_index = 0,
- data_interval,
- bin_index = 0,
- bin_interval = [],
- cur_bin;
-
- // Set bin interval.
- var set_bin_interval = function(interval, low, bin_index, bin_size) {
- interval[0] = low + bin_index * bin_size;
- interval[1] = low + (bin_index + 1) * bin_size;
- };
-
- // Loop through bins, data to compute bin counts. Only compute bin counts as long
- // as there is data.
- while (bin_index < num_bins && data_index_start !== data.length) {
- // Find next bin that has data.
- var bin_has_data = false;
- for (; bin_index < num_bins && !bin_has_data; bin_index++) {
- set_bin_interval(bin_interval, low, bin_index, bin_size);
- // Loop through data and break if data found that goes in bin.
- for (data_index = data_index_start; data_index < data.length; data_index++) {
- data_interval = data[data_index].slice(1, 3);
- if (is_overlap(data_interval, bin_interval)) {
- bin_has_data = true;
- break;
- }
- }
- // Break from bin loop if this bin has data.
- if (bin_has_data) {
- break;
- }
- }
-
- // Set start index to current data, which is the first to overlap with this bin
- // and perhaps with later bins.
- data_start_index = data_index;
-
- // Count intervals that overlap with bin.
- bins[bins.length] = cur_bin = [bin_interval[0], 0];
- for (; data_index < data.length; data_index++) {
- data_interval = data[data_index].slice(1, 3);
- if (is_overlap(data_interval, bin_interval)) {
- cur_bin[1]++;
- }
- else { break; }
- }
-
- // Update max count.
- if (cur_bin[1] > max_count) {
- max_count = cur_bin[1];
- }
-
- // Go to next bin.
- bin_index++;
- }
- return {max: max_count, delta: bin_size, data: bins};
- },
/**
* Returns appropriate display mode based on data.
*/
@@ -4766,8 +4686,7 @@ extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
* number of pixels required.
*/
get_canvas_height: function(result, mode, w_scale, canvas_width) {
- if (mode === "summary_tree" || mode === "Histogram") {
- // Extra padding at top of summary tree so label does not overlap data.
+ if (mode === "summary_tree" || mode === "Coverage") {
return this.summary_draw_height;
}
else {
@@ -4796,16 +4715,8 @@ extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
tile_high = region.get('end'),
left_offset = this.left_offset;
- // Drawing the summary tree (feature coverage histogram)
- if (mode === "summary_tree" || mode === "Histogram") {
- // Get summary tree data if necessary and set max if there is one.
- if (result.dataset_type !== "summary_tree") {
- var st_data = this.get_summary_tree_data(result.data, tile_low, tile_high, 200);
- if (result.max) {
- st_data.max = result.max;
- }
- result = st_data;
- }
+ // Drawing the summary tree.
+ if (mode === "summary_tree" || mode === "Coverage") {
// Paint summary tree into canvas
var painter = new painters.SummaryTreePainter(result, tile_low, tile_high, this.prefs);
painter.draw(ctx, canvas.width, canvas.height, w_scale);
@@ -4872,7 +4783,11 @@ extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, {
if (mode === "Auto") {
return true;
}
- // All other modes--Histogram, Dense, Squish, Pack--require data + details.
+ // Histogram mode requires summary_tree data.
+ else if (mode === "Coverage") {
+ return data.dataset_type === "summary_tree";
+ }
+ // All other modes--Dense, Squish, Pack--require data + details.
else if (data.extra_info === "no_detail" || data.dataset_type === "summary_tree") {
return false;
}
@@ -5775,7 +5690,7 @@ extend(LinkedFeaturePainter.prototype, FeaturePainter.prototype, {
ctx.globalAlpha = 1;
// Draw label for Pack mode.
- if (mode === "Pack" && feature_start > tile_low) {
+ if (feature_name && mode === "Pack" && feature_start > tile_low) {
ctx.fillStyle = label_color;
// FIXME: assumption here that the entire view starts at 0
if (tile_low === 0 && f_start - ctx.measureText(feature_name).width < 0) {
diff --git a/templates/admin/data_admin/data_form.mako b/templates/admin/data_admin/data_form.mako
index 1ed3e25f3c3..1094841be07 100644
--- a/templates/admin/data_admin/data_form.mako
+++ b/templates/admin/data_admin/data_form.mako
@@ -27,7 +27,7 @@
%def>
<%def name="javascripts()">
${parent.javascripts()}
- ${h.js("jquery.autocomplete", "autocomplete_tagging" )}
+ ${h.js("libs/jquery/jquery.autocomplete", "galaxy.autocom_tagging" )}
%def>
##
## Override methods from base.mako and base_panels.mako
@@ -53,7 +53,7 @@
@@ -75,22 +75,31 @@
Parameters
-
+
-
-
+
+
+
+ A descriptive name for this build.
+
-
-
+
+
+
+ The internal DB key for this build. WARNING: Using a value that already exists in one or more .loc files may have unpredictable results.
+
-
-
+
+
+
+ The URL to download this build from.
+
@@ -101,7 +110,9 @@
- If you can't find the build you want in this list, <insert link to instructions here>
+ If you can't find the build you want in this list, open a terminal and execute
+
sh cron/updatencbi.sh
+ in your galaxy root directory.
@@ -116,7 +127,9 @@
- If you can't find the build you want in this list, <insert link to instructions here>
+ If you can't find the build you want in this list, open a terminal and execute
+
sh cron/updateensembl.sh
+ in your galaxy root directory.
@@ -135,7 +148,9 @@
- If you can't find the build you want in this list, <insert link to instructions here>
+ If you can't find the build you want in this list, open a terminal and execute
+