1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/ba9452fd7e61/ Changeset: ba9452fd7e61 User: jgoecks Date: 2014-06-26 16:56:05 Summary: Circster: add config options for min/max values and color. Affected #: 4 files diff -r 9198bb0ed8c9a4a862defa9a28f4c8ba2c3dca0f -r ba9452fd7e6119e4958fa2ddd10e45f6739c725a static/scripts/packed/viz/circster.js --- a/static/scripts/packed/viz/circster.js +++ b/static/scripts/packed/viz/circster.js @@ -1,1 +1,1 @@ -define(["utils/utils","libs/underscore","libs/d3","viz/visualization","utils/config"],function(h,i,n,k,c){h.cssLoadFile("static/style/circster.css");var o=Backbone.Model.extend({is_visible:function(s,p){var q=s.getBoundingClientRect(),r=$("svg")[0].getBoundingClientRect();if(q.right<0||q.left>r.right||q.bottom<0||q.top>r.bottom){return false}return true}});var j={drawTicks:function(t,s,x,r,p){var w=t.append("g").selectAll("g").data(s).enter().append("g").selectAll("g").data(x).enter().append("g").attr("class","tick").attr("transform",function(y){return"rotate("+(y.angle*180/Math.PI-90)+")translate("+y.radius+",0)"});var v=[],u=[],q=function(y){return y.angle>Math.PI?"end":null};if(p){v=[0,0,0,-4];u=[4,0,"",".35em"];q=null}else{v=[1,0,4,0];u=[0,4,".35em",""]}w.append("line").attr("x1",v[0]).attr("y1",v[1]).attr("x2",v[2]).attr("y1",v[3]).style("stroke","#000");w.append("text").attr("x",u[0]).attr("y",u[1]).attr("dx",u[2]).attr("dy",u[3]).attr("text-anchor",q).attr("transform",r).text(function(y){return y.label})},formatNum:function(q,p){if(p===undefined){p=2}if(q===null){return null}var s=null;if(Math.abs(q)<1){s=q.toPrecision(p)}else{var r=Math.round(q.toPrecision(p));q=Math.abs(q);if(q<1000){s=r}else{if(q<1000000){s=Math.round((r/1000).toPrecision(3)).toFixed(0)+"K"}else{if(q<1000000000){s=Math.round((r/1000000).toPrecision(3)).toFixed(0)+"M"}}}}return s}};var d=Backbone.Model.extend({});var a=Backbone.View.extend({className:"circster",initialize:function(p){this.genome=p.genome;this.label_arc_height=50;this.scale=1;this.circular_views=null;this.chords_views=null;this.model.get("drawables").on("add",this.add_track,this);this.model.get("drawables").on("remove",this.remove_track,this);var q=this.model.get("config");q.get("arc_dataset_height").on("change:value",this.update_track_bounds,this);q.get("track_gap").on("change:value",this.update_track_bounds,this)},get_circular_tracks:function(){return this.model.get("drawables").filter(function(p){return p.get("track_type")!=="DiagonalHeatmapTrack"})},get_chord_tracks:function(){return this.model.get("drawables").filter(function(p){return p.get("track_type")==="DiagonalHeatmapTrack"})},get_tracks_bounds:function(){var r=this.get_circular_tracks(),t=this.model.get("config").get_value("arc_dataset_height"),s=this.model.get("config").get_value("track_gap"),p=Math.min(this.$el.width(),this.$el.height())-20,v=p/2-r.length*(t+s)+s-this.label_arc_height,u=n.range(v,p/2,t+s);var q=this;return i.map(u,function(w){return[w,w+t]})},render:function(){var y=this,p=y.$el.width(),x=y.$el.height(),u=this.get_circular_tracks(),s=this.get_chord_tracks(),r=y.model.get("config").get_value("total_gap"),t=this.get_tracks_bounds(),q=n.select(y.$el[0]).append("svg").attr("width",p).attr("height",x).attr("pointer-events","all").append("svg:g").call(n.behavior.zoom().on("zoom",function(){var z=n.event.scale;q.attr("transform","translate("+n.event.translate+") scale("+z+")");if(y.scale!==z){if(y.zoom_drag_timeout){clearTimeout(y.zoom_drag_timeout)}y.zoom_drag_timeout=setTimeout(function(){},400)}})).attr("transform","translate("+p/2+","+x/2+")").append("svg:g").attr("class","tracks");this.circular_views=u.map(function(A,B){var z=new e({el:q.append("g")[0],track:A,radius_bounds:t[B],genome:y.genome,total_gap:r});z.render();return z});this.chords_views=s.map(function(A){var z=new l({el:q.append("g")[0],track:A,radius_bounds:t[0],genome:y.genome,total_gap:r});z.render();return z});var w=this.circular_views[this.circular_views.length-1].radius_bounds[1],v=[w,w+this.label_arc_height];this.label_track_view=new b({el:q.append("g")[0],track:new d(),radius_bounds:v,genome:y.genome,total_gap:r});this.label_track_view.render()},add_track:function(v){var q=this.model.get("config").get_value("total_gap");if(v.get("track_type")==="DiagonalHeatmapTrack"){var r=this.circular_views[0].radius_bounds,u=new l({el:n.select("g.tracks").append("g")[0],track:v,radius_bounds:r,genome:this.genome,total_gap:q});u.render();this.chords_views.push(u)}else{var t=this.get_tracks_bounds();i.each(this.circular_views,function(w,x){w.update_radius_bounds(t[x])});i.each(this.chords_views,function(w){w.update_radius_bounds(t[0])});var s=this.circular_views.length,p=new e({el:n.select("g.tracks").append("g")[0],track:v,radius_bounds:t[s],genome:this.genome,total_gap:q});p.render();this.circular_views.push(p)}},remove_track:function(q,s,r){var p=this.circular_views[r.index];this.circular_views.splice(r.index,1);p.$el.remove();var t=this.get_tracks_bounds();i.each(this.circular_views,function(u,v){u.update_radius_bounds(t[v])})},update_track_bounds:function(){var p=this.get_tracks_bounds();i.each(this.circular_views,function(q,r){q.update_radius_bounds(p[r])});i.each(this.chords_views,function(q){q.update_radius_bounds(p[0])})}});var m=Backbone.View.extend({tagName:"g",initialize:function(p){this.bg_stroke="ddd";this.loading_bg_fill="ffc";this.bg_fill="ddd";this.total_gap=p.total_gap;this.track=p.track;this.radius_bounds=p.radius_bounds;this.genome=p.genome;this.chroms_layout=this._chroms_layout();this.data_bounds=[];this.scale=1;this.parent_elt=n.select(this.$el[0])},get_fill_color:function(){var p=this.track.get("config").get_value("block_color");if(!p){p=this.track.get("config").get_value("color")}return p},render:function(){var t=this.parent_elt;var s=this.chroms_layout,v=n.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]),p=t.selectAll("g").data(s).enter().append("svg:g"),r=p.append("path").attr("d",v).attr("class","chrom-background").style("stroke",this.bg_stroke).style("fill",this.loading_bg_fill);r.append("title").text(function(x){return x.data.chrom});var q=this,u=q.track.get("data_manager"),w=(u?u.data_is_ready():true);$.when(w).then(function(){$.when(q._render_data(t)).then(function(){r.style("fill",q.bg_fill);q.render_labels()})})},render_labels:function(){},update_radius_bounds:function(q){this.radius_bounds=q;var p=n.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]);this.parent_elt.selectAll("g>path.chrom-background").transition().duration(1000).attr("d",p);this._transition_chrom_data();this._transition_labels()},update_scale:function(s){var r=this.scale;this.scale=s;if(s<=r){return}var q=this,p=new o();this.parent_elt.selectAll("path.chrom-data").filter(function(u,t){return p.is_visible(this)}).each(function(z,v){var y=n.select(this),u=y.attr("chrom"),x=q.genome.get_chrom_region(u),w=q.track.get("data_manager"),t;if(!w.can_get_more_detailed_data(x)){return}t=q.track.get("data_manager").get_more_detailed_data(x,"Coverage",0,s);$.when(t).then(function(C){y.remove();q._update_data_bounds();var B=i.find(q.chroms_layout,function(D){return D.data.chrom===u});var A=q.get_fill_color();q._render_chrom_data(q.parent_elt,B,C).style("stroke",A).style("fill",A)})});return q},_transition_chrom_data:function(){var q=this.track,s=this.chroms_layout,p=this.parent_elt.selectAll("g>path.chrom-data"),t=p[0].length;if(t>0){var r=this;$.when(q.get("data_manager").get_genome_wide_data(this.genome)).then(function(v){var u=i.reject(i.map(v,function(w,x){var y=null,z=r._get_path_function(s[x],w);if(z){y=z(w.data)}return y}),function(w){return w===null});p.each(function(x,w){n.select(this).transition().duration(1000).attr("d",u[w])})})}},_transition_labels:function(){},_update_data_bounds:function(){var p=this.data_bounds;this.data_bounds=this.get_data_bounds(this.track.get("data_manager").get_genome_wide_data(this.genome));if(this.data_bounds[0]<p[0]||this.data_bounds[1]>p[1]){this._transition_chrom_data()}},_render_data:function(s){var r=this,q=this.chroms_layout,p=this.track,t=$.Deferred();$.when(p.get("data_manager").get_genome_wide_data(this.genome)).then(function(v){r.data_bounds=r.get_data_bounds(v);layout_and_data=i.zip(q,v),chroms_data_layout=i.map(layout_and_data,function(w){var x=w[0],y=w[1];return r._render_chrom_data(s,x,y)});var u=r.get_fill_color();r.parent_elt.selectAll("path.chrom-data").style("stroke",u).style("fill",u);t.resolve(s)});return t},_render_chrom_data:function(p,q,r){},_get_path_function:function(q,p){},_chroms_layout:function(){var q=this.genome.get_chroms_info(),s=n.layout.pie().value(function(u){return u.len}).sort(null),t=s(q),p=2*Math.PI*this.total_gap/q.length,r=i.map(t,function(w,v){var u=w.endAngle-p;w.endAngle=(u>w.startAngle?u:w.startAngle);return w});return r}});var b=m.extend({initialize:function(p){m.prototype.initialize.call(this,p);this.innerRadius=this.radius_bounds[0];this.radius_bounds[0]=this.radius_bounds[1];this.bg_stroke="fff";this.bg_fill="fff";this.min_arc_len=0.05},_render_data:function(r){var q=this,p=r.selectAll("g");p.selectAll("path").attr("id",function(v){return"label-"+v.data.chrom});p.append("svg:text").filter(function(v){return v.endAngle-v.startAngle>q.min_arc_len}).attr("text-anchor","middle").append("svg:textPath").attr("class","chrom-label").attr("xlink:href",function(v){return"#label-"+v.data.chrom}).attr("startOffset","25%").text(function(v){return v.data.chrom});var s=function(x){var v=(x.endAngle-x.startAngle)/x.value,w=n.range(0,x.value,25000000).map(function(y,z){return{radius:q.innerRadius,angle:y*v+x.startAngle,label:z===0?0:(z%3?null:q.formatNum(y))}});if(w.length<4){w[w.length-1].label=q.formatNum(Math.round((w[w.length-1].angle-x.startAngle)/v))}return w};var u=function(v){return v.angle>Math.PI?"rotate(180)translate(-16)":null};var t=i.filter(this.chroms_layout,function(v){return v.endAngle-v.startAngle>q.min_arc_len});this.drawTicks(this.parent_elt,t,s,u)}});i.extend(b.prototype,j);var g=m.extend({_quantile:function(q,p){q.sort(n.ascending);return n.quantile(q,p)},_render_chrom_data:function(p,s,q){var t=this._get_path_function(s,q);if(!t){return null}var r=p.datum(q.data),u=r.append("path").attr("class","chrom-data").attr("chrom",s.data.chrom).attr("d",t);return u},_get_path_function:function(s,r){if(typeof r==="string"||!r.data||r.data.length===0){return null}var p=n.scale.linear().domain(this.data_bounds).range(this.radius_bounds).clamp(true);var t=n.scale.linear().domain([0,r.data.length]).range([s.startAngle,s.endAngle]);var q=n.svg.line.radial().interpolate("linear").radius(function(u){return p(u[1])}).angle(function(v,u){return t(u)});return n.svg.area.radial().interpolate(q.interpolate()).innerRadius(p(0)).outerRadius(q.radius()).angle(q.angle())},render_labels:function(){var p=this,q=function(){return"rotate(90)"};this.drawTicks(this.parent_elt,[this.chroms_layout[0]],this._data_bounds_ticks_fn(),q,true)},_transition_labels:function(){if(this.data_bounds.length===0){return}var q=this,s=i.filter(this.chroms_layout,function(t){return t.endAngle-t.startAngle>0.08}),r=i.filter(s,function(u,t){return t%3===0}),p=i.flatten(i.map(r,function(t){return q._data_bounds_ticks_fn()(t)}));this.parent_elt.selectAll("g.tick").data(p).transition().attr("transform",function(t){return"rotate("+(t.angle*180/Math.PI-90)+")translate("+t.radius+",0)"})},_data_bounds_ticks_fn:function(){var p=this;visibleChroms=0;return function(q){return[{radius:p.radius_bounds[0],angle:q.startAngle,label:p.formatNum(p.data_bounds[0])},{radius:p.radius_bounds[1],angle:q.startAngle,label:p.formatNum(p.data_bounds[1])}]}},get_data_bounds:function(p){}});i.extend(g.prototype,j);var e=g.extend({get_data_bounds:function(q){var p=i.flatten(i.map(q,function(r){if(r){return i.map(r.data,function(s){return parseInt(s[1],10)||0})}else{return 0}}));return[i.min(p),this._quantile(p,0.5)||i.max(p)]}});var l=m.extend({render:function(){var p=this;$.when(p.track.get("data_manager").data_is_ready()).then(function(){$.when(p.track.get("data_manager").get_genome_wide_data(p.genome)).then(function(s){var r=[],q=p.genome.get_chroms_info();i.each(s,function(w,v){var t=q[v].chrom;var u=i.map(w.data,function(y){var x=p._get_region_angle(t,y[1]),z=p._get_region_angle(y[3],y[4]);return{source:{startAngle:x,endAngle:x+0.01},target:{startAngle:z,endAngle:z+0.01}}});r=r.concat(u)});p.parent_elt.append("g").attr("class","chord").selectAll("path").data(r).enter().append("path").style("fill",p.get_fill_color()).attr("d",n.svg.chord().radius(p.radius_bounds[0])).style("opacity",1)})})},update_radius_bounds:function(p){this.radius_bounds=p;this.parent_elt.selectAll("path").transition().attr("d",n.svg.chord().radius(this.radius_bounds[0]))},_get_region_angle:function(r,p){var q=i.find(this.chroms_layout,function(s){return s.data.chrom===r});return q.endAngle-((q.endAngle-q.startAngle)*(q.data.len-p)/q.data.len)}});var f=Backbone.View.extend({initialize:function(){var p=new k.Genome(galaxy_config.app.genome),q=new k.GenomeVisualization(galaxy_config.app.viz_config);q.get("config").add([{key:"arc_dataset_height",label:"Arc Dataset Height",type:"int",value:25,view:"circster"},{key:"track_gap",label:"Gap Between Tracks",type:"int",value:5,view:"circster"},{key:"total_gap",label:"Gap [0-1]",type:"float",value:0.4,view:"circster",hidden:true}]);var s=new a({el:$("#center .unified-panel-body"),genome:p,model:q});s.render();$("#center .unified-panel-header-inner").append(galaxy_config.app.viz_config.title+" "+galaxy_config.app.viz_config.dbkey);var r=create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){k.select_datasets(galaxy_config.root+"visualization/list_current_history_datasets",galaxy_config.root+"api/datasets",q.get("dbkey"),function(t){q.add_tracks(t)})}},{icon_class:"gear",title:"Settings",on_click:function(){var t=new c.ConfigSettingCollectionView({collection:q.get("config")});t.render_in_modal("Configure Visualization")}},{icon_class:"disk--arrow",title:"Save",on_click:function(){Galaxy.modal.show({title:"Saving...",body:"progress"});$.ajax({url:galaxy_config.root+"visualization/save",type:"POST",dataType:"json",data:{id:q.get("vis_id"),title:q.get("title"),dbkey:q.get("dbkey"),type:"trackster",vis_json:JSON.stringify(q)}}).success(function(t){Galaxy.modal.hide();q.set("vis_id",t.vis_id)}).error(function(){Galaxy.modal.show({title:"Could Not Save",body:"Could not save visualization. Please try again later.",buttons:{Cancel:function(){Galaxy.modal.hide()}}})})}},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location=galaxy_config.root+"visualization/list"}}],{tooltip_config:{placement:"bottom"}});r.$el.attr("style","float: right");$("#center .unified-panel-header-inner").append(r.$el);$(".menu-button").tooltip({placement:"bottom"})}});return{GalaxyApp:f}}); \ No newline at end of file +require(["utils/utils","libs/farbtastic",],function(a){a.cssLoadFile("static/style/circster.css")});define(["libs/underscore","libs/d3","viz/visualization","utils/config"],function(h,m,j,c){var n=Backbone.Model.extend({is_visible:function(r,o){var p=r.getBoundingClientRect(),q=$("svg")[0].getBoundingClientRect();if(p.right<0||p.left>q.right||p.bottom<0||p.top>q.bottom){return false}return true}});var i={drawTicks:function(s,r,w,q,o){var v=s.append("g").selectAll("g").data(r).enter().append("g").selectAll("g").data(w).enter().append("g").attr("class","tick").attr("transform",function(x){return"rotate("+(x.angle*180/Math.PI-90)+")translate("+x.radius+",0)"});var u=[],t=[],p=function(x){return x.angle>Math.PI?"end":null};if(o){u=[0,0,0,-4];t=[4,0,"",".35em"];p=null}else{u=[1,0,4,0];t=[0,4,".35em",""]}v.append("line").attr("x1",u[0]).attr("y1",u[1]).attr("x2",u[2]).attr("y1",u[3]).style("stroke","#000");return v.append("text").attr("x",t[0]).attr("y",t[1]).attr("dx",t[2]).attr("dy",t[3]).attr("text-anchor",p).attr("transform",q).text(function(x){return x.label})},formatNum:function(p,o){if(o===undefined){o=2}if(p===null){return null}var r=null;if(Math.abs(p)<1){r=p.toPrecision(o)}else{var q=Math.round(p.toPrecision(o));p=Math.abs(p);if(p<1000){r=q}else{if(p<1000000){r=Math.round((q/1000).toPrecision(3)).toFixed(0)+"K"}else{if(p<1000000000){r=Math.round((q/1000000).toPrecision(3)).toFixed(0)+"M"}}}}return r}};var d=Backbone.Model.extend({});var a=Backbone.View.extend({className:"circster",initialize:function(o){this.genome=o.genome;this.label_arc_height=50;this.scale=1;this.circular_views=null;this.chords_views=null;this.model.get("drawables").on("add",this.add_track,this);this.model.get("drawables").on("remove",this.remove_track,this);var p=this.model.get("config");p.get("arc_dataset_height").on("change:value",this.update_track_bounds,this);p.get("track_gap").on("change:value",this.update_track_bounds,this)},get_circular_tracks:function(){return this.model.get("drawables").filter(function(o){return o.get("track_type")!=="DiagonalHeatmapTrack"})},get_chord_tracks:function(){return this.model.get("drawables").filter(function(o){return o.get("track_type")==="DiagonalHeatmapTrack"})},get_tracks_bounds:function(){var q=this.get_circular_tracks(),s=this.model.get("config").get_value("arc_dataset_height"),r=this.model.get("config").get_value("track_gap"),o=Math.min(this.$el.width(),this.$el.height())-20,u=o/2-q.length*(s+r)+r-this.label_arc_height,t=m.range(u,o/2,s+r);var p=this;return h.map(t,function(v){return[v,v+s]})},render:function(){var x=this,o=x.$el.width(),w=x.$el.height(),t=this.get_circular_tracks(),r=this.get_chord_tracks(),q=x.model.get("config").get_value("total_gap"),s=this.get_tracks_bounds(),p=m.select(x.$el[0]).append("svg").attr("width",o).attr("height",w).attr("pointer-events","all").append("svg:g").call(m.behavior.zoom().on("zoom",function(){var y=m.event.scale;p.attr("transform","translate("+m.event.translate+") scale("+y+")");if(x.scale!==y){if(x.zoom_drag_timeout){clearTimeout(x.zoom_drag_timeout)}x.zoom_drag_timeout=setTimeout(function(){},400)}})).attr("transform","translate("+o/2+","+w/2+")").append("svg:g").attr("class","tracks");this.circular_views=t.map(function(z,A){var y=new e({el:p.append("g")[0],track:z,radius_bounds:s[A],genome:x.genome,total_gap:q});y.render();return y});this.chords_views=r.map(function(z){var y=new k({el:p.append("g")[0],track:z,radius_bounds:s[0],genome:x.genome,total_gap:q});y.render();return y});var v=this.circular_views[this.circular_views.length-1].radius_bounds[1],u=[v,v+this.label_arc_height];this.label_track_view=new b({el:p.append("g")[0],track:new d(),radius_bounds:u,genome:x.genome,total_gap:q});this.label_track_view.render()},add_track:function(u){var p=this.model.get("config").get_value("total_gap");if(u.get("track_type")==="DiagonalHeatmapTrack"){var q=this.circular_views[0].radius_bounds,t=new k({el:m.select("g.tracks").append("g")[0],track:u,radius_bounds:q,genome:this.genome,total_gap:p});t.render();this.chords_views.push(t)}else{var s=this.get_tracks_bounds();h.each(this.circular_views,function(v,w){v.update_radius_bounds(s[w])});h.each(this.chords_views,function(v){v.update_radius_bounds(s[0])});var r=this.circular_views.length,o=new e({el:m.select("g.tracks").append("g")[0],track:u,radius_bounds:s[r],genome:this.genome,total_gap:p});o.render();this.circular_views.push(o)}},remove_track:function(p,r,q){var o=this.circular_views[q.index];this.circular_views.splice(q.index,1);o.$el.remove();var s=this.get_tracks_bounds();h.each(this.circular_views,function(t,u){t.update_radius_bounds(s[u])})},update_track_bounds:function(){var o=this.get_tracks_bounds();h.each(this.circular_views,function(p,q){p.update_radius_bounds(o[q])});h.each(this.chords_views,function(p){p.update_radius_bounds(o[0])})}});var l=Backbone.View.extend({tagName:"g",initialize:function(o){this.bg_stroke="ddd";this.loading_bg_fill="ffc";this.bg_fill="ddd";this.total_gap=o.total_gap;this.track=o.track;this.radius_bounds=o.radius_bounds;this.genome=o.genome;this.chroms_layout=this._chroms_layout();this.data_bounds=[];this.scale=1;this.parent_elt=m.select(this.$el[0])},get_fill_color:function(){var o=this.track.get("config").get_value("block_color");if(!o){o=this.track.get("config").get_value("color")}return o},render:function(){var s=this.parent_elt;var r=this.chroms_layout,u=m.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]),o=s.selectAll("g").data(r).enter().append("svg:g"),q=o.append("path").attr("d",u).attr("class","chrom-background").style("stroke",this.bg_stroke).style("fill",this.loading_bg_fill);q.append("title").text(function(w){return w.data.chrom});var p=this,t=p.track.get("data_manager"),v=(t?t.data_is_ready():true);$.when(v).then(function(){$.when(p._render_data(s)).then(function(){q.style("fill",p.bg_fill);p.render_labels()})})},render_labels:function(){},update_radius_bounds:function(p){this.radius_bounds=p;var o=m.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]);this.parent_elt.selectAll("g>path.chrom-background").transition().duration(1000).attr("d",o);this._transition_chrom_data();this._transition_labels()},update_scale:function(r){var q=this.scale;this.scale=r;if(r<=q){return}var p=this,o=new n();this.parent_elt.selectAll("path.chrom-data").filter(function(t,s){return o.is_visible(this)}).each(function(y,u){var x=m.select(this),t=x.attr("chrom"),w=p.genome.get_chrom_region(t),v=p.track.get("data_manager"),s;if(!v.can_get_more_detailed_data(w)){return}s=p.track.get("data_manager").get_more_detailed_data(w,"Coverage",0,r);$.when(s).then(function(B){x.remove();p._update_data_bounds();var A=h.find(p.chroms_layout,function(C){return C.data.chrom===t});var z=p.get_fill_color();p._render_chrom_data(p.parent_elt,A,B).style("stroke",z).style("fill",z)})});return p},_transition_chrom_data:function(){var p=this.track,r=this.chroms_layout,o=this.parent_elt.selectAll("g>path.chrom-data"),s=o[0].length;if(s>0){var q=this;$.when(p.get("data_manager").get_genome_wide_data(this.genome)).then(function(v){var u=h.reject(h.map(v,function(w,x){var y=null,z=q._get_path_function(r[x],w);if(z){y=z(w.data)}return y}),function(w){return w===null});var t=p.get("config").get_value("color");o.each(function(x,w){m.select(this).transition().duration(1000).style("stroke",t).style("fill",t).attr("d",u[w])})})}},_transition_labels:function(){},_update_data_bounds:function(p){var o=this.data_bounds;this.data_bounds=p||this.get_data_bounds(this.track.get("data_manager").get_genome_wide_data(this.genome));this._transition_chrom_data()},_render_data:function(r){var q=this,p=this.chroms_layout,o=this.track,s=$.Deferred();$.when(o.get("data_manager").get_genome_wide_data(this.genome)).then(function(u){q.data_bounds=q.get_data_bounds(u);o.get("config").set_value("min_value",q.data_bounds[0]);o.get("config").set_value("max_value",q.data_bounds[1]);layout_and_data=h.zip(p,u),chroms_data_layout=h.map(layout_and_data,function(v){var w=v[0],x=v[1];return q._render_chrom_data(r,w,x)});var t=q.get_fill_color();q.parent_elt.selectAll("path.chrom-data").style("stroke",t).style("fill",t);s.resolve(r)});return s},_render_chrom_data:function(o,p,q){},_get_path_function:function(p,o){},_chroms_layout:function(){var p=this.genome.get_chroms_info(),r=m.layout.pie().value(function(t){return t.len}).sort(null),s=r(p),o=2*Math.PI*this.total_gap/p.length,q=h.map(s,function(v,u){var t=v.endAngle-o;v.endAngle=(t>v.startAngle?t:v.startAngle);return v});return q}});var b=l.extend({initialize:function(o){l.prototype.initialize.call(this,o);this.innerRadius=this.radius_bounds[0];this.radius_bounds[0]=this.radius_bounds[1];this.bg_stroke="fff";this.bg_fill="fff";this.min_arc_len=0.05},_render_data:function(q){var p=this,o=q.selectAll("g");o.selectAll("path").attr("id",function(u){return"label-"+u.data.chrom});o.append("svg:text").filter(function(u){return u.endAngle-u.startAngle>p.min_arc_len}).attr("text-anchor","middle").append("svg:textPath").attr("class","chrom-label").attr("xlink:href",function(u){return"#label-"+u.data.chrom}).attr("startOffset","25%").text(function(u){return u.data.chrom});var r=function(w){var u=(w.endAngle-w.startAngle)/w.value,v=m.range(0,w.value,25000000).map(function(x,y){return{radius:p.innerRadius,angle:x*u+w.startAngle,label:y===0?0:(y%3?null:p.formatNum(x))}});if(v.length<4){v[v.length-1].label=p.formatNum(Math.round((v[v.length-1].angle-w.startAngle)/u))}return v};var t=function(u){return u.angle>Math.PI?"rotate(180)translate(-16)":null};var s=h.filter(this.chroms_layout,function(u){return u.endAngle-u.startAngle>p.min_arc_len});this.drawTicks(this.parent_elt,s,r,t)}});h.extend(b.prototype,i);var g=l.extend({initialize:function(o){l.prototype.initialize.call(this,o);var p=this.track.get("config");p.get("min_value").on("change:value",this._update_min_max,this);p.get("max_value").on("change:value",this._update_min_max,this);p.get("color").on("change:value",this._transition_chrom_data,this)},_update_min_max:function(){var p=this.track.get("config"),o=[p.get_value("min_value"),p.get_value("max_value")];this._update_data_bounds(o);this.parent_elt.selectAll(".min_max").text(function(r,q){return o[q]})},_quantile:function(p,o){p.sort(m.ascending);return m.quantile(p,o)},_render_chrom_data:function(o,r,p){var s=this._get_path_function(r,p);if(!s){return null}var q=o.datum(p.data),t=q.append("path").attr("class","chrom-data").attr("chrom",r.data.chrom).attr("d",s);return t},_get_path_function:function(r,q){if(typeof q==="string"||!q.data||q.data.length===0){return null}var o=m.scale.linear().domain(this.data_bounds).range(this.radius_bounds).clamp(true);var s=m.scale.linear().domain([0,q.data.length]).range([r.startAngle,r.endAngle]);var p=m.svg.line.radial().interpolate("linear").radius(function(t){return o(t[1])}).angle(function(u,t){return s(t)});return m.svg.area.radial().interpolate(p.interpolate()).innerRadius(o(0)).outerRadius(p.radius()).angle(p.angle())},render_labels:function(){var o=this,q=function(){return"rotate(90)"};var p=this.drawTicks(this.parent_elt,[this.chroms_layout[0]],this._data_bounds_ticks_fn(),q,true).classed("min_max",true);h.each(p,function(r){$(r).click(function(){var s=new c.ConfigSettingCollectionView({collection:o.track.get("config")});s.render_in_modal("Configure Track")})})},_transition_labels:function(){if(this.data_bounds.length===0){return}var p=this,r=h.filter(this.chroms_layout,function(s){return s.endAngle-s.startAngle>0.08}),q=h.filter(r,function(t,s){return s%3===0}),o=h.flatten(h.map(q,function(s){return p._data_bounds_ticks_fn()(s)}));this.parent_elt.selectAll("g.tick").data(o).transition().attr("transform",function(s){return"rotate("+(s.angle*180/Math.PI-90)+")translate("+s.radius+",0)"})},_data_bounds_ticks_fn:function(){var o=this;visibleChroms=0;return function(p){return[{radius:o.radius_bounds[0],angle:p.startAngle,label:o.formatNum(o.data_bounds[0])},{radius:o.radius_bounds[1],angle:p.startAngle,label:o.formatNum(o.data_bounds[1])}]}},get_data_bounds:function(o){}});h.extend(g.prototype,i);var e=g.extend({get_data_bounds:function(p){var o=h.flatten(h.map(p,function(q){if(q){return h.map(q.data,function(r){return parseInt(r[1],10)||0})}else{return 0}}));return[h.min(o),this._quantile(o,0.98)||h.max(o)]}});var k=l.extend({render:function(){var o=this;$.when(o.track.get("data_manager").data_is_ready()).then(function(){$.when(o.track.get("data_manager").get_genome_wide_data(o.genome)).then(function(r){var q=[],p=o.genome.get_chroms_info();h.each(r,function(v,u){var s=p[u].chrom;var t=h.map(v.data,function(x){var w=o._get_region_angle(s,x[1]),y=o._get_region_angle(x[3],x[4]);return{source:{startAngle:w,endAngle:w+0.01},target:{startAngle:y,endAngle:y+0.01}}});q=q.concat(t)});o.parent_elt.append("g").attr("class","chord").selectAll("path").data(q).enter().append("path").style("fill",o.get_fill_color()).attr("d",m.svg.chord().radius(o.radius_bounds[0])).style("opacity",1)})})},update_radius_bounds:function(o){this.radius_bounds=o;this.parent_elt.selectAll("path").transition().attr("d",m.svg.chord().radius(this.radius_bounds[0]))},_get_region_angle:function(q,o){var p=h.find(this.chroms_layout,function(r){return r.data.chrom===q});return p.endAngle-((p.endAngle-p.startAngle)*(p.data.len-o)/p.data.len)}});var f=Backbone.View.extend({initialize:function(){var o=new j.Genome(galaxy_config.app.genome),p=new j.GenomeVisualization(galaxy_config.app.viz_config);p.get("config").add([{key:"arc_dataset_height",label:"Arc Dataset Height",type:"int",value:25,view:"circster"},{key:"track_gap",label:"Gap Between Tracks",type:"int",value:5,view:"circster"},{key:"total_gap",label:"Gap [0-1]",type:"float",value:0.4,view:"circster",hidden:true}]);var r=new a({el:$("#center .unified-panel-body"),genome:o,model:p});r.render();$("#center .unified-panel-header-inner").append(galaxy_config.app.viz_config.title+" "+galaxy_config.app.viz_config.dbkey);var q=create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){j.select_datasets(galaxy_config.root+"visualization/list_current_history_datasets",galaxy_config.root+"api/datasets",p.get("dbkey"),function(s){p.add_tracks(s)})}},{icon_class:"gear",title:"Settings",on_click:function(){var s=new c.ConfigSettingCollectionView({collection:p.get("config")});s.render_in_modal("Configure Visualization")}},{icon_class:"disk--arrow",title:"Save",on_click:function(){Galaxy.modal.show({title:"Saving...",body:"progress"});$.ajax({url:galaxy_config.root+"visualization/save",type:"POST",dataType:"json",data:{id:p.get("vis_id"),title:p.get("title"),dbkey:p.get("dbkey"),type:"trackster",vis_json:JSON.stringify(p)}}).success(function(s){Galaxy.modal.hide();p.set("vis_id",s.vis_id)}).error(function(){Galaxy.modal.show({title:"Could Not Save",body:"Could not save visualization. Please try again later.",buttons:{Cancel:function(){Galaxy.modal.hide()}}})})}},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location=galaxy_config.root+"visualization/list"}}],{tooltip_config:{placement:"bottom"}});q.$el.attr("style","float: right");$("#center .unified-panel-header-inner").append(q.$el);$(".menu-button").tooltip({placement:"bottom"})}});return{GalaxyApp:f}}); \ No newline at end of file diff -r 9198bb0ed8c9a4a862defa9a28f4c8ba2c3dca0f -r ba9452fd7e6119e4958fa2ddd10e45f6739c725a static/scripts/packed/viz/visualization.js --- a/static/scripts/packed/viz/visualization.js +++ b/static/scripts/packed/viz/visualization.js @@ -1,1 +1,1 @@ -define(["libs/underscore","mvc/data","viz/trackster/util","utils/config"],function(t,k,m,p){var f={toJSON:function(){var v=this,w={};t.each(v.constructor.to_json_keys,function(x){var y=v.get(x);if(x in v.constructor.to_json_mappers){y=v.constructor.to_json_mappers[x](y,v)}w[x]=y});return w}};var a=function(v,y,x,w){$.ajax({url:v,data:x,error:function(){alert("Grid failed")},success:function(z){Galaxy.modal.show({title:"Select datasets for new tracks",body:z,buttons:{Cancel:function(){Galaxy.modal.hide()},Add:function(){var A=[];$("input[name=id]:checked,input[name=ldda_ids]:checked").each(function(){var B={data_type:"track_config",hda_ldda:"hda"},C=$(this).val();if($(this).attr("name")!=="id"){B.hda_ldda="ldda"}A[A.length]=$.ajax({url:y+"/"+C,data:B,dataType:"json"})});$.when.apply($,A).then(function(){var B=(arguments[0] instanceof Array?$.map(arguments,function(C){return C[0]}):[arguments[0]]);w(B)});Galaxy.modal.hide()}}})}})};var g=function(v){this.default_font=v!==undefined?v:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};t.extend(g.prototype,{load_pattern:function(v,z){var w=this.patterns,x=this.dummy_context,y=new Image();y.src=galaxy_config.root+"static/images"+z;y.onload=function(){w[v]=x.createPattern(y,"repeat")}},get_pattern:function(v){return this.patterns[v]},new_canvas:function(){var v=$("<canvas/>")[0];if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(v)}v.manager=this;return v}});var r=Backbone.Model.extend({defaults:{num_elements:20,obj_cache:null,key_ary:null},initialize:function(v){this.clear()},get_elt:function(x){var y=this.attributes.obj_cache,z=this.attributes.key_ary,w=x.toString(),v=t.indexOf(z,function(A){return A.toString()===w});if(v!==-1){if(y[w].stale){z.splice(v,1);delete y[w]}else{this.move_key_to_end(x,v)}}return y[w]},set_elt:function(x,z){var A=this.attributes.obj_cache,B=this.attributes.key_ary,w=x.toString(),y=this.attributes.num_elements;if(!A[w]){if(B.length>=y){var v=B.shift();delete A[v.toString()]}B.push(x)}A[w]=z;return z},move_key_to_end:function(w,v){this.attributes.key_ary.splice(v,1);this.attributes.key_ary.push(w)},clear:function(){this.attributes.obj_cache={};this.attributes.key_ary=[]},size:function(){return this.attributes.key_ary.length},most_recently_added:function(){return this.size()===0?null:this.attributes.key_ary[this.attributes.key_ary.length-1]}});var d=r.extend({defaults:t.extend({},r.prototype.defaults,{dataset:null,genome:null,init_data:null,min_region_size:200,filters_manager:null,data_type:"data",data_mode_compatible:function(v,w){return true},can_subset:function(v){return false}}),initialize:function(v){r.prototype.initialize.call(this);var w=this.get("init_data");if(w){this.add_data(w)}},add_data:function(v){if(this.get("num_elements")<v.length){this.set("num_elements",v.length)}var w=this;t.each(v,function(x){w.set_data(x.region,x)})},data_is_ready:function(){var y=this.get("dataset"),x=$.Deferred(),v=(this.get("data_type")==="raw_data"?"state":this.get("data_type")==="data"?"converted_datasets_state":"error"),w=new m.ServerStateDeferred({ajax_settings:{url:this.get("dataset").url(),data:{hda_ldda:y.get("hda_ldda"),data_type:v},dataType:"json"},interval:5000,success_fn:function(z){return z!=="pending"}});$.when(w.go()).then(function(z){x.resolve(z==="ok"||z==="data")});return x},search_features:function(v){var w=this.get("dataset"),x={query:v,hda_ldda:w.get("hda_ldda"),data_type:"features"};return $.getJSON(w.url(),x)},load_data:function(D,C,w,B){var z=this.get("dataset"),y={data_type:this.get("data_type"),chrom:D.get("chrom"),low:D.get("start"),high:D.get("end"),mode:C,resolution:w,hda_ldda:z.get("hda_ldda")};$.extend(y,B);var F=this.get("filters_manager");if(F){var G=[];var v=F.filters;for(var A=0;A<v.length;A++){G.push(v[A].name)}y.filter_cols=JSON.stringify(G)}var x=this,E=$.getJSON(z.url(),y,function(H){H.region=D;x.set_data(D,H)});this.set_data(D,E);return E},get_data:function(C,B,x,z){var D=this.get_elt(C);if(D&&(m.is_deferred(D)||this.get("data_mode_compatible")(D,B))){return D}var E=this.get("key_ary"),v=this.get("obj_cache"),w,A;for(var y=0;y<E.length;y++){w=E[y];if(w.contains(C)){A=true;D=v[w.toString()];if(m.is_deferred(D)||(this.get("data_mode_compatible")(D,B)&&this.get("can_subset")(D))){this.move_key_to_end(w,y);if(!m.is_deferred(D)){var G=this.subset_entry(D,C);this.set_data(C,G);D=G}return D}}}if(!A&&C.length()<this.attributes.min_region_size){C=C.copy();var F=this.most_recently_added();if(!F||(C.get("start")>F.get("start"))){C.set("end",C.get("start")+this.attributes.min_region_size)}else{C.set("start",C.get("end")-this.attributes.min_region_size)}C.set("genome",this.attributes.genome);C.trim()}return this.load_data(C,B,x,z)},set_data:function(w,v){this.set_elt(w,v)},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(D,C,y,B,z){var F=this._mark_stale(D);if(!(F&&this.get("data_mode_compatible")(F,C))){console.log("ERROR: problem with getting more data: current data is not compatible");return}var x=D.get("start");if(z===this.DEEP_DATA_REQ){$.extend(B,{start_val:F.data.length+1})}else{if(z===this.BROAD_DATA_REQ){x=(F.max_high?F.max_high:F.data[F.data.length-1][2])+1}}var E=D.copy().set("start",x);var w=this,A=this.load_data(E,C,y,B),v=$.Deferred();this.set_data(D,v);$.when(A).then(function(G){if(G.data){G.data=F.data.concat(G.data);if(G.max_low){G.max_low=F.max_low}if(G.message){G.message=G.message.replace(/[0-9]+/,G.data.length)}}w.set_data(D,G);v.resolve(G)});return v},can_get_more_detailed_data:function(w){var v=this.get_elt(w);return(v.dataset_type==="bigwig"&&v.data.length<8000)},get_more_detailed_data:function(y,A,w,z,x){var v=this._mark_stale(y);if(!v){console.log("ERROR getting more detailed data: no current data");return}if(!x){x={}}if(v.dataset_type==="bigwig"){x.num_samples=1000*z}return this.load_data(y,A,w,x)},_mark_stale:function(w){var v=this.get_elt(w);if(!v){console.log("ERROR: no data to mark as stale: ",this.get("dataset"),w.toString())}v.stale=true;return v},get_genome_wide_data:function(v){var x=this,z=true,y=t.map(v.get("chroms_info").chrom_info,function(B){var A=x.get_elt(new h({chrom:B.chrom,start:0,end:B.len}));if(!A){z=false}return A});if(z){return y}var w=$.Deferred();$.getJSON(this.get("dataset").url(),{data_type:"genome_data"},function(A){x.add_data(A.data);w.resolve(A.data)});return w},subset_entry:function(x,y){var v={bigwig:function(z,A){return t.filter(z,function(B){return B[0]>=A.get("start")&&B[0]<=A.get("end")})},refseq:function(z,A){var B=A.get("start")-x.region.get("start");return x.data.slice(B,B+A.length())}};var w=x.data;if(!x.region.same(y)&&x.dataset_type in v){w=v[x.dataset_type](x.data,y)}return{region:y,data:w,dataset_type:x.dataset_type}}});var q=d.extend({initialize:function(v){var w=new Backbone.Model();w.urlRoot=v.data_url;this.set("dataset",w)},load_data:function(x,y,v,w){return(x.length()<=100000?d.prototype.load_data.call(this,x,y,v,w):{data:null,region:x})}});var c=Backbone.Model.extend({defaults:{name:null,key:null,chroms_info:null},initialize:function(v){this.id=v.dbkey},get_chroms_info:function(){return this.attributes.chroms_info.chrom_info},get_chrom_region:function(v){var w=t.find(this.get_chroms_info(),function(x){return x.chrom===v});return new h({chrom:w.chrom,end:w.len})},get_chrom_len:function(v){return t.find(this.get_chroms_info(),function(w){return w.chrom===v}).len}});var h=Backbone.Model.extend({defaults:{chrom:null,start:0,end:0,str_val:null,genome:null},same:function(v){return this.attributes.chrom===v.get("chrom")&&this.attributes.start===v.get("start")&&this.attributes.end===v.get("end")},initialize:function(w){if(w.from_str){var y=w.from_str.split(":"),x=y[0],v=y[1].split("-");this.set({chrom:x,start:parseInt(v[0],10),end:parseInt(v[1],10)})}this.attributes.str_val=this.get("chrom")+":"+this.get("start")+"-"+this.get("end");this.on("change",function(){this.attributes.str_val=this.get("chrom")+":"+this.get("start")+"-"+this.get("end")},this)},copy:function(){return new h({chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")})},length:function(){return this.get("end")-this.get("start")},toString:function(){return this.attributes.str_val},toJSON:function(){return{chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")}},compute_overlap:function(C){var w=this.get("chrom"),B=C.get("chrom"),A=this.get("start"),y=C.get("start"),z=this.get("end"),x=C.get("end"),v;if(w&&B&&w!==B){return h.overlap_results.DIF_CHROMS}if(A<y){if(z<y){v=h.overlap_results.BEFORE}else{if(z<x){v=h.overlap_results.OVERLAP_START}else{v=h.overlap_results.CONTAINS}}}else{if(A>y){if(A>x){v=h.overlap_results.AFTER}else{if(z<=x){v=h.overlap_results.CONTAINED_BY}else{v=h.overlap_results.OVERLAP_END}}}else{v=(z>=x?h.overlap_results.CONTAINS:h.overlap_results.CONTAINED_BY)}}return v},trim:function(v){if(this.attributes.start<0){this.attributes.start=0}if(this.attributes.genome){var w=this.attributes.genome.get_chrom_len(this.attributes.chrom);if(this.attributes.end>w){this.attributes.end=w-1}}return this},contains:function(v){return this.compute_overlap(v)===h.overlap_results.CONTAINS},overlaps:function(v){return t.intersection([this.compute_overlap(v)],[h.overlap_results.DIF_CHROMS,h.overlap_results.BEFORE,h.overlap_results.AFTER]).length===0}},{overlap_results:{DIF_CHROMS:1000,BEFORE:1001,CONTAINS:1002,OVERLAP_START:1003,OVERLAP_END:1004,CONTAINED_BY:1005,AFTER:1006}});var n=Backbone.Collection.extend({model:h});var e=Backbone.Model.extend({defaults:{region:null,note:""},initialize:function(v){this.set("region",new h(v.region))}});var s=Backbone.Collection.extend({model:e});var u=Backbone.Model.extend(f).extend({defaults:{mode:"Auto"},initialize:function(v){this.set("dataset",new k.Dataset(v.dataset));var x=[{key:"name",value:this.get("dataset").get("name")},{key:"color"}];this.set("config",p.ConfigSettingCollection.from_models_and_saved_values(x,v.prefs));var w=this.get("preloaded_data");if(w){w=w.data}else{w=[]}this.set("data_manager",new d({dataset:this.get("dataset"),init_data:w}))}},{to_json_keys:["track_type","dataset","prefs","mode","filters","tool_state"],to_json_mappers:{prefs:function(w,v){if(t.size(w)===0){w={name:v.get("config").get("name").get("value"),color:v.get("config").get("color").get("value")}}return w},dataset:function(v){return{id:v.id,hda_ldda:v.get("hda_ldda")}}}});var j=Backbone.Collection.extend({model:u});var o=Backbone.Model.extend({defaults:{title:"",type:""},url:galaxy_config.root+"visualization/save",save:function(){return $.ajax({url:this.url(),type:"POST",dataType:"json",data:{vis_json:JSON.stringify(this)}})}});var l=o.extend(f).extend({defaults:t.extend({},o.prototype.defaults,{dbkey:"",drawables:null,bookmarks:null,viewport:null}),initialize:function(v){this.set("drawables",new j(v.tracks));var w=[];this.set("config",p.ConfigSettingCollection.from_models_and_saved_values(w,v.prefs));this.unset("tracks");this.get("drawables").each(function(x){x.unset("preloaded_data")})},add_tracks:function(v){this.get("drawables").add(v)}},{to_json_keys:["view","viewport","bookmarks"],to_json_mappers:{view:function(w,v){return{obj_type:"View",prefs:{name:v.get("title"),content_visible:true},drawables:v.get("drawables")}}}});var b=Backbone.Model.extend({});var i=Backbone.Router.extend({initialize:function(w){this.view=w.view;this.route(/([\w]+)$/,"change_location");this.route(/([\w\+]+\:[\d,]+-[\d,]+)$/,"change_location");var v=this;v.view.on("navigate",function(x){v.navigate(x)})},change_location:function(v){this.view.go_to(v)}});return{BackboneTrack:u,BrowserBookmark:e,BrowserBookmarkCollection:s,Cache:r,CanvasManager:g,Genome:c,GenomeDataManager:d,GenomeRegion:h,GenomeRegionCollection:n,GenomeVisualization:l,GenomeReferenceDataManager:q,TrackBrowserRouter:i,TrackConfig:b,Visualization:o,select_datasets:a}}); \ No newline at end of file +define(["libs/underscore","mvc/data","viz/trackster/util","utils/config"],function(t,k,m,p){var f={toJSON:function(){var v=this,w={};t.each(v.constructor.to_json_keys,function(x){var y=v.get(x);if(x in v.constructor.to_json_mappers){y=v.constructor.to_json_mappers[x](y,v)}w[x]=y});return w}};var a=function(v,y,x,w){$.ajax({url:v,data:x,error:function(){alert("Grid failed")},success:function(z){Galaxy.modal.show({title:"Select datasets for new tracks",body:z,buttons:{Cancel:function(){Galaxy.modal.hide()},Add:function(){var A=[];$("input[name=id]:checked,input[name=ldda_ids]:checked").each(function(){var B={data_type:"track_config",hda_ldda:"hda"},C=$(this).val();if($(this).attr("name")!=="id"){B.hda_ldda="ldda"}A[A.length]=$.ajax({url:y+"/"+C,data:B,dataType:"json"})});$.when.apply($,A).then(function(){var B=(arguments[0] instanceof Array?$.map(arguments,function(C){return C[0]}):[arguments[0]]);w(B)});Galaxy.modal.hide()}}})}})};var g=function(v){this.default_font=v!==undefined?v:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};t.extend(g.prototype,{load_pattern:function(v,z){var w=this.patterns,x=this.dummy_context,y=new Image();y.src=galaxy_config.root+"static/images"+z;y.onload=function(){w[v]=x.createPattern(y,"repeat")}},get_pattern:function(v){return this.patterns[v]},new_canvas:function(){var v=$("<canvas/>")[0];if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(v)}v.manager=this;return v}});var r=Backbone.Model.extend({defaults:{num_elements:20,obj_cache:null,key_ary:null},initialize:function(v){this.clear()},get_elt:function(x){var y=this.attributes.obj_cache,z=this.attributes.key_ary,w=x.toString(),v=t.indexOf(z,function(A){return A.toString()===w});if(v!==-1){if(y[w].stale){z.splice(v,1);delete y[w]}else{this.move_key_to_end(x,v)}}return y[w]},set_elt:function(x,z){var A=this.attributes.obj_cache,B=this.attributes.key_ary,w=x.toString(),y=this.attributes.num_elements;if(!A[w]){if(B.length>=y){var v=B.shift();delete A[v.toString()]}B.push(x)}A[w]=z;return z},move_key_to_end:function(w,v){this.attributes.key_ary.splice(v,1);this.attributes.key_ary.push(w)},clear:function(){this.attributes.obj_cache={};this.attributes.key_ary=[]},size:function(){return this.attributes.key_ary.length},most_recently_added:function(){return this.size()===0?null:this.attributes.key_ary[this.attributes.key_ary.length-1]}});var d=r.extend({defaults:t.extend({},r.prototype.defaults,{dataset:null,genome:null,init_data:null,min_region_size:200,filters_manager:null,data_type:"data",data_mode_compatible:function(v,w){return true},can_subset:function(v){return false}}),initialize:function(v){r.prototype.initialize.call(this);var w=this.get("init_data");if(w){this.add_data(w)}},add_data:function(v){if(this.get("num_elements")<v.length){this.set("num_elements",v.length)}var w=this;t.each(v,function(x){w.set_data(x.region,x)})},data_is_ready:function(){var y=this.get("dataset"),x=$.Deferred(),v=(this.get("data_type")==="raw_data"?"state":this.get("data_type")==="data"?"converted_datasets_state":"error"),w=new m.ServerStateDeferred({ajax_settings:{url:this.get("dataset").url(),data:{hda_ldda:y.get("hda_ldda"),data_type:v},dataType:"json"},interval:5000,success_fn:function(z){return z!=="pending"}});$.when(w.go()).then(function(z){x.resolve(z==="ok"||z==="data")});return x},search_features:function(v){var w=this.get("dataset"),x={query:v,hda_ldda:w.get("hda_ldda"),data_type:"features"};return $.getJSON(w.url(),x)},load_data:function(D,C,w,B){var z=this.get("dataset"),y={data_type:this.get("data_type"),chrom:D.get("chrom"),low:D.get("start"),high:D.get("end"),mode:C,resolution:w,hda_ldda:z.get("hda_ldda")};$.extend(y,B);var F=this.get("filters_manager");if(F){var G=[];var v=F.filters;for(var A=0;A<v.length;A++){G.push(v[A].name)}y.filter_cols=JSON.stringify(G)}var x=this,E=$.getJSON(z.url(),y,function(H){H.region=D;x.set_data(D,H)});this.set_data(D,E);return E},get_data:function(C,B,x,z){var D=this.get_elt(C);if(D&&(m.is_deferred(D)||this.get("data_mode_compatible")(D,B))){return D}var E=this.get("key_ary"),v=this.get("obj_cache"),w,A;for(var y=0;y<E.length;y++){w=E[y];if(w.contains(C)){A=true;D=v[w.toString()];if(m.is_deferred(D)||(this.get("data_mode_compatible")(D,B)&&this.get("can_subset")(D))){this.move_key_to_end(w,y);if(!m.is_deferred(D)){var G=this.subset_entry(D,C);this.set_data(C,G);D=G}return D}}}if(!A&&C.length()<this.attributes.min_region_size){C=C.copy();var F=this.most_recently_added();if(!F||(C.get("start")>F.get("start"))){C.set("end",C.get("start")+this.attributes.min_region_size)}else{C.set("start",C.get("end")-this.attributes.min_region_size)}C.set("genome",this.attributes.genome);C.trim()}return this.load_data(C,B,x,z)},set_data:function(w,v){this.set_elt(w,v)},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(D,C,y,B,z){var F=this._mark_stale(D);if(!(F&&this.get("data_mode_compatible")(F,C))){console.log("ERROR: problem with getting more data: current data is not compatible");return}var x=D.get("start");if(z===this.DEEP_DATA_REQ){$.extend(B,{start_val:F.data.length+1})}else{if(z===this.BROAD_DATA_REQ){x=(F.max_high?F.max_high:F.data[F.data.length-1][2])+1}}var E=D.copy().set("start",x);var w=this,A=this.load_data(E,C,y,B),v=$.Deferred();this.set_data(D,v);$.when(A).then(function(G){if(G.data){G.data=F.data.concat(G.data);if(G.max_low){G.max_low=F.max_low}if(G.message){G.message=G.message.replace(/[0-9]+/,G.data.length)}}w.set_data(D,G);v.resolve(G)});return v},can_get_more_detailed_data:function(w){var v=this.get_elt(w);return(v.dataset_type==="bigwig"&&v.data.length<8000)},get_more_detailed_data:function(y,A,w,z,x){var v=this._mark_stale(y);if(!v){console.log("ERROR getting more detailed data: no current data");return}if(!x){x={}}if(v.dataset_type==="bigwig"){x.num_samples=1000*z}return this.load_data(y,A,w,x)},_mark_stale:function(w){var v=this.get_elt(w);if(!v){console.log("ERROR: no data to mark as stale: ",this.get("dataset"),w.toString())}v.stale=true;return v},get_genome_wide_data:function(v){var x=this,z=true,y=t.map(v.get("chroms_info").chrom_info,function(B){var A=x.get_elt(new h({chrom:B.chrom,start:0,end:B.len}));if(!A){z=false}return A});if(z){return y}var w=$.Deferred();$.getJSON(this.get("dataset").url(),{data_type:"genome_data"},function(A){x.add_data(A.data);w.resolve(A.data)});return w},subset_entry:function(x,y){var v={bigwig:function(z,A){return t.filter(z,function(B){return B[0]>=A.get("start")&&B[0]<=A.get("end")})},refseq:function(z,A){var B=A.get("start")-x.region.get("start");return x.data.slice(B,B+A.length())}};var w=x.data;if(!x.region.same(y)&&x.dataset_type in v){w=v[x.dataset_type](x.data,y)}return{region:y,data:w,dataset_type:x.dataset_type}}});var q=d.extend({initialize:function(v){var w=new Backbone.Model();w.urlRoot=v.data_url;this.set("dataset",w)},load_data:function(x,y,v,w){return(x.length()<=100000?d.prototype.load_data.call(this,x,y,v,w):{data:null,region:x})}});var c=Backbone.Model.extend({defaults:{name:null,key:null,chroms_info:null},initialize:function(v){this.id=v.dbkey},get_chroms_info:function(){return this.attributes.chroms_info.chrom_info},get_chrom_region:function(v){var w=t.find(this.get_chroms_info(),function(x){return x.chrom===v});return new h({chrom:w.chrom,end:w.len})},get_chrom_len:function(v){return t.find(this.get_chroms_info(),function(w){return w.chrom===v}).len}});var h=Backbone.Model.extend({defaults:{chrom:null,start:0,end:0,str_val:null,genome:null},same:function(v){return this.attributes.chrom===v.get("chrom")&&this.attributes.start===v.get("start")&&this.attributes.end===v.get("end")},initialize:function(w){if(w.from_str){var y=w.from_str.split(":"),x=y[0],v=y[1].split("-");this.set({chrom:x,start:parseInt(v[0],10),end:parseInt(v[1],10)})}this.attributes.str_val=this.get("chrom")+":"+this.get("start")+"-"+this.get("end");this.on("change",function(){this.attributes.str_val=this.get("chrom")+":"+this.get("start")+"-"+this.get("end")},this)},copy:function(){return new h({chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")})},length:function(){return this.get("end")-this.get("start")},toString:function(){return this.attributes.str_val},toJSON:function(){return{chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")}},compute_overlap:function(C){var w=this.get("chrom"),B=C.get("chrom"),A=this.get("start"),y=C.get("start"),z=this.get("end"),x=C.get("end"),v;if(w&&B&&w!==B){return h.overlap_results.DIF_CHROMS}if(A<y){if(z<y){v=h.overlap_results.BEFORE}else{if(z<x){v=h.overlap_results.OVERLAP_START}else{v=h.overlap_results.CONTAINS}}}else{if(A>y){if(A>x){v=h.overlap_results.AFTER}else{if(z<=x){v=h.overlap_results.CONTAINED_BY}else{v=h.overlap_results.OVERLAP_END}}}else{v=(z>=x?h.overlap_results.CONTAINS:h.overlap_results.CONTAINED_BY)}}return v},trim:function(v){if(this.attributes.start<0){this.attributes.start=0}if(this.attributes.genome){var w=this.attributes.genome.get_chrom_len(this.attributes.chrom);if(this.attributes.end>w){this.attributes.end=w-1}}return this},contains:function(v){return this.compute_overlap(v)===h.overlap_results.CONTAINS},overlaps:function(v){return t.intersection([this.compute_overlap(v)],[h.overlap_results.DIF_CHROMS,h.overlap_results.BEFORE,h.overlap_results.AFTER]).length===0}},{overlap_results:{DIF_CHROMS:1000,BEFORE:1001,CONTAINS:1002,OVERLAP_START:1003,OVERLAP_END:1004,CONTAINED_BY:1005,AFTER:1006}});var n=Backbone.Collection.extend({model:h});var e=Backbone.Model.extend({defaults:{region:null,note:""},initialize:function(v){this.set("region",new h(v.region))}});var s=Backbone.Collection.extend({model:e});var u=Backbone.Model.extend(f).extend({defaults:{mode:"Auto"},initialize:function(v){this.set("dataset",new k.Dataset(v.dataset));var x=[{key:"name",value:this.get("dataset").get("name")},{key:"color"},{key:"min_value",label:"Min Value",type:"float",default_value:0},{key:"max_value",label:"Max Value",type:"float",default_value:1}];this.set("config",p.ConfigSettingCollection.from_models_and_saved_values(x,v.prefs));var w=this.get("preloaded_data");if(w){w=w.data}else{w=[]}this.set("data_manager",new d({dataset:this.get("dataset"),init_data:w}))}},{to_json_keys:["track_type","dataset","prefs","mode","filters","tool_state"],to_json_mappers:{prefs:function(w,v){if(t.size(w)===0){w={name:v.get("config").get("name").get("value"),color:v.get("config").get("color").get("value")}}return w},dataset:function(v){return{id:v.id,hda_ldda:v.get("hda_ldda")}}}});var j=Backbone.Collection.extend({model:u});var o=Backbone.Model.extend({defaults:{title:"",type:""},url:galaxy_config.root+"visualization/save",save:function(){return $.ajax({url:this.url(),type:"POST",dataType:"json",data:{vis_json:JSON.stringify(this)}})}});var l=o.extend(f).extend({defaults:t.extend({},o.prototype.defaults,{dbkey:"",drawables:null,bookmarks:null,viewport:null}),initialize:function(v){this.set("drawables",new j(v.tracks));var w=[];this.set("config",p.ConfigSettingCollection.from_models_and_saved_values(w,v.prefs));this.unset("tracks");this.get("drawables").each(function(x){x.unset("preloaded_data")})},add_tracks:function(v){this.get("drawables").add(v)}},{to_json_keys:["view","viewport","bookmarks"],to_json_mappers:{view:function(w,v){return{obj_type:"View",prefs:{name:v.get("title"),content_visible:true},drawables:v.get("drawables")}}}});var b=Backbone.Model.extend({});var i=Backbone.Router.extend({initialize:function(w){this.view=w.view;this.route(/([\w]+)$/,"change_location");this.route(/([\w\+]+\:[\d,]+-[\d,]+)$/,"change_location");var v=this;v.view.on("navigate",function(x){v.navigate(x)})},change_location:function(v){this.view.go_to(v)}});return{BackboneTrack:u,BrowserBookmark:e,BrowserBookmarkCollection:s,Cache:r,CanvasManager:g,Genome:c,GenomeDataManager:d,GenomeRegion:h,GenomeRegionCollection:n,GenomeVisualization:l,GenomeReferenceDataManager:q,TrackBrowserRouter:i,TrackConfig:b,Visualization:o,select_datasets:a}}); \ No newline at end of file diff -r 9198bb0ed8c9a4a862defa9a28f4c8ba2c3dca0f -r ba9452fd7e6119e4958fa2ddd10e45f6739c725a static/scripts/viz/circster.js --- a/static/scripts/viz/circster.js +++ b/static/scripts/viz/circster.js @@ -1,7 +1,15 @@ -define(["utils/utils", "libs/underscore", "libs/d3", "viz/visualization", "utils/config"], function(utils, _, d3, visualization, config) { +// load required libraries +require( +[ + 'utils/utils', + 'libs/farbtastic', +], function(mod_utils) +{ + // load css + mod_utils.cssLoadFile("static/style/circster.css"); +}); -// Load needed CSS. -utils.cssLoadFile("static/style/circster.css"); +define(["libs/underscore", "libs/d3", "viz/visualization", "utils/config"], function(_, d3, visualization, config) { /** * Utility class for working with SVG. @@ -72,14 +80,14 @@ .attr("y1", tick_coords[3]) .style("stroke", "#000"); - ticks.append("text") - .attr("x", text_coords[0]) - .attr("y", text_coords[1]) - .attr("dx", text_coords[2]) - .attr("dy", text_coords[3]) - .attr("text-anchor", text_anchor) - .attr("transform", textTransform) - .text(function(d) { return d.label; }); + return ticks.append("text") + .attr("x", text_coords[0]) + .attr("y", text_coords[1]) + .attr("dx", text_coords[2]) + .attr("dy", text_coords[3]) + .attr("text-anchor", text_anchor) + .attr("transform", textTransform) + .text(function(d) { return d.label; }); }, /** @@ -572,11 +580,13 @@ return rval; }), function(p_data) { return p_data === null; } ); - // Transition each path. + // Transition each path for data and color. + var color = track.get('config').get_value('color'); chrom_data_paths.each(function(path, index) { - d3.select(this).transition().duration(1000).attr('d', path_data[index]); + d3.select(this).transition().duration(1000) + .style('stroke', color).style('fill', color) + .attr('d', path_data[index]); }); - }); } }, @@ -587,16 +597,14 @@ _transition_labels: function() {}, /** - * Update data bounds. + * Update data bounds. If there are new_bounds, use them; otherwise use + * default data bounds. */ - _update_data_bounds: function() { + _update_data_bounds: function(new_bounds) { var old_bounds = this.data_bounds; - this.data_bounds = this.get_data_bounds(this.track.get('data_manager').get_genome_wide_data(this.genome)); - - // If bounds have changed, transition all paths to use the new data bounds. - if (this.data_bounds[0] < old_bounds[0] || this.data_bounds[1] > old_bounds[1]) { - this._transition_chrom_data(); - } + this.data_bounds = new_bounds || + this.get_data_bounds(this.track.get('data_manager').get_genome_wide_data(this.genome)); + this._transition_chrom_data(); }, /** @@ -612,6 +620,8 @@ $.when(track.get('data_manager').get_genome_wide_data(this.genome)).then(function(genome_wide_data) { // Set bounds. self.data_bounds = self.get_data_bounds(genome_wide_data); + track.get('config').set_value('min_value', self.data_bounds[0]); + track.get('config').set_value('max_value', self.data_bounds[1]); // Merge chroms layout with data. layout_and_data = _.zip(chrom_arcs, genome_wide_data), @@ -746,6 +756,31 @@ */ var CircsterQuantitativeTrackView = CircsterTrackView.extend({ + initialize: function(options) { + CircsterTrackView.prototype.initialize.call(this, options); + + // When config settings change, update view. + var track_config = this.track.get('config'); + track_config.get('min_value').on('change:value', this._update_min_max, this); + track_config.get('max_value').on('change:value', this._update_min_max, this); + track_config.get('color').on('change:value', this._transition_chrom_data, this); + }, + + /** + * Update track when min and/or max are changed. + */ + _update_min_max: function() { + var track_config = this.track.get('config'), + new_bounds = [track_config.get_value('min_value'), track_config.get_value('max_value')]; + this._update_data_bounds(new_bounds); + + // FIXME: this works to update tick/text bounds, but there's probably a better way to do this + // by updating the data itself. + this.parent_elt.selectAll('.min_max').text(function(d, i) { + return new_bounds[i]; + }); + }, + /** * Returns quantile for an array of numbers. */ @@ -816,8 +851,26 @@ return "rotate(90)"; }; + // FIXME: + // (1) using min_max class below is needed for _update_min_max, which could be improved. + // (2) showing config on tick click should be replaced by proper track config icon. + // Draw min, max on first chrom only. - this.drawTicks(this.parent_elt, [ this.chroms_layout[0] ], this._data_bounds_ticks_fn(), textTransform, true); + var ticks = this.drawTicks(this.parent_elt, [ this.chroms_layout[0] ], + this._data_bounds_ticks_fn(), textTransform, true) + .classed('min_max', true); + + // Show config when ticks are clicked on. + _.each(ticks, function(tick) { + $(tick).click(function() { + var view = new config.ConfigSettingCollectionView({ + collection: self.track.get('config') + }); + view.render_in_modal('Configure Track'); + }); + }); + + /* // Filter for visible chroms, then for every third chrom so that labels attached to only every @@ -909,7 +962,7 @@ // For max, use 98% quantile in attempt to avoid very large values. However, this max may be 0 // for sparsely populated data, so use max in that case. - return [ _.min(values), this._quantile(values, 0.5) || _.max(values) ]; + return [ _.min(values), this._quantile(values, 0.98) || _.max(values) ]; } }); diff -r 9198bb0ed8c9a4a862defa9a28f4c8ba2c3dca0f -r ba9452fd7e6119e4958fa2ddd10e45f6739c725a static/scripts/viz/visualization.js --- a/static/scripts/viz/visualization.js +++ b/static/scripts/viz/visualization.js @@ -895,7 +895,9 @@ // -- Set up config settings. -- var models = [ { key: 'name', value: this.get('dataset').get('name') }, - { key: 'color' } + { key: 'color' }, + { key: 'min_value', label: 'Min Value', type: 'float', default_value: 0 }, + { key: 'max_value', label: 'Max Value', type: 'float', default_value: 1 } ]; this.set('config', config_mod.ConfigSettingCollection.from_models_and_saved_values(models, options.prefs)); Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.