mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
trackster: Implemented drag-zooming by letting you drag a region in the top label track (where chrom position is shown). Refactored to not use zoom levels anymore.
This commit is contained in:
@@ -454,6 +454,15 @@ function init_history_items(historywrapper, noinit, nochanges) {
|
||||
}
|
||||
}
|
||||
|
||||
function commatize( number ) {
|
||||
number += ''; // Convert to string
|
||||
var rgx = /(\d+)(\d{3})/;
|
||||
while (rgx.test(number)) {
|
||||
number = number.replace(rgx, '$1' + ',' + '$2');
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
$(document).ready( function() {
|
||||
// Links with confirmation
|
||||
$( "a[confirm]" ).click( function() {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+30
-42
@@ -1,7 +1,6 @@
|
||||
/* Trackster
|
||||
2010, James Taylor, Kanwei Li
|
||||
*/
|
||||
var DEBUG = false;
|
||||
|
||||
var DENSITY = 200,
|
||||
FEATURE_LEVELS = 10,
|
||||
@@ -37,15 +36,6 @@ left_img_inv.onload = function() {
|
||||
LEFT_STRAND_INV = CONTEXT.createPattern(left_img_inv, "repeat");
|
||||
};
|
||||
|
||||
function commatize( number ) {
|
||||
number += ''; // Convert to string
|
||||
var rgx = /(\d+)(\d{3})/;
|
||||
while (rgx.test(number)) {
|
||||
number = number.replace(rgx, '$1' + ',' + '$2');
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
var Cache = function( num_elements ) {
|
||||
this.num_elements = num_elements;
|
||||
this.clear();
|
||||
@@ -87,11 +77,11 @@ var View = function( chrom, title, vis_id, dbkey ) {
|
||||
this.label_tracks = [];
|
||||
this.max_low = 0;
|
||||
this.max_high = 0;
|
||||
this.center = (this.max_high - this.max_low) / 2;
|
||||
this.zoom_factor = 3;
|
||||
this.zoom_level = 0;
|
||||
this.track_id_counter = 0;
|
||||
this.zoom_factor = 3;
|
||||
this.min_separation = 30;
|
||||
this.has_changes = false;
|
||||
this.reset();
|
||||
};
|
||||
$.extend( View.prototype, {
|
||||
add_track: function ( track ) {
|
||||
@@ -129,27 +119,24 @@ $.extend( View.prototype, {
|
||||
reset: function() {
|
||||
this.low = this.max_low;
|
||||
this.high = this.max_high;
|
||||
this.center = this.center = (this.max_high - this.max_low) / 2;
|
||||
this.zoom_level = 0;
|
||||
$(".yaxislabel").remove();
|
||||
},
|
||||
redraw: function(nodraw) {
|
||||
this.span = this.max_high - this.max_low;
|
||||
var span = this.span / Math.pow(this.zoom_factor, this.zoom_level),
|
||||
low = this.center - (span / 2),
|
||||
high = low + span;
|
||||
var span = this.high - this.low,
|
||||
low = this.low,
|
||||
high = this.high;
|
||||
|
||||
if (low < 0) {
|
||||
low = 0;
|
||||
high = low + span;
|
||||
|
||||
} else if (high > this.max_high) {
|
||||
if (low < this.max_low) {
|
||||
low = this.max_low;
|
||||
}
|
||||
if (high > this.max_high) {
|
||||
high = this.max_high;
|
||||
low = high - span;
|
||||
}
|
||||
if (span < this.min_separation) {
|
||||
high = low + this.min_separation;
|
||||
}
|
||||
this.low = Math.floor(low);
|
||||
this.high = Math.ceil(high);
|
||||
this.center = Math.round( this.low + (this.high - this.low) / 2 );
|
||||
|
||||
// 10^log10(range / DENSITY) Close approximation for browser window, assuming DENSITY = window width
|
||||
this.resolution = Math.pow( 10, Math.ceil( Math.log( (this.high - this.low) / 200 ) / Math.LN10 ) );
|
||||
@@ -157,9 +144,9 @@ $.extend( View.prototype, {
|
||||
|
||||
// Overview
|
||||
$("#overview-box").css( {
|
||||
left: ( this.low / this.span ) * $("#overview-viewport").width(),
|
||||
left: ( this.low / (this.max_high - this.max_low) ) * $("#overview-viewport").width(),
|
||||
// Minimum width for usability
|
||||
width: Math.max( 12, ( ( this.high - this.low ) / this.span ) * $("#overview-viewport").width() )
|
||||
width: Math.max( 12, (this.high - this.low)/(this.max_high - this.max_low) * $("#overview-viewport").width() )
|
||||
}).show();
|
||||
$("#low").val( commatize(this.low) );
|
||||
$("#high").val( commatize(this.high) );
|
||||
@@ -174,26 +161,29 @@ $.extend( View.prototype, {
|
||||
}
|
||||
}
|
||||
},
|
||||
zoom_in: function ( point, container ) {
|
||||
if (this.max_high === 0 || this.high - this.low < 30) {
|
||||
zoom_in: function (point, container) {
|
||||
if (this.max_high === 0 || this.high - this.low < this.min_separation) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( point ) {
|
||||
this.center = point / container.width() * (this.high - this.low) + this.low;
|
||||
var span = this.high - this.low,
|
||||
cur_center = span / 2 + this.low,
|
||||
new_half = (span / this.zoom_factor) / 2;
|
||||
if (point) {
|
||||
cur_center = point / container.width() * (this.high - this.low) + this.low;
|
||||
}
|
||||
this.zoom_level += 1;
|
||||
this.low = Math.round(cur_center - new_half);
|
||||
this.high = Math.round(cur_center + new_half);
|
||||
this.redraw();
|
||||
},
|
||||
zoom_out: function () {
|
||||
if (this.max_high === 0) {
|
||||
return;
|
||||
}
|
||||
if (this.zoom_level <= 0) {
|
||||
this.zoom_level = 0;
|
||||
return;
|
||||
}
|
||||
this.zoom_level -= 1;
|
||||
var span = this.high - this.low,
|
||||
cur_center = span / 2 + this.low,
|
||||
new_half = (span * this.zoom_factor) / 2;
|
||||
this.low = Math.round(cur_center - new_half);
|
||||
this.high = Math.round(cur_center + new_half);
|
||||
this.redraw();
|
||||
}
|
||||
});
|
||||
@@ -269,8 +259,6 @@ $.extend( TiledTrack.prototype, Track.prototype, {
|
||||
high = this.view.high,
|
||||
range = high - low,
|
||||
resolution = this.view.resolution;
|
||||
|
||||
if (DEBUG) { $("#debug").text(resolution + " " + this.view.zoom_res); }
|
||||
|
||||
var parent_element = $("<div style='position: relative;'></div>"),
|
||||
w_scale = this.content_div.width() / range,
|
||||
@@ -283,7 +271,7 @@ $.extend( TiledTrack.prototype, Track.prototype, {
|
||||
var tile_index = Math.floor( low / resolution / DENSITY );
|
||||
while ( ( tile_index * DENSITY * resolution ) < high ) {
|
||||
// Check in cache
|
||||
var key = this.content_div.width() + '_' + this.view.zoom_level + '_' + tile_index;
|
||||
var key = this.content_div.width() + '_' + w_scale + '_' + tile_index;
|
||||
var cached = this.tile_cache.get(key);
|
||||
if ( cached ) {
|
||||
// console.log("cached tile " + tile_index);
|
||||
|
||||
@@ -111,7 +111,6 @@
|
||||
.label-track {
|
||||
/* font-weight: bold; */
|
||||
/* font-size: 10px; */
|
||||
|
||||
}
|
||||
.label-track .label {
|
||||
border-left: solid #999 1px;
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="document">
|
||||
<div class="warningmessagelarge">
|
||||
<div class="donemessagelarge">
|
||||
<strong>Hello world! It's running...</strong>
|
||||
<hr>
|
||||
To customize this page edit <code>static/welcome.html</code>
|
||||
|
||||
@@ -32,11 +32,11 @@ ${h.css( "history", "autocomplete_tagging" )}
|
||||
<div class="unified-panel-header" unselectable="on">
|
||||
<div class="unified-panel-header-inner">Trackster Visualization | ${config['title']}
|
||||
<a id="save-button" class="panel-header-button right-float" href="javascript:void(0);">Save</a>
|
||||
<a id="refresh-button" class="panel-header-button right-float" href="javascript:void(0);">Refresh</a>
|
||||
<a id="refresh-button" class="panel-header-button right-float" href="javascript:void(0);" onclick="view.update_options();return false;">Refresh</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="top-labeltrack"></div>
|
||||
<div id="top-labeltrack" style="position: relative;"></div>
|
||||
<div id="viewport-container" style="overflow-x: hidden; overflow-y: auto;">
|
||||
<div id="viewport"></div>
|
||||
</div>
|
||||
@@ -63,7 +63,6 @@ ${h.css( "history", "autocomplete_tagging" )}
|
||||
<img src="${h.url_for('/static/images/fugue/magnifier-zoom-out.png')}" />
|
||||
</a>
|
||||
</form>
|
||||
<div id="debug" style="float: right"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -146,6 +145,9 @@ ${h.js( 'galaxy.base', 'galaxy.panels', "json2", "jquery", "jquery.event.drag",
|
||||
});
|
||||
|
||||
$("#content").bind("mousewheel", function( e, delta ) {
|
||||
if (Math.abs(delta) < 0.5) {
|
||||
return;
|
||||
}
|
||||
if (delta > 0) {
|
||||
view.zoom_in(e.pageX, $("#viewport-container"));
|
||||
} else {
|
||||
@@ -166,19 +168,19 @@ ${h.js( 'galaxy.base', 'galaxy.panels', "json2", "jquery", "jquery.event.drag",
|
||||
this.current_x = e.offsetX;
|
||||
|
||||
var delta_chrom = Math.round(delta / $(document).width() * view.span);
|
||||
view.center += delta_chrom;
|
||||
view.high += delta_chrom;
|
||||
view.low += delta_chrom;
|
||||
view.redraw();
|
||||
});
|
||||
|
||||
// To adjust the size of the viewport to fit the fixed-height footer
|
||||
var refresh = function( e ) {
|
||||
$("#viewport-container").height( $(window).height() - 120 );
|
||||
$("#viewport-container").height( $(window).height() - 100 );
|
||||
$("#nav-container").width( $("#center").width() );
|
||||
view.redraw();
|
||||
};
|
||||
$(window).bind( "resize", function(e) { refresh(e); } );
|
||||
$("#right-border").bind( "click", function(e) { refresh(e); } );
|
||||
$("#right-border").bind( "dragend", function(e) { refresh(e); } );
|
||||
$("#right-border").bind( "click dragend", function(e) { refresh(e); } );
|
||||
$(window).trigger( "resize" );
|
||||
|
||||
$("#viewport-container").bind( "dragstart", function( e ) {
|
||||
@@ -195,8 +197,9 @@ ${h.js( 'galaxy.base', 'galaxy.panels', "json2", "jquery", "jquery.event.drag",
|
||||
this.current_height = e.clientY;
|
||||
this.current_x = e.offsetX;
|
||||
|
||||
var delta_chrom = Math.round(delta / $(document).width() * (view.high - view.low));
|
||||
view.center -= delta_chrom;
|
||||
var delta_chrom = Math.round(delta / $("#viewport-container").width() * (view.high - view.low));
|
||||
view.high -= delta_chrom;
|
||||
view.low -= delta_chrom;
|
||||
view.redraw();
|
||||
});
|
||||
|
||||
@@ -286,6 +289,35 @@ ${h.js( 'galaxy.base', 'galaxy.panels', "json2", "jquery", "jquery.event.drag",
|
||||
view.add_label_track( new LabelTrack( $("#top-labeltrack") ) );
|
||||
view.add_label_track( new LabelTrack( $("#nav-labeltrack") ) );
|
||||
|
||||
$("#top-labeltrack").bind( "dragstart", function(e) {
|
||||
this.drag_origin_x = e.clientX;
|
||||
this.drag_origin_pos = e.clientX / $("#viewport-container").width() * (view.high - view.low) + view.low;
|
||||
this.drag_div = $("<div />").css( {
|
||||
"height": $("#viewport-container").height(), "top": "0px", "position": "absolute",
|
||||
"background-color": "#cfc", "border": "1px solid #6a6", "opacity": 0.5
|
||||
} ).appendTo( $(this) );
|
||||
}).bind( "drag", function(e) {
|
||||
var min = Math.min(e.clientX, this.drag_origin_x),
|
||||
max = Math.max(e.clientX, this.drag_origin_x),
|
||||
span = (view.high - view.low),
|
||||
width = $("#viewport-container").width();
|
||||
|
||||
$("#low").val(commatize(Math.round(min / width * span) + view.low));
|
||||
$("#high").val(commatize(Math.round(max / width * span) + view.low));
|
||||
this.drag_div.css( { "left": min + "px", "width": (max - min) + "px" } );
|
||||
}).bind( "dragend", function(e) {
|
||||
var min = Math.min(e.clientX, this.drag_origin_x),
|
||||
max = Math.max(e.clientX, this.drag_origin_x),
|
||||
span = (view.high - view.low),
|
||||
width = $("#viewport-container").width(),
|
||||
old_low = view.low;
|
||||
|
||||
view.low = Math.round(min / width * span) + old_low;
|
||||
view.high = Math.round(max / width * span) + old_low;
|
||||
this.drag_div.remove();
|
||||
view.redraw();
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: "${h.url_for( action='chroms' )}",
|
||||
%if config.get('vis_id'):
|
||||
|
||||
Reference in New Issue
Block a user