[galaxy-dev] [hg] galaxy 3349: trackster:
Greg Von Kuster
greg at bx.psu.edu
Tue Feb 9 11:29:17 EST 2010
details: http://www.bx.psu.edu/hg/galaxy/rev/432a32ba55bb
changeset: 3349:432a32ba55bb
user: Kanwei Li <kanwei at gmail.com>
date: Fri Feb 05 19:08:37 2010 -0500
description:
trackster:
- New interface for new track browsers
- Saving shows progress bar
- Can now add tracks async
- Switching dbkeys is now async
diffstat:
lib/galaxy/web/controllers/tracks.py | 128 ++++------
lib/galaxy/web/controllers/visualization.py | 2 +-
static/scripts/trackster.js | 61 +++-
static/trackster.css | 1 +
templates/grid_base.mako | 4 +
templates/tracks/add_tracks.mako | 3 +-
templates/tracks/browser.mako | 344 ++++++++++++++++-----------
templates/tracks/index.mako | 52 +++-
templates/tracks/new_browser.mako | 81 +-----
9 files changed, 359 insertions(+), 317 deletions(-)
diffs (955 lines):
diff -r 99483ae6c738 -r 432a32ba55bb lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py Fri Feb 05 16:34:30 2010 -0500
+++ b/lib/galaxy/web/controllers/tracks.py Fri Feb 05 19:08:37 2010 -0500
@@ -57,10 +57,7 @@
use_paging = False
columns = [
grids.TextColumn( "Name", key="name", model_class=model.HistoryDatasetAssociation ),
- # grids.IndividualTagsColumn( "Tags", "tags", model.History, model.HistoryTagAssociation, filterable="advanced"),
grids.GridColumn( "Filetype", key="extension" ),
- # Columns that are valid for filtering but are not visible.
- # SharingColumn( "Shared", key="shared", visible=False, filterable="advanced" )
]
def apply_default_filter( self, trans, query, **kwargs ):
if self.available_tracks is None:
@@ -80,62 +77,40 @@
@web.expose
def index( self, trans ):
- return trans.fill_template( "tracks/index.mako" )
-
+ config = {}
+
+ return trans.fill_template( "tracks/browser.mako", config=config )
+
@web.expose
@web.require_login()
- def new_browser( self, trans, dbkey=None, dataset_ids=None, browse=None, title=None ):
- """
- Build a new browser from datasets in the current history. Redirects
- to 'browser' once datasets to browse have been selected.
- """
- session = trans.sa_session
- # If the user clicked the submit button explicitly, try to build the browser
- if title and browse and dataset_ids:
- if not isinstance( dataset_ids, list ):
- dataset_ids = [ dataset_ids ]
- # Build config
- tracks = []
- for dataset_id in dataset_ids:
- tracks.append( { "dataset_id": str( dataset_id ) } )
- config = { "tracks": tracks }
- # Build visualization object
- vis = model.Visualization()
- vis.user = trans.user
- vis.title = title
- vis.type = "trackster"
- vis_rev = model.VisualizationRevision()
- vis_rev.visualization = vis
- vis_rev.title = title
- vis_rev.config = config
- vis.latest_revision = vis_rev
- session.add( vis )
- session.add( vis_rev )
- session.flush()
- trans.response.send_redirect( web.url_for( controller='tracks', action='browser', id=trans.security.encode_id( vis.id ) ) )
+ def new_browser( self, trans ):
+ dbkeys = [ d.metadata.dbkey for d in trans.get_history().datasets if not d.deleted ]
+ dbkey_set = set( dbkeys )
+ if not dbkey_set:
+ return trans.show_error_message( "Current history has no valid datasets to visualize." )
else:
- # Determine the set of all dbkeys that are used in the current history
- dbkeys = [ d.metadata.dbkey for d in trans.get_history().datasets if not d.deleted ]
- dbkey_set = set( dbkeys )
- if not dbkey_set:
- return trans.show_error_message( "Current history has no valid datasets to visualize." )
-
- # If a dbkey argument was not provided, or is no longer valid, default
- # to the first one
- if dbkey is None or dbkey not in dbkey_set:
- dbkey = dbkeys[0]
- # Find all datasets in the current history that are of that dbkey
- # and can be displayed
- datasets = {}
- if self.available_tracks is None:
- self.available_tracks = trans.app.datatypes_registry.get_available_tracks()
- for dataset in session.query( model.HistoryDatasetAssociation ).filter_by( deleted=False, history_id=trans.history.id ):
- if dataset.metadata.dbkey == dbkey and dataset.extension in self.available_tracks:
- datasets[dataset.id] = (dataset.extension, dataset.name)
- # Render the template
- return trans.fill_template( "tracks/new_browser.mako", available_tracks=self.available_tracks, dbkey=dbkey, dbkey_set=dbkey_set, datasets=datasets )
-
+ return trans.fill_template( "tracks/new_browser.mako", dbkey_set=dbkey_set )
+
+ @web.json
+ @web.require_login()
+ def add_track_async(self, trans, id):
+ dataset_id = trans.security.decode_id( id )
+
+ hda_query = trans.sa_session.query( model.HistoryDatasetAssociation )
+ dataset = hda_query.get( dataset_id )
+ track_type, indexer = dataset.datatype.get_track_type()
+
+ track = {
+ "track_type": track_type,
+ "indexer": indexer,
+ "name": dataset.name,
+ "dataset_id": dataset.id,
+ "prefs": {},
+ }
+ return track
+
@web.expose
+ @web.require_login()
def browser(self, trans, id, chrom=""):
"""
Display browser for the datasets listed in `dataset_ids`.
@@ -143,8 +118,10 @@
decoded_id = trans.security.decode_id( id )
session = trans.sa_session
vis = session.query( model.Visualization ).get( decoded_id )
+ latest_revision = vis.latest_revision
tracks = []
- dbkey = ""
+
+ dbkey = latest_revision.config['dbkey']
hda_query = session.query( model.HistoryDatasetAssociation )
for t in vis.latest_revision.config['tracks']:
dataset_id = t['dataset_id']
@@ -161,18 +138,10 @@
"dataset_id": dataset.id,
"prefs": simplejson.dumps(prefs),
} )
- dbkey = dataset.dbkey
- chrom_lengths = self._chroms( trans, dbkey )
- if chrom_lengths is None:
- error( "No chromosome lengths file found for '%s'" % dataset.name )
- return trans.fill_template( 'tracks/browser.mako',
- #dataset_ids=dataset_ids,
- title = vis.title,
- id=id,
- tracks=tracks,
- chrom=chrom,
- dbkey=dbkey,
- LEN=chrom_lengths.get(chrom, 0) )
+ if dbkey is None: dbkey = dataset.dbkey # Hack for backward compat
+
+ config = { "title": vis.title, "vis_id": id, "tracks": tracks, "chrom": chrom, "dbkey": dbkey }
+ return trans.fill_template( 'tracks/browser.mako', config=config )
@web.json
def chroms(self, trans, dbkey=None ):
@@ -288,9 +257,19 @@
@web.json
def save( self, trans, **kwargs ):
- decoded_id = trans.security.decode_id( kwargs['id'] )
session = trans.sa_session
- vis = session.query( model.Visualization ).get( decoded_id )
+ vis_id = kwargs['vis_id'].strip('"')
+ dbkey = kwargs['dbkey']
+
+ if vis_id == "undefined": # new vis
+ vis = model.Visualization()
+ vis.user = trans.user
+ vis.title = kwargs['vis_title']
+ vis.type = "trackster"
+ session.add( vis )
+ else:
+ decoded_id = trans.security.decode_id( vis_id )
+ vis = session.query( model.Visualization ).get( decoded_id )
decoded_payload = simplejson.loads( kwargs['payload'] )
vis_rev = model.VisualizationRevision()
@@ -304,10 +283,11 @@
"track_type": track['track_type'],
"prefs": track['prefs']
} )
- vis_rev.config = { "tracks": tracks }
+ vis_rev.config = { "dbkey": dbkey, "tracks": tracks }
vis.latest_revision = vis_rev
session.add( vis_rev )
session.flush()
+ return trans.security.encode_id(vis.id)
data_grid = DatasetSelectionGrid()
@@ -316,11 +296,5 @@
def list_datasets( self, trans, **kwargs ):
"""List all datasets that can be added as tracks"""
-
# Render the list view
- # return trans.fill_template( 'tracks/add_tracks.mako', grid=data_grid( trans, status=status, message=message, **kwargs ) )
return self.data_grid( trans, **kwargs )
-
- #
-
-
\ No newline at end of file
diff -r 99483ae6c738 -r 432a32ba55bb lib/galaxy/web/controllers/visualization.py
--- a/lib/galaxy/web/controllers/visualization.py Fri Feb 05 16:34:30 2010 -0500
+++ b/lib/galaxy/web/controllers/visualization.py Fri Feb 05 19:08:37 2010 -0500
@@ -7,7 +7,7 @@
# Grid definition
title = "Visualizations"
model_class = model.Visualization
- default_sort_key = "-create_time"
+ default_sort_key = "-update_time"
columns = [
grids.GridColumn( "Title", key="title", attach_popup=True,
link=( lambda item: dict( controller="tracks", action="browser", id=item.id ) ) ),
diff -r 99483ae6c738 -r 432a32ba55bb static/scripts/trackster.js
--- a/static/scripts/trackster.js Fri Feb 05 16:34:30 2010 -0500
+++ b/static/scripts/trackster.js Fri Feb 05 19:08:37 2010 -0500
@@ -77,14 +77,16 @@
}
});
-var View = function( chrom, max_high, config ) {
+var View = function( chrom, title, vis_id, dbkey ) {
+ this.vis_id = vis_id;
+ this.dbkey = dbkey;
+ this.title = title;
this.chrom = chrom;
- this.config = config;
this.tracks = [];
+ this.label_tracks = [];
this.max_low = 0;
- this.max_high = max_high;
+ this.max_high = 0;
this.center = (this.max_high - this.max_low) / 2;
- this.span = this.max_high - this.max_low;
this.zoom_factor = 3;
this.zoom_level = 0;
};
@@ -94,6 +96,10 @@
this.tracks.push( track );
if (track.init) { track.init(); }
},
+ add_label_track: function ( label_track ) {
+ label_track.view = this;
+ this.label_tracks.push( label_track );
+ },
remove_track: function( track ) {
delete this.tracks[track];
},
@@ -105,7 +111,8 @@
}
}
},
- redraw: function() {
+ 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;
@@ -134,11 +141,14 @@
}).show();
$("#low").val( commatize(this.low) );
$("#high").val( commatize(this.high) );
- for ( var i = 0, len = this.tracks.length; i < len; i++ ) {
- this.tracks[i].draw();
+ if (!nodraw) {
+ for ( var i = 0, len = this.tracks.length; i < len; i++ ) {
+ this.tracks[i].draw();
+ }
+ for ( var i = 0, len = this.label_tracks.length; i < len; i++ ) {
+ this.label_tracks[i].draw();
+ }
}
- //$("#bottom-spacer").remove();
- //$("#viewport").append('<div id="bottom-spacer" style="height: 200px;"></div>');
},
zoom_in: function ( point ) {
if (this.max_high === 0 || this.high - this.low < 30) {
@@ -238,6 +248,7 @@
var LabelTrack = function ( parent_element ) {
Track.call( this, null, parent_element );
+ this.track_type = "LabelTrack";
this.hidden = true;
this.container_div.addClass( "label-track" );
};
@@ -273,26 +284,27 @@
this.height_px = 100;
this.container_div.addClass( "line-track" );
this.dataset_id = dataset_id;
- this.data_queue = {};
- this.data_cache = new Cache(CACHED_DATA); // We need to cache some data because of
- // asynchronous calls
this.prefs = { 'min_value': undefined, 'max_value': undefined };
if (prefs.min_value !== undefined) { this.prefs.min_value = prefs.min_value; }
if (prefs.max_value !== undefined) { this.prefs.max_value = prefs.max_value; }
};
$.extend( LineTrack.prototype, TiledTrack.prototype, {
init: function() {
+ this.data_queue = {};
+ this.data_cache = new Cache(CACHED_DATA); // We need to cache some data because of
+ // asynchronous calls
var track = this,
track_id = track.view.tracks.indexOf(track);
-
+
track.content_div.text(DATA_LOADING);
+ track.container_div.removeClass("nodata error pending");
$.getJSON( data_url, { stats: true, indexer: track.indexer,
chrom: track.view.chrom, low: null, high: null,
dataset_id: track.dataset_id }, function ( data ) {
if (!data || data == "error") {
track.container_div.addClass("error");
track.content_div.text(DATA_ERROR);
- } else if (data == "no data") {
+ } else if (data.length === 0 || data == "no data") {
track.container_div.addClass("nodata");
track.content_div.text(DATA_NONE);
} else if (data == "pending") {
@@ -313,15 +325,17 @@
}
track.vertical_range = track.prefs.max_value - track.prefs.min_value;
- // Draw y-axis labels
- var min_label = $("<div></div>").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_minval').text(track.prefs.min_value);
- var max_label = $("<div></div>").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_maxval').text(track.prefs.max_value);
+ // Draw y-axis labels if necessary
+ if ( $('#linetrack_' + track_id + '_minval').length === 0) {
+ var min_label = $("<div></div>").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_minval').text(track.prefs.min_value);
+ var max_label = $("<div></div>").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_maxval').text(track.prefs.max_value);
- max_label.css({ position: "relative", top: "25px" });
- max_label.prependTo(track.container_div);
+ max_label.css({ position: "relative", top: "25px" });
+ max_label.prependTo(track.container_div);
- min_label.css({ position: "relative", top: track.height_px + 55 + "px" });
- min_label.prependTo(track.container_div);
+ min_label.css({ position: "relative", top: track.height_px + 55 + "px" });
+ min_label.prependTo(track.container_div);
+ }
track.draw();
}
@@ -345,7 +359,7 @@
}
},
draw_tile: function( resolution, tile_index, parent_element, w_scale ) {
- if (!this.vertical_range) { // We don't have the necessary information yet
+ if (this.vertical_range === undefined) { // We don't have the necessary information yet
return;
}
@@ -463,6 +477,7 @@
init: function() {
var track = this;
track.content_div.text(DATA_LOADING);
+ track.container_div.removeClass("nodata error pending");
$.getJSON( data_url, { indexer: track.indexer, low: track.view.max_low,
high: track.view.max_high, dataset_id: track.dataset_id,
chrom: track.view.chrom }, function ( data ) {
@@ -473,7 +488,7 @@
track.container_div.addClass("nodata");
track.content_div.text(DATA_NONE);
} else if (data == "pending") {
- track.container_div.addClass("pending");
+ track.container_div.adClass("pending");
track.content_div.text(DATA_PENDING);
setTimeout(function() { track.init(); }, 5000);
} else {
diff -r 99483ae6c738 -r 432a32ba55bb static/trackster.css
--- a/static/trackster.css Fri Feb 05 16:34:30 2010 -0500
+++ b/static/trackster.css Fri Feb 05 19:08:37 2010 -0500
@@ -8,6 +8,7 @@
#nav-container {
position: fixed;
+ left: 0;
bottom: 0;
}
diff -r 99483ae6c738 -r 432a32ba55bb templates/grid_base.mako
--- a/templates/grid_base.mako Fri Feb 05 16:34:30 2010 -0500
+++ b/templates/grid_base.mako Fri Feb 05 19:08:37 2010 -0500
@@ -27,6 +27,10 @@
<%def name="javascripts()">
${parent.javascripts()}
+ ${self.grid_javascripts()}
+</%def>
+
+<%def name="grid_javascripts()">
${h.js("jquery.autocomplete", "autocomplete_tagging" )}
<script type="text/javascript">
## TODO: generalize and move into galaxy.base.js
diff -r 99483ae6c738 -r 432a32ba55bb templates/tracks/add_tracks.mako
--- a/templates/tracks/add_tracks.mako Fri Feb 05 16:34:30 2010 -0500
+++ b/templates/tracks/add_tracks.mako Fri Feb 05 19:08:37 2010 -0500
@@ -1,8 +1,9 @@
## Template generates a grid that enables user to add tracks
<%namespace file="../grid_base.mako" import="*" />
-${javascripts()}
${stylesheets()}
+${grid_javascripts()}
+
${render_grid_table( grid, show_item_checkboxes=True )}
## Initialize the grid.
diff -r 99483ae6c738 -r 432a32ba55bb templates/tracks/browser.mako
--- a/templates/tracks/browser.mako Fri Feb 05 16:34:30 2010 -0500
+++ b/templates/tracks/browser.mako Fri Feb 05 19:08:37 2010 -0500
@@ -45,7 +45,7 @@
</div>
</div>
-<div id="nav-container">
+<div id="nav-container" style="width:100%;">
<div id="nav-labeltrack"></div>
<div id="nav">
<div id="overview">
@@ -59,8 +59,7 @@
<option value="">Loading</option>
</select>
<input id="low" size="12" />:<input id="high" size="12" />
- ## <input type="hidden" name="dataset_ids" value="${dataset_ids}" />
- <input type="hidden" name="id" value="${id}" />
+ <input type="hidden" name="id" value="${config.get('vis_id', '')}" />
<a href="#" onclick="javascript:view.zoom_in();view.redraw();">+</a>
<a href="#" onclick="javascript:view.zoom_out();view.redraw();">-</a>
</form>
@@ -75,11 +74,10 @@
<div class="unified-panel-header-inner">Configuration</div>
</div>
<form action="${h.url_for( action='update_config' )}">
-## <input name="title" id="title" value="${title}" />
+## <input name="title" id="title" value="${config.title}" />
<div id="show-hide-move">
<ul id="sortable-ul"></ul>
</div>
-## <input type="submit" id="update-config" value="Save settings" />
<input type="button" id="refresh-button" value="Refresh" />
<input type="button" id="save-button" value="Save" />
<input id="add-track" type="button" value="Add Track" />
@@ -89,154 +87,227 @@
<%def name="javascripts()">
${parent.javascripts()}
-${h.js( "json2", "jquery", "jquery.event.drag", "jquery.mousewheel", "trackster", "ui.core", "ui.sortable" )}
+${h.js( 'galaxy.base', 'galaxy.panels', "json2", "jquery", "jquery.event.drag", "jquery.mousewheel", "trackster", "ui.core", "ui.sortable" )}
<script type="text/javascript">
var data_url = "${h.url_for( action='data' )}";
- var view = new View( "${chrom}", ${LEN} );
+ var view;
$(function() {
- view.add_track( new LabelTrack( $("#top-labeltrack" ) ) );
- view.add_track( new LabelTrack( $("#nav-labeltrack" ) ) );
-
- %for track in tracks:
- view.add_track(
- new ${track["track_type"]}( "${track['name']}", ${track['dataset_id']}, "${track['indexer']}", ${track['prefs']} )
- );
- %endfor
-
- $(document).bind( "redraw", function( e ) {
- view.redraw();
- });
-
- $("#content").bind("mousewheel", function( e, delta ) {
- if (delta > 0) {
- view.zoom_in(e.pageX);
- } else {
- view.zoom_out();
- }
- e.preventDefault();
- });
-
- $("#content").bind("dblclick", function( e ) {
- view.zoom_in(e.pageX);
- });
-
- // To let the overview box be draggable
- $("#overview-box").bind("dragstart", function( e ) {
- this.current_x = e.offsetX;
- }).bind("drag", function( e ) {
- var delta = e.offsetX - this.current_x;
- this.current_x = e.offsetX;
-
- var delta_chrom = Math.round(delta / $(document).width() * view.span);
- view.center += delta_chrom;
- view.redraw();
- });
-
- // To adjust the size of the viewport to fit the fixed-height footer
- var refresh = function( e ) {
- $("#content").height( $(window).height() - $("#nav-container").height() - $("#masthead").height());
- $("#viewport-container").height( $("#content").height() - $("#top-labeltrack").height() - $("#nav-labeltrack").height() );
- $("#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); } );
- $(window).trigger( "resize" );
-
- $("#viewport").bind( "dragstart", function( e ) {
- this.original_low = view.low;
- this.current_height = e.clientY;
- this.current_x = e.offsetX;
- }).bind( "drag", function( e ) {
- var container = $(this).parent();
- var delta = e.offsetX - this.current_x;
- var new_scroll = container.scrollTop() - (e.clientY - this.current_height);
- if ( new_scroll < container.get(0).scrollHeight - container.height() ) {
- container.scrollTop(new_scroll);
- }
- 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;
- view.redraw();
- });
-
- $("#refresh-button").bind( "click", function(e) {
- view.update_options();
- });
-
- // Use a popup grid to add more tracks
- $("#add-track").bind( "click", function(e) {
+ %if config:
+ view = new View( "${config.get('chrom')}", "${config.get('title') | h}", "${config.get('vis_id')}", "${config.get('dbkey')}" );
+ %for track in config.get('tracks'):
+ view.add_track(
+ new ${track["track_type"]}( "${track['name'] | h}", ${track['dataset_id']}, "${track['indexer']}", ${track['prefs']} )
+ );
+ %endfor
+ init();
+ %else:
$.ajax({
- url: "${h.url_for( action='list_datasets' )}",
+ url: "${h.url_for( action='new_browser' )}",
data: {},
- error: function() { alert( "Grid refresh failed" ) },
- success: function(table_html) {
- show_modal("Add Track — Select Dataset(s)", table_html, {
- "Insert": function() {
- hide_modal();
- },
- "Cancel": function() {
+ error: function() { alert( "Couldn't create new browser" ) },
+ success: function(form_html) {
+ show_modal("New Track Browser", form_html, {
+ "Continue": function() {
+ view = new View( undefined, $("#new-title").val(), undefined, $("#new-dbkey").val() );
+ init();
hide_modal();
}
});
}
});
- });
+ %endif
- $("#save-button").bind("click", function(e) {
- view.update_options();
- var sorted = $("ul#sortable-ul").sortable('toArray');
- var payload = [];
- for (var i in sorted) {
- var track_id = parseInt(sorted[i].split("track_")[1]),
- track = view.tracks[track_id];
-
- payload.push( {
- "track_type": track.track_type,
- "indexer": track.indexer,
- "name": track.name,
- "dataset_id": track.dataset_id,
- "prefs": track.prefs
- });
- }
- $.ajax({
- url: "${h.url_for( action='save' )}",
- data: {
- 'id': '${id}',
- 'payload': JSON.stringify(payload)
+ // Execute this when everything is ready
+ function init() {
+ $("ul#sortable-ul").sortable({
+ update: function(event, ui) {
+ for (var track_id in view.tracks) {
+ var track = view.tracks[track_id];
+ }
}
});
- });
-
- // Execute this on page load
- (function () {
- $.getJSON( "${h.url_for( action='chroms' )}", { dbkey: "${dbkey}" }, function ( data ) {
+
+ $(document).bind( "redraw", function( e ) {
+ view.redraw();
+ });
+
+ $("#content").bind("mousewheel", function( e, delta ) {
+ if (delta > 0) {
+ view.zoom_in(e.pageX);
+ } else {
+ view.zoom_out();
+ }
+ e.preventDefault();
+ });
+
+ $("#content").bind("dblclick", function( e ) {
+ view.zoom_in(e.pageX);
+ });
+
+ // To let the overview box be draggable
+ $("#overview-box").bind("dragstart", function( e ) {
+ this.current_x = e.offsetX;
+ }).bind("drag", function( e ) {
+ var delta = e.offsetX - this.current_x;
+ this.current_x = e.offsetX;
+
+ var delta_chrom = Math.round(delta / $(document).width() * view.span);
+ view.center += delta_chrom;
+ view.redraw();
+ });
+
+ // To adjust the size of the viewport to fit the fixed-height footer
+ var refresh = function( e ) {
+ $("#content").height( $(window).height() - $("#nav-container").height() - $("#masthead").height());
+ $("#viewport-container").height( $("#content").height() - $("#top-labeltrack").height() - $("#nav-labeltrack").height() );
+ $("#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); } );
+ $(window).trigger( "resize" );
+
+ $("#viewport").bind( "dragstart", function( e ) {
+ this.original_low = view.low;
+ this.current_height = e.clientY;
+ this.current_x = e.offsetX;
+ }).bind( "drag", function( e ) {
+ var container = $(this).parent();
+ var delta = e.offsetX - this.current_x;
+ var new_scroll = container.scrollTop() - (e.clientY - this.current_height);
+ if ( new_scroll < container.get(0).scrollHeight - container.height() ) {
+ container.scrollTop(new_scroll);
+ }
+ 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;
+ view.redraw();
+ });
+
+ $("#refresh-button").bind( "click", function(e) {
+ view.update_options();
+ });
+
+ // Use a popup grid to add more tracks
+ $("#add-track").bind( "click", function(e) {
+ $.ajax({
+ url: "${h.url_for( action='list_datasets' )}",
+ data: {},
+ error: function() { alert( "Grid refresh failed" ) },
+ success: function(table_html) {
+ show_modal("Add Track — Select Dataset(s)", table_html, {
+ "Insert": function() {
+ $('input[name=id]:checked').each(function() {
+ var item_id = $(this).val();
+ $.ajax( {
+ url: "${h.url_for( action='add_track_async' )}",
+ data: { id: item_id },
+ dataType: "json",
+ error: function() {},
+ success: function(track_data) {
+ var new_track;
+ var td = track_data;
+ switch(track_data.track_type) {
+ case "LineTrack":
+ new_track = new LineTrack( track_data.name, track_data.dataset_id, track_data.indexer, track_data.prefs );
+ break;
+ case "FeatureTrack":
+ new_track = new FeatureTrack( track_data.name, track_data.dataset_id, track_data.indexer, track_data.prefs );
+ break;
+ case "ReadTrack":
+ new_track = new ReadTrack( track_data.name, track_data.dataset_id, track_data.indexer, track_data.prefs );
+ break;
+ }
+ view.add_track(new_track);
+ sidebar_box(new_track);
+ }
+ });
+
+ });
+
+ hide_modal();
+ },
+ "Cancel": function() {
+ hide_modal();
+ }
+ });
+ }
+ });
+ });
+
+ $("#save-button").bind("click", function(e) {
+ view.update_options();
+ var sorted = $("ul#sortable-ul").sortable('toArray');
+ var payload = [];
+ for (var i in sorted) {
+ var track_id = parseInt(sorted[i].split("track_")[1]),
+ track = view.tracks[track_id];
+
+ payload.push( {
+ "track_type": track.track_type,
+ "indexer": track.indexer,
+ "name": track.name,
+ "dataset_id": track.dataset_id,
+ "prefs": track.prefs
+ });
+ }
+ // Show saving dialog box
+ show_modal("Saving...", "<img src='${h.url_for('/static/images/yui/rel_interstitial_loading.gif')}'/>");
+
+ $.ajax({
+ url: "${h.url_for( action='save' )}",
+ data: {
+ 'vis_id': view.vis_id,
+ 'vis_title': view.title,
+ 'dbkey': view.dbkey,
+ 'payload': JSON.stringify(payload)
+ },
+ success: function(vis_id) {
+ view.vis_id = vis_id;
+ hide_modal();
+ }
+ });
+ });
+
+ view.add_label_track( new LabelTrack( $("#top-labeltrack" ) ) );
+ view.add_label_track( new LabelTrack( $("#nav-labeltrack" ) ) );
+
+ $.getJSON( "${h.url_for( action='chroms' )}", { dbkey: view.dbkey }, function ( data ) {
+ view.chrom_data = data;
var chrom_options = '<option value="">Select Chrom/Contig</option>';
for (i in data) {
- chrom = data[i]['chrom']
- if( chrom == view.chrom ) {
- chrom_options += '<option value="' + chrom + '" selected="true">' + chrom + '</option>';
- } else {
- chrom_options += '<option value="' + chrom + '">' + chrom + '</option>';
- }
+ var chrom = data[i]['chrom']
+ chrom_options += '<option value="' + chrom + '">' + chrom + '</option>';
}
$("#chrom").html(chrom_options);
$("#chrom").bind( "change", function () {
- $("#chr").submit();
+ view.chrom = $("#chrom").val();
+ var found = $.grep(view.chrom_data, function(v, i) {
+ return v.chrom === view.chrom;
+ })[0];
+ view.max_high = found.len;
+ view.redraw(true);
+
+ for (var track_id in view.tracks) {
+ var track = view.tracks[track_id];
+ if (track.init) {
+ track.init();
+ }
+ }
+ // view.redraw();
});
});
- // Populate sort/move ul
- for (var track_id in view.tracks) {
- var track = view.tracks[track_id];
+ function sidebar_box(track) {
if (!track.hidden) {
+ var track_id = view.tracks.length -1; // Track was just added to view, so index is current length -1
var label = $('<label for="track_' + track_id + 'title">' + track.name + '</label>');
var title = $('<div class="historyItemTitle"></div>');
var del_icon = $('<a style="display:block; float:right" href="#" class="icon-button delete" />');
@@ -255,18 +326,17 @@
li.append(div);
$("ul#sortable-ul").append(li);
}
+ };
+
+ // Populate sort/move ul
+ for (var track_id in view.tracks) {
+ var track = view.tracks[track_id];
+ sidebar_box(track);
}
- $("ul#sortable-ul").sortable({
- update: function(event, ui) {
- for (var track_id in view.tracks) {
- var track = view.tracks[track_id];
- }
- }
- });
-
- })();
- $(window).trigger("resize");
+ $(window).trigger("resize");
+ };
+
});
</script>
diff -r 99483ae6c738 -r 432a32ba55bb templates/tracks/index.mako
--- a/templates/tracks/index.mako Fri Feb 05 16:34:30 2010 -0500
+++ b/templates/tracks/index.mako Fri Feb 05 19:08:37 2010 -0500
@@ -1,16 +1,38 @@
-<%inherit file="/base_panels.mako"/>
+<form id="form" method="POST">
+ <div class="form-row">
+ <label for="dbkey">Browser name:</label>
+ <div class="form-row-input">
+ <input type="text" name="title" id="title" value="Unnamed Browser"></input>
+ </div>
+ <div style="clear: both;"></div>
+ </div>
+ <div class="form-row">
+ <label for="dbkey">Reference genome build (dbkey): </label>
+ <div class="form-row-input">
+ <select name="dbkey" id="dbkey" refresh_on_change="true">
+ %for tmp_dbkey in dbkey_set:
+ <option value="${tmp_dbkey}"
+ %if tmp_dbkey == dbkey:
+ selected="selected"
+ %endif
+ >${tmp_dbkey}</option>
+ %endfor
+ </select>
+ </div>
+ <div style="clear: both;"></div>
+ </div>
+ <div class="form-row">
+ <label for="dataset_ids">Datasets to visualize: (${", ".join(available_tracks)} files are supported)</label>
+ %for dataset_id, (dataset_ext, dataset_name) in datasets.iteritems():
+ <div>
+ <input type="checkbox" id="${dataset_id}" name="dataset_ids" value="${dataset_id}" />
+ <label style="display:inline; font-weight: normal" for="${dataset_id}">[${dataset_ext}] ${dataset_name}</label>
+ </div>
+ %endfor
-<%def name="init()">
-<%
- self.has_left_panel=False
- self.has_right_panel=False
- self.active_view="visualization"
- self.message_box_visible=False
-%>
-</%def>
-
-<%def name="center_panel()">
-
- <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${h.url_for( controller="tracks", action="new_browser" )}"> </iframe>
-
-</%def>
\ No newline at end of file
+ <div style="clear: both;"></div>
+ </div>
+ <div class="form-row">
+ <input type="submit" name="browse" value="Browse"/>
+ </div>
+</form>
diff -r 99483ae6c738 -r 432a32ba55bb templates/tracks/new_browser.mako
--- a/templates/tracks/new_browser.mako Fri Feb 05 16:34:30 2010 -0500
+++ b/templates/tracks/new_browser.mako Fri Feb 05 19:08:37 2010 -0500
@@ -1,65 +1,20 @@
-<%inherit file="/base.mako"/>
-
-<%def name="javascripts()">
-${parent.javascripts()}
-<script type="text/javascript">
-$( function() {
- $( "select[refresh_on_change='true']").change( function() {
- $("#form").submit();
- });
-});
-</script>
-</%def>
-
-% if not available_tracks:
- <div class="errormessagelarge">
- There are no available converters needed for visualization. Please verify that your tool_conf.xml file contains
- converters for datatypes (see tool_conf.xml.sample) for examples.
+<form id="form" method="POST">
+ <div class="form-row">
+ <label for="title">Browser name:</label>
+ <div class="form-row-input">
+ <input type="text" name="title" id="new-title" value="Unnamed Browser"></input>
+ </div>
+ <div style="clear: both;"></div>
</div>
-
-% else:
- <div class="form">
- <div class="form-title">Create new track browser</div>
-
- <div id="dbkey" class="form-body">
- <form id="form" method="POST">
- <div class="form-row">
- <label for="dbkey">Browser name:</label>
- <div class="form-row-input">
- <input type="text" name="title" id="title" value="Unnamed Browser"></input>
- </div>
- <div style="clear: both;"></div>
- </div>
- <div class="form-row">
- <label for="dbkey">Reference genome build (dbkey): </label>
- <div class="form-row-input">
- <select name="dbkey" id="dbkey" refresh_on_change="true">
- %for tmp_dbkey in dbkey_set:
- <option value="${tmp_dbkey}"
- %if tmp_dbkey == dbkey:
- selected="selected"
- %endif
- >${tmp_dbkey}</option>
- %endfor
- </select>
- </div>
- <div style="clear: both;"></div>
- </div>
- <div class="form-row">
- <label for="dataset_ids">Datasets to visualize: (${", ".join(available_tracks)} files are supported)</label>
- %for dataset_id, (dataset_ext, dataset_name) in datasets.iteritems():
- <div>
- <input type="checkbox" id="${dataset_id}" name="dataset_ids" value="${dataset_id}" />
- <label style="display:inline; font-weight: normal" for="${dataset_id}">[${dataset_ext}] ${dataset_name}</label>
- </div>
- %endfor
-
- <div style="clear: both;"></div>
- </div>
- </div>
- <div class="form-row">
- <input type="submit" name="browse" value="Browse"/>
- </div>
- </form>
+ <div class="form-row">
+ <label for="dbkey">Reference genome build (dbkey): </label>
+ <div class="form-row-input">
+ <select name="dbkey" id="new-dbkey">
+ %for dbkey in dbkey_set:
+ <option value="${dbkey}">${dbkey}</option>
+ %endfor
+ </select>
+ </div>
+ <div style="clear: both;"></div>
</div>
-% endif
+</form>
More information about the galaxy-dev
mailing list