From f7669f3cd668ffa229241a2bc4e62768e517564c Mon Sep 17 00:00:00 2001 From: Carl Eberhard Date: Tue, 31 Mar 2015 17:05:50 -0400 Subject: [PATCH] Fix to ba44452: properly scope mod_icon_btn in define not require --- client/galaxy/scripts/viz/circster.js | 96 ++++++++++++++------------- static/scripts/packed/viz/circster.js | 2 +- static/scripts/viz/circster.js | 96 ++++++++++++++------------- 3 files changed, 101 insertions(+), 93 deletions(-) diff --git a/client/galaxy/scripts/viz/circster.js b/client/galaxy/scripts/viz/circster.js index a673d971891..756d8e3f085 100644 --- a/client/galaxy/scripts/viz/circster.js +++ b/client/galaxy/scripts/viz/circster.js @@ -1,16 +1,20 @@ // load required libraries -require( -[ +require([ 'utils/utils', - 'mvc/ui/icon-button', - 'libs/farbtastic', -], function(mod_utils, mod_icon_btn) +], function(mod_utils) { // load css mod_utils.cssLoadFile("static/style/circster.css"); }); -define(["libs/underscore", "libs/d3", "viz/visualization", "utils/config"], function(_, d3, visualization, config) { +define([ + "libs/underscore", + "libs/d3", + "viz/visualization", + "utils/config", + 'mvc/ui/icon-button', + 'libs/farbtastic' +], function(_, d3, visualization, config, mod_icon_btn) { /** * Utility class for working with SVG. @@ -71,7 +75,7 @@ var UsesTicks = { else { tick_coords = [1, 0, 4, 0]; text_coords = [0, 4, ".35em", ""]; - + } ticks.append("line") @@ -80,7 +84,7 @@ var UsesTicks = { .attr("x2", tick_coords[2]) .attr("y1", tick_coords[3]) .style("stroke", "#000"); - + return ticks.append("text") .attr("x", text_coords[0]) .attr("y", text_coords[1]) @@ -98,11 +102,11 @@ var UsesTicks = { // Use default of 2 sig. digits. if (sigDigits === undefined) sigDigits = 2; - + // Verify input number if (num === null) return null; - + // Calculate return value var rval = null; if (Math.abs(num) < 1) { @@ -141,7 +145,7 @@ var CircsterLabelTrack = Backbone.Model.extend({}); */ var CircsterView = Backbone.View.extend({ className: 'circster', - + initialize: function(options) { this.genome = options.genome; this.label_arc_height = 50; @@ -188,7 +192,7 @@ var CircsterView = Backbone.View.extend({ track_gap = this.model.get('config').get_value('track_gap'), // Subtract 20 to make sure chrom labels are on screen. min_dimension = Math.min(this.$el.width(), this.$el.height()) - 20, - // Compute radius start based on model, will be centered + // Compute radius start based on model, will be centered // and fit entirely inside element by default. radius_start = min_dimension / 2 - circular_tracks.length * (dataset_arc_height + track_gap) + @@ -198,14 +202,14 @@ var CircsterView = Backbone.View.extend({ // Compute range of track starting radii. tracks_start_radii = d3.range(radius_start, min_dimension / 2, dataset_arc_height + track_gap); - + // Map from track start to bounds. var self = this; return _.map(tracks_start_radii, function(radius) { return [radius, radius + dataset_arc_height]; }); }, - + /** * Renders circular tracks, chord tracks, and label tracks. */ @@ -254,7 +258,7 @@ var CircsterView = Backbone.View.extend({ })) .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") .append('svg:g').attr('class', 'tracks'); - + // -- Render circular tracks. -- // Create a view for each track in the visualization and render. @@ -266,12 +270,12 @@ var CircsterView = Backbone.View.extend({ genome: self.genome, total_gap: total_gap }); - + view.render(); - + return view; }); - + // -- Render chords tracks. -- this.chords_views = chords_tracks.map(function(track) { @@ -289,10 +293,10 @@ var CircsterView = Backbone.View.extend({ }); // -- Render label track. -- - + // Track bounds are: // (a) outer radius of last circular track; - // (b) + // (b) var outermost_radius = this.circular_views[this.circular_views.length-1].radius_bounds[1], track_bounds = [ outermost_radius, @@ -305,7 +309,7 @@ var CircsterView = Backbone.View.extend({ genome: self.genome, total_gap: total_gap }); - + this.label_track_view.render(); }, @@ -356,7 +360,7 @@ var CircsterView = Backbone.View.extend({ // Update label track. /* - FIXME: should never have to update label track because vis always expands to fit area + FIXME: should never have to update label track because vis always expands to fit area within label track. var track_bounds = new_track_bounds[ new_track_bounds.length-1 ]; track_bounds[1] = track_bounds[0]; @@ -373,7 +377,7 @@ var CircsterView = Backbone.View.extend({ var track_view = this.circular_views[options.index]; this.circular_views.splice(options.index, 1); track_view.$el.remove(); - + // Recompute and update track bounds. var new_track_bounds = this.get_tracks_bounds(); _.each(this.circular_views, function(track_view, i) { @@ -392,7 +396,7 @@ var CircsterView = Backbone.View.extend({ _.each(this.chords_views, function(track_view) { track_view.update_radius_bounds(new_track_bounds[0]); }); - + } }); @@ -455,7 +459,7 @@ var CircsterTrackView = Backbone.View.extend({ // Append titles to paths. chroms_paths.append("title").text(function(d) { return d.data.chrom; }); - + // -- Render track data and, when track data is rendered, apply preferences and update chrom_elts fill. -- var self = this, @@ -490,7 +494,7 @@ var CircsterTrackView = Backbone.View.extend({ var new_d = d3.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', new_d); this._transition_chrom_data(); @@ -511,7 +515,7 @@ var CircsterTrackView = Backbone.View.extend({ } // -- Scale increased, so render visible data with more detail. -- - + var self = this, utils = new SVGUtils(); @@ -539,7 +543,7 @@ var CircsterTrackView = Backbone.View.extend({ $.when(data_deferred).then(function(data) { // Remove current data path. path_elt.remove(); - + // Update data bounds with new data. self._update_data_bounds(); @@ -598,12 +602,12 @@ var CircsterTrackView = Backbone.View.extend({ _transition_labels: function() {}, /** - * Update data bounds. If there are new_bounds, use them; otherwise use + * Update data bounds. If there are new_bounds, use them; otherwise use * default data bounds. */ _update_data_bounds: function(new_bounds) { var old_bounds = this.data_bounds; - this.data_bounds = new_bounds || + this.data_bounds = new_bounds || this.get_data_bounds(this.track.get('data_manager').get_genome_wide_data(this.genome)); this._transition_chrom_data(); }, @@ -624,7 +628,7 @@ var CircsterTrackView = Backbone.View.extend({ // Set min, max value in config so that they can be adjusted. Make this silent // because these attributes are watched for changes and the viz is updated - // accordingly (set up in initialize). Because we are setting up, we don't want + // accordingly (set up in initialize). Because we are setting up, we don't want // the watch to trigger events here. track.get('config').set_value('min_value', self.data_bounds[0], {silent: true}); track.get('config').set_value('max_value', self.data_bounds[1], {silent: true}); @@ -660,7 +664,7 @@ var CircsterTrackView = Backbone.View.extend({ _get_path_function: function(chrom_arc, chrom_data) {}, /** - * Returns arc layouts for genome's chromosomes/contigs. Arcs are arranged in a circle + * Returns arc layouts for genome's chromosomes/contigs. Arcs are arranged in a circle * separated by gaps. */ _chroms_layout: function() { @@ -700,14 +704,14 @@ var CircsterChromLabelTrackView = CircsterTrackView.extend({ * Render labels. */ _render_data: function(svg) { - // -- Add chromosome label where it will fit; an alternative labeling mechanism + // -- Add chromosome label where it will fit; an alternative labeling mechanism // would be nice for small chromosomes. -- var self = this, chrom_arcs = svg.selectAll('g'); chrom_arcs.selectAll('path') .attr('id', function(d) { return 'label-' + d.data.chrom; }); - + chrom_arcs.append("svg:text") .filter(function(d) { return d.endAngle - d.startAngle > self.min_arc_len; @@ -857,12 +861,12 @@ var CircsterQuantitativeTrackView = CircsterTrackView.extend({ return "rotate(90)"; }; - // FIXME: + // 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. - var ticks = this.drawTicks(this.parent_elt, [ this.chroms_layout[0] ], + var ticks = this.drawTicks(this.parent_elt, [ this.chroms_layout[0] ], this._data_bounds_ticks_fn(), textTransform, true) .classed('min_max', true); @@ -872,7 +876,7 @@ var CircsterQuantitativeTrackView = CircsterTrackView.extend({ var view = new config.ConfigSettingCollectionView({ collection: self.track.get('config') }); - view.render_in_modal('Configure Track'); + view.render_in_modal('Configure Track'); }); }); @@ -951,7 +955,7 @@ _.extend(CircsterQuantitativeTrackView.prototype, UsesTicks); var CircsterBigWigTrackView = CircsterQuantitativeTrackView.extend({ get_data_bounds: function(data) { - // Set max across dataset by extracting all values, flattening them into a + // Set max across dataset by extracting all values, flattening them into a // single array, and getting third quartile. var values = _.flatten( _.map(data, function(d) { if (d) { @@ -965,8 +969,8 @@ var CircsterBigWigTrackView = CircsterQuantitativeTrackView.extend({ return 0; } }) ); - - // For max, use 98% quantile in attempt to avoid very large values. However, this max may be 0 + + // 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.98) || _.max(values) ]; } @@ -1068,13 +1072,13 @@ var Circster = Backbone.View.extend( genome : genome, model : vis }); - + // Render vizualization viz_view.render(); - + // setup title $('#center .unified-panel-header-inner').append(galaxy_config.app.viz_config.title + " " + galaxy_config.app.viz_config.dbkey); - + // setup menu var menu = mod_icon_btn.create_icon_buttons_menu([ { @@ -1100,7 +1104,7 @@ var Circster = Backbone.View.extend( { // show saving dialog box Galaxy.modal.show({title: "Saving...", body: "progress" }); - + // send to server $.ajax({ url: galaxy_config.root + "visualization/save", @@ -1132,11 +1136,11 @@ var Circster = Backbone.View.extend( window.location = galaxy_config.root + "visualization/list"; } }], { tooltip_config: { placement: 'bottom' } }); - + // add menu menu.$el.attr("style", "float: right"); $("#center .unified-panel-header-inner").append(menu.$el); - + // manual tooltip config because default gravity is S and cannot be changed $(".menu-button").tooltip( { placement: 'bottom' } ); } diff --git a/static/scripts/packed/viz/circster.js b/static/scripts/packed/viz/circster.js index 4ec36ea6a50..9ca00af11af 100644 --- a/static/scripts/packed/viz/circster.js +++ b/static/scripts/packed/viz/circster.js @@ -1 +1 @@ -require(["utils/utils","mvc/ui/icon-button","libs/farbtastic",],function(b,a){b.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],{silent:true});o.get("config").set_value("max_value",q.data_bounds[1],{silent:true});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=mod_icon_btn.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 +require(["utils/utils",],function(a){a.cssLoadFile("static/style/circster.css")});define(["libs/underscore","libs/d3","viz/visualization","utils/config","mvc/ui/icon-button","libs/farbtastic"],function(i,n,k,c,f){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");return 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(w){var v=i.reject(i.map(w,function(x,y){var z=null,A=r._get_path_function(s[y],x);if(A){z=A(x.data)}return z}),function(x){return x===null});var u=q.get("config").get_value("color");p.each(function(y,x){n.select(this).transition().duration(1000).style("stroke",u).style("fill",u).attr("d",v[x])})})}},_transition_labels:function(){},_update_data_bounds:function(q){var p=this.data_bounds;this.data_bounds=q||this.get_data_bounds(this.track.get("data_manager").get_genome_wide_data(this.genome));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);p.get("config").set_value("min_value",r.data_bounds[0],{silent:true});p.get("config").set_value("max_value",r.data_bounds[1],{silent:true});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 h=m.extend({initialize:function(p){m.prototype.initialize.call(this,p);var q=this.track.get("config");q.get("min_value").on("change:value",this._update_min_max,this);q.get("max_value").on("change:value",this._update_min_max,this);q.get("color").on("change:value",this._transition_chrom_data,this)},_update_min_max:function(){var q=this.track.get("config"),p=[q.get_value("min_value"),q.get_value("max_value")];this._update_data_bounds(p);this.parent_elt.selectAll(".min_max").text(function(s,r){return p[r]})},_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,r=function(){return"rotate(90)"};var q=this.drawTicks(this.parent_elt,[this.chroms_layout[0]],this._data_bounds_ticks_fn(),r,true).classed("min_max",true);i.each(q,function(s){$(s).click(function(){var t=new c.ConfigSettingCollectionView({collection:p.track.get("config")});t.render_in_modal("Configure Track")})})},_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(h.prototype,j);var e=h.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.98)||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 g=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=f.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:g}}); \ No newline at end of file diff --git a/static/scripts/viz/circster.js b/static/scripts/viz/circster.js index a673d971891..756d8e3f085 100644 --- a/static/scripts/viz/circster.js +++ b/static/scripts/viz/circster.js @@ -1,16 +1,20 @@ // load required libraries -require( -[ +require([ 'utils/utils', - 'mvc/ui/icon-button', - 'libs/farbtastic', -], function(mod_utils, mod_icon_btn) +], function(mod_utils) { // load css mod_utils.cssLoadFile("static/style/circster.css"); }); -define(["libs/underscore", "libs/d3", "viz/visualization", "utils/config"], function(_, d3, visualization, config) { +define([ + "libs/underscore", + "libs/d3", + "viz/visualization", + "utils/config", + 'mvc/ui/icon-button', + 'libs/farbtastic' +], function(_, d3, visualization, config, mod_icon_btn) { /** * Utility class for working with SVG. @@ -71,7 +75,7 @@ var UsesTicks = { else { tick_coords = [1, 0, 4, 0]; text_coords = [0, 4, ".35em", ""]; - + } ticks.append("line") @@ -80,7 +84,7 @@ var UsesTicks = { .attr("x2", tick_coords[2]) .attr("y1", tick_coords[3]) .style("stroke", "#000"); - + return ticks.append("text") .attr("x", text_coords[0]) .attr("y", text_coords[1]) @@ -98,11 +102,11 @@ var UsesTicks = { // Use default of 2 sig. digits. if (sigDigits === undefined) sigDigits = 2; - + // Verify input number if (num === null) return null; - + // Calculate return value var rval = null; if (Math.abs(num) < 1) { @@ -141,7 +145,7 @@ var CircsterLabelTrack = Backbone.Model.extend({}); */ var CircsterView = Backbone.View.extend({ className: 'circster', - + initialize: function(options) { this.genome = options.genome; this.label_arc_height = 50; @@ -188,7 +192,7 @@ var CircsterView = Backbone.View.extend({ track_gap = this.model.get('config').get_value('track_gap'), // Subtract 20 to make sure chrom labels are on screen. min_dimension = Math.min(this.$el.width(), this.$el.height()) - 20, - // Compute radius start based on model, will be centered + // Compute radius start based on model, will be centered // and fit entirely inside element by default. radius_start = min_dimension / 2 - circular_tracks.length * (dataset_arc_height + track_gap) + @@ -198,14 +202,14 @@ var CircsterView = Backbone.View.extend({ // Compute range of track starting radii. tracks_start_radii = d3.range(radius_start, min_dimension / 2, dataset_arc_height + track_gap); - + // Map from track start to bounds. var self = this; return _.map(tracks_start_radii, function(radius) { return [radius, radius + dataset_arc_height]; }); }, - + /** * Renders circular tracks, chord tracks, and label tracks. */ @@ -254,7 +258,7 @@ var CircsterView = Backbone.View.extend({ })) .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") .append('svg:g').attr('class', 'tracks'); - + // -- Render circular tracks. -- // Create a view for each track in the visualization and render. @@ -266,12 +270,12 @@ var CircsterView = Backbone.View.extend({ genome: self.genome, total_gap: total_gap }); - + view.render(); - + return view; }); - + // -- Render chords tracks. -- this.chords_views = chords_tracks.map(function(track) { @@ -289,10 +293,10 @@ var CircsterView = Backbone.View.extend({ }); // -- Render label track. -- - + // Track bounds are: // (a) outer radius of last circular track; - // (b) + // (b) var outermost_radius = this.circular_views[this.circular_views.length-1].radius_bounds[1], track_bounds = [ outermost_radius, @@ -305,7 +309,7 @@ var CircsterView = Backbone.View.extend({ genome: self.genome, total_gap: total_gap }); - + this.label_track_view.render(); }, @@ -356,7 +360,7 @@ var CircsterView = Backbone.View.extend({ // Update label track. /* - FIXME: should never have to update label track because vis always expands to fit area + FIXME: should never have to update label track because vis always expands to fit area within label track. var track_bounds = new_track_bounds[ new_track_bounds.length-1 ]; track_bounds[1] = track_bounds[0]; @@ -373,7 +377,7 @@ var CircsterView = Backbone.View.extend({ var track_view = this.circular_views[options.index]; this.circular_views.splice(options.index, 1); track_view.$el.remove(); - + // Recompute and update track bounds. var new_track_bounds = this.get_tracks_bounds(); _.each(this.circular_views, function(track_view, i) { @@ -392,7 +396,7 @@ var CircsterView = Backbone.View.extend({ _.each(this.chords_views, function(track_view) { track_view.update_radius_bounds(new_track_bounds[0]); }); - + } }); @@ -455,7 +459,7 @@ var CircsterTrackView = Backbone.View.extend({ // Append titles to paths. chroms_paths.append("title").text(function(d) { return d.data.chrom; }); - + // -- Render track data and, when track data is rendered, apply preferences and update chrom_elts fill. -- var self = this, @@ -490,7 +494,7 @@ var CircsterTrackView = Backbone.View.extend({ var new_d = d3.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', new_d); this._transition_chrom_data(); @@ -511,7 +515,7 @@ var CircsterTrackView = Backbone.View.extend({ } // -- Scale increased, so render visible data with more detail. -- - + var self = this, utils = new SVGUtils(); @@ -539,7 +543,7 @@ var CircsterTrackView = Backbone.View.extend({ $.when(data_deferred).then(function(data) { // Remove current data path. path_elt.remove(); - + // Update data bounds with new data. self._update_data_bounds(); @@ -598,12 +602,12 @@ var CircsterTrackView = Backbone.View.extend({ _transition_labels: function() {}, /** - * Update data bounds. If there are new_bounds, use them; otherwise use + * Update data bounds. If there are new_bounds, use them; otherwise use * default data bounds. */ _update_data_bounds: function(new_bounds) { var old_bounds = this.data_bounds; - this.data_bounds = new_bounds || + this.data_bounds = new_bounds || this.get_data_bounds(this.track.get('data_manager').get_genome_wide_data(this.genome)); this._transition_chrom_data(); }, @@ -624,7 +628,7 @@ var CircsterTrackView = Backbone.View.extend({ // Set min, max value in config so that they can be adjusted. Make this silent // because these attributes are watched for changes and the viz is updated - // accordingly (set up in initialize). Because we are setting up, we don't want + // accordingly (set up in initialize). Because we are setting up, we don't want // the watch to trigger events here. track.get('config').set_value('min_value', self.data_bounds[0], {silent: true}); track.get('config').set_value('max_value', self.data_bounds[1], {silent: true}); @@ -660,7 +664,7 @@ var CircsterTrackView = Backbone.View.extend({ _get_path_function: function(chrom_arc, chrom_data) {}, /** - * Returns arc layouts for genome's chromosomes/contigs. Arcs are arranged in a circle + * Returns arc layouts for genome's chromosomes/contigs. Arcs are arranged in a circle * separated by gaps. */ _chroms_layout: function() { @@ -700,14 +704,14 @@ var CircsterChromLabelTrackView = CircsterTrackView.extend({ * Render labels. */ _render_data: function(svg) { - // -- Add chromosome label where it will fit; an alternative labeling mechanism + // -- Add chromosome label where it will fit; an alternative labeling mechanism // would be nice for small chromosomes. -- var self = this, chrom_arcs = svg.selectAll('g'); chrom_arcs.selectAll('path') .attr('id', function(d) { return 'label-' + d.data.chrom; }); - + chrom_arcs.append("svg:text") .filter(function(d) { return d.endAngle - d.startAngle > self.min_arc_len; @@ -857,12 +861,12 @@ var CircsterQuantitativeTrackView = CircsterTrackView.extend({ return "rotate(90)"; }; - // FIXME: + // 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. - var ticks = this.drawTicks(this.parent_elt, [ this.chroms_layout[0] ], + var ticks = this.drawTicks(this.parent_elt, [ this.chroms_layout[0] ], this._data_bounds_ticks_fn(), textTransform, true) .classed('min_max', true); @@ -872,7 +876,7 @@ var CircsterQuantitativeTrackView = CircsterTrackView.extend({ var view = new config.ConfigSettingCollectionView({ collection: self.track.get('config') }); - view.render_in_modal('Configure Track'); + view.render_in_modal('Configure Track'); }); }); @@ -951,7 +955,7 @@ _.extend(CircsterQuantitativeTrackView.prototype, UsesTicks); var CircsterBigWigTrackView = CircsterQuantitativeTrackView.extend({ get_data_bounds: function(data) { - // Set max across dataset by extracting all values, flattening them into a + // Set max across dataset by extracting all values, flattening them into a // single array, and getting third quartile. var values = _.flatten( _.map(data, function(d) { if (d) { @@ -965,8 +969,8 @@ var CircsterBigWigTrackView = CircsterQuantitativeTrackView.extend({ return 0; } }) ); - - // For max, use 98% quantile in attempt to avoid very large values. However, this max may be 0 + + // 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.98) || _.max(values) ]; } @@ -1068,13 +1072,13 @@ var Circster = Backbone.View.extend( genome : genome, model : vis }); - + // Render vizualization viz_view.render(); - + // setup title $('#center .unified-panel-header-inner').append(galaxy_config.app.viz_config.title + " " + galaxy_config.app.viz_config.dbkey); - + // setup menu var menu = mod_icon_btn.create_icon_buttons_menu([ { @@ -1100,7 +1104,7 @@ var Circster = Backbone.View.extend( { // show saving dialog box Galaxy.modal.show({title: "Saving...", body: "progress" }); - + // send to server $.ajax({ url: galaxy_config.root + "visualization/save", @@ -1132,11 +1136,11 @@ var Circster = Backbone.View.extend( window.location = galaxy_config.root + "visualization/list"; } }], { tooltip_config: { placement: 'bottom' } }); - + // add menu menu.$el.attr("style", "float: right"); $("#center .unified-panel-header-inner").append(menu.$el); - + // manual tooltip config because default gravity is S and cannot be changed $(".menu-button").tooltip( { placement: 'bottom' } ); }