mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
trackster: Changing display mode from "Auto" now fetches additional detail data and displays features. Displays error messages in canvas elements if present. Limit number of features displayed in one tile due to above feature. Fix bugs in visualization creation from form
This commit is contained in:
@@ -9,6 +9,8 @@ import pkg_resources; pkg_resources.require( "bx-python" )
|
||||
from bx.interval_index_file import Indexes
|
||||
from galaxy.datatypes.interval import Bed, Gff
|
||||
|
||||
MAX_VALS = 500 # only display first MAX_VALS features
|
||||
|
||||
class IntervalIndexDataProvider( object ):
|
||||
def __init__( self, converted_dataset, original_dataset ):
|
||||
self.original_dataset = original_dataset
|
||||
@@ -20,8 +22,14 @@ class IntervalIndexDataProvider( object ):
|
||||
source = open( self.original_dataset.file_name )
|
||||
index = Indexes( self.converted_dataset.file_name )
|
||||
results = []
|
||||
count = 0
|
||||
message = None
|
||||
|
||||
for start, end, offset in index.find(chrom, start, end):
|
||||
if count >= MAX_VALS:
|
||||
message = "Only the first %s features are being displayed." % MAX_VALS
|
||||
break
|
||||
count += 1
|
||||
source.seek(offset)
|
||||
feature = source.readline().split()
|
||||
payload = [ offset, start, end ]
|
||||
@@ -53,4 +61,4 @@ class IntervalIndexDataProvider( object ):
|
||||
|
||||
results.append(payload)
|
||||
|
||||
return results
|
||||
return { 'data': results, 'message': message }
|
||||
|
||||
@@ -291,7 +291,8 @@ class TracksController( BaseController, UsesVisualization ):
|
||||
# Have to choose between indexer and data provider
|
||||
indexer = dataset_type_to_data_provider[data_sources['index']]( dataset.get_converted_dataset(trans, data_sources['index']), dataset )
|
||||
summary = indexer.get_summary( chrom, low, high, **kwargs )
|
||||
if summary is not None:
|
||||
if summary is not None and kwargs.get("mode", "Auto") == "Auto":
|
||||
# Only check for summary if it's Auto mode (which is the default)
|
||||
if summary == "no_detail":
|
||||
kwargs["no_detail"] = True # meh
|
||||
extra_info = "no_detail"
|
||||
|
||||
@@ -228,7 +228,7 @@ class VisualizationController( BaseController, Sharable, UsesAnnotations, UsesVi
|
||||
|
||||
# Get session and visualization.
|
||||
session = trans.sa_session
|
||||
visualization = trans.sa_session.query( model.Visualization ).get( trans.security.decode_id( id ) )
|
||||
visualization = self.get_visualization( trans, id, check_ownership=True )
|
||||
|
||||
# Do operation on visualization.
|
||||
if 'make_accessible_via_link' in kwargs:
|
||||
@@ -261,7 +261,7 @@ class VisualizationController( BaseController, Sharable, UsesAnnotations, UsesVi
|
||||
def share( self, trans, id=None, email="", use_panels=False ):
|
||||
""" Handle sharing a visualization with a particular user. """
|
||||
msg = mtype = None
|
||||
visualization = trans.sa_session.query( model.Visualization ).get( trans.security.decode_id( id ) )
|
||||
visualization = self.get_visualization( trans, id, check_ownership=True )
|
||||
if email:
|
||||
other = trans.sa_session.query( model.User ) \
|
||||
.filter( and_( model.User.table.c.email==email,
|
||||
@@ -330,7 +330,7 @@ class VisualizationController( BaseController, Sharable, UsesAnnotations, UsesVi
|
||||
@web.require_login( "get item name and link" )
|
||||
def get_name_and_link_async( self, trans, id=None ):
|
||||
""" Returns visualization's name and link. """
|
||||
visualization = self.get_visualization( trans, id )
|
||||
visualization = self.get_visualization( trans, id, check_ownership=False, check_accessible=True )
|
||||
|
||||
if self.create_item_slug( trans.sa_session, visualization ):
|
||||
trans.sa_session.flush()
|
||||
@@ -342,7 +342,7 @@ class VisualizationController( BaseController, Sharable, UsesAnnotations, UsesVi
|
||||
""" Returns item content in HTML format. """
|
||||
|
||||
# Get visualization, making sure it's accessible.
|
||||
visualization = self.get_visualization( trans, id, False, True )
|
||||
visualization = self.get_visualization( trans, id, check_ownership=False, check_accessible=True )
|
||||
if visualization is None:
|
||||
raise web.httpexceptions.HTTPNotFound()
|
||||
|
||||
@@ -373,25 +373,26 @@ class VisualizationController( BaseController, Sharable, UsesAnnotations, UsesVi
|
||||
visualization = model.Visualization()
|
||||
visualization.title = visualization_title
|
||||
visualization.slug = visualization_slug
|
||||
visualization.dbkey = visualization_dbkey
|
||||
visualization.type = 'trackster' # HACK: set visualization type to trackster since it's the only viz
|
||||
visualization_annotation = sanitize_html( visualization_annotation, 'utf-8', 'text/html' )
|
||||
self.add_item_annotation( trans, visualization, visualization_annotation )
|
||||
visualization.user = user
|
||||
|
||||
# And the first (empty) visualization revision
|
||||
visualization_revision = model.VisualizationRevision()
|
||||
visualization_revision.title = visualization_title
|
||||
visualization_revision.config = {}
|
||||
visualization_revision.dbkey = visualization_dbkey
|
||||
visualization_revision.visualization = visualization
|
||||
# HACK: set visualization type to trackster; when we have multiple visualization types, we'll need to get type from the user.
|
||||
visualization.type = 'trackster'
|
||||
visualization.latest_revision = visualization_revision
|
||||
# Visualization config is dbkey for now.
|
||||
visualization.latest_revision.config = { 'dbkey' : visualization_dbkey }
|
||||
visualization_revision.content = ""
|
||||
|
||||
# Persist
|
||||
session = trans.sa_session
|
||||
session.add( visualization )
|
||||
session.add(visualization)
|
||||
session.add(visualization_revision)
|
||||
session.flush()
|
||||
# Display the management visualization
|
||||
## trans.set_message( "Visualization '%s' created" % visualization.title )
|
||||
|
||||
return trans.response.send_redirect( web.url_for( action='list' ) )
|
||||
|
||||
return trans.show_form(
|
||||
@@ -414,12 +415,9 @@ class VisualizationController( BaseController, Sharable, UsesAnnotations, UsesVi
|
||||
"""
|
||||
Edit a visualization's attributes.
|
||||
"""
|
||||
encoded_id = id
|
||||
id = trans.security.decode_id( id )
|
||||
visualization = self.get_visualization( trans, id, check_ownership=True )
|
||||
session = trans.sa_session
|
||||
visualization = session.query( model.Visualization ).get( id )
|
||||
user = trans.user
|
||||
assert visualization.user == user
|
||||
|
||||
visualization_title_err = visualization_slug_err = visualization_annotation_err = ""
|
||||
if trans.request.method == "POST":
|
||||
if not visualization_title:
|
||||
@@ -428,7 +426,7 @@ class VisualizationController( BaseController, Sharable, UsesAnnotations, UsesVi
|
||||
visualization_slug_err = "Visualization id is required"
|
||||
elif not VALID_SLUG_RE.match( visualization_slug ):
|
||||
visualization_slug_err = "Visualization identifier must consist of only lowercase letters, numbers, and the '-' character"
|
||||
elif visualization_slug != visualization.slug and trans.sa_session.query( model.Visualization ).filter_by( user=user, slug=visualization_slug, deleted=False ).first():
|
||||
elif visualization_slug != visualization.slug and trans.sa_session.query( model.Visualization ).filter_by( user=visualization.user, slug=visualization_slug, deleted=False ).first():
|
||||
visualization_slug_err = "Visualization id must be unique"
|
||||
else:
|
||||
visualization.title = visualization_title
|
||||
@@ -449,7 +447,7 @@ class VisualizationController( BaseController, Sharable, UsesAnnotations, UsesVi
|
||||
if not visualization_annotation:
|
||||
visualization_annotation = ""
|
||||
return trans.show_form(
|
||||
web.FormBuilder( web.url_for( id=encoded_id ), "Edit visualization attributes", submit_text="Submit" )
|
||||
web.FormBuilder( web.url_for( id=id ), "Edit visualization attributes", submit_text="Submit" )
|
||||
.add_text( "visualization_title", "Visualization title", value=visualization_title, error=visualization_title_err )
|
||||
.add_text( "visualization_slug", "Visualization identifier", value=visualization_slug, error=visualization_slug_err,
|
||||
help="""A unique identifier that will be used for
|
||||
@@ -460,18 +458,5 @@ class VisualizationController( BaseController, Sharable, UsesAnnotations, UsesVi
|
||||
.add_text( "visualization_annotation", "Visualization annotation", value=visualization_annotation, error=visualization_annotation_err,
|
||||
help="A description of the visualization; annotation is shown alongside published visualizations."),
|
||||
template="visualization/create.mako" )
|
||||
|
||||
# @web.expose
|
||||
# @web.require_login()
|
||||
# def list( self, trans, *args, **kwargs ):
|
||||
# return self.list_grid( trans, *args, **kwargs )
|
||||
|
||||
#@web.expose
|
||||
#@web.require_admin
|
||||
#def index( self, trans, *args, **kwargs ):
|
||||
# # Build grid
|
||||
# grid = self.list( trans, *args, **kwargs )
|
||||
# # Render grid wrapped in panels
|
||||
# return trans.fill_template( "visualization/index.mako", grid=grid )
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -951,9 +951,8 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
var track = this,
|
||||
key = "initial";
|
||||
|
||||
this.init_each({ low: track.view.max_low,
|
||||
high: track.view.max_high, dataset_id: track.dataset_id,
|
||||
chrom: track.view.chrom, resolution: this.view.resolution }, function (result) {
|
||||
this.init_each({ low: track.view.max_low, high: track.view.max_high, dataset_id: track.dataset_id,
|
||||
chrom: track.view.chrom, resolution: this.view.resolution, mode: track.mode }, function (result) {
|
||||
track.mode_div.show();
|
||||
track.data_cache.set(key, result);
|
||||
track.draw();
|
||||
@@ -1089,12 +1088,11 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
var k = (!this.initial_canvas ? "initial" : tile_low + '_' + tile_high);
|
||||
var result = this.data_cache.get(k);
|
||||
var cur_mode;
|
||||
|
||||
if (result === undefined) {
|
||||
if (result === undefined || (this.mode !== "Auto" && result.dataset_type === "summary_tree")) {
|
||||
this.data_queue[ [tile_low, tile_high] ] = true;
|
||||
this.get_data(tile_low, tile_high);
|
||||
return;
|
||||
@@ -1112,7 +1110,7 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
if (result.dataset_type === "summary_tree") {
|
||||
required_height = this.summary_draw_height;
|
||||
} else if (mode === "Dense") {
|
||||
required_height = 15;
|
||||
required_height = 25;
|
||||
y_scale = 10;
|
||||
} else {
|
||||
// Calculate new slots incrementally for this new chunk of data and update height if necessary
|
||||
@@ -1169,6 +1167,16 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
return new_canvas;
|
||||
}
|
||||
|
||||
if (result.message) {
|
||||
new_canvas.css({
|
||||
border: "solid red",
|
||||
"border-width": "2px 2px 2px 0px"
|
||||
});
|
||||
ctx.fillStyle = "red";
|
||||
ctx.textAlign = "left";
|
||||
ctx.fillText(result.message, 100 + left_offset, y_scale);
|
||||
}
|
||||
|
||||
var data = result.data;
|
||||
var j = 0;
|
||||
for (var i = 0, len = data.length; i < len; i++) {
|
||||
@@ -1181,7 +1189,7 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
if (feature_start <= tile_high && feature_end >= tile_low) {
|
||||
var f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ),
|
||||
f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
|
||||
y_center = (mode === "Dense" ? 0 : slots[feature_uid] * y_scale);
|
||||
y_center = (mode === "Dense" ? 1 : (1 + slots[feature_uid])) * y_scale;
|
||||
|
||||
if (result.dataset_type === "bai") {
|
||||
ctx.fillStyle = block_color;
|
||||
@@ -1222,6 +1230,7 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
|
||||
// console.log(feature_uid, feature_start, feature_end, f_start, f_end, y_center);
|
||||
if (no_detail) {
|
||||
ctx.fillStyle = block_color;
|
||||
ctx.fillRect(f_start + left_offset, y_center + 5, f_end - f_start, 1);
|
||||
} else {
|
||||
// Showing labels, blocks, details
|
||||
@@ -1291,7 +1300,7 @@ $.extend( FeatureTrack.prototype, TiledTrack.prototype, {
|
||||
ctx.fillStyle = LEFT_STRAND_INV;
|
||||
}
|
||||
ctx.fillRect(f_start + left_offset, y_center, f_end - f_start, 10);
|
||||
ctx.fillStyle = prefs.block_color;
|
||||
ctx.fillStyle = block_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ ${h.css( "history", "autocomplete_tagging", "trackster" )}
|
||||
<div class="unified-panel-header" unselectable="on">
|
||||
<div class="unified-panel-header-inner">
|
||||
<div style="float:left;" id="title"></div>
|
||||
<a class="panel-header-button right-float" href="${h.url_for( controller='visualization', action='list' )}">Close</a>
|
||||
<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);" onclick="view.update_options();return false;">Refresh</a>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user