3 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/3dafc5ce805f/ changeset: 3dafc5ce805f user: jgoecks date: 2012-10-16 17:26:42 summary: Circster: enable tracks to be added dynamically. affected #: 4 files diff -r 1425614da4ea5eb4011f8176eb8afbb4a4dea6a1 -r 3dafc5ce805ffb12086e0697fc607450025bd681 static/scripts/viz/circster.js --- a/static/scripts/viz/circster.js +++ b/static/scripts/viz/circster.js @@ -51,6 +51,33 @@ this.track_gap = 5; this.label_arc_height = 20; this.scale = 1; + this.track_renderers = null; + + // When track added to the model, add to view as well. + this.model.get('tracks').on('add', this.add_track, this); + + }, + + /** + * Returns a list of tracks' radius bounds. + */ + get_tracks_bounds: function() { + var dataset_arc_height = this.dataset_arc_height, + min_dimension = Math.min(this.$el.width(), this.$el.height()), + // Compute radius start based on model, will be centered + // and fit entirely inside element by default. + radius_start = min_dimension / 2 - + this.model.get('tracks').length * (this.dataset_arc_height + this.track_gap) - + (this.label_arc_height + this.track_gap), + + // Compute range of track starting radii. + tracks_start_radii = d3.range(radius_start, min_dimension / 2, this.dataset_arc_height + this.track_gap); + + // Map from track start to bounds; for label track + var self = this; + return _.map(tracks_start_radii, function(radius) { + return [radius, radius + self.dataset_arc_height]; + }); }, render: function() { @@ -58,31 +85,11 @@ dataset_arc_height = this.dataset_arc_height, width = self.$el.width(), height = self.$el.height(), - // Compute radius start based on model, will be centered - // and fit entirely inside element by default. - init_radius_start = Math.min(width, height) / 2 - - this.model.get('tracks').length * (this.dataset_arc_height + this.track_gap) - - (this.label_arc_height + this.track_gap), tracks = this.model.get('tracks'), + tracks_bounds = this.get_tracks_bounds(), - // Create a renderer for each track in the visualiation. - track_renderers = tracks.map(function(track, index) { - var radius_start = init_radius_start + index * (dataset_arc_height + self.track_gap), - track_renderer_class = (track.get('track_type') === 'LineTrack' ? - CircsterBigWigTrackRenderer : - CircsterSummaryTreeTrackRenderer ); - - return new track_renderer_class({ - track: track, - track_index: index, - radius_bounds: [radius_start, radius_start + dataset_arc_height], - genome: self.genome, - total_gap: self.total_gap - }); - }); - - // Set up SVG element. - var svg = d3.select(self.$el[0]) + // Set up SVG element. + svg = d3.select(self.$el[0]) .append("svg") .attr("width", width) .attr("height", height) @@ -104,32 +111,85 @@ } self.zoom_drag_timeout = setTimeout(function() { // Render more detail in tracks' visible elements. - _.each(track_renderers, function(renderer) { + _.each(self.track_renderers, function(renderer) { renderer.update_scale(scale); }); }, 400); } })) .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") - .append('svg:g'); + .append('svg:g').attr('class', 'tracks'); // -- Render each dataset in the visualization. -- - _.each(track_renderers, function(renderer) { + + // Create a renderer for each track in the visualiation and render. + this.track_renderers = tracks.map(function(track, index) { + track_renderer_class = (track.get('track_type') === 'LineTrack' ? + CircsterBigWigTrackRenderer : + CircsterSummaryTreeTrackRenderer ); + + return new track_renderer_class({ + track: track, + track_index: index, + radius_bounds: tracks_bounds[index], + genome: self.genome, + total_gap: self.total_gap + }); + }); + + _.each(this.track_renderers, function(renderer) { renderer.render(svg); }); // -- Render chromosome labels. -- - var radius_start = init_radius_start + tracks.length * (dataset_arc_height + self.track_gap) + self.track_gap; - var chrom_labels_track = new CircsterLabelTrackRenderer({ + + // Set radius start = end for track bounds. + var track_bounds = tracks_bounds[tracks.length]; + track_bounds[1] = track_bounds[0]; + this.label_track_renderer = new CircsterLabelTrackRenderer({ track: new CircsterLabelTrack(), track_index: tracks.length, - radius_bounds: [radius_start, radius_start], + radius_bounds: track_bounds, genome: self.genome, total_gap: self.total_gap }); + + this.label_track_renderer.render(svg); + }, - chrom_labels_track.render(svg); + /** + * Render a single track on the outside of the current visualization. + */ + add_track: function(new_track) { + // Reset scale and zoom. + + // Recompute and update track bounds. + var new_track_bounds = this.get_tracks_bounds(); + _.each(this.track_renderers, function(track_renderer, i) { + //console.log(self.get_tracks_bounds(), i); + track_renderer.update_radius_bounds(new_track_bounds[i]); + }); + + // Render new track. + var track_index = this.track_renderers.length + track_renderer_class = (new_track.get('track_type') === 'LineTrack' ? + CircsterBigWigTrackRenderer : + CircsterSummaryTreeTrackRenderer ), + track_renderer = new track_renderer_class({ + track: new_track, + track_index: track_index, + radius_bounds: new_track_bounds[track_index], + genome: this.genome, + total_gap: this.total_gap + }); + track_renderer.render(d3.select('g.tracks')); + this.track_renderers.push(track_renderer); + + // Update label track. + var track_bounds = new_track_bounds[ new_track_bounds.length-1 ]; + track_bounds[1] = track_bounds[0]; + this.label_track_renderer.update_radius_bounds(track_bounds); } }); @@ -172,8 +232,9 @@ .data(genome_arcs).enter().append('svg:g'), // Draw chrom arcs/paths. - chroms_paths = chroms_elts.append("path") + chroms_paths = chroms_elts.append('path') .attr("d", arc_gen) + .attr('class', 'chrom-background') .style("stroke", this.options.bg_stroke) .style("fill", this.options.loading_bg_fill); @@ -203,6 +264,48 @@ }, /** + * Update radius bounds. + */ + update_radius_bounds: function(radius_bounds) { + // Update bounds. + this.options.radius_bounds = radius_bounds; + + // -- Update background arcs. -- + var new_d = d3.svg.arc() + .innerRadius(this.options.radius_bounds[0]) + .outerRadius(this.options.radius_bounds[1]); + + this.options.parent_elt.selectAll('g>path.chrom-background').transition().duration(1000).attr('d', new_d); + + // -- Update chrom data. -- + var track = this.options.track, + chrom_arcs = this.options.chroms_layout, + chrom_data_paths = this.options.parent_elt.selectAll('g>path.chrom-data'), + num_paths = chrom_data_paths[0].length; + + if (num_paths > 0) { + var self = this; + $.when(track.get('data_manager').get_genome_wide_data(this.options.genome)).then(function(genome_wide_data) { + // Map chrom data to path data, filtering out null values. + var path_data = _.reject( _.map(genome_wide_data, function(chrom_data, i) { + var rval = null, + path_fn = self._compute_path_data(chrom_arcs[i], chrom_data); + if (path_fn) { + rval = path_fn(chrom_data.data); + } + return rval; + }), function(p_data) { return p_data === null; } ); + + // Transition each path. + chrom_data_paths.each(function(path, index) { + d3.select(this).transition().duration(1000).attr('d', path_data[index]); + }); + + }); + } + }, + + /** * Update renderer scale. This fetches more data if scale is increased. */ update_scale: function(new_scale) { @@ -304,7 +407,7 @@ /** * Returns data for creating a path for the given data using chrom_arc and data bounds. */ - _compute_path_data: function(chrom_arc, data) {}, + _compute_path_data: function(chrom_arc, chrom_data) {}, /** * Returns arc layouts for genome's chromosomes/contigs. Arcs are arranged in a circle @@ -373,14 +476,11 @@ * chromosome. Attachs a dict with track and chrom name information to DOM element. */ _render_chrom_data: function(svg, chrom_arc, chrom_data) { - // If no chrom data, return null. - if (typeof chrom_data === "string" || !chrom_data.data || chrom_data.data.length === 0) { - return null; - } + var path_data = this._compute_path_data(chrom_arc, chrom_data); - var path_data = this._compute_path_data(chrom_arc, chrom_data.data); + if (!path_data) { return null; } - // Render data. + // There is path data, so render as path. var parent = svg.datum(chrom_data.data), path = parent.append('path') .attr('class', 'chrom-data') @@ -393,7 +493,12 @@ /** * Returns data for creating a path for the given data using chrom_arc, radius bounds, and data bounds. */ - _compute_path_data: function(chrom_arc, data) { + _compute_path_data: function(chrom_arc, chrom_data) { + // If no chrom data, return null. + if (typeof chrom_data === "string" || !chrom_data.data || chrom_data.data.length === 0) { + return null; + } + // Radius scaler. var radius = d3.scale.linear() .domain(this.options.data_bounds) @@ -401,7 +506,7 @@ // Scaler for placing data points across arc. var angle = d3.scale.linear() - .domain([0, data.length]) + .domain([0, chrom_data.data.length]) .range([chrom_arc.startAngle, chrom_arc.endAngle]); // Use line generator to create area. diff -r 1425614da4ea5eb4011f8176eb8afbb4a4dea6a1 -r 3dafc5ce805ffb12086e0697fc607450025bd681 static/scripts/viz/trackster/tracks.js --- a/static/scripts/viz/trackster/tracks.js +++ b/static/scripts/viz/trackster/tracks.js @@ -907,7 +907,7 @@ // Introduction div shown when there are no tracks. this.intro_div = $("<div/>").addClass("intro").appendTo(this.viewport_container).hide(); var add_tracks_button = $("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function () { - visualization.select_datasets(select_datasets_url, add_track_async_url, function(tracks) { + visualization.select_datasets(select_datasets_url, add_track_async_url, { "f-dbkey": view.dbkey }, function(tracks) { _.each(tracks, function(track) { view.add_drawable( object_from_template(track, view, view) ); }); diff -r 1425614da4ea5eb4011f8176eb8afbb4a4dea6a1 -r 3dafc5ce805ffb12086e0697fc607450025bd681 static/scripts/viz/visualization.js --- a/static/scripts/viz/visualization.js +++ b/static/scripts/viz/visualization.js @@ -48,7 +48,7 @@ // them sequentially. $.when.apply($, requests).then(function() { // jQuery always returns an Array for arguments, so need to look at first element - // to determine whether multiple requests were made and consequently how to + // to determine whether multiple requests were made and consequently how to // map arguments to track definitions. var track_defs = (arguments[0] instanceof Array ? $.map(arguments, function(arg) { return arg[0]; }) : @@ -795,8 +795,11 @@ } ], - add_track: function(track) { - this.get('tracks').push(track); + /** + * Add a track or array of tracks to the visualization. + */ + add_tracks: function(tracks) { + this.get('tracks').add(tracks); } }); diff -r 1425614da4ea5eb4011f8176eb8afbb4a4dea6a1 -r 3dafc5ce805ffb12086e0697fc607450025bd681 templates/visualization/circster.mako --- a/templates/visualization/circster.mako +++ b/templates/visualization/circster.mako @@ -37,16 +37,32 @@ } }); - require( [ "viz/visualization", "viz/circster" ], function(visualization, circster ) { + require( [ "viz/visualization", "viz/circster" ], function(visualization_mod, circster ) { $(function() { + // -- Viz set up. -- + var genome = new visualization_mod.Genome(JSON.parse('${ h.to_json_string( genome ) }')) + vis = new visualization_mod.GenomeVisualization(JSON.parse('${ h.to_json_string( viz_config ) }')), + viz_view = new circster.CircsterView({ + el: $('#vis'), + // Gap is difficult to set because it very dependent on chromosome size and organization. + total_gap: 2 * Math.PI * 0.1, + genome: genome, + model: vis, + dataset_arc_height: 25 + }); + + // -- Render viz. -- + + viz_view.render(); + // -- Visualization menu and set up. var menu = create_icon_buttons_menu([ { icon_class: 'plus-button', title: 'Add tracks', on_click: function() { - visualization.select_datasets(select_datasets_url, add_track_async_url, {}, function(tracks) { - console.log(tracks); - }); + visualization_mod.select_datasets(select_datasets_url, add_track_async_url, {}, function(tracks) { + vis.add_tracks(tracks); + }); } }, { icon_class: 'disk--arrow', title: 'Save', on_click: function() { // Show saving dialog box @@ -88,24 +104,6 @@ $("#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' } ); - - // -- Viz set up. -- - - var genome = new visualization.Genome(JSON.parse('${ h.to_json_string( genome ) }')) - vis = new visualization.GenomeVisualization(JSON.parse('${ h.to_json_string( viz_config ) }')), - viz_view = new circster.CircsterView({ - el: $('#vis'), - // Gap is difficult to set because it very dependent on chromosome size and organization. - total_gap: 2 * Math.PI * 0.1, - genome: genome, - model: vis, - dataset_arc_height: 25 - }); - - // -- Render viz. -- - - viz_view.render(); - }); }); </script> https://bitbucket.org/galaxy/galaxy-central/changeset/8fd7bc979e07/ changeset: 8fd7bc979e07 user: jgoecks date: 2012-10-16 17:32:55 summary: When adding datasets to visualization, pass dbky directly rather than in dict. affected #: 4 files diff -r 3dafc5ce805ffb12086e0697fc607450025bd681 -r 8fd7bc979e07c089b0476d11157df5ce5a4bba95 static/scripts/viz/trackster/tracks.js --- a/static/scripts/viz/trackster/tracks.js +++ b/static/scripts/viz/trackster/tracks.js @@ -907,7 +907,7 @@ // Introduction div shown when there are no tracks. this.intro_div = $("<div/>").addClass("intro").appendTo(this.viewport_container).hide(); var add_tracks_button = $("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function () { - visualization.select_datasets(select_datasets_url, add_track_async_url, { "f-dbkey": view.dbkey }, function(tracks) { + visualization.select_datasets(select_datasets_url, add_track_async_url, view.dbkey, function(tracks) { _.each(tracks, function(track) { view.add_drawable( object_from_template(track, view, view) ); }); diff -r 3dafc5ce805ffb12086e0697fc607450025bd681 -r 8fd7bc979e07c089b0476d11157df5ce5a4bba95 static/scripts/viz/trackster_ui.js --- a/static/scripts/viz/trackster_ui.js +++ b/static/scripts/viz/trackster_ui.js @@ -20,7 +20,7 @@ var self = this, menu = create_icon_buttons_menu([ { icon_class: 'plus-button', title: 'Add tracks', on_click: function() { - visualization.select_datasets(select_datasets_url, add_track_async_url, { "f-dbkey": view.dbkey }, function(tracks) { + visualization.select_datasets(select_datasets_url, add_track_async_url, view.dbkey, function(tracks) { _.each(tracks, function(track) { view.add_drawable( object_from_template(track, view, view) ); }); diff -r 3dafc5ce805ffb12086e0697fc607450025bd681 -r 8fd7bc979e07c089b0476d11157df5ce5a4bba95 static/scripts/viz/visualization.js --- a/static/scripts/viz/visualization.js +++ b/static/scripts/viz/visualization.js @@ -15,10 +15,11 @@ * track definitions are obtained from the server and the success_fn is called with the list of * definitions for selected datasets. */ -var select_datasets = function(dataset_url, add_track_async_url, filter_params, success_fn) { +var select_datasets = function(dataset_url, add_track_async_url, dbkey, success_fn) { $.ajax({ url: dataset_url, - data: filter_params, + // Filter by dbkey if available. + data: ( dbkey ? { 'f-dbkey': dbkey } : {} ), error: function() { alert( "Grid failed" ); }, success: function(table_html) { show_modal( diff -r 3dafc5ce805ffb12086e0697fc607450025bd681 -r 8fd7bc979e07c089b0476d11157df5ce5a4bba95 templates/visualization/circster.mako --- a/templates/visualization/circster.mako +++ b/templates/visualization/circster.mako @@ -60,9 +60,10 @@ // -- Visualization menu and set up. var menu = create_icon_buttons_menu([ { icon_class: 'plus-button', title: 'Add tracks', on_click: function() { - visualization_mod.select_datasets(select_datasets_url, add_track_async_url, {}, function(tracks) { - vis.add_tracks(tracks); - }); + visualization_mod.select_datasets(select_datasets_url, add_track_async_url, vis.get('dbkey'), function(tracks) { + vis.add_tracks(tracks); + } + ); } }, { icon_class: 'disk--arrow', title: 'Save', on_click: function() { // Show saving dialog box https://bitbucket.org/galaxy/galaxy-central/changeset/3b292aa60eae/ changeset: 3b292aa60eae user: jgoecks date: 2012-10-16 18:12:52 summary: Merge affected #: 1 file diff -r 8fd7bc979e07c089b0476d11157df5ce5a4bba95 -r 3b292aa60eae153e4c162df30221b9d28bc26017 lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py --- a/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py +++ b/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py @@ -314,11 +314,15 @@ repository_clone_url = self.__generate_clone_url( trans, repository ) repository.deleted = False repository.status = trans.model.ToolShedRepository.installation_status.INSTALLED - trans.sa_session.add( repository ) - trans.sa_session.flush() if repository.includes_tools: metadata = repository.metadata - repository_tools_tups = get_repository_tools_tups( trans.app, metadata ) + try: + repository_tools_tups = get_repository_tools_tups( trans.app, metadata ) + except Exception, e: + error = "Error activating repository %s: %s" % ( repository.name, str( e ) ) + log.debug( error ) + return trans.show_error_message( '%s.<br/>You may be able to resolve this by uninstalling and then reinstalling the repository. Click <a href="%s">here</a> to uninstall the repository.' + % ( error, web.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) ) ) ) # Reload tools into the appropriate tool panel section. tool_panel_dict = repository.metadata[ 'tool_panel_section' ] add_to_tool_panel( trans.app, @@ -330,6 +334,8 @@ shed_tool_conf, tool_panel_dict, new_install=False ) + trans.sa_session.add( repository ) + trans.sa_session.flush() if repository.includes_datatypes: repository_install_dir = os.path.abspath ( relative_install_dir ) # Deactivate proprietary datatypes. @@ -476,7 +482,11 @@ removed = True except Exception, e: log.debug( "Error removing repository installation directory %s: %s" % ( str( repository_install_dir ), str( e ) ) ) - removed = False + if isinstance( e, OSError ) and not os.path.exists( repository_install_dir ): + removed = True + log.debug( "Repository directory does not exist on disk, marking as uninstalled." ) + else: + removed = False if removed: tool_shed_repository.uninstalled = True # Remove all installed tool dependencies. 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.