mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Trackster: create a set of shared functions for managing the user interface and use functions in both visualization editor and display.
This commit is contained in:
@@ -464,7 +464,7 @@ extend(ReferenceTrackDataManager.prototype, DataManager.prototype, Cache.prototy
|
||||
/**
|
||||
* View object manages complete viz view, including tracks and user interactions.
|
||||
*/
|
||||
var View = function( container, title, vis_id, dbkey, callback ) {
|
||||
var View = function(container, title, vis_id, dbkey, callback) {
|
||||
this.container = container;
|
||||
this.chrom = null;
|
||||
this.vis_id = vis_id;
|
||||
@@ -826,6 +826,7 @@ extend( View.prototype, {
|
||||
sortable( track.container_div, '.draghandle' );
|
||||
this.track_id_counter += 1;
|
||||
this.num_tracks += 1;
|
||||
this.has_changes = true;
|
||||
this.update_intro_div();
|
||||
},
|
||||
add_label_track: function (label_track) {
|
||||
@@ -993,9 +994,9 @@ extend( View.prototype, {
|
||||
view.overview_track.set_is_overview(false);
|
||||
}
|
||||
view.overview_track = track;
|
||||
view.has_changes = true;
|
||||
track.set_is_overview(true);
|
||||
});
|
||||
view.has_changes = true;
|
||||
},
|
||||
/** Close and reset overview. */
|
||||
reset_overview: function() {
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/************************************************************************
|
||||
* Functions used for creating and managing the Trackster user interface.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* Add bookmark.
|
||||
*/
|
||||
var add_bookmark = function(position, annotation) {
|
||||
var
|
||||
bookmarks_container = $("#bookmarks-container"),
|
||||
new_bookmark = $("<div/>").addClass("bookmark").appendTo(bookmarks_container),
|
||||
delete_icon_container = $("<div/>").addClass("delete-icon-container").appendTo(new_bookmark).click(function (){
|
||||
// Remove bookmark.
|
||||
new_bookmark.slideUp("fast");
|
||||
new_bookmark.remove();
|
||||
view.has_changes = true;
|
||||
return false;
|
||||
}),
|
||||
delete_icon = $("<a href=''/>").addClass("icon-button delete").appendTo(delete_icon_container),
|
||||
position_div = $("<div/>").addClass("position").appendTo(new_bookmark),
|
||||
position_link = $("<a href=''/>").text(position).appendTo(position_div).click(function() {
|
||||
view.go_to(position);
|
||||
return false;
|
||||
});
|
||||
annotation_div = get_editable_text_elt(annotation, true).addClass("annotation").appendTo(new_bookmark);
|
||||
|
||||
view.has_changes = true;
|
||||
return new_bookmark;
|
||||
};
|
||||
|
||||
/**
|
||||
* Types of tracks that can be added to a view.
|
||||
*/
|
||||
var addable_track_types = { "LineTrack": LineTrack, "FeatureTrack": FeatureTrack, "ReadTrack": ReadTrack };
|
||||
|
||||
/**
|
||||
* Decode a track from a dictionary.
|
||||
*/
|
||||
var track_from_dict = function(track_dict) {
|
||||
return new addable_track_types[track_dict.track_type](
|
||||
track_dict.name, view, track_dict.hda_ldda, track_dict.dataset_id,
|
||||
track_dict.prefs, track_dict.filters, track_dict.tool
|
||||
/* TODO: ( track_dict.is_child ? parent_track : undefined */ );
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a complete Trackster visualization. Returns view.
|
||||
*/
|
||||
var create_visualization = function(parent_elt, title, id, dbkey, callback, tracks_config, bookmarks_config) {
|
||||
|
||||
// Create view.
|
||||
view = new View(parent_elt, title, id, dbkey, callback);
|
||||
view.editor = true;
|
||||
|
||||
// Add tracks to view.
|
||||
if (tracks_config) {
|
||||
var track_config, track, parent_track, parent_obj;
|
||||
for (var i = 0; i < tracks_config.length; i++) {
|
||||
track_config = tracks_config[i];
|
||||
// TODO: set parent for child track:
|
||||
track = track_from_dict(track_config);
|
||||
parent_obj = view;
|
||||
if (track_config.is_child) {
|
||||
parent_obj = parent_track;
|
||||
}
|
||||
else {
|
||||
// New parent track is this track.
|
||||
parent_track = track;
|
||||
}
|
||||
parent_obj.add_track(track);
|
||||
}
|
||||
}
|
||||
|
||||
// Load bookmarks.
|
||||
if (bookmarks_config) {
|
||||
var bookmark;
|
||||
for (var i = 0; i < bookmarks_config.length; i++) {
|
||||
bookmark = bookmarks_config[i];
|
||||
add_bookmark(bookmark['position'], bookmark['annotation']);
|
||||
}
|
||||
}
|
||||
|
||||
// View has no changes as of yet.
|
||||
view.has_changes = false;
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set up keyboard navigation for a visualization.
|
||||
*/
|
||||
var init_keyboard_nav = function(view) {
|
||||
// Keyboard navigation. Scroll ~7% of height when scrolling up/down.
|
||||
$(document).keydown(function(e) {
|
||||
// Do not navigate if arrow keys used in input element.
|
||||
if ($(e.srcElement).is(':input')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Key codes: left == 37, up == 38, right == 39, down == 40
|
||||
switch(e.which) {
|
||||
case 37:
|
||||
view.move_fraction(0.25);
|
||||
break
|
||||
case 38:
|
||||
var change = Math.round(view.viewport_container.height()/15.0);
|
||||
view.viewport_container.scrollTo('-=' + change + 'px');
|
||||
break;
|
||||
case 39:
|
||||
view.move_fraction(-0.25);
|
||||
break;
|
||||
case 40:
|
||||
var change = Math.round(view.viewport_container.height()/15.0);
|
||||
view.viewport_container.scrollTo('+=' + change + 'px');
|
||||
break;
|
||||
}
|
||||
});
|
||||
};
|
||||
+26
-123
@@ -42,7 +42,7 @@ ${parent.javascripts()}
|
||||
<script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script>
|
||||
<![endif]-->
|
||||
|
||||
${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "jquery.ui.sortable.slider", "jquery.scrollTo", "farbtastic" )}
|
||||
${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "jquery.scrollTo", "farbtastic" )}
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -57,51 +57,8 @@ ${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.e
|
||||
chrom_url = "${h.url_for( action='chroms' )}",
|
||||
dataset_state_url = "${h.url_for( action='dataset_state' )}",
|
||||
converted_datasets_state_url = "${h.url_for( action='converted_datasets_state' )}",
|
||||
addable_track_types = { "LineTrack": LineTrack, "FeatureTrack": FeatureTrack, "ReadTrack": ReadTrack },
|
||||
view;
|
||||
|
||||
/**
|
||||
* Add bookmark.
|
||||
*/
|
||||
var add_bookmark = function(position, annotation) {
|
||||
var
|
||||
bookmarks_container = $("#bookmarks-container"),
|
||||
new_bookmark = $("<div/>").addClass("bookmark").appendTo(bookmarks_container),
|
||||
delete_icon_container = $("<div/>").addClass("delete-icon-container").appendTo(new_bookmark).click(function (){
|
||||
// Remove bookmark.
|
||||
new_bookmark.slideUp("fast");
|
||||
new_bookmark.remove();
|
||||
view.has_changes = true;
|
||||
return false;
|
||||
}),
|
||||
delete_icon = $("<a href=''/>").addClass("icon-button delete").appendTo(delete_icon_container),
|
||||
position_div = $("<div/>").addClass("position").appendTo(new_bookmark),
|
||||
position_link = $("<a href=''/>").text(position).appendTo(position_div).click(function() {
|
||||
view.go_to(position);
|
||||
return false;
|
||||
});
|
||||
annotation_div = get_editable_text_elt(annotation, true).addClass("annotation").appendTo(new_bookmark);
|
||||
|
||||
view.has_changes = true;
|
||||
return new_bookmark;
|
||||
};
|
||||
|
||||
/**
|
||||
* Use track data to add a track to a view.
|
||||
* TODO: rename function?
|
||||
*/
|
||||
var add_async_success = function(track_data) {
|
||||
var td = track_data,
|
||||
new_track = new addable_track_types[track_data.track_type](
|
||||
track_data.name, view, track_data.hda_ldda, track_data.dataset_id,
|
||||
track_data.prefs, track_data.filters, track_data.tool );
|
||||
view.add_track(new_track);
|
||||
// Should replace with live event but can't get working
|
||||
sortable(new_track.container_div, ".draghandle");
|
||||
view.has_changes = true;
|
||||
$("#no-tracks").hide();
|
||||
};
|
||||
|
||||
/**
|
||||
* Use a popup grid to add more tracks.
|
||||
*/
|
||||
@@ -144,7 +101,7 @@ ${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.e
|
||||
[ arguments[0] ]
|
||||
);
|
||||
for (var i= 0; i < track_defs.length; i++) {
|
||||
add_async_success(track_defs[i]);
|
||||
view.add_track( track_from_dict(track_defs[i]) );
|
||||
}
|
||||
});
|
||||
hide_modal();
|
||||
@@ -165,6 +122,7 @@ ${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.e
|
||||
%if config:
|
||||
var callback;
|
||||
%if 'viewport' in config:
|
||||
// TODO: find better way to handle this code.
|
||||
var callback = function() {
|
||||
view.change_chrom( '${config['viewport']['chrom']}', ${config['viewport']['start']}, ${config['viewport']['end']} );
|
||||
// Set overview.
|
||||
@@ -180,51 +138,20 @@ ${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.e
|
||||
}
|
||||
}
|
||||
%endif
|
||||
}
|
||||
view.has_changes = false;
|
||||
};
|
||||
%endif
|
||||
view = new View( $("#browser-container"), "${config.get('title') | h}", "${config.get('vis_id')}", "${config.get('dbkey')}", callback );
|
||||
view.editor = true;
|
||||
## A little ugly and redundant, but it gets the job done moving the config from python to JS:
|
||||
var tracks_config = JSON.parse('${ h.to_json_string( config.get('tracks') ) }');
|
||||
var track_config, track, parent_track, parent_obj;
|
||||
for (var i = 0; i < tracks_config.length; i++) {
|
||||
track_config = tracks_config[i];
|
||||
track = new addable_track_types[track_config["track_type"]](
|
||||
track_config['name'],
|
||||
view,
|
||||
track_config['hda_ldda'],
|
||||
track_config['dataset_id'],
|
||||
track_config['prefs'],
|
||||
track_config['filters'],
|
||||
track_config['tool'],
|
||||
(track_config.is_child ? parent_track : undefined));
|
||||
parent_obj = view;
|
||||
if (track_config.is_child) {
|
||||
parent_obj = parent_track;
|
||||
}
|
||||
else {
|
||||
// New parent track is this track.
|
||||
parent_track = track;
|
||||
}
|
||||
parent_obj.add_track(track);
|
||||
}
|
||||
init();
|
||||
|
||||
// Load bookmarks.
|
||||
var bookmarks = JSON.parse('${ h.to_json_string( config.get('bookmarks') ) }'),
|
||||
bookmark;
|
||||
for (var i = 0; i < bookmarks.length; i++) {
|
||||
bookmark = bookmarks[i];
|
||||
add_bookmark(bookmark['position'], bookmark['annotation']);
|
||||
}
|
||||
|
||||
// View has no changes as of yet.
|
||||
view.has_changes = false;
|
||||
view = create_visualization( $("#browser-container"), "${config.get('title') | h}",
|
||||
"${config.get('vis_id')}", "${config.get('dbkey')}", callback,
|
||||
JSON.parse('${ h.to_json_string( config.get('tracks') ) }'),
|
||||
JSON.parse('${ h.to_json_string( config.get('bookmarks') ) }')
|
||||
);
|
||||
init_editor();
|
||||
%else:
|
||||
var continue_fn = function() {
|
||||
view = new View( $("#browser-container"), $("#new-title").val(), undefined, $("#new-dbkey").val() );
|
||||
view = create_visualization( $("#browser-container"), $("#new-title").val(), undefined, $("#new-dbkey").val() );
|
||||
view.editor = true;
|
||||
init();
|
||||
init_editor();
|
||||
hide_modal();
|
||||
};
|
||||
$.ajax({
|
||||
@@ -242,11 +169,10 @@ ${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.e
|
||||
});
|
||||
%endif
|
||||
|
||||
// Execute initializer for EDITOR specific javascript
|
||||
function init() {
|
||||
if (view.num_tracks === 0) {
|
||||
$("#no-tracks").show();
|
||||
}
|
||||
/**
|
||||
* Initialization for editor-specific functions.
|
||||
*/
|
||||
function init_editor() {
|
||||
$("#title").text(view.title + " (" + view.dbkey + ")");
|
||||
|
||||
window.onbeforeunload = function() {
|
||||
@@ -260,13 +186,16 @@ ${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.e
|
||||
url: "${h.url_for( action='add_track_async' )}",
|
||||
data: { hda_id: "${add_dataset}" },
|
||||
dataType: "json",
|
||||
success: add_async_success
|
||||
success: function(track_data) { view.add_track( track_from_dict(track_data) ) }
|
||||
});
|
||||
|
||||
%endif
|
||||
|
||||
$("#viz-options-button").css( "position", "relative" );
|
||||
make_popupmenu( $("#viz-options-button"), {
|
||||
//
|
||||
// Make actions menu.
|
||||
//
|
||||
$("#viz-actions-button").css( "position", "relative" );
|
||||
make_popupmenu( $("#viz-actions-button"), {
|
||||
"Add Tracks": add_tracks,
|
||||
"Save": function() {
|
||||
// Show saving dialog box
|
||||
@@ -344,34 +273,8 @@ ${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.e
|
||||
annotation = "Bookmark description";
|
||||
return add_bookmark(position, annotation);
|
||||
});
|
||||
|
||||
//
|
||||
// Keyboard navigation. Scroll ~7% of height when scrolling up/down.
|
||||
//
|
||||
$(document).keydown(function(e) {
|
||||
// Do not navigate if arrow keys used in input element.
|
||||
if ($(e.srcElement).is(':input')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Key codes: left == 37, up == 38, right == 39, down == 40
|
||||
switch(e.which) {
|
||||
case 37:
|
||||
view.move_fraction(0.25);
|
||||
break
|
||||
case 38:
|
||||
var change = Math.round(view.viewport_container.height()/15.0);
|
||||
view.viewport_container.scrollTo('-=' + change + 'px');
|
||||
break;
|
||||
case 39:
|
||||
view.move_fraction(-0.25);
|
||||
break;
|
||||
case 40:
|
||||
var change = Math.round(view.viewport_container.height()/15.0);
|
||||
view.viewport_container.scrollTo('+=' + change + 'px');
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
init_keyboard_nav(view);
|
||||
};
|
||||
|
||||
});
|
||||
@@ -384,7 +287,7 @@ ${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.e
|
||||
<div class="unified-panel-header-inner">
|
||||
<div style="float:left;" id="title"></div>
|
||||
<div style="float: right">
|
||||
<a id="viz-options-button" class='panel-header-button popup' href="javascript:void(0)" target="galaxy_main">${_('Options')}</a>
|
||||
<a id="viz-actions-button" class='panel-header-button popup' href="javascript:void(0)" target="galaxy_main">${_('Actions')}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script>
|
||||
<![endif]-->
|
||||
|
||||
${h.js( "jquery.event.drag", "jquery.autocomplete", "jquery.mousewheel", "jquery.autocomplete", "trackster", "jquery.ui.sortable.slider", "jquery.scrollTo", "farbtastic" )}
|
||||
${h.js( "jquery.event.drag", "jquery.autocomplete", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "jquery.scrollTo", "farbtastic" )}
|
||||
</%def>
|
||||
|
||||
<%def name="stylesheets()">
|
||||
@@ -86,64 +86,19 @@
|
||||
$("#right-border").click(function() { view.resize_window(); });
|
||||
}
|
||||
|
||||
// Create view and add tracks.
|
||||
// Create visualization.
|
||||
var callback;
|
||||
%if 'viewport' in config:
|
||||
var callback = function() { view.change_chrom( '${config['viewport']['chrom']}', ${config['viewport']['start']}, ${config['viewport']['end']} ); }
|
||||
%endif
|
||||
view = new View(container_element, "${config.get('title') | h}", "${config.get('vis_id')}", "${config.get('dbkey')}", callback);
|
||||
## A little ugly and redundant, but it gets the job done moving the config from python to JS:
|
||||
var tracks_config = JSON.parse('${ h.to_json_string( config.get('tracks') ) }');
|
||||
var track_config, track, parent_track, parent_obj;
|
||||
for (var i = 0; i < tracks_config.length; i++) {
|
||||
track_config = tracks_config[i];
|
||||
track = new addable_track_types[track_config["track_type"]](
|
||||
track_config['name'],
|
||||
view,
|
||||
track_config['hda_ldda'],
|
||||
track_config['dataset_id'],
|
||||
track_config['prefs'],
|
||||
track_config['filters'],
|
||||
track_config['tool'],
|
||||
(track_config.is_child ? parent_track : undefined));
|
||||
parent_obj = view;
|
||||
if (track_config.is_child) {
|
||||
parent_obj = parent_track;
|
||||
}
|
||||
else {
|
||||
// New parent track is this track.
|
||||
parent_track = track;
|
||||
}
|
||||
parent_obj.add_track(track);
|
||||
}
|
||||
view = create_visualization( container_element, "${config.get('title') | h}",
|
||||
"${config.get('vis_id')}", "${config.get('dbkey')}", callback,
|
||||
JSON.parse('${ h.to_json_string( config.get('tracks') ) }'),
|
||||
JSON.parse('${ h.to_json_string( config.get('bookmarks') ) }')
|
||||
);
|
||||
|
||||
//
|
||||
// Keyboard navigation. Scroll ~7% of height when scrolling up/down.
|
||||
//
|
||||
$(document).keydown(function(e) {
|
||||
// Do not navigate if arrow keys used in input element.
|
||||
if ($(e.srcElement).is(':input')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Key codes: left == 37, up == 38, right == 39, down == 40
|
||||
switch(e.which) {
|
||||
case 37:
|
||||
view.move_fraction(0.25);
|
||||
break
|
||||
case 38:
|
||||
var change = Math.round(view.viewport_container.height()/15.0);
|
||||
view.viewport_container.scrollTo('-=' + change + 'px');
|
||||
break;
|
||||
case 39:
|
||||
view.move_fraction(-0.25);
|
||||
break;
|
||||
case 40:
|
||||
var change = Math.round(view.viewport_container.height()/15.0);
|
||||
view.viewport_container.scrollTo('+=' + change + 'px');
|
||||
break;
|
||||
}
|
||||
});
|
||||
// Set up keyboard navigation.
|
||||
init_keyboard_nav(view);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user