commit/galaxy-central: jgoecks: Circster: support data indexing and loading for datasets not previously indexed. Also add visual indicator when drawing/loading tracks.
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/1b031693bd34/ changeset: 1b031693bd34 user: jgoecks date: 2012-10-11 16:31:13 summary: Circster: support data indexing and loading for datasets not previously indexed. Also add visual indicator when drawing/loading tracks. affected #: 5 files diff -r 60757a1ab16476d3fc19b21bc1fb9bd42f567cf3 -r 1b031693bd3470172c90533726e4ad6dd7d54e5f lib/galaxy/visualization/data_providers/genome.py --- a/lib/galaxy/visualization/data_providers/genome.py +++ b/lib/galaxy/visualization/data_providers/genome.py @@ -184,9 +184,15 @@ chrom = chrom_info[ 'chrom' ] chrom_len = chrom_info[ 'len' ] chrom_data = self.get_data( chrom, 0, chrom_len, **kwargs ) - if chrom_data: - chrom_data[ 'region' ] = "%s:%i-%i" % ( chrom, 0, chrom_len ) - genome_data.append( chrom_data ) + # FIXME: data providers probably should never return None. + # Some data providers return None when there's no data, so + # create a dummy dict if necessary. + if not chrom_data: + chrom_data = { + 'data': None + } + chrom_data[ 'region' ] = "%s:%i-%i" % ( chrom, 0, chrom_len ) + genome_data.append( chrom_data ) return { 'data': genome_data, diff -r 60757a1ab16476d3fc19b21bc1fb9bd42f567cf3 -r 1b031693bd3470172c90533726e4ad6dd7d54e5f lib/galaxy/webapps/galaxy/api/datasets.py --- a/lib/galaxy/webapps/galaxy/api/datasets.py +++ b/lib/galaxy/webapps/galaxy/api/datasets.py @@ -52,7 +52,7 @@ elif data_type == 'track_config': rval = self.get_new_track_config( trans, dataset ) elif data_type == 'genome_data': - rval = self._get_genome_data( self, trans, dataset, kwd.get('dbkey', None) ) + rval = self._get_genome_data( trans, dataset, kwd.get('dbkey', None) ) else: # Default: return dataset as API value. rval = dataset.get_api_value() @@ -89,12 +89,13 @@ if msg: return msg - # Check for data in the genome window. - data_provider_registry = trans.app.data_provider_registry - data_provider = trans.app.data_provider_registry.get_data_provider( trans, original_dataset= dataset, source='index' ) - if not data_provider.has_data( chrom ): - return messages.NO_DATA - + # If there is a chrom, check for data on the chrom. + if chrom: + data_provider_registry = trans.app.data_provider_registry + data_provider = trans.app.data_provider_registry.get_data_provider( trans, original_dataset= dataset, source='index' ) + if not data_provider.has_data( chrom ): + return messages.NO_DATA + # Have data if we get here return { "status": messages.DATA, "valid_chroms": None } diff -r 60757a1ab16476d3fc19b21bc1fb9bd42f567cf3 -r 1b031693bd3470172c90533726e4ad6dd7d54e5f static/scripts/viz/circster.js --- a/static/scripts/viz/circster.js +++ b/static/scripts/viz/circster.js @@ -143,9 +143,12 @@ initialize: function(options) { this.options = options; this.options.bg_stroke = 'ccc'; + // Fill color when loading data. + this.options.loading_bg_fill = '000'; + // Fill color when data has been loaded. this.options.bg_fill = 'ccc'; this.options.chroms_layout = this._chroms_layout(); - this.options.data_bounds = this.get_data_bounds(this.options.track.get_genome_wide_data(this.options.genome)); + this.options.data_bounds = []; this.options.scale = 1; this.options.parent_elt = null; }, @@ -154,34 +157,49 @@ * Render track's data by adding SVG elements to parent. */ render: function(parent) { - // Create track group element. + // -- Create track group element. -- this.options.parent_elt = parent.append("g").attr("id", "parent-" + this.options.track_index); var track_parent_elt = this.options.parent_elt; - // Render background arcs. + // -- Render background arcs. -- var genome_arcs = this.options.chroms_layout, arc_gen = d3.svg.arc() .innerRadius(this.options.radius_bounds[0]) .outerRadius(this.options.radius_bounds[1]), + // Attach data to group element. chroms_elts = track_parent_elt.selectAll('g') - .data(genome_arcs).enter().append('svg:g'); + .data(genome_arcs).enter().append('svg:g'), - // Draw arcs. - chroms_elts.append("path") - .attr("d", arc_gen) - .style("stroke", this.options.bg_stroke) - .style("fill", this.options.bg_fill) - .append("title").text(function(d) { return d.data.chrom; }); + // Draw chrom arcs/paths. + chroms_paths = chroms_elts.append("path") + .attr("d", arc_gen) + .style("stroke", this.options.bg_stroke) + .style("fill", this.options.loading_bg_fill); + + // Append titles to paths. + chroms_paths.append("title").text(function(d) { return d.data.chrom; }); - // Render track data. - this._render_data(track_parent_elt); + // -- Render track data and, when track data is rendered, apply preferences and update chrom_elts fill. -- - // Apply prefs. - var prefs = this.options.track.get('prefs'), - block_color = prefs.block_color; - if (!block_color) { block_color = prefs.color; } - track_parent_elt.selectAll('path.chrom-data').style('stroke', block_color).style('fill', block_color); + var self = this, + data_manager = self.options.track.get('data_manager'), + // If track has a data manager, get deferred that resolves when data is ready. + data_ready_deferred = (data_manager ? data_manager.data_is_ready() : true ); + + // When data is ready, render track. + $.when(data_ready_deferred).then(function() { + $.when(self._render_data(track_parent_elt)).then(function() { + // Apply prefs to all track data. + // TODO: move to _render_data? + var prefs = self.options.track.get('prefs'), + block_color = prefs.block_color; + if (!block_color) { block_color = prefs.color; } + track_parent_elt.selectAll('path.chrom-data').style('stroke', block_color).style('fill', block_color); + + chroms_paths.style("fill", self.options.bg_fill); + }); + }); }, /** @@ -243,7 +261,7 @@ * Update data bounds. */ _update_data_bounds: function() { - this.options.data_bounds = this.get_data_bounds(this.options.track.get_genome_wide_data(this.options.genome)); + //this.options.data_bounds = this.get_data_bounds(this.options.track.get_genome_wide_data(this.options.genome)); // TODO: transition all paths to use the new data bounds. }, @@ -255,8 +273,13 @@ var self = this, chrom_arcs = this.options.chroms_layout, track = this.options.track, - genome_wide_data = track.get_genome_wide_data(this.options.genome), - + rendered_deferred = $.Deferred(); + + // When genome-wide data is available, render data. + $.when(track.get('data_manager').get_genome_wide_data(this.options.genome)).then(function(genome_wide_data) { + // Set bounds. + self.options.data_bounds = self.get_data_bounds(genome_wide_data); + // Merge chroms layout with data. layout_and_data = _.zip(chrom_arcs, genome_wide_data), @@ -267,7 +290,10 @@ return self._render_chrom_data(svg, chrom_arc, data); }); - return svg; + rendered_deferred.resolve(svg); + }); + + return rendered_deferred; }, /** @@ -348,7 +374,7 @@ */ _render_chrom_data: function(svg, chrom_arc, chrom_data) { // If no chrom data, return null. - if (!chrom_data || typeof chrom_data === "string" || chrom_data.data.length === 0) { + if (typeof chrom_data === "string" || !chrom_data.data || chrom_data.data.length === 0) { return null; } @@ -407,7 +433,7 @@ get_data_bounds: function(data) { // Get max across data. var max_data = _.map(data, function(d) { - if (!d || typeof d === 'string') { return 0; } + if (typeof d === 'string' || !d.max) { return 0; } return d.max; }); return [ 0, (max_data && typeof max_data !== 'string' ? _.max(max_data) : 0) ]; diff -r 60757a1ab16476d3fc19b21bc1fb9bd42f567cf3 -r 1b031693bd3470172c90533726e4ad6dd7d54e5f static/scripts/viz/sweepster.js --- a/static/scripts/viz/sweepster.js +++ b/static/scripts/viz/sweepster.js @@ -928,7 +928,7 @@ }, output.first().get('track_config')), track_obj = tracks.object_from_template(track_config, self, null); - // Track uses only raw data. + // Track uses raw data. track_obj.data_manager.set('data_type', 'raw_data'); // Set track block colors. diff -r 60757a1ab16476d3fc19b21bc1fb9bd42f567cf3 -r 1b031693bd3470172c90533726e4ad6dd7d54e5f static/scripts/viz/visualization.js --- a/static/scripts/viz/visualization.js +++ b/static/scripts/viz/visualization.js @@ -136,6 +136,7 @@ var GenomeDataManager = Cache.extend({ defaults: _.extend({}, Cache.prototype.defaults, { dataset: null, + init_data: null, filters_manager: null, data_type: "data", data_mode_compatible: function(entry, mode) { return true; }, @@ -143,18 +144,52 @@ }), /** + * Initialization. + */ + initialize: function(options) { + Cache.prototype.initialize.call(this); + + // Set initial entries in data manager. + var initial_entries = this.get('init_data'); + if (initial_entries) { + this.add_data(initial_entries); + } + }, + + /** + * Add data entries to manager; each entry should be a dict with attributes region (key), data, and data_type. + * If necessary, manager size is increased to hold all data. + */ + add_data: function(entries) { + // Increase size to accomodate all entries. + if (this.get('num_elements') < entries.length) { + this.set('num_elements', entries.length); + } + + // Put data into manager. + var self = this; + _.each(entries, function(entry) { + self.set_data(entry.region, entry); + }); + }, + + /** * Returns deferred that resolves to true when dataset is ready (or false if dataset * cannot be used). */ data_is_ready: function() { var dataset = this.get('dataset'), ready_deferred = $.Deferred(), + // If requesting raw data, query dataset state; if requesting (converted) data, + // need to query converted datasets state. + query_type = (this.get('data_type') == 'raw_data' ? 'state' : + this.get('data_type') == 'data' ? 'converted_datasets_state' : "error" ), ss_deferred = new util_mod.ServerStateDeferred({ ajax_settings: { url: this.get('dataset').url(), data: { hda_ldda: dataset.get('hda_ldda'), - data_type: 'state' + data_type: query_type }, dataType: "json" }, @@ -312,8 +347,7 @@ // Get additional data, append to current data, and set new data. Use a custom deferred object // to signal when new data is available. // - var - data_manager = this, + var data_manager = this, new_data_request = this.load_data(query_region, mode, resolution, extra_params), new_data_available = $.Deferred(); // load_data sets cache to new_data_request, but use custom deferred object so that signal and data @@ -372,6 +406,49 @@ entry.stale = true; return entry; }, + + /** + * Returns an array of data with each entry representing one chromosome/contig + * of data or, if data is not available, returns a Deferred that resolves to the + * data when it becomes available. + */ + get_genome_wide_data: function(genome) { + // -- Get all data. -- + + var self = this, + all_data_available = true, + + // Map chromosome info into genome data. + gw_data = _.map(genome.get('chroms_info').chrom_info, function(chrom_info) { + var chrom_data = self.get_elt( + new GenomeRegion({ + chrom: chrom_info.chrom, + start: 0, + end: chrom_info.len + }) + ); + + // Set flag if data is not available. + if (!chrom_data) { all_data_available = false; } + + return chrom_data; + }); + + // -- If all data is available, return it. -- + if (all_data_available) { + return gw_data; + } + + // -- All data is not available, so load from server. -- + + var deferred = $.Deferred(); + $.getJSON(this.get('dataset').url(), { data_type: 'genome_data' }, function(genome_wide_data) { + self.add_data(genome_wide_data.data); + deferred.resolve(genome_wide_data.data); + }); + + return deferred; + }, /** * Get data from the cache. @@ -397,7 +474,6 @@ }, load_data: function(region, mode, resolution, extra_params) { - console.log(region, mode, resolution); if (resolution > 1) { // Now that data is pre-fetched before draw, we don't load reference tracks // unless it's at the bottom level. @@ -598,41 +674,17 @@ this.set('id', options.dataset_id); // Set up data manager. - var data_manager = new GenomeDataManager({ - dataset: this - }); - this.set('data_manager', data_manager); - - // If there's preloaded data, add it to data manager. var preloaded_data = this.get('preloaded_data'); if (preloaded_data) { - // Increase size to accomodate all preloaded data. - data_manager.set('num_elements', preloaded_data.data.length); - - // Put data into manager. - _.each(preloaded_data.data, function(entry) { - data_manager.set_data(entry.region, entry); - }); + preloaded_data = preloaded_data.data } - }, - - /** - * Returns an array of data with each entry representing one chromosome/contig - * of data. - */ - get_genome_wide_data: function(genome) { - var data_manager = this.get('data_manager'); - - // Map chromosome data into track data. - return _.map(genome.get('chroms_info').chrom_info, function(chrom_info) { - return data_manager.get_elt( - new GenomeRegion({ - chrom: chrom_info.chrom, - start: 0, - end: chrom_info.len - }) - ); - }); + else { + preloaded_data = []; + } + this.set('data_manager', new GenomeDataManager({ + dataset: this, + init_data: preloaded_data + })); } }); 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.
participants (1)
-
Bitbucket