mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Make it simpler to save/restore visualizations and enable saving/restoring of paramamonster visualizations.
This commit is contained in:
@@ -353,8 +353,6 @@ class UsesVisualizationMixin( SharableItemSecurityMixin, UsesLibraryMixinItems )
|
||||
|
||||
viz_types = [ "trackster", "circster" ]
|
||||
|
||||
len_files = None
|
||||
|
||||
def create_visualization( self, trans, title, slug, type, dbkey, annotation=None, config={} ):
|
||||
""" Create visualiation and first revision. """
|
||||
visualization = self._create_visualization( trans, title, type, dbkey, slug, annotation )
|
||||
@@ -434,9 +432,9 @@ class UsesVisualizationMixin( SharableItemSecurityMixin, UsesLibraryMixinItems )
|
||||
end = config['viewport']['end']
|
||||
overview = config['viewport']['overview']
|
||||
vis_rev.config[ "viewport" ] = { 'chrom': chrom, 'start': start, 'end': end, 'overview': overview }
|
||||
elif type == 'circster':
|
||||
# TODO.
|
||||
pass
|
||||
else:
|
||||
# Default action is to save the config as is with no validation.
|
||||
vis_rev.config = config
|
||||
|
||||
vis.latest_revision = vis_rev
|
||||
session.add( vis_rev )
|
||||
@@ -543,6 +541,10 @@ class UsesVisualizationMixin( SharableItemSecurityMixin, UsesLibraryMixinItems )
|
||||
|
||||
if 'viewport' in latest_revision.config:
|
||||
config['viewport'] = latest_revision.config['viewport']
|
||||
else:
|
||||
# Default action is to return config unaltered.
|
||||
latest_revision = visualization.latest_revision
|
||||
config = latest_revision.config
|
||||
|
||||
return config
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ from galaxy.datatypes.interval import Gff, Bed
|
||||
from galaxy.model import NoConverterException, ConverterDependencyException
|
||||
from galaxy.visualization.tracks.data_providers import *
|
||||
from galaxy.visualization.genomes import decode_dbkey, Genomes
|
||||
from galaxy.visualization.tracks.visual_analytics import get_tool_def, get_dataset_job
|
||||
from galaxy.visualization.tracks.visual_analytics import get_dataset_job
|
||||
|
||||
|
||||
class NameColumn( grids.TextColumn ):
|
||||
@@ -471,12 +471,42 @@ class TracksController( BaseUIController, UsesVisualizationMixin, UsesHistoryDat
|
||||
|
||||
@web.expose
|
||||
@web.require_login( "use Galaxy visualizations", use_panels=True )
|
||||
def paramamonster( self, trans, hda_ldda, dataset_id ):
|
||||
# Get dataset.
|
||||
dataset = self.get_hda_or_ldda( trans, hda_ldda, dataset_id )
|
||||
def paramamonster( self, trans, id=None, hda_ldda=None, dataset_id=None, regions=None ):
|
||||
if id:
|
||||
# Loading a shared visualization.
|
||||
viz = self.get_visualization( trans, id )
|
||||
viz_config = self.get_visualization_config( trans, viz )
|
||||
dataset = self.get_dataset( trans, viz_config[ 'dataset_id' ] )
|
||||
else:
|
||||
# Loading new visualization.
|
||||
dataset = self.get_hda_or_ldda( trans, hda_ldda, dataset_id )
|
||||
job = get_dataset_job( dataset )
|
||||
viz_config = {
|
||||
'dataset_id': dataset_id,
|
||||
'tool_id': job.tool_id,
|
||||
'regions': regions
|
||||
}
|
||||
|
||||
viz_config[ 'regions' ] = [
|
||||
{
|
||||
'chrom': 'chr19',
|
||||
'start': '10000',
|
||||
'end': '26000'
|
||||
},
|
||||
{
|
||||
'chrom': 'chr19',
|
||||
'start': '150000',
|
||||
'end': '175000'
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
return trans.fill_template_mako( "visualization/paramamonster.mako", dataset=dataset,
|
||||
tool=self.app.toolbox.tools_by_id[ 'cufflinks' ].to_dict( trans, for_display=True ) )
|
||||
# Add tool, dataset attributes to config based on id.
|
||||
tool = trans.app.toolbox.get_tool( viz_config[ 'tool_id' ] )
|
||||
viz_config[ 'tool' ] = tool.to_dict( trans, for_display=True )
|
||||
viz_config[ 'dataset' ] = dataset.get_api_value()
|
||||
|
||||
return trans.fill_template_mako( "visualization/paramamonster.mako", config=viz_config )
|
||||
|
||||
@web.expose
|
||||
@web.require_login( "use Galaxy visualizations", use_panels=True )
|
||||
|
||||
@@ -5,14 +5,26 @@ from galaxy.web.framework.helpers import time_ago, grids, iff
|
||||
from galaxy.util.sanitize_html import sanitize_html
|
||||
|
||||
class VisualizationListGrid( grids.Grid ):
|
||||
def get_link( item ):
|
||||
"""
|
||||
Returns dictionary used to create item link.
|
||||
"""
|
||||
controller = "tracks"
|
||||
if item.type == "trackster":
|
||||
action = "browser"
|
||||
elif item.type == "paramamonster":
|
||||
action = "paramamonster"
|
||||
elif item.type == "circster":
|
||||
action = "circster"
|
||||
return dict( controller=controller, action=action, id=item.id )
|
||||
|
||||
# Grid definition
|
||||
title = "Saved Visualizations"
|
||||
model_class = model.Visualization
|
||||
default_sort_key = "-update_time"
|
||||
default_filter = dict( title="All", deleted="False", tags="All", sharing="All" )
|
||||
columns = [
|
||||
grids.TextColumn( "Title", key="title", attach_popup=True,
|
||||
link=( lambda item: dict( controller="tracks", action="browser", id=item.id ) ) ),
|
||||
grids.TextColumn( "Title", key="title", attach_popup=True, link=get_link ),
|
||||
grids.TextColumn( "Type", key="type" ),
|
||||
grids.TextColumn( "Dbkey", key="dbkey" ),
|
||||
grids.IndividualTagsColumn( "Tags", key="tags", model_tag_association_class=model.VisualizationTagAssociation, filterable="advanced", grid_name="VisualizationListGrid" ),
|
||||
@@ -383,12 +395,20 @@ class VisualizationController( BaseUIController, SharableMixin, UsesAnnotations,
|
||||
template="visualization/create.mako" )
|
||||
|
||||
@web.json
|
||||
def save( self, trans, config, type, id=None, title=None, dbkey=None, annotation=None ):
|
||||
def save( self, trans, vis_json=None, type=None, id=None, title=None, dbkey=None, annotation=None ):
|
||||
"""
|
||||
Save a visualization; if visualization does not have an ID, a new
|
||||
visualization is created. Returns JSON of visualization.
|
||||
"""
|
||||
return self.save_visualization( trans, from_json_string( config ), type, id, title, dbkey, annotation )
|
||||
|
||||
# Get visualization attributes from kwargs or from config.
|
||||
vis_config = from_json_string( vis_json )
|
||||
vis_type = type or vis_config[ 'type' ]
|
||||
vis_id = id or vis_config.get( 'id', None )
|
||||
vis_title = title or vis_config.get( 'title', None )
|
||||
vis_dbkey = dbkey or vis_config.get( 'dbkey', None )
|
||||
vis_annotation = annotation or vis_config.get( 'annotation', None )
|
||||
return self.save_visualization( trans, vis_config, vis_type, vis_id, vis_title, vis_dbkey, vis_annotation )
|
||||
|
||||
@web.expose
|
||||
@web.require_login( "edit visualizations" )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* A dataset. In Galaxy, datasets are associated with a history, so
|
||||
* this object is also known as a HistoryDatasetAssociation.
|
||||
*/
|
||||
var Dataset = Backbone.Model.extend({
|
||||
var Dataset = Backbone.RelationalModel.extend({
|
||||
defaults: {
|
||||
id: "",
|
||||
type: "",
|
||||
|
||||
@@ -46,7 +46,8 @@ var Tool = BaseModel.extend({
|
||||
key: 'inputs',
|
||||
relatedModel: 'ToolInput',
|
||||
reverseRelation: {
|
||||
key: 'tool'
|
||||
key: 'tool',
|
||||
includeInJSON: false
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/**
|
||||
* Tree for a tool's parameters.
|
||||
*/
|
||||
var ToolParameterTree = Backbone.Model.extend({
|
||||
var ToolParameterTree = Backbone.RelationalModel.extend({
|
||||
defaults: {
|
||||
tool: null,
|
||||
tree_data: null
|
||||
@@ -18,9 +18,6 @@ var ToolParameterTree = Backbone.Model.extend({
|
||||
this.get('tool').get('inputs').each(function(input) {
|
||||
if (!input.get_samples()) { return; }
|
||||
|
||||
// All inputs are in tree to start.
|
||||
self.add_param(input);
|
||||
|
||||
// Listen for changes to input's attributes.
|
||||
input.on('change:min change:max change:num_samples', function(input) {
|
||||
if (input.get('in_ptree')) {
|
||||
@@ -38,7 +35,16 @@ var ToolParameterTree = Backbone.Model.extend({
|
||||
}, self);
|
||||
});
|
||||
|
||||
self.set_tree_data();
|
||||
// If there is a config, use it.
|
||||
if (options.config) {
|
||||
_.each(options.config, function(input_config) {
|
||||
var input = self.get('tool').get('inputs').find(function(input) {
|
||||
return input.get('name') === input_config.name;
|
||||
});
|
||||
self.add_param(input);
|
||||
input.set(input_config);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
add_param: function(param) {
|
||||
@@ -203,16 +209,51 @@ var ToolParameterTree = Backbone.Model.extend({
|
||||
cur_node = find_child(cur_node.children);
|
||||
}
|
||||
return cur_node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a list of parameters used in tree.
|
||||
*/
|
||||
toJSON: function() {
|
||||
// FIXME: returning and jsonifying complete param causes trouble on the server side,
|
||||
// so just use essential attributes for now.
|
||||
return this.get_tree_params().map(function(param) {
|
||||
return {
|
||||
name: param.get('name'),
|
||||
min: param.get('min'),
|
||||
max: param.get('max'),
|
||||
num_samples: param.get('num_samples')
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var ParamaMonsterTrack = Backbone.Model.extend({
|
||||
var ParamaMonsterTrack = Backbone.RelationalModel.extend({
|
||||
defaults: {
|
||||
track: null,
|
||||
settings: null,
|
||||
regions: null
|
||||
},
|
||||
|
||||
relations: [
|
||||
{
|
||||
type: Backbone.HasMany,
|
||||
key: 'regions',
|
||||
relatedModel: 'GenomeRegion'
|
||||
}
|
||||
],
|
||||
|
||||
initialize: function(options) {
|
||||
// FIXME: find a better way to deal with needed URLs:
|
||||
var track_config = _.extend({
|
||||
data_url: galaxy_paths.get('raw_data_url'),
|
||||
converted_datasets_state_url: galaxy_paths.get('dataset_state_url')
|
||||
}, options.track);
|
||||
// HACK: remove prefs b/c they cause a redraw, which is not supported now.
|
||||
delete track_config.mode;
|
||||
this.set('track', object_from_template(track_config, {}, null));
|
||||
},
|
||||
|
||||
same_settings: function(a_track) {
|
||||
var this_settings = this.get('settings'),
|
||||
other_settings = a_track.get('settings');
|
||||
@@ -223,6 +264,14 @@ var ParamaMonsterTrack = Backbone.Model.extend({
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
toJSON: function() {
|
||||
return {
|
||||
track: this.get('track').to_dict(),
|
||||
settings: this.get('settings'),
|
||||
regions: this.get('regions')
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -235,18 +284,45 @@ var TrackCollection = Backbone.Collection.extend({
|
||||
*/
|
||||
var ParamaMonsterVisualization = Visualization.extend({
|
||||
defaults: _.extend({}, Visualization.prototype.defaults, {
|
||||
dataset: null,
|
||||
tool: null,
|
||||
parameter_tree: null,
|
||||
regions: null,
|
||||
tracks: null
|
||||
}),
|
||||
|
||||
relations: [
|
||||
{
|
||||
type: Backbone.HasOne,
|
||||
key: 'dataset',
|
||||
relatedModel: 'Dataset'
|
||||
},
|
||||
{
|
||||
type: Backbone.HasOne,
|
||||
key: 'tool',
|
||||
relatedModel: 'Tool'
|
||||
},
|
||||
{
|
||||
type: Backbone.HasMany,
|
||||
key: 'regions',
|
||||
relatedModel: 'GenomeRegion'
|
||||
},
|
||||
{
|
||||
type: Backbone.HasMany,
|
||||
key: 'tracks',
|
||||
relatedModel: 'ParamaMonsterTrack'
|
||||
}
|
||||
// NOTE: cannot use relationship for parameter tree because creating tree is complex.
|
||||
],
|
||||
|
||||
initialize: function(options) {
|
||||
var tool_with_samplable_inputs = this.get('tool').copy(true);
|
||||
this.set('tool_with_samplable_inputs', tool_with_samplable_inputs);
|
||||
|
||||
this.set('parameter_tree', new ToolParameterTree({ tool: tool_with_samplable_inputs }));
|
||||
this.set('tracks', new TrackCollection());
|
||||
this.set('parameter_tree', new ToolParameterTree({
|
||||
tool: tool_with_samplable_inputs,
|
||||
config: options.tree_config
|
||||
}));
|
||||
},
|
||||
|
||||
add_placeholder: function(settings) {
|
||||
@@ -255,6 +331,20 @@ var ParamaMonsterVisualization = Visualization.extend({
|
||||
|
||||
add_track: function(track) {
|
||||
this.get('tracks').add(track);
|
||||
},
|
||||
|
||||
toJSON: function() {
|
||||
// TODO: could this be easier by using relational models?
|
||||
return {
|
||||
id: this.get('id'),
|
||||
title: 'Parameter exploration for dataset \'' + this.get('dataset').get('name') + '\'',
|
||||
type: 'paramamonster',
|
||||
dataset_id: this.get('dataset').id,
|
||||
tool_id: this.get('tool').id,
|
||||
regions: this.get('regions').toJSON(),
|
||||
tree_config: this.get('parameter_tree').toJSON(),
|
||||
tracks: this.get('tracks').toJSON()
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -301,7 +391,7 @@ var ParamaMonsterTrackView = Backbone.View.extend({
|
||||
settings_td.prepend(icon_menu.$el);
|
||||
|
||||
// Render tile placeholders.
|
||||
_.each(this.model.get('regions'), function() {
|
||||
this.model.get('regions').each(function() {
|
||||
self.$el.append($('<td/>').addClass('tile').html(
|
||||
$('<img/>').attr('src', galaxy_paths.get('image_path') + '/loading_large_white_bg.gif')
|
||||
));
|
||||
@@ -322,7 +412,7 @@ var ParamaMonsterTrackView = Backbone.View.extend({
|
||||
// When data is ready, draw tiles.
|
||||
$.when(track.data_manager.data_is_ready()).then(function(data_ok) {
|
||||
// Draw tile for each region.
|
||||
_.each(regions, function(region, index) {
|
||||
regions.each(function(region, index) {
|
||||
var resolution = region.length() / 300,
|
||||
w_scale = 1/resolution,
|
||||
mode = 'Pack';
|
||||
@@ -550,6 +640,12 @@ var ParamaMonsterVisualizationView = Backbone.View.extend({
|
||||
|
||||
// Handle node clicks for tree data.
|
||||
this.model.get('parameter_tree').on('change:tree_data', this.handle_node_clicks, this);
|
||||
|
||||
// Each track must have a view so it has a canvas manager.
|
||||
var self = this;
|
||||
this.model.get('tracks').each(function(track) {
|
||||
track.get('track').view = self;
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
@@ -565,13 +661,17 @@ var ParamaMonsterVisualizationView = Backbone.View.extend({
|
||||
regions = self.model.get('regions'),
|
||||
tr = $('<tr/>').appendTo(this.track_collection_container);
|
||||
|
||||
_.each(regions, function(region) {
|
||||
regions.each(function(region) {
|
||||
tr.append( $('<th>').text(region.toString()) );
|
||||
});
|
||||
tr.children().first().attr('colspan', 2);
|
||||
|
||||
$('#right').append(this.track_collection_container);
|
||||
|
||||
self.model.get('tracks').each(function(track) {
|
||||
self.add_track(track);
|
||||
});
|
||||
|
||||
// Render tool parameter tree in center panel.
|
||||
this.tool_param_tree_view.render();
|
||||
$('#center').append(this.tool_param_tree_view.$el);
|
||||
@@ -588,6 +688,34 @@ var ParamaMonsterVisualizationView = Backbone.View.extend({
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Add track to model and view.
|
||||
*/
|
||||
add_track: function(pm_track) {
|
||||
var self = this;
|
||||
self.model.add_track(pm_track);
|
||||
var track_view = new ParamaMonsterTrackView({
|
||||
model: pm_track,
|
||||
canvas_manager: self.canvas_manager
|
||||
});
|
||||
track_view.on('run_on_dataset', self.run_tool_on_dataset, self);
|
||||
self.track_collection_container.append(track_view.$el);
|
||||
track_view.$el.hover(function() {
|
||||
var settings_leaf = param_tree.get_leaf(settings);
|
||||
var connected_node_ids = _.pluck(param_tree.get_connected_nodes(settings_leaf), 'id');
|
||||
|
||||
// TODO: can do faster with enter?
|
||||
d3.select(self.tool_param_tree_view.$el[0]).selectAll("g.node")
|
||||
.filter(function(d) {
|
||||
return _.find(connected_node_ids, function(id) { return id === d.id; }) !== undefined;
|
||||
}).style('fill', '#f00');
|
||||
},
|
||||
function() {
|
||||
d3.select(self.tool_param_tree_view.$el[0]).selectAll("g.node").style('fill', '#000');
|
||||
});
|
||||
return pm_track;
|
||||
},
|
||||
|
||||
handle_node_clicks: function() {
|
||||
// When node clicked in tree, run tool and add tracks to model.
|
||||
var self = this,
|
||||
|
||||
@@ -69,7 +69,7 @@ var CanvasManager = function(default_font) {
|
||||
this.load_pattern( 'left_strand', "/visualization/strand_left.png" );
|
||||
this.load_pattern( 'right_strand_inv', "/visualization/strand_right_inv.png" );
|
||||
this.load_pattern( 'left_strand_inv', "/visualization/strand_left_inv.png" );
|
||||
}
|
||||
};
|
||||
|
||||
_.extend( CanvasManager.prototype, {
|
||||
load_pattern: function( key, path ) {
|
||||
@@ -79,7 +79,7 @@ _.extend( CanvasManager.prototype, {
|
||||
image.src = galaxy_paths.attributes.image_path + path;
|
||||
image.onload = function() {
|
||||
patterns[key] = dummy_context.createPattern( image, "repeat" );
|
||||
}
|
||||
};
|
||||
},
|
||||
get_pattern: function( key ) {
|
||||
return this.patterns[key];
|
||||
@@ -215,8 +215,8 @@ var GenomeDataManager = Cache.extend({
|
||||
|
||||
// ReferenceDataManager does not have dataset.
|
||||
if (dataset) {
|
||||
params['dataset_id'] = dataset.id;
|
||||
params['hda_ldda'] = dataset.get('hda_ldda');
|
||||
params.dataset_id = dataset.id;
|
||||
params.hda_ldda = dataset.get('hda_ldda');
|
||||
}
|
||||
|
||||
$.extend(params, extra_params);
|
||||
@@ -265,17 +265,16 @@ var GenomeDataManager = Cache.extend({
|
||||
// TODO: this logic could be improved if the visualization knew whether
|
||||
// the data was "index" or "data."
|
||||
//
|
||||
var
|
||||
key_ary = this.get('key_ary'),
|
||||
var key_ary = this.get('key_ary'),
|
||||
obj_cache = this.get('obj_cache'),
|
||||
key, region, entry_region, mode, entry;
|
||||
key, entry_region;
|
||||
for (var i = 0; i < key_ary.length; i++) {
|
||||
entry_region = new GenomeRegion(key_ary[i]);
|
||||
|
||||
if (entry_region.contains(region)) {
|
||||
// This entry has data in the requested range. Return if data
|
||||
// is compatible and can be subsetted.
|
||||
var entry = obj_cache[key];
|
||||
entry = obj_cache[key];
|
||||
if ( is_deferred(entry) ||
|
||||
( this.get('data_mode_compatible')(entry, mode) && this.get('can_subset')(entry) ) ) {
|
||||
this.move_key_to_end(key, i);
|
||||
@@ -298,8 +297,6 @@ var GenomeDataManager = Cache.extend({
|
||||
this.set_elt(region, entry);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
/** "Deep" data request; used as a parameter for DataManager.get_more_data() */
|
||||
DEEP_DATA_REQ: "deep",
|
||||
|
||||
@@ -341,7 +338,7 @@ var GenomeDataManager = Cache.extend({
|
||||
//
|
||||
var
|
||||
data_manager = this,
|
||||
new_data_request = this.load_data(query_region, mode, resolution, extra_params)
|
||||
new_data_request = this.load_data(query_region, mode, resolution, extra_params),
|
||||
new_data_available = $.Deferred();
|
||||
// load_data sets cache to new_data_request, but use custom deferred object so that signal and data
|
||||
// is all data, not just new data.
|
||||
@@ -408,7 +405,7 @@ var Genome = Backbone.Model.extend({
|
||||
/**
|
||||
* A genomic region.
|
||||
*/
|
||||
var GenomeRegion = Backbone.Model.extend({
|
||||
var GenomeRegion = Backbone.RelationalModel.extend({
|
||||
defaults: {
|
||||
chrom: null,
|
||||
start: 0,
|
||||
@@ -431,9 +428,9 @@ var GenomeRegion = Backbone.Model.extend({
|
||||
!this.get('end') && 'as_str' in options) {
|
||||
var pieces = options.as_str.split(':'),
|
||||
chrom = pieces[0],
|
||||
pieces = pieces.split('-'),
|
||||
start = pieces[0],
|
||||
end = pieces[1];
|
||||
start_end = pieces.split('-'),
|
||||
start = start_end[0],
|
||||
end = start_end[1];
|
||||
this.set('chrom', chrom);
|
||||
this.set('start', start);
|
||||
this.set('end', end);
|
||||
@@ -462,7 +459,7 @@ var GenomeRegion = Backbone.Model.extend({
|
||||
chrom: this.get('chrom'),
|
||||
start: this.get('start'),
|
||||
end: this.get('end')
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -556,7 +553,7 @@ var Visualization = Backbone.RelationalModel.extend({
|
||||
datasets: []
|
||||
},
|
||||
|
||||
url: function() { return galaxy_paths.get("visualization_url"); },
|
||||
url: galaxy_paths.get("visualization_url"),
|
||||
|
||||
/**
|
||||
* POSTs visualization's JSON to its URL using the parameter 'vis_json'
|
||||
@@ -565,7 +562,7 @@ var Visualization = Backbone.RelationalModel.extend({
|
||||
*/
|
||||
save: function() {
|
||||
return $.ajax({
|
||||
url: this.url(),
|
||||
url: this.url,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: {
|
||||
@@ -818,7 +815,7 @@ var add_datasets = function(dataset_url, add_track_async_url, success_fn) {
|
||||
requests[requests.length] = $.ajax({
|
||||
url: add_track_async_url,
|
||||
data: data,
|
||||
dataType: "json",
|
||||
dataType: "json"
|
||||
});
|
||||
});
|
||||
// To preserve order, wait until there are definitions for all tracks and then add
|
||||
|
||||
@@ -57,7 +57,8 @@
|
||||
data_url: '${h.url_for( controller="tracks", action="data" )}',
|
||||
raw_data_url: '${h.url_for( controller="tracks", action="raw_data" )}',
|
||||
converted_datasets_state_url: '${h.url_for( controller="tracks", action="converted_datasets_state" )}',
|
||||
dataset_state_url: '${h.url_for( controller="tracks", action="dataset_state" )}'
|
||||
dataset_state_url: '${h.url_for( controller="tracks", action="dataset_state" )}',
|
||||
visualization_url: '${h.url_for( controller="visualization", action="save" )}'
|
||||
});
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
@@ -90,34 +90,43 @@
|
||||
<script type="text/javascript">
|
||||
var viz;
|
||||
$(function() {
|
||||
// -- Viz set up. --
|
||||
|
||||
var tool = new Tool(JSON.parse('${ h.to_json_string( tool ) }')),
|
||||
regions = [
|
||||
new GenomeRegion({
|
||||
chrom: 'chr19',
|
||||
start: '10000',
|
||||
end: '26000'
|
||||
}),
|
||||
new GenomeRegion({
|
||||
chrom: 'chr19',
|
||||
start: '150000',
|
||||
end: '175000'
|
||||
})
|
||||
],
|
||||
// HACK: need to replace \ with \\ due to simplejson bug.
|
||||
dataset = new Dataset(JSON.parse('${ h.to_json_string( dataset.get_api_value() ).replace('\\', '\\\\' ) }'));
|
||||
|
||||
|
||||
viz = new ParamaMonsterVisualization({
|
||||
tool: tool,
|
||||
dataset: dataset,
|
||||
regions: regions
|
||||
});
|
||||
// -- Viz set up. --
|
||||
var viz = new ParamaMonsterVisualization(
|
||||
${ h.to_json_string( config ).replace('\\', '\\\\' )}
|
||||
);
|
||||
var viz_view = new ParamaMonsterVisualizationView({ model: viz });
|
||||
|
||||
viz_view.render();
|
||||
$('.unified-panel-body').append(viz_view.$el);
|
||||
|
||||
// -- Menu set up. --
|
||||
var menu = create_icon_buttons_menu([
|
||||
{ icon_class: 'disk--arrow', title: 'Save', on_click: function() {
|
||||
// Show saving dialog box
|
||||
show_modal("Saving...", "progress");
|
||||
|
||||
viz.save().success(function(vis_info) {
|
||||
hide_modal();
|
||||
viz.set({
|
||||
'id': vis_info.vis_id,
|
||||
'has_changes': false
|
||||
});
|
||||
})
|
||||
.error(function() {
|
||||
show_modal( "Could Not Save", "Could not save visualization. Please try again later.",
|
||||
{ "Close" : hide_modal } );
|
||||
});
|
||||
} },
|
||||
{ icon_class: 'cross-circle', title: 'Close', on_click: function() {
|
||||
window.location = "${h.url_for( controller='visualization', action='list' )}";
|
||||
} }
|
||||
],
|
||||
{
|
||||
tipsy_config: {gravity: 'n'}
|
||||
});
|
||||
|
||||
menu.$el.attr("style", "float: right");
|
||||
$("#right .unified-panel-header-inner").append(menu.$el);
|
||||
});
|
||||
</script>
|
||||
</%def>
|
||||
@@ -129,4 +138,8 @@
|
||||
</%def>
|
||||
|
||||
<%def name="right_panel()">
|
||||
<div class="unified-panel-header" unselectable="on">
|
||||
<div class="unified-panel-header-inner">
|
||||
</div>
|
||||
</div>
|
||||
</%def>
|
||||
Reference in New Issue
Block a user