details: http://www.bx.psu.edu/hg/galaxy/rev/8f57bd9b180c changeset: 2917:8f57bd9b180c user: Kanwei Li <kanwei@gmail.com> date: Fri Oct 23 14:57:08 2009 -0400 description: trackster: fix blocks display, navigation issues, now displays strand direction arrows 7 file(s) affected in this change: lib/galaxy/visualization/tracks/data/interval_index.py static/images/visualization/draggable_horizontal.png static/images/visualization/strand_left.png static/images/visualization/strand_right.png static/scripts/trackster.js static/trackster.css templates/tracks/browser.mako diffs (218 lines): diff -r 02127dd91492 -r 8f57bd9b180c lib/galaxy/visualization/tracks/data/interval_index.py --- a/lib/galaxy/visualization/tracks/data/interval_index.py Fri Oct 23 14:51:22 2009 -0400 +++ b/lib/galaxy/visualization/tracks/data/interval_index.py Fri Oct 23 14:57:08 2009 -0400 @@ -21,19 +21,19 @@ for start, end, offset in index.find(chrom, start, end): source.seek(offset) feature = source.readline().split() - payload = { 'start': start, 'end': end, 'name': feature[3] } + payload = { 'start': start, 'end': end, 'name': feature[3], 'strand': feature[5] } try: block_sizes = [ int(n) for n in feature[10].split(',') if n != ''] block_starts = [ int(n) for n in feature[11].split(',') if n != '' ] blocks = zip(block_sizes, block_starts) - payload['block_start_end'] = [ (chrom_start + block[1], chrom_start + block[1] + block[0]) for block in blocks] - except: + payload['blocks'] = [ (start + block[1], start + block[1] + block[0]) for block in blocks] + except IndexError: pass try: payload['exon_start'] = int(feature[6]) payload['exon_end'] = int(feature[7]) - except: + except IndexError: pass results.append(payload) diff -r 02127dd91492 -r 8f57bd9b180c static/images/visualization/draggable_horizontal.png Binary file static/images/visualization/draggable_horizontal.png has changed diff -r 02127dd91492 -r 8f57bd9b180c static/images/visualization/strand_left.png Binary file static/images/visualization/strand_left.png has changed diff -r 02127dd91492 -r 8f57bd9b180c static/images/visualization/strand_right.png Binary file static/images/visualization/strand_right.png has changed diff -r 02127dd91492 -r 8f57bd9b180c static/scripts/trackster.js --- a/static/scripts/trackster.js Fri Oct 23 14:51:22 2009 -0400 +++ b/static/scripts/trackster.js Fri Oct 23 14:57:08 2009 -0400 @@ -6,7 +6,20 @@ DATA_ERROR = "There was an error in indexing this dataset.", DATA_NONE = "No data for this chrom/contig.", CACHED_TILES = 50, - CACHED_DATA = 20; + CACHED_DATA = 20, + CONTEXT = $("<canvas></canvas>").get(0).getContext("2d"), + RIGHT_STRAND, LEFT_STRAND; + +var right_img = new Image(); +right_img.src = "../images/visualization/strand_right.png"; +right_img.onload = function() { + RIGHT_STRAND = CONTEXT.createPattern(right_img, "repeat"); +} +var left_img = new Image(); +left_img.src = "../images/visualization/strand_left.png"; +left_img.onload = function() { + LEFT_STRAND = CONTEXT.createPattern(left_img, "repeat"); +} function commatize( number ) { number += ''; // Convert to string @@ -101,6 +114,7 @@ var TiledTrack = function() { this.tile_cache = new Cache(CACHED_TILES); + // this.tile_cache = {}; }; $.extend( TiledTrack.prototype, Track.prototype, { draw: function() { @@ -126,20 +140,20 @@ while ( ( tile_index * DENSITY * resolution ) < high ) { // Check in cache var key = this.view.zoom_level + "_" + tile_index; - if ( this.tile_cache[key] ) { + var cached = this.tile_cache.getItem(key); + if ( cached ) { // console.log("cached tile"); - tile_element = this.tile_cache[key]; var tile_low = tile_index * DENSITY * resolution; - tile_element.css( { + cached.css( { left: ( tile_low - this.view.low ) * w_scale }); // Our responsibility to move the element to the new parent - parent_element.append( tile_element ); + parent_element.append( cached ); } else { tile_element = this.draw_tile( resolution, tile_index, parent_element, w_scale, h ); } if ( tile_element ) { - this.tile_cache[key] = tile_element; + this.tile_cache.setItem(key, tile_element); } tile_index += 1; } @@ -340,6 +354,7 @@ if (!this.values) { // Still loading return null; } + // console.log("drawing"); // Once we zoom in enough, show name labels if (w_scale > this.show_labels_scale && !this.showing_labels) { this.showing_labels = true; @@ -373,7 +388,7 @@ ctx.fillStyle = "#000"; ctx.font = "10px monospace"; ctx.textAlign = "right"; - + var j = 0; for (var i = 0, len = this.values.length; i < len; i++) { var feature = this.values[i]; @@ -381,9 +396,19 @@ var f_start = Math.floor( Math.max(0, (feature.start - tile_low) * w_scale) ), f_end = Math.ceil( Math.min(width, (feature.end - tile_low) * w_scale) ), y_center = this.slots[feature.name] * this.vertical_gap; - - // console.log(feature.start, feature.end, f_start, f_end, j); - ctx.fillRect(f_start, y_center + 5, f_end - f_start, 1); + + if (feature.strand && this.showing_labels) { + if (feature.strand == "+") { + ctx.fillStyle = RIGHT_STRAND; + } else if (feature.strand == "-") { + ctx.fillStyle = LEFT_STRAND; + } + ctx.fillRect(f_start, y_center, f_end - f_start, 10); + ctx.fillStyle = "#000"; + } else { + ctx.fillStyle = "#000"; + ctx.fillRect(f_start, y_center + 5, f_end - f_start, 1); + } if (this.showing_labels && ctx.fillText) { ctx.fillText(feature.name, f_start, y_center + 8); @@ -393,18 +418,17 @@ if (feature.exon_start && feature.exon_end) { exon_start = Math.floor( Math.max(0, (feature.exon_start - tile_low) * w_scale) ); exon_end = Math.ceil( Math.min(width, (feature.exon_end - tile_low) * w_scale) ); - ctx.fillRect(exon_start, y_center + 4, exon_end - exon_start, 3); } - if (feature.blocks) { + if (feature.blocks && this.showing_labels) { for (var k = 0, k_len = feature.blocks.length; k < k_len; k++) { var block = feature.blocks[k], block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ), block_end = Math.ceil( Math.min(width, (block[1] - tile_low) * w_scale) ); - var thickness = 3, y_start = 4; + var thickness = 5, y_start = 3; if (exon_start && block_start >= exon_start && block_end <= exon_end) { - thickness = 5; - y_start = 3; + thickness = 7; + y_start = 2; } ctx.fillRect(block_start, y_center + y_start, block_end - block_start, thickness); // console.log(block_start, block_end); diff -r 02127dd91492 -r 8f57bd9b180c static/trackster.css --- a/static/trackster.css Fri Oct 23 14:51:22 2009 -0400 +++ b/static/trackster.css Fri Oct 23 14:57:08 2009 -0400 @@ -63,7 +63,7 @@ position: absolute; margin-top: 1px; height: 16px; - background: #ddd url(images/draggable_horizontal.png) center center no-repeat; + background: #ddd url(images/visualization/draggable_horizontal.png) center center no-repeat; border-style: outset; border-width: 1px; } @@ -79,7 +79,6 @@ width: 100%; height: 100px; } - .track { /* border-top: solid gray 1px;*/ border-bottom: solid gray 1px; diff -r 02127dd91492 -r 8f57bd9b180c templates/tracks/browser.mako --- a/templates/tracks/browser.mako Fri Oct 23 14:51:22 2009 -0400 +++ b/templates/tracks/browser.mako Fri Oct 23 14:57:08 2009 -0400 @@ -16,7 +16,7 @@ $(function() { - view.add_track( new LabelTrack( $("#viewport" ) ) ); + view.add_track( new LabelTrack( $("#top-labeltrack" ) ) ); view.add_track( new LabelTrack( $("#nav-labeltrack" ) ) ); %for track in tracks: @@ -51,11 +51,6 @@ var delta_chrom = Math.round(delta / $(document).width() * view.span); view.center += delta_chrom; - if (view.center < 0) { - view.center = 0; - } else if (view.center > view.max_high) { - view.center = view.max_high; - } view.redraw(); }); @@ -79,8 +74,8 @@ this.current_height = e.clientY; this.current_x = e.offsetX; - var delta_chrom = Math.round(delta / $(document).width() * (view.max_high - view.max_low)); - view.center += delta_chrom; + var delta_chrom = Math.round(delta / $(document).width() * (view.high - view.low)); + view.center -= delta_chrom; view.redraw(); }); (function () { @@ -108,6 +103,7 @@ </%def> <div id="content"> + <div id="top-labeltrack"></div> <div id="viewport"></div> </div> <div id="nav">