Style fixes

This commit is contained in:
guerler
2016-06-22 11:32:40 -04:00
parent f36ad6a53b
commit 930c37ffb1
10 changed files with 696 additions and 954 deletions
@@ -1,107 +1,67 @@
// dependencies
define(['mvc/ui/ui-modal', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'utils/utils',
'plugin/library/jobs', 'plugin/library/datasets', 'plugin/library/storage', 'utils/deferred',
'plugin/views/viewer', 'plugin/views/editor',
'plugin/models/config', 'plugin/models/chart',
'plugin/charts/types'],
function( Modal, Portlet, Ui, Utils, Jobs, Datasets, Storage, Deferred,
ViewerView, EditorView,
Config, Chart, Types
) {
/**
* Main application class.
*/
return Backbone.View.extend({
// initialize
initialize: function(options){
// deactivate all debugs outputs
//window.console.debug = function() {};
// link options
this.options = options;
define([ 'mvc/ui/ui-modal', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'utils/utils',
'plugin/library/jobs', 'plugin/library/datasets', 'plugin/library/storage', 'utils/deferred',
'plugin/views/viewer', 'plugin/views/editor',
'plugin/models/config', 'plugin/models/chart', 'plugin/charts/types' ],
function( Modal, Portlet, Ui, Utils, Jobs, Datasets, Storage, Deferred,
ViewerView, EditorView, Config, Chart, Types ) {
return Backbone.View.extend({
initialize: function(options){
this.options = options;
this.modal = parent.Galaxy && parent.Galaxy.modal || new Modal.View();
// link galaxy modal or create one
if (Galaxy && Galaxy.modal) {
this.modal = Galaxy.modal;
} else {
this.modal = new Modal.View();
}
//
// models
//
this.config = new Config();
this.types = new Types();
this.chart = new Chart();
//
// libraries
//
this.jobs = new Jobs(this);
this.datasets = new Datasets(this);
this.storage = new Storage(this);
this.deferred = new Deferred();
//
// views
//
this.viewer_view = new ViewerView(this);
this.editor_view = new EditorView(this);
// append views
this.$el.append(this.viewer_view.$el);
this.$el.append(this.editor_view.$el);
// pick start screen
if (!this.storage.load()) {
// show editor
this.go('editor');
} else {
// show viewport
this.go('viewer');
// draw chart
var self = this;
this.deferred.execute(function() {
self.chart.trigger('redraw');
});
}
},
// loads a view and makes sure that all others are hidden
go: function(view_id) {
// hide all tooltips
$('.tooltip').hide();
// pick view
switch (view_id) {
case 'editor' :
this.editor_view.show();
this.viewer_view.hide();
break;
case 'viewer' :
this.editor_view.hide();
this.viewer_view.show();
break;
}
},
// get root path
chartPath: function(chart_type) {
// create path from id
var path = chart_type.split(/_(.+)/);
// check path
if (path.length >= 2) {
// return path
return path[0] + '/' + path[1];
} else {
// log status
console.debug('FAILED App:chartPath() - Invalid format: ' + chart_type);
}
return undefined;
}
});
// models
this.config = new Config();
this.types = new Types();
this.chart = new Chart();
// libraries
this.jobs = new Jobs(this);
this.datasets = new Datasets( this );
this.storage = new Storage( this );
this.deferred = new Deferred();
// views
this.viewer_view = new ViewerView( this );
this.editor_view = new EditorView( this );
// append views
this.$el.append( this.viewer_view.$el );
this.$el.append( this.editor_view.$el );
// pick start screen
if ( !this.storage.load() ) {
this.go( 'editor' );
} else {
this.go( 'viewer' );
this.chart.trigger( 'redraw' );
}
},
/** Loads a view and makes sure that all others are hidden */
go: function(view_id) {
$( '.tooltip' ).hide();
switch ( view_id ) {
case 'editor' :
this.editor_view.show();
this.viewer_view.hide();
break;
case 'viewer' :
this.editor_view.hide();
this.viewer_view.show();
break;
}
},
/** Returns root path */
chartPath: function( chart_type ) {
var path = chart_type.split( /_(.+)/ );
if ( path.length >= 2 ) {
return path[ 0 ] + '/' + path[ 1 ];
}
console.debug( 'FAILED app:chartPath() - Invalid format: ' + chart_type );
}
});
});
@@ -1,11 +1,8 @@
// dependencies
define(['utils/utils'], function(Utils) {
/**
* This class handles, formats and caches datasets.
*/
return Backbone.Collection.extend(
{
define( [ 'utils/utils' ], function( Utils ) {
return Backbone.Collection.extend({
// list of datasets
list: {},
@@ -14,10 +11,7 @@ return Backbone.Collection.extend(
// initialize
initialize: function(app, options){
// link app
this.app = app;
// configure options
this.options = Utils.merge(options, this.optionsDefault);
},
@@ -1,190 +1,153 @@
// dependencies
define(['utils/utils'], function(Utils) {
/**
* This class handles job submissions to the charts tool.
*/
return Backbone.Model.extend({
// initialize
initialize: function(app, options) {
// link app
this.app = app;
define( [ 'utils/utils' ], function( Utils ) {
return Backbone.Model.extend({
initialize: function( app, options ) {
this.app = app;
this.options = Utils.merge( options, this.optionsDefault );
},
// link options
this.options = Utils.merge(options, this.optionsDefault);
},
// request job results
request: function(chart, settings_string, columns_string, success, error) {
// link this
var self = this;
// set chart state
chart.state('wait', 'Requesting job results...');
// get dataset job id if already set
var dataset_id_job = chart.get('dataset_id_job');
if (dataset_id_job != '') {
// wait for job completion
self._wait(chart, success, error);
} else {
// post job
self._submit(chart, settings_string, columns_string, success, error);
}
},
// clean
cleanup: function(chart) {
// link this
var self = this;
// cleanup previous dataset file
var previous = chart.get('dataset_id_job');
if (previous != '') {
Utils.request({
type : 'PUT',
url : config.root + 'api/histories/none/contents/' + previous,
data : { deleted: true },
success : function() {
// update galaxy history
self._refreshHdas();
}
});
// reset id
chart.set('dataset_id_job', '');
}
},
// create job
_submit: function(chart, settings_string, columns_string, success, error) {
// link this
var self = this;
// backup chart details
var chart_id = chart.id;
var chart_type = chart.get('type');
// get chart settings
var chart_definition = chart.definition;
// configure tool
data = {
'tool_id' : 'charts',
'inputs' : {
'input' : {
'id' : chart.get('dataset_id'),
'src' : 'hda'
},
'module' : chart_definition.execute,
'columns' : columns_string,
'settings' : settings_string
/* Request job results */
request: function( chart, settings_string, columns_string, success, error ) {
var self = this;
chart.state( 'wait', 'Requesting job results...' );
var dataset_id_job = chart.get( 'dataset_id_job' );
if (dataset_id_job != '') {
self._wait( chart, success, error );
} else {
self._submit( chart, settings_string, columns_string, success, error );
}
}
},
// set chart state
chart.state('wait', 'Sending job request...');
/* Remove previous data when re-running jobs */
cleanup: function( chart ) {
var self = this;
var previous = chart.get( 'dataset_id_job' );
if (previous != '') {
Utils.request({
type : 'PUT',
url : config.root + 'api/histories/none/contents/' + previous,
data : { deleted: true },
success : function() {
self._refreshHdas();
}
});
chart.set( 'dataset_id_job', '' );
}
},
// post job
Utils.request({
type : 'POST',
url : config.root + 'api/tools',
data : data,
success : function(response) {
if (!response.outputs || response.outputs.length == 0) {
chart.state('failed', 'Job submission failed. No response.');
// create job
_submit: function(chart, settings_string, columns_string, success, error) {
// link this
var self = this;
// backup chart details
var chart_id = chart.id;
var chart_type = chart.get('type');
// get chart settings
var chart_definition = chart.definition;
// configure tool
data = {
'tool_id' : 'charts',
'inputs' : {
'input' : {
'id' : chart.get('dataset_id'),
'src' : 'hda'
},
'module' : chart_definition.execute,
'columns' : columns_string,
'settings' : settings_string
}
}
// set chart state
chart.state('wait', 'Sending job request...');
// post job
Utils.request({
type : 'POST',
url : config.root + 'api/tools',
data : data,
success : function(response) {
if (!response.outputs || response.outputs.length == 0) {
chart.state('failed', 'Job submission failed. No response.');
// call error
error && error();
} else {
// update galaxy history
self._refreshHdas();
// get dataset
var job = response.outputs[0];
// check dataset
chart.state('wait', 'Your job has been queued. You may close the browser window. The job will run in the background.');
// backup resulting dataset id
chart.set('dataset_id_job', job.id);
// save
self.app.storage.save();
// wait for job completion
self._wait(chart, success, error);
}
},
error : function(response) {
var message = '';
if (response && response.message && response.message.data && response.message.data.input) {
message = response.message.data.input + '.';
}
// update state
chart.state('failed', 'This visualization requires the \'charts\' tool. Please make sure it is installed. ' + message);
// call error
error && error();
} else {
// update galaxy history
self._refreshHdas();
}
});
},
// get dataset
var job = response.outputs[0];
// check dataset
chart.state('wait', 'Your job has been queued. You may close the browser window. The job will run in the background.');
// backup resulting dataset id
chart.set('dataset_id_job', job.id);
// save
self.app.storage.save();
// wait for job completion
self._wait(chart, success, error);
/** Request job details */
_wait: function( chart, success, error ) {
var self = this;
Utils.request({
type : 'GET',
url : config.root + 'api/datasets/' + chart.get( 'dataset_id_job' ),
data : {},
success : function( dataset ) {
var ready = false;
switch ( dataset.state ) {
case 'ok':
chart.state( 'wait', 'Job completed successfully...' );
success && success( dataset );
ready = true;
break;
case 'error':
chart.state( 'failed', 'Job has failed. Please check the history for details.' );
error && error( dataset );
ready = true;
break;
case 'running':
chart.state( 'wait', 'Your job is running. You may close the browser window. The job will continue in the background.' );
}
if ( !ready ) {
setTimeout( function() {
self._wait( chart, success, error );
}, self.app.config.get( 'query_timeout' ) );
}
}
},
error : function(response) {
var message = '';
if (response && response.message && response.message.data && response.message.data.input) {
message = response.message.data.input + '.';
}
// update state
chart.state('failed', 'This visualization requires the \'charts\' tool. Please make sure it is installed. ' + message);
// call error
error && error();
}
});
},
// request job details
_wait: function(chart, success, error) {
var self = this;
Utils.request({
type : 'GET',
url : config.root + 'api/datasets/' + chart.get('dataset_id_job'),
data : {},
success : function(dataset) {
// check dataset state
var ready = false;
switch (dataset.state) {
case 'ok':
// update state
chart.state('wait', 'Job completed successfully...');
// execute success
success && success(dataset);
// stop loop
ready = true;
break;
case 'error':
// update state
chart.state('failed', 'Job has failed. Please check the history for details.');
// call error
error && error(dataset);
// stop loop
ready = true;
break;
case 'running':
// wait
chart.state('wait', 'Your job is running. You may close the browser window. The job will continue in the background.');
}
// wait and try again
if (!ready) {
setTimeout(function() {
self._wait(chart, success, error);
}, self.app.config.get('query_timeout'));
}
}
});
},
// refresh history panel
_refreshHdas: function() {
// update galaxy history
if (Galaxy && Galaxy.currHistoryPanel) {
Galaxy.currHistoryPanel.refreshContents();
});
},
/** Refresh history panel */
_refreshHdas: function() {
Galaxy && Galaxy.currHistoryPanel && Galaxy.currHistoryPanel.refreshContents();
}
}
});
});
});
@@ -1,142 +1,83 @@
// dependencies
define(['utils/utils', 'plugin/models/chart', 'plugin/models/group', 'mvc/visualization/visualization-model'], function(Utils, Chart, Group) {
/**
* This class saves and loads a chart through the api.
*/
return Backbone.Model.extend({
// viz model
vis: null,
// initialize
initialize: function(app) {
// link app
this.app = app;
// link chart
this.chart = this.app.chart;
// link options
this.options = this.app.options;
// initialize parameters
this.id = this.options.id;
// create visualization
this.vis = new Visualization({
type : 'charts',
config : {
dataset_id : this.options.config.dataset_id,
chart_dict : {}
}
});
// add visualization id
if (this.id) {
this.vis.id = this.id;
}
// add charts
var chart_dict = this.options.config.chart_dict;
if (chart_dict) {
this.vis.get('config').chart_dict = chart_dict;
}
},
// pack and save nested chart model
save: function() {
// link chart
var chart = this.app.chart;
// reset
this.vis.get('config').chart_dict = {};
// set title
var title = chart.get('title');
if (title != '') {
this.vis.set('title', title);
}
// create chart dictionary
var chart_dict = {
attributes : chart.attributes,
settings : chart.settings.attributes,
groups : []
};
// append groups
chart.groups.each(function(group) {
chart_dict.groups.push(group.attributes);
});
// add chart to charts array
this.vis.get('config').chart_dict = chart_dict;
// save visualization
var self = this;
this.vis.save()
.fail(function(xhr, status, message) {
console.error(xhr, status, message);
})
.then(function(response) {
if (response && response.id) {
self.id = response.id;
define( [ 'utils/utils', 'plugin/models/chart', 'plugin/models/group', 'mvc/visualization/visualization-model' ],
function( Utils, Chart, Group ) {
return Backbone.Model.extend({
vis: null,
initialize: function( app ) {
this.app = app;
this.chart = this.app.chart;
this.options = this.app.options;
this.id = this.options.id;
this.vis = new Visualization({
id : this.id,
type : 'charts',
config : {
dataset_id : this.options.config.dataset_id,
chart_dict : {}
}
});
},
// load nested models/collections from packed dictionary
load: function() {
// get charts array
var chart_dict = this.vis.get('config').chart_dict;
// check
if (!chart_dict.attributes) {
return false;
}
// get chart type
var chart_type = chart_dict.attributes['type'];
// check chart type
if (!chart_type) {
console.debug('Storage::load() - Chart type not provided. Invalid format.');
return false;
}
// get chart definition
var chart_definition = this.app.types.get(chart_type);
if (!chart_definition) {
console.debug('Storage::load() - Chart type not supported. Please re-configure the chart. Resetting chart.');
return false;
}
// initiating chart
console.debug('Storage::load() - Loading chart type ' + chart_type + '.');
// parse chart definition
this.chart.definition = chart_definition;
// main
this.chart.set(chart_dict.attributes);
// set state
this.chart.state('ok', 'Loading saved visualization...');
// get settings
this.chart.settings.set(chart_dict.settings);
// get groups
for (var j in chart_dict.groups) {
this.chart.groups.add(new Group(chart_dict.groups[j]));
}
// reset modified flag
this.chart.set('modified', false);
// return
return true;
}
});
var chart_dict = this.options.config.chart_dict;
if ( chart_dict ) {
this.vis.get( 'config' ).chart_dict = chart_dict;
}
},
/** Pack and save nested chart model */
save: function() {
var self = this;
var chart = this.app.chart;
var chart_dict = {
attributes : chart.attributes,
settings : chart.settings.attributes,
groups : []
};
chart.groups.each( function( group ) {
chart_dict.groups.push( group.attributes );
});
this.vis.set( 'title', chart.get( 'title' ) || '' );
this.vis.get( 'config' ).chart_dict = chart_dict;
this.vis.save().fail(function( xhr, status, message ) {
console.error( xhr, status, message );
})
.then( function( response ) {
if ( response && response.id ) {
self.id = response.id;
} else {
console.debug('Storage::save() - Unrecognized response. Saving may have failed.');
}
});
},
/** Load nested models/collections from packed dictionary */
load: function() {
var chart_dict = this.vis.get( 'config' ).chart_dict;
if ( !chart_dict.attributes ) {
console.debug('Storage::load() - Chart attributes not found. Invalid format.');
return false;
}
var chart_type = chart_dict.attributes[ 'type' ];
if ( !chart_type ) {
console.debug('Storage::load() - Chart type not provided. Invalid format.');
return false;
}
var chart_definition = this.app.types.get( chart_type );
if ( !chart_definition ) {
console.debug('Storage::load() - Chart type not supported. Please re-configure the chart. Resetting chart.');
return false;
}
this.chart.definition = chart_definition;
this.chart.set( chart_dict.attributes );
this.chart.state( 'ok', 'Loading saved visualization...' );
this.chart.settings.set( chart_dict.settings );
for ( var j in chart_dict.groups ) {
this.chart.groups.add( new Group( chart_dict.groups[ j ] ) );
}
this.chart.set( 'modified', false );
console.debug('Storage::load() - Loading chart type ' + chart_type + '.');
return true;
}
});
});
@@ -1,67 +1,45 @@
// dependencies
define(['plugin/models/groups'], function(Groups) {
define( [ 'plugin/models/groups' ], function( Groups ) {
return Backbone.Model.extend({
defaults : {
id : null,
title : '',
type : '',
date : null,
state : '',
state_info : '',
modified : false,
dataset_id : '',
dataset_id_job : ''
},
// model
return Backbone.Model.extend({
// defaults
defaults : {
id : null,
title : '',
type : '',
date : null,
state : '',
state_info : '',
modified : false,
dataset_id : '',
dataset_id_job : ''
},
// initialize
initialize: function(options) {
this.groups = new Groups();
this.settings = new Backbone.Model();
},
// reset
reset: function() {
this.clear({silent: true}).set(this.defaults);
this.groups.reset();
this.settings.clear();
this.trigger('reset', this);
},
// copy
copy: function(new_chart) {
// copy chart/groups
var current = this;
// set attributes
current.clear({silent: true}).set(this.defaults);
current.set(new_chart.attributes);
// set nested models/collections
current.settings = new_chart.settings.clone();
current.groups.reset();
new_chart.groups.each(function(group) {
current.groups.add(group.clone());
});
// trigger change
current.trigger('change', current);
},
// set state
state: function(value, info) {
// set status
this.set('state', value);
this.set('state_info', info);
// trigger set state
this.trigger('set:state');
// log status
console.debug('Chart:state() - ' + info + ' (' + value + ')');
}
});
initialize: function( options ) {
this.groups = new Groups();
this.settings = new Backbone.Model();
},
reset: function() {
this.clear( { silent: true } ).set( this.defaults );
this.groups.reset();
this.settings.clear();
this.trigger( 'reset', this );
},
copy: function( new_chart ) {
var current = this;
current.clear( { silent: true } ).set( this.defaults );
current.set( new_chart.attributes );
current.settings = new_chart.settings.clone();
current.groups.reset();
new_chart.groups.each( function( group ) {
current.groups.add( group.clone() );
});
current.trigger( 'change', current );
},
state: function( value, info ) {
this.set( { 'state': value, 'state_info', info } );
this.trigger( 'set:state' );
console.debug( 'Chart:state() - ' + info + ' (' + value + ')' );
}
});
});
@@ -1,13 +1,8 @@
// dependencies
define([], function() {
// model
return Backbone.Model.extend({
// options
defaults : {
query_limit : 10000,
query_timeout : 100
}
});
define( [], function() {
return Backbone.Model.extend({
defaults : {
query_limit : 10000,
query_timeout : 100
}
});
});
@@ -1,19 +1,13 @@
// dependencies
define([], function() {
// model
return Backbone.Model.extend({
// options
defaults : {
key : 'Data label',
date : ''
},
// reset
reset: function(){
this.clear({silent: true}).set(this.defaults);
this.trigger('reset', this);
}
});
define( [], function() {
return Backbone.Model.extend({
defaults : {
key : 'Data label',
date : ''
},
reset: function(){
this.clear( { silent: true } ).set( this.defaults );
this.trigger( 'reset', this );
}
});
});
@@ -1,9 +1,5 @@
// dependencies
define(['plugin/models/group'], function(Group) {
// collection
return Backbone.Collection.extend({
model: Group
});
define( [ 'plugin/models/group' ], function( Group ) {
return Backbone.Collection.extend({
model: Group
});
});
@@ -1,162 +1,140 @@
// dependencies
define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-portlet',
'plugin/views/viewport', 'plugin/library/screenshot'],
function(Utils, Ui, Portlet, ViewportView, Screenshot) {
/**
* This class renders the chart viewer which encapsulates the chart viewport.
*/
return Backbone.View.extend({
// initialize
initialize: function(app, options){
// link app
this.app = app;
// link chart
this.chart = this.app.chart;
// create viewport
this.viewport_view = new ViewportView(app);
// link this
var self = this;
// message element
this.message = new Ui.Message();
// button menu
var picture_button_menu = new Ui.ButtonMenu({
icon : 'fa-camera',
title : 'Screenshot',
tooltip : 'Download as PNG, SVG or PDF file'
});
// add png option
picture_button_menu.addMenu({
id : 'button-png',
title : 'Save as PNG',
icon : 'fa-file',
onclick : function() {
self._wait (self.chart, function() {
Screenshot.createPNG({
$el : self.viewport_view.$el,
title : self.chart.get('title'),
error : function(err) {
self.message.update({ message: err, status: 'danger' });
}
define( [ 'utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-portlet',
'plugin/views/viewport', 'plugin/library/screenshot' ],
function( Utils, Ui, Portlet, ViewportView, Screenshot ) {
return Backbone.View.extend({
initialize: function(app, options){
var self = this;
this.app = app;
this.chart = this.app.chart;
this.viewport_view = new ViewportView( app );
this.message = new Ui.Message();
// button menu
var picture_button_menu = new Ui.ButtonMenu({
icon : 'fa-camera',
title : 'Screenshot',
tooltip : 'Download as PNG, SVG or PDF file'
});
// add png option
picture_button_menu.addMenu({
id : 'button-png',
title : 'Save as PNG',
icon : 'fa-file',
onclick : function() {
self._wait( self.chart, function() {
Screenshot.createPNG({
$el : self.viewport_view.$el,
title : self.chart.get( 'title' ),
error : function( err ) {
self.message.update( { message: err, status: 'danger' } );
}
});
});
});
}
});
// add png option
picture_button_menu.addMenu({
id : 'button-svg',
title : 'Save as SVG',
icon : 'fa-file-text-o',
onclick : function() {
self._wait (self.chart, function() {
Screenshot.createSVG({
$el : self.viewport_view.$el,
title : self.chart.get('title'),
error : function(err) {
self.message.update({ message: err, status: 'danger' });
}
}
});
// add svg option
picture_button_menu.addMenu({
id : 'button-svg',
title : 'Save as SVG',
icon : 'fa-file-text-o',
onclick : function() {
self._wait( self.chart, function() {
Screenshot.createSVG({
$el : self.viewport_view.$el,
title : self.chart.get( 'title' ),
error : function( err ) {
self.message.update( { message: err, status: 'danger' } );
}
});
});
});
}
});
// add png option
picture_button_menu.addMenu({
id : 'button-png',
title : 'Save as PDF',
icon : 'fa-file-o',
onclick : function() {
self.app.modal.show({
title : 'Send chart data for PDF creation',
body : 'Galaxy does not provide integrated PDF export scripts. You may click \'Continue\' to create the PDF by using a 3rd party service (https://export.highcharts.com).',
buttons : {
'Cancel' : function() {self.app.modal.hide()},
'Continue' : function() {
self.app.modal.hide();
self._wait (self.chart, function() {
Screenshot.createPDF({
$el : self.viewport_view.$el,
title : self.chart.get('title'),
error : function(err) {
self.message.update({ message: err, status: 'danger' });
}
}
});
// add pdf option
picture_button_menu.addMenu({
id : 'button-png',
title : 'Save as PDF',
icon : 'fa-file-o',
onclick : function() {
self.app.modal.show({
title : 'Send chart data for PDF creation',
body : 'Galaxy does not provide integrated PDF export scripts. You may click \'Continue\' to create the PDF by using a 3rd party service (https://export.highcharts.com).',
buttons : {
'Cancel' : function() { self.app.modal.hide() },
'Continue' : function() {
self.app.modal.hide();
self._wait( self.chart, function() {
Screenshot.createPDF({
$el : self.viewport_view.$el,
title : self.chart.get( 'title' ),
error : function( err ) {
self.message.update( { message: err, status: 'danger' } );
}
});
});
}
}
});
}
});
// create portlet
this.portlet = new Portlet.View({
icon : 'fa-bar-chart-o',
title: 'Viewport',
operations: {
edit_button: new Ui.ButtonIcon({
icon : 'fa-edit',
tooltip : 'Customize this chart',
title : 'Editor',
onclick : function() {
self._wait( self.chart, function() {
self.app.go( 'editor' );
});
}
}
});
}
});
}),
picture_button_menu: picture_button_menu
}
});
// create portlet
this.portlet = new Portlet.View({
icon : 'fa-bar-chart-o',
title: 'Viewport',
operations: {
edit_button: new Ui.ButtonIcon({
icon : 'fa-edit',
tooltip : 'Customize this chart',
title : 'Editor',
onclick : function() {
self._wait (self.chart, function() {
self.app.go('editor');
});
}
}),
picture_button_menu: picture_button_menu
}
});
// append portlet
this.portlet.append(this.message.$el.addClass('ui-margin-top'));
this.portlet.append(this.viewport_view.$el);
// set element
this.setElement(this.portlet.$el);
// events
var self = this;
this.chart.on('change:title', function() {
self._refreshTitle();
});
},
// append elements
this.portlet.append( this.message.$el.addClass( 'ui-margin-top' ) );
this.portlet.append( this.viewport_view.$el );
this.setElement( this.portlet.$el );
// show
show: function() {
// show element
this.$el.show();
// trigger resize to refresh d3 element
$(window).trigger('resize');
},
// hide
hide: function() {
this.$el.hide();
},
// refresh title
_refreshTitle: function() {
var title = this.chart.get('title');
this.portlet.title(title);
},
// wait for chart to be ready
_wait: function(chart, callback) {
// get chart
if (this.app.deferred.ready()) {
callback();
} else {
this.message.update({message: 'Your chart is currently being processed. Please wait and try again.'});
// events
this.chart.on( 'change:title', function() { self._refreshTitle() } );
},
/** Show and refresh viewer */
show: function() {
this.$el.show();
$( window ).trigger( 'resize' );
},
/** Hide viewer */
hide: function() {
this.$el.hide();
},
/** Change title */
_refreshTitle: function() {
var title = this.chart.get( 'title' );
this.portlet.title( title );
},
/** Check if chart is ready for export */
_wait: function(chart, callback) {
if ( this.app.deferred.ready() ) {
callback();
} else {
this.message.update( { message: 'Your chart is currently being processed. Please wait and try again.' } );
}
}
}
});
});
});
@@ -1,303 +1,246 @@
// dependencies
define(['mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'utils/utils'],
function(Portlet, Ui, Utils) {
/**
* The viewport creates and manages the dom elements used by the visualization plugins to draw the chart.
* Additionally, this class creates default request strings and request dictionaries parsed to the visualization plugins.
* This is the last class of the charts core classes before handing control over to the visualization plugins.
*/
return Backbone.View.extend({
define([ 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', 'utils/utils' ],
function( Portlet, Ui, Utils ) {
return Backbone.View.extend({
// list of container/canvas elements
container_list: [],
canvas_list: [],
// list of canvas elements
container_list: [],
canvas_list: [],
// initialize
initialize: function(app, options) {
// link app
this.app = app;
// link chart
this.chart = this.app.chart;
// link options
this.options = Utils.merge(options, this.optionsDefault);
// create element
this.setElement($(this._template()));
// use full screen for viewer
this._fullscreen(this.$el, 50);
// prevent window scrolling
var initial_overflow = $('body').css('overflow');
this.$el.on('mouseover', function() {
$('body').css('overflow', 'hidden');
}).on('mouseout', function() {
$('body').css('overflow', initial_overflow);
});
// create container element
this._createContainer('div');
// events
var self = this;
this.chart.on('redraw', function() {
self.app.deferred.execute(function(process) {
self._draw(process, self.chart);
initialize: function( app, options ) {
this.app = app;
this.chart = this.app.chart;
this.options = options;
this.setElement( $( this._template() ) );
// use full screen for viewer
this._fullscreen( this.$el, 50 );
// prevent window scrolling
var initial_overflow = $( 'body' ).css( 'overflow' );
this.$el.on( 'mouseover', function() {
$( 'body' ).css( 'overflow', 'hidden' );
}).on('mouseout', function() {
$( 'body' ).css( 'overflow', initial_overflow );
});
});
// link status handler
this.chart.on('set:state', function() {
// get info element
var $info = self.$el.find('#info');
var $container = self.$el.find('.charts-viewport-container');
// get icon
var $icon = $info.find('#icon');
// remove icon
$icon.removeClass();
// show info
$info.show();
$info.find('#text').html(self.chart.get('state_info'));
// check status
var state = self.chart.get('state');
switch (state) {
case 'ok':
$info.hide();
$container.show();
break;
case 'failed':
$icon.addClass('icon fa fa-warning');
$container.hide();
break;
default:
$icon.addClass('icon fa fa-spinner fa-spin');
$container.show();
}
});
},
// show
show: function() {
this.$el.show();
},
// hide
hide: function() {
this.$el.hide();
},
// resize to fullscreen
_fullscreen: function($el, margin) {
// fix size
$el.css('height', $(window).height() - margin);
// catch window resize event
$(window).resize(function () {
$el.css('height', $(window).height() - margin);
});
},
// creates n canvas elements
_createContainer: function(tag, n) {
// check size of requested canvas elements
n = n || 1;
// clear previous canvas elements
for (var i in this.container_list) {
this.container_list[i].remove();
}
// reset lists
this.container_list = [];
this.canvas_list = [];
// create requested canvas elements
for (var i = 0; i < n; i++) {
// create element
var container_el = $(this._templateContainer(tag, parseInt(100 / n)));
// add to view
this.$el.append(container_el);
// add to list
this.container_list[i] = container_el;
// add a separate list for canvas elements
this.canvas_list[i] = container_el.find('.charts-viewport-canvas').attr('id');
}
},
// add
_draw: function(process, chart) {
// link this
var self = this;
// identify chart type
var chart_type = chart.get('type');
// load chart settings
this.chart_definition = chart.definition;
// determine number of svg/div-elements to create
var n_panels = 1;
if (chart.settings.get('use_panels') === 'true') {
n_panels = chart.groups.length;
}
// create canvas element and add to canvas list
this._createContainer(this.chart_definition.tag, n_panels);
// set chart state
chart.state('wait', 'Please wait...');
// clean up data if there is any from previous jobs
if (!this.chart_definition.execute ||
(this.chart_definition.execute && chart.get('modified'))) {
// reset jobs
this.app.jobs.cleanup(chart);
// reset modified flag
chart.set('modified', false);
}
// create chart view
var self = this;
require(['plugin/charts/' + this.app.chartPath(chart_type) + '/wrapper'], function(ChartView) {
if (self.chart_definition.execute) {
self.app.jobs.request(chart, self._defaultSettingsString(chart), self._defaultRequestString(chart),
function() {
var view = new ChartView(self.app, {
process : process,
chart : chart,
request_dictionary : self._defaultRequestDictionary(chart),
canvas_list : self.canvas_list
});
},
function() {
process.reject();
}
);
} else {
var view = new ChartView(self.app, {
process : process,
chart : chart,
request_dictionary : self._defaultRequestDictionary(chart),
canvas_list : self.canvas_list
// create container element
this._createContainer( 'div' );
// link redraw trigger
var self = this;
this.chart.on( 'redraw', function() {
self.app.deferred.execute( function( process ) {
self._draw( process, self.chart );
});
}
});
},
});
//
// REQUEST STRING FUNCTIONS
//
// create default chart request
_defaultRequestString: function(chart) {
// configure request
var request_string = '';
// link status handler
this.chart.on( 'set:state', function() {
var $info = self.$el.find( '#info' );
var $container = self.$el.find( '.charts-viewport-container' );
var $icon = $info.find( '#icon' );
var $info_text = $info.find( '#text' );
$icon.removeClass();
$info.show();
$info_text.html( self.chart.get( 'state_info' ) );
var state = self.chart.get( 'state' );
switch ( state ) {
case 'ok':
$info.hide();
$container.show();
break;
case 'failed':
$icon.addClass( 'icon fa fa-warning' );
$container.hide();
break;
default:
$icon.addClass( 'icon fa fa-spinner fa-spin' );
$container.show();
}
});
},
/** Show rendered chart */
show: function() {
this.$el.show();
},
/** Hide chart */
hide: function() {
this.$el.hide();
},
/** Force resize to fullscreen */
_fullscreen: function( $el, margin ) {
$el.css( 'height', $( window ).height() - margin );
$( window ).resize( function() {
$el.css( 'height', $( window ).height() - margin );
});
},
/** A chart may contain multiple sub charts/containers which are created here */
_createContainer: function( tag, n ) {
n = n || 1;
for ( var i in this.container_list ) {
this.container_list[ i ].remove();
}
this.container_list = [];
this.canvas_list = [];
for ( var i = 0; i < n; i++ ) {
var container_el = $( this._templateContainer( tag, parseInt( 100 / n ) ) );
this.$el.append( container_el );
this.container_list[ i ] = container_el;
this.canvas_list[ i ] = container_el.find( '.charts-viewport-canvas' ).attr( 'id' );
}
},
/** Draws a new chart by loading and executing the corresponding chart wrapper */
_draw: function( process, chart ) {
var self = this;
var chart_type = chart.get( 'type' );
this.chart_definition = chart.definition;
var n_panels = 1;
if ( chart.settings.get( 'use_panels' ) === 'true' ) {
n_panels = chart.groups.length;
}
this._createContainer( this.chart_definition.tag, n_panels );
chart.state( 'wait', 'Please wait...' );
if ( !this.chart_definition.execute || ( this.chart_definition.execute && chart.get( 'modified' ) ) ) {
this.app.jobs.cleanup( chart );
chart.set( 'modified', false );
}
require( [ 'plugin/charts/' + this.app.chartPath( chart_type ) + '/wrapper' ], function( ChartView ) {
if ( self.chart_definition.execute ) {
self.app.jobs.request( chart, self._defaultSettingsString( chart ), self._defaultRequestString( chart ),
function() {
var view = new ChartView( self.app, {
process : process,
chart : chart,
request_dictionary : self._defaultRequestDictionary( chart ),
canvas_list : self.canvas_list
});
},
function() {
process.reject();
}
);
} else {
var view = new ChartView( self.app, {
process : process,
chart : chart,
request_dictionary : self._defaultRequestDictionary( chart ),
canvas_list : self.canvas_list
});
}
});
},
//
// REQUEST STRING FUNCTIONS
//
// create default chart request
_defaultRequestString: function(chart) {
// add groups to data request
var group_index = 0;
var self = this;
chart.groups.each(function(group) {
// increase group counter
group_index++;
// configure request
var request_string = '';
// add selected columns to column string
for (var key in self.chart_definition.columns) {
request_string += key + '_' + group_index + ':' + (parseInt(group.get(key)) + 1) + ', ';
}
});
// add groups to data request
var group_index = 0;
var self = this;
chart.groups.each(function(group) {
// increase group counter
group_index++;
// add selected columns to column string
for (var key in self.chart_definition.columns) {
request_string += key + '_' + group_index + ':' + (parseInt(group.get(key)) + 1) + ', ';
}
});
// return
return request_string.substring(0, request_string.length - 2);
},
// return
return request_string.substring(0, request_string.length - 2);
},
// create default chart request
_defaultSettingsString: function(chart) {
// configure settings
var settings_string = '';
// create default chart request
_defaultSettingsString: function(chart) {
// add settings to settings string
for (key in chart.settings.attributes) {
settings_string += key + ':' + chart.settings.get(key) + ', ';
};
// return
return settings_string.substring(0, settings_string.length - 2);
},
// configure settings
var settings_string = '';
// add settings to settings string
for (key in chart.settings.attributes) {
settings_string += key + ':' + chart.settings.get(key) + ', ';
};
// return
return settings_string.substring(0, settings_string.length - 2);
},
// create default chart request
_defaultRequestDictionary: function(chart) {
// configure request
var request_dictionary = {
groups : []
};
// create default chart request
_defaultRequestDictionary: function(chart) {
// update request dataset id
if (this.chart_definition.execute) {
request_dictionary.id = chart.get('dataset_id_job');
} else {
request_dictionary.id = chart.get('dataset_id');
// configure request
var request_dictionary = {
groups : []
};
// update request dataset id
if (this.chart_definition.execute) {
request_dictionary.id = chart.get('dataset_id_job');
} else {
request_dictionary.id = chart.get('dataset_id');
}
// add groups to data request
var group_index = 0;
var self = this;
chart.groups.each(function(group) {
// add columns
var columns = {};
for (var column_key in self.chart_definition.columns) {
// get settings for column
var column_settings = self.chart_definition.columns[column_key];
// add to columns
columns[column_key] = Utils.merge ({
index : group.get(column_key)
}, column_settings);
}
// add group data
request_dictionary.groups.push({
key : (++group_index) + ':' + group.get('key'),
columns : columns
});
});
// return
return request_dictionary;
},
// template
_template: function() {
return '<div class="charts-viewport">' +
'<div id="info" class="info">' +
'<span id="icon" class="icon"/>' +
'<span id="text" class="text" />' +
'</div>' +
'</div>';
},
// template svg/div element
_templateContainer: function(tag, width) {
return '<div class="charts-viewport-container" style="width:' + width + '%;">' +
'<div id="menu"/>' +
'<' + tag + ' id="' + Utils.uid() + '" class="charts-viewport-canvas">' +
'</div>';
}
// add groups to data request
var group_index = 0;
var self = this;
chart.groups.each(function(group) {
// add columns
var columns = {};
for (var column_key in self.chart_definition.columns) {
// get settings for column
var column_settings = self.chart_definition.columns[column_key];
// add to columns
columns[column_key] = Utils.merge ({
index : group.get(column_key)
}, column_settings);
}
// add group data
request_dictionary.groups.push({
key : (++group_index) + ':' + group.get('key'),
columns : columns
});
});
// return
return request_dictionary;
},
// template
_template: function() {
return '<div class="charts-viewport">' +
'<div id="info" class="info">' +
'<span id="icon" class="icon"/>' +
'<span id="text" class="text" />' +
'</div>' +
'</div>';
},
// template svg/div element
_templateContainer: function(tag, width) {
return '<div class="charts-viewport-container" style="width:' + width + '%;">' +
'<div id="menu"/>' +
'<' + tag + ' id="' + Utils.uid() + '" class="charts-viewport-canvas">' +
'</div>';
}
});
});
});