1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/ee176b881f37/ Changeset: ee176b881f37 User: guerler Date: 2014-01-16 18:24:47 Summary: Charts: Update view organization Affected #: 14 files diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/app.js --- a/config/plugins/visualizations/charts/static/app.js +++ b/config/plugins/visualizations/charts/static/app.js @@ -1,9 +1,9 @@ // dependencies define(['library/portlet', 'library/ui', 'library/utils', - 'main', 'viewport', 'create', 'config', + 'views/charts', 'views/viewport', 'views/chart', 'views/group', 'models/datasets', 'models/chart', 'models/charts', 'models/types'], function( Portlet, Ui, Utils, - Main, Viewport, Create, Config, + ChartsView, ViewportView, ChartView, GroupView, Datasets, Chart, Charts, Types ) { @@ -19,32 +19,32 @@ // link galaxy this.modal = parent.Galaxy.modal; - // create chart objects + // create chart models this.types = new Types(); this.chart = new Chart(); - this.charts = new Charts(this); + this.charts = new Charts(); // create dataset handler this.datasets = new Datasets(this); // create views - this.main = new Main(this); - this.viewport = new Viewport(this); - this.config = new Config(this); - this.create = new Create(this); + this.charts_view = new ChartsView(this); + this.group_view = new GroupView(this); + this.chart_view = new ChartView(this); + this.viewport_view = new ViewportView(this); // portlet this.portlet = new Portlet({icon : 'fa-bar-chart-o', label : 'Charts'}); - this.portlet.append(this.main.$el); - this.portlet.append(this.config.$el); - this.portlet.append(this.create.$el); + this.portlet.append(this.charts_view.$el); + this.portlet.append(this.group_view.$el); + this.portlet.append(this.chart_view.$el); // append main - this.main.append(this.viewport.$el); + this.charts_view.append(this.viewport_view.$el); // create - this.config.$el.hide(); - this.main.$el.hide(); + this.group_view.$el.hide(); + this.charts_view.$el.hide(); // set elements this.setElement(this.portlet.$el); diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/config.js --- a/config/plugins/visualizations/charts/static/config.js +++ /dev/null @@ -1,219 +0,0 @@ -// dependencies -define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/group'], - function(Portlet, Table, Ui, Utils, Group) { - -// chart config -return Backbone.View.extend( -{ - // model - group: new Group(), - - // columns - columns: [], - - // initialize - initialize: function(app, options) { - // link app - this.app = app; - - // get current chart object - this.chart = this.app.chart; - - // ui elements - this.message = new Ui.Message(); - this.label = new Ui.Input({placeholder: 'Group label'}); - this.table = new Table({content: 'No data column.'}); - - // add table to portlet - var self = this; - this.portlet = new Portlet({ - icon : 'fa-edit', - label : 'Define group properties:', - operations : { - 'save' : new Ui.ButtonIcon({ - icon : 'fa-save', - tooltip : 'Save', - onclick : function() { - // save/add group - self._saveGroup(); - } - }), - 'back' : new Ui.ButtonIcon({ - icon : 'fa-caret-left', - tooltip : 'Return', - onclick : function() { - self.$el.hide(); - self.app.create.$el.show(); - } - }) - } - }); - this.portlet.append(this.message.$el); - this.portlet.append(this.label.$el); - this.portlet.append(this.table.$el); - - // add element - this.setElement(this.portlet.$el); - - // change - var self = this; - this.chart.on('change:dataset_id', function() { - self._refreshDataset(); - }); - this.chart.on('change:type', function() { - self._refreshType(); - }); - this.group.on('change:label', function() { - self._refreshLabel(); - }); - this.group.on('change', function() { - self._refreshGroup(); - }); - }, - - // show - show: function() { - this.$el.show(); - }, - - // reset - reset: function() { - this.group.reset(); - this.group.set('id', Utils.uuid()); - this.group.set('label', 'Group label'); - }, - - // update dataset - _refreshDataset: function() { - // identify datasets - var dataset_id = this.chart.get('dataset_id'); - - // check if dataset is available - if (!dataset_id) { - return; - } - - // get dataset - var dataset = this.app.datasets.get({id : dataset_id}); - - // check - if (!dataset) { - this.app.log('Config::render()', 'Failed to retrieve dataset.'); - return; - } - - // configure columns - this.columns = []; - var meta = dataset.metadata_column_types; - for (var key in meta){ - this.columns.push({ - 'label' : key + ' [' + meta[key] + ']', - 'value' : key - }); - } - - // update select fields - for (var key in this.list) { - this.list[key].update(this.columns); - } - }, - - // update - _refreshType: function() { - // configure chart type - var self = this; - var chart_type = this.chart.get('type'); - if (chart_type) { - var chart_settings = this.app.types.get(chart_type); - - // table - this.table.removeAll(); - this.list = {}; - for (var id in chart_settings.data) { - // create select field - var data_def = chart_settings.data[id]; - var select = new Ui.Select({ - id : 'select_' + id, - gid : id, - data : this.columns, - onchange : function(value) { - self.group.set(this.gid, value); - } - }); - - // add row to table - this.table.add(data_def.title); - this.table.add(select.$el); - this.table.append(id); - - // add select field to list - this.list[id] = select; - } - } - }, - - // update - _refreshGroup: function() { - // update select fields - for (var id in this.list) { - var col = this.group.get(id); - if (col === undefined) { - col = 0; - } - this.list[id].value(col); - } - }, - - // update label - _refreshLabel: function() { - var label_text = this.group.get('label'); - if (label_text === undefined) { - label_text = ''; - } - this.label.value(label_text); - }, - - // create group - _saveGroup: function() { - // get current chart - var chart = this.chart; - - // update group object - var group = this.group; - for (var key in this.list) { - group.set(key, this.list[key].value()); - } - - // add label - group.set({ - dataset_id : this.chart.get('dataset_id'), - label : this.label.value(), - date : Utils.time() - }); - - // validate - if (!group.get('label')) { - this.message.update({message : 'Please enter a label for your group.'}); - return; - } - - // get groups of current chart - var groups = this.chart.groups; - - // create/update group - var group_update = groups.get(group.id); - if (group_update) { - group_update.set(group.attributes); - } else { - groups.add(group.clone()); - } - - // hide - this.$el.hide(); - - // update main - this.app.create.$el.show(); - } -}); - -}); \ No newline at end of file diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/create.js --- a/config/plugins/visualizations/charts/static/create.js +++ /dev/null @@ -1,207 +0,0 @@ -// dependencies -define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/chart', 'groups'], - function(Portlet, Table, Ui, Utils, Chart, Groups) { - -// widget -return Backbone.View.extend( -{ - // defaults options - optionsDefault: { - header : true, - content : 'No content available.' - }, - - // current chart - chart : null, - - // initialize - initialize: function(app, options) - { - // link application - this.app = app; - - // get current chart object - this.chart = this.app.chart; - - // configure options - this.options = Utils.merge(options, this.optionsDefault); - - // main elements - this.message = new Ui.Message(); - this.title = new Ui.Input({placeholder: 'Chart title'}); - this.dataset = new Ui.Input({value : app.options.dataset.id, disabled: true, visible: false}); - - // configure dataset - this.groups = new Groups(this.app); - - // table - var self = this; - this.table = new Table({ - header : false, - onconfirm : function(type) { - if (self.chart.groups.length > 0) { - // show modal - self.app.modal.show({ - title : 'Switching the chart type?', - body : 'You configured data sources. If you switch chart types your configurations will be removed.', - buttons : { - 'Cancel' : function() { - // hide modal - self.app.modal.hide(); - }, - 'Continue' : function() { - // hide modal - self.app.modal.hide(); - - // confirm - self.table.confirm(type); - } - } - }); - } else { - // confirm - self.table.confirm(type); - } - }, - onchange : function(type) { - // update chart type - self.chart.set({type: type}); - - // reset groups - self.chart.groups.reset(); - }, - content: 'No chart types available' - }); - - // add types - var types_n = 0; - var types = app.types.attributes; - for (var id in types){ - var chart_type = types[id]; - this.table.add (++types_n + '.'); - this.table.add (chart_type.title); - this.table.append(id); - } - - // add table to portlet - var self = this; - this.portlet = new Portlet({ - icon : 'fa-edit', - label : 'Create a new chart:', - operations : { - 'save' : new Ui.ButtonIcon({ - icon : 'fa-save', - tooltip : 'Save Chart', - onclick : function() { - self._saveChart(); - } - }), - 'back' : new Ui.ButtonIcon({ - icon : 'fa-caret-left', - tooltip : 'Return', - onclick : function() { - self.$el.hide(); - self.app.main.$el.show(); - } - }) - } - }); - this.portlet.append(this.message.$el); - this.portlet.append(this.dataset.$el); - this.portlet.append((new Ui.Label({ label : 'Provide a chart title:'})).$el); - this.portlet.append(this.title.$el); - this.portlet.append((new Ui.Label({ label : 'Select a chart type:'})).$el); - this.portlet.append(this.table.$el); - this.portlet.append(this.groups.$el); - - // elements - this.setElement(this.portlet.$el); - - // hide back button on startup - this.portlet.hideOperation('back'); - - // model events - var self = this; - this.chart.on('change:title', function(chart) { - self.title.value(chart.get('title')); - }); - this.chart.on('change:type', function(chart) { - self.table.value(chart.get('type')); - }); - - // collection events - this.app.charts.on('add', function(chart) { - self.portlet.showOperation('back'); - }); - this.app.charts.on('remove', function(chart) { - if (self.app.charts.length == 1) { - self.portlet.hideOperation('back'); - } - }); - this.app.charts.on('reset', function(chart) { - self.portlet.hideOperation('back'); - }); - - // reset - this.reset(); - }, - - // reset - reset: function() { - this.chart.reset(); - this.chart.set('id', Utils.uuid()); - this.chart.set('dataset_id', this.app.options.dataset.id); - this.chart.set('type', 'bardiagram'); - this.chart.set('title', 'Chart title'); - }, - - // set chart - setChart: function(new_chart) { - this.chart.copy(new_chart); - }, - - // create chart - _saveChart: function() { - // update chart data - this.chart.set({ - type : this.table.value(), - title : this.title.value(), - dataset_id : this.dataset.value(), - date : Utils.time() - }); - - // validate - if (!this.chart.get('title')) { - this.message.update({message : 'Please enter a title for your chart.'}); - return; - } - - if (!this.chart.get('type')) { - this.message.update({message : 'Please select a chart type.'}); - return; - } - - if (this.chart.groups.length == 0) { - this.message.update({message : 'Please configure at least one data source.'}); - return; - } - - // create/get chart - var current = this.app.charts.get(this.chart.id); - if (!current) { - current = this.chart.clone(); - this.app.charts.add(current); - } - - // update chart model - current.copy(this.chart); - - // hide - this.$el.hide(); - - // update main - this.app.main.$el.show(); - } -}); - -}); \ No newline at end of file diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/groups.js --- a/config/plugins/visualizations/charts/static/groups.js +++ /dev/null @@ -1,154 +0,0 @@ -// dependencies -define(['library/portlet', 'library/table', 'library/ui', 'library/utils'], function(Portlet, Table, Ui, Utils) { - -// chart config -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - // link app - this.app = app; - - // get current chart object - this.chart = this.app.chart; - - // table - this.table = new Table({ - content : 'Add data columns to this table.', - ondblclick : function(group_id) { - // get group - var group = self.app.chart.groups.get(group_id); - - // show edit - self.app.create.$el.hide(); - self.app.config.show(); - self.app.config.group.set(group.attributes); - } - }); - - // add table to portlet - var self = this; - this.portlet = new Portlet({ - icon : '', - label : 'Select data columns:', - height : 100, - operations : { - 'new' : new Ui.ButtonIcon({ - icon : 'fa-plus', - tooltip: 'Create', - onclick: function() { - self.app.create.$el.hide(); - self.app.config.show(); - self.app.config.reset(); - } - }), - 'edit' : new Ui.ButtonIcon({ - icon : 'fa-pencil', - tooltip: 'Edit', - onclick: function() { - // check if element has been selected - var group_id = self.table.value(); - if (!group_id) { - return; - } - - // get group - var group = self.app.chart.groups.get(group_id); - - // show edit - self.app.create.$el.hide(); - self.app.config.show(); - self.app.config.group.set(group.attributes); - } - }), - 'delete' : new Ui.ButtonIcon({ - icon : 'fa-minus', - tooltip: 'Delete', - onclick: function() { - // check if element has been selected - var id = self.table.value(); - if (!id) { - return; - } - // remove group from chart - self.chart.groups.remove(id); - } - }) - } - }); - this.portlet.append(this.table.$el); - - // add element - this.setElement(this.portlet.$el); - - // change - var self = this; - this.chart.on('change', function() { - self._refresh(); - }); - this.chart.on('reset', function() { - self._removeGroupAll(); - }); - this.chart.on('change:type', function() { - self.app.config.trigger('change'); - }); - this.chart.groups.on('add', function(group) { - self._addGroup(group); - }); - this.chart.groups.on('remove', function(group) { - self._removeGroup(group); - }); - this.chart.groups.on('reset', function(group) { - self._removeGroupAll(); - }); - this.chart.groups.on('change', function(group) { - self._removeGroup(group); - self._addGroup(group); - }); - }, - - // refresh - _refresh: function() { - this._removeGroupAll(); - var self = this; - var groups = this.chart.groups; - if (groups) { - groups.each(function(group) { self._addGroup(group); }); - } - }, - - // add - _addGroup: function(group) { - // make custom info string - var info = '['; - var chart_type = this.chart.get('type'); - if (chart_type) { - var chart_settings = this.app.types.get(chart_type); - for (var key in chart_settings.data) { - info += key + '=' + group.get(key) + ', ' - } - } - info = info.substring(0, info.length - 2) + ']'; - - // add to table - this.table.add(group.get('label')); - this.table.add(info); - this.table.add('Last changed: ' + group.get('date')); - this.table.prepend(group.id); - this.table.value(group.id); - }, - - // remove - _removeGroup: function(group) { - // remove from to table - this.table.remove(group.id); - }, - - // data config reset - _removeGroupAll: function() { - // reset options table - this.table.removeAll(); - } -}); - -}); \ No newline at end of file diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/library/ui.js --- a/config/plugins/visualizations/charts/static/library/ui.js +++ b/config/plugins/visualizations/charts/static/library/ui.js @@ -48,14 +48,14 @@ this.options = Utils.merge(options, this.optionsDefault); // create new element - this.setElement(this.template(this.options)); + this.setElement(this._template(this.options)); // add event $(this.el).on('click', options.onclick); }, // element - template: function(options) { + _template: function(options) { var str = '<button id="' + options.id + '" type="' + options.type + '" style="margin-right: 5px; float: ' + options.float + ';" type="button" class="btn ' + options.cls + '">'; if (options.icon) { str += '<i class="icon fa ' + options.icon + '"></i> ' ; @@ -80,14 +80,14 @@ this.options = Utils.merge(options, this.optionsDefault); // create new element - this.setElement(this.template(this.options)); + this.setElement(this._template(this.options)); // add event $(this.el).on('click', options.onclick); }, // element - template: function(options) { + _template: function(options) { return '<div><a href="javascript:void(0)">' + options.label + '</a></div>'; } }); @@ -218,7 +218,7 @@ var ButtonMenu = Backbone.View.extend( { // main options - options: + optionsDefault: { id : '', title : '', @@ -237,9 +237,8 @@ // initialize initialize: function (options) { - // read in defaults - if (options) - this.options = _.defaults(options, this.options); + // get options + this.options = Utils.merge(options, this.optionsDefault); // add template for tab this.setElement($(this._template(this.options))); @@ -290,9 +289,8 @@ icon : null } - // read in defaults - if (options) - menuOptions = _.defaults(options, menuOptions); + // get options + menuOptions = Utils.merge(options, menuOptions); // check if submenu element is available if (!this.$menu) @@ -388,10 +386,7 @@ // initialize initialize : function(options) { // get options - if (options) - this.options = _.defaults(options, this.optionsDefault); - else - this.options = this.optionsDefault; + this.options = Utils.merge(options, this.optionsDefault); // create new element this.setElement(this.template(this.options)); @@ -430,11 +425,8 @@ // initialize initialize : function(options) { - // get options - if (options) - this.options = _.defaults(options, this.optionsDefault); - else - this.options = this.optionsDefault; + // configure options + this.options = Utils.merge(options, this.optionsDefault); // create new element this.setElement(this.template(this.options)); diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/library/ui.select.js --- a/config/plugins/visualizations/charts/static/library/ui.select.js +++ b/config/plugins/visualizations/charts/static/library/ui.select.js @@ -1,14 +1,14 @@ // dependencies define(['library/utils'], function(Utils) { - // plugin return Backbone.View.extend( { // options optionsDefault: { - id : '', - cls : '' + id : '', + cls : '', + empty : 'No data available' }, // initialize @@ -17,21 +17,41 @@ this.options = Utils.merge(options, this.optionsDefault); // create new element - this.setElement(this.template(this.options)); + this.setElement(this._template(this.options)); // add change event var self = this; if (this.options.onchange) { - this.$el.on('change', function() { self.options.onchange(self.value()) }); + this.$el.on('change', function() { self.options.onchange(self.value()); }); } + + // refresh + this._refresh(); }, // value - value : function (new_val) { - if (new_val !== undefined) { - this.$el.val(new_val); + value : function (new_value) { + // get current id/value + var before = this.$el.val(); + + // check if new_value is defined + if (new_value !== undefined) { + this.$el.val(new_value); } - return this.$el.val(); + + // get current id/value + var after = this.$el.val(); + if(after === undefined) { + return null; + } else { + // fire onchange + if ((after != before && this.options.onchange) || this.$el.find('option').length == 1) { + this.options.onchange(after); + } + + // return current value + return after; + } }, // label @@ -43,6 +63,35 @@ disabled: function() { return this.$el.is(':disabled'); }, + + // enable + enable: function() { + this.$el.prop('disabled', false); + }, + + // disable + disable: function() { + this.$el.prop('disabled', true); + }, + + // add + add: function(options) { + // add options + $(this.el).append(this._templateOption(options)); + + // refresh + this._refresh(); + }, + + // remove + remove: function(value) { + // remove option + $(this.el).find('option[value=' + value + ']').remove(); + $(this.el).trigger('change'); + + // refresh + this._refresh(); + }, // render update: function(options) { @@ -54,47 +103,46 @@ // add new options for (var key in options.data) { - $(this.el).append(this.templateOption(options.data[key])); + $(this.el).append(this._templateOption(options.data[key])); } - // check if selected value exists - var exists = 0 != $(this.el).find('option[value=' + selected + ']').length; + // add selected value + if (this._exists(selected)) + $(this.el).val(selected); - // add selected value - if (exists) - $(this.el).val(selected); + // refresh + this._refresh(); }, - // update from url - updateUrl : function(options, callback) { - // get json - var self = this; - Utils.get(options.url, function(json) { - // write data into array - var data = []; - for (key in json) { - data.push({label: json[key].name, value: json[key].id}); - } - - // check if disabled. do not update disabled select elements. - if (!self.disabled()) { - self.update({data: data}); - } - - // callback - if (callback) { - callback(); - } - }); + // refresh + _refresh: function() { + // remove placeholder + $(this.el).find('option[value=null]').remove(); + + // count remaining entries + var remaining = $(this.el).find('option').length; + if (remaining == 0) { + // append placeholder + $(this.el).append(this._templateOption({value : 'null', label : this.options.empty})); + this.disable(); + } else { + this.enable(); + } + }, + + // exists + _exists: function(value) { + // check if selected value exists + return 0 != $(this.el).find('option[value=' + value + ']').length; }, // option - templateOption: function(options) { + _templateOption: function(options) { return '<option value="' + options.value + '">' + options.label + '</option>'; }, // element - template: function(options) { + _template: function(options) { var tmpl = '<select id="' + options.id + '" class="select ' + options.cls + ' ' + options.id + '">'; for (key in options.data) { // options diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/library/utils.js --- a/config/plugins/visualizations/charts/static/library/utils.js +++ b/config/plugins/visualizations/charts/static/library/utils.js @@ -6,21 +6,6 @@ request('GET', url, {}, success, error); }; -// delete -function del (url, success, error) { - request('DELETE', url, {}, success, error); -}; - -// post -function post (url, data, success, error) { - request('POST', url, data, success, error); -}; - -// put -function put (url, data, success, error) { - request('PUT', url, data, success, error); -}; - // generic function to send json to url function request (method, url, data, success, error) { @@ -134,11 +119,8 @@ return { cssLoadFile : cssLoadFile, cssGetAttribute : cssGetAttribute, + get : get, merge : merge, - get : get, - post : post, - del : del, - put : put, request: request, uuid: uuid, wrap : wrap, diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/main.js --- a/config/plugins/visualizations/charts/static/main.js +++ /dev/null @@ -1,150 +0,0 @@ -// dependencies -define(['library/portlet', 'library/table', 'library/ui', 'library/utils'], function(Portlet, Table, Ui, Utils) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) - { - // link app - this.app = app; - - // table - this.table = new Table({ - content : 'Add charts to this table.', - ondblclick : function(chart_id) { - // get chart - var chart = self.app.charts.get(chart_id); - - // show edit - self.$el.hide(); - - // update model and show create - self.app.create.setChart(chart); - self.app.create.$el.show(); - }, - onchange : function(chart_id) { - self.app.viewport.show(chart_id); - } - }); - - // add table to portlet - var self = this; - this.portlet = new Portlet({ - icon : 'fa-list', - label : 'List of created charts:', - height : 100, - operations : { - 'new' : new Ui.ButtonIcon({ - icon : 'fa-plus', - tooltip: 'Create', - onclick: function() { - self.$el.hide(); - self.app.create.reset(); - self.app.create.$el.show(); - } - }), - 'edit' : new Ui.ButtonIcon({ - icon : 'fa-pencil', - tooltip: 'Edit', - onclick: function() { - // check if element has been selected - var chart_id = self.table.value(); - if (!chart_id) { - return; - } - - // get chart - var chart = self.app.charts.get(chart_id); - - // show edit - self.$el.hide(); - self.app.create.$el.show(); - self.app.create.setChart(chart); - } - }), - 'delete' : new Ui.ButtonIcon({ - icon : 'fa-minus', - tooltip: 'Delete', - onclick: function() { - - // check if element has been selected - var chart_id = self.table.value(); - if (!chart_id) { - return; - } - - // title - var chart = self.app.charts.get(chart_id); - - // show modal - self.app.modal.show({ - title : 'Are you sure?', - body : 'The selected chart "' + chart.get('title') + '" will be irreversibly deleted.', - buttons : { - 'Cancel' : function() {self.app.modal.hide();}, - 'Delete' : function() { - // hide modal - self.app.modal.hide(); - - // remove chart - self.app.charts.remove(chart_id); - } - } - }); - } - }), - } - }); - this.portlet.append(this.table.$el); - - // append to main - this.$el.append(this.portlet.$el); - - // events - var self = this; - this.app.charts.on('add', function(chart) { - // add - self._addChart(chart); - }); - this.app.charts.on('remove', function(chart) { - // remove - self._removeChart(chart); - }); - this.app.charts.on('change', function(chart) { - // replace - self._removeChart(chart); - self._addChart(chart); - }); - }, - - // append - append : function($el) { - this.$el.append(Utils.wrap('')); - this.$el.append($el); - }, - - // add - _addChart: function(chart) { - // add title to table - this.table.add(chart.get('title')); - - // get chart type - var type = this.app.types.get(chart.get('type')); - this.table.add(type.title); - - // add additional columns - this.table.add('Last change: ' + chart.get('date')); - this.table.prepend(chart.get('id')); - this.table.value(chart.get('id')); - }, - - // remove - _removeChart: function(chart) { - // remove from to table - this.table.remove(chart.id); - } -}); - -}); \ No newline at end of file diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/viewport.js --- a/config/plugins/visualizations/charts/static/viewport.js +++ /dev/null @@ -1,202 +0,0 @@ -// dependencies -define(['library/portlet', 'library/ui', 'library/utils'], - function(Portlet, Ui, Utils) { - -// widget -return Backbone.View.extend( -{ - // list - list: {}, - - // options - optionsDefault : - { - height : 300 - }, - - // initialize - initialize: function(app, options) - { - // link app - this.app = app; - - // link options - this.options = Utils.merge(options, this.optionsDefault); - - // add table to portlet - this.portlet = new Portlet({ - height : this.options.height, - overflow : 'hidden' - }); - - // set this element - this.setElement(this.portlet.$el); - - // events - var self = this; - - // add - this.app.charts.on('add', function(chart) { - self._addChart(chart); - }); - - // remove - this.app.charts.on('remove', function(chart) { - self._removeChart(chart.id); - }); - - // replace - this.app.charts.on('change', function(chart) { - self._removeChart(chart.id); - self._addChart(chart); - }); - }, - - // show - show: function(id) { - // hide all - this.$el.find('svg').hide(); - - var item = this.list[id]; - if (item) { - // show selected chart - this.$el.find(item.svg_id).show(); - - // this trigger d3 update events - $(window).trigger('resize'); - } - }, - - // add - _addChart: function(chart) { - // make sure that svg does not exist already - this._removeChart(chart.id); - - // create id - var svg_id = '#svg_' + chart.id; - - // create element - var chart_el = $(this._template({id: svg_id, height : this.options.height})); - - // add to portlet - this.portlet.append(chart_el); - - // backup id - this.list[chart.id] = { - svg_id : svg_id - } - - // identify chart type - var chart_type = chart.get('type'); - var chart_settings = this.app.types.get(chart_type); - - // create chart view - var self = this; - require(['charts/' + chart_type], function(ChartView) { - // create chart - var view = new ChartView(self.app, {svg_id : svg_id, chart : chart}); - - // reset chart data - var chart_data = []; - - // request data - var chart_index = 0; - chart.groups.each(function(group) { - - // add group data - chart_data.push({ - key : (chart_index + 1) + ':' + group.get('label'), - values : [] - }); - - // get data - for (var key in chart_settings.data) { - // configure request - var data_options = { - view : view, - data : chart_data, - index : chart_index, - dataset_id : group.get('dataset_id'), - column : group.get(key), - column_key : key - } - - // make request - self._data(data_options); - } - - // count - chart_index++; - }); - - // add view - self.list[chart.id].view = view; - }); - }, - - // data - _data: function(options) { - // gather objects - var view = options.view; - var data = options.data; - - // gather parameters - var index = options.index; - var column = options.column; - var dataset_id = options.dataset_id; - var column_key = options.column_key; - var group_data = data[options.index]; - - // send request - self.app.datasets.get({id : dataset_id, column: column}, function(dataset) { - // select column - var values = dataset.values[column]; - var n_values = values.length; - - // read column values - var column_values = []; - for (var i = 0; i < n_values; i++) { - var value = values[i]; - if(!isNaN(value)) { - column_values.push(value); - } else { - column_values.push(0) - } - } - - // write column values - for (var i = 0; i < n_values; i++) { - // make sure dictionary exists - if (group_data.values[i] === undefined) { - group_data.values[i] = { - x : i, - y : 0 - } - } - - // write data - group_data.values[i][column_key] = column_values[i]; - } - - // refresh view - view.refresh(data); - }); - - }, - - // remove - _removeChart: function(id) { - var item = this.list[id]; - if (item) { - d3.select(item.svg_id).remove(); - $(item.svg_id).remove(); - } - }, - - // template - _template: function(options) { - return '<svg id="' + options.id.substr(1) + '"style="height: ' + options.height + 'px;"></svg>'; - } -}); - -}); \ No newline at end of file diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/views/chart.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/views/chart.js @@ -0,0 +1,204 @@ +// dependencies +define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/chart', 'views/groups'], + function(Portlet, Table, Ui, Utils, Chart, GroupsView) { + +// widget +return Backbone.View.extend( +{ + // defaults options + optionsDefault: { + header : true, + content : 'No content available.' + }, + + // initialize + initialize: function(app, options) + { + // link application + this.app = app; + + // get current chart object + this.chart = this.app.chart; + + // configure options + this.options = Utils.merge(options, this.optionsDefault); + + // main elements + this.message = new Ui.Message(); + this.title = new Ui.Input({placeholder: 'Chart title'}); + this.dataset = new Ui.Input({value : app.options.dataset.id, disabled: true, visible: false}); + + // configure dataset + this.groups_view = new GroupsView(this.app); + + // table + var self = this; + this.table = new Table({ + header : false, + onconfirm : function(type) { + if (self.chart.groups.length > 0) { + // show modal + self.app.modal.show({ + title : 'Switching the chart type?', + body : 'You configured data sources. If you switch chart types your configurations will be removed.', + buttons : { + 'Cancel' : function() { + // hide modal + self.app.modal.hide(); + }, + 'Continue' : function() { + // hide modal + self.app.modal.hide(); + + // confirm + self.table.confirm(type); + } + } + }); + } else { + // confirm + self.table.confirm(type); + } + }, + onchange : function(type) { + // update chart type + self.chart.set({type: type}); + + // reset groups + self.chart.groups.reset(); + }, + content: 'No chart types available' + }); + + // add types + var types_n = 0; + var types = app.types.attributes; + for (var id in types){ + var chart_type = types[id]; + this.table.add (++types_n + '.'); + this.table.add (chart_type.title); + this.table.append(id); + } + + // add table to portlet + var self = this; + this.portlet = new Portlet({ + icon : 'fa-edit', + label : 'Create a new chart:', + operations : { + 'save' : new Ui.ButtonIcon({ + icon : 'fa-save', + tooltip : 'Save Chart', + onclick : function() { + self._saveChart(); + } + }), + 'back' : new Ui.ButtonIcon({ + icon : 'fa-caret-left', + tooltip : 'Return', + onclick : function() { + self.$el.hide(); + self.app.charts_view.$el.show(); + } + }) + } + }); + this.portlet.append(this.message.$el); + this.portlet.append(this.dataset.$el); + this.portlet.append((new Ui.Label({ label : 'Provide a chart title:'})).$el); + this.portlet.append(this.title.$el); + this.portlet.append((new Ui.Label({ label : 'Select a chart type:'})).$el); + this.portlet.append(this.table.$el); + this.portlet.append(this.groups_view.$el); + + // elements + this.setElement(this.portlet.$el); + + // hide back button on startup + this.portlet.hideOperation('back'); + + // model events + var self = this; + this.chart.on('change:title', function(chart) { + self.title.value(chart.get('title')); + }); + this.chart.on('change:type', function(chart) { + self.table.value(chart.get('type')); + }); + + // collection events + this.app.charts.on('add', function(chart) { + self.portlet.showOperation('back'); + }); + this.app.charts.on('remove', function(chart) { + if (self.app.charts.length == 1) { + self.portlet.hideOperation('back'); + } + }); + this.app.charts.on('reset', function(chart) { + self.portlet.hideOperation('back'); + }); + + // reset + this.reset(); + }, + + // reset + reset: function() { + this.chart.reset(); + this.chart.set('id', Utils.uuid()); + this.chart.set('dataset_id', this.app.options.dataset.id); + this.chart.set('type', 'bardiagram'); + this.chart.set('title', 'Chart title'); + }, + + // set chart + setChart: function(new_chart) { + this.chart.copy(new_chart); + }, + + // create chart + _saveChart: function() { + // update chart data + this.chart.set({ + type : this.table.value(), + title : this.title.value(), + dataset_id : this.dataset.value(), + date : Utils.time() + }); + + // validate + if (!this.chart.get('title')) { + this.message.update({message : 'Please enter a title for your chart.'}); + return; + } + + if (!this.chart.get('type')) { + this.message.update({message : 'Please select a chart type.'}); + return; + } + + if (this.chart.groups.length == 0) { + this.message.update({message : 'Please configure at least one data source.'}); + return; + } + + // create/get chart + var current = this.app.charts.get(this.chart.id); + if (!current) { + current = this.chart.clone(); + this.app.charts.add(current); + } + + // update chart model + current.copy(this.chart); + + // hide + this.$el.hide(); + + // update main + this.app.charts_view.$el.show(); + } +}); + +}); \ No newline at end of file diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/views/charts.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/views/charts.js @@ -0,0 +1,150 @@ +// dependencies +define(['library/portlet', 'library/table', 'library/ui', 'library/utils'], function(Portlet, Table, Ui, Utils) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) + { + // link app + this.app = app; + + // table + this.table = new Table({ + content : 'Add charts to this table.', + ondblclick : function(chart_id) { + // get chart + var chart = self.app.charts.get(chart_id); + + // show edit + self.$el.hide(); + + // update model and show create + self.app.chart_view.setChart(chart); + self.app.chart_view.$el.show(); + }, + onchange : function(chart_id) { + self.app.viewport_view.show(chart_id); + } + }); + + // add table to portlet + var self = this; + this.portlet = new Portlet({ + icon : 'fa-list', + label : 'List of created charts:', + height : 100, + operations : { + 'new' : new Ui.ButtonIcon({ + icon : 'fa-plus', + tooltip: 'Create', + onclick: function() { + self.$el.hide(); + self.app.chart_view.reset(); + self.app.chart_view.$el.show(); + } + }), + 'edit' : new Ui.ButtonIcon({ + icon : 'fa-pencil', + tooltip: 'Edit', + onclick: function() { + // check if element has been selected + var chart_id = self.table.value(); + if (!chart_id) { + return; + } + + // get chart + var chart = self.app.charts.get(chart_id); + + // show edit + self.$el.hide(); + self.app.chart_view.$el.show(); + self.app.chart_view.setChart(chart); + } + }), + 'delete' : new Ui.ButtonIcon({ + icon : 'fa-minus', + tooltip: 'Delete', + onclick: function() { + + // check if element has been selected + var chart_id = self.table.value(); + if (!chart_id) { + return; + } + + // title + var chart = self.app.charts.get(chart_id); + + // show modal + self.app.modal.show({ + title : 'Are you sure?', + body : 'The selected chart "' + chart.get('title') + '" will be irreversibly deleted.', + buttons : { + 'Cancel' : function() {self.app.modal.hide();}, + 'Delete' : function() { + // hide modal + self.app.modal.hide(); + + // remove chart + self.app.charts.remove(chart_id); + } + } + }); + } + }), + } + }); + this.portlet.append(this.table.$el); + + // append to main + this.$el.append(this.portlet.$el); + + // events + var self = this; + this.app.charts.on('add', function(chart) { + // add + self._addChart(chart); + }); + this.app.charts.on('remove', function(chart) { + // remove + self._removeChart(chart); + }); + this.app.charts.on('change', function(chart) { + // replace + self._removeChart(chart); + self._addChart(chart); + }); + }, + + // append + append : function($el) { + this.$el.append(Utils.wrap('')); + this.$el.append($el); + }, + + // add + _addChart: function(chart) { + // add title to table + this.table.add(chart.get('title')); + + // get chart type + var type = this.app.types.get(chart.get('type')); + this.table.add(type.title); + + // add additional columns + this.table.add('Last change: ' + chart.get('date')); + this.table.prepend(chart.get('id')); + this.table.value(chart.get('id')); + }, + + // remove + _removeChart: function(chart) { + // remove from to table + this.table.remove(chart.id); + } +}); + +}); \ No newline at end of file diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/views/group.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/views/group.js @@ -0,0 +1,219 @@ +// dependencies +define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/group'], + function(Portlet, Table, Ui, Utils, Group) { + +// chart config +return Backbone.View.extend( +{ + // model + group: new Group(), + + // columns + columns: [], + + // initialize + initialize: function(app, options) { + // link app + this.app = app; + + // get current chart object + this.chart = this.app.chart; + + // ui elements + this.message = new Ui.Message(); + this.label = new Ui.Input({placeholder: 'Group label'}); + this.table = new Table({content: 'No data column.'}); + + // add table to portlet + var self = this; + this.portlet = new Portlet({ + icon : 'fa-edit', + label : 'Define group properties:', + operations : { + 'save' : new Ui.ButtonIcon({ + icon : 'fa-save', + tooltip : 'Save', + onclick : function() { + // save/add group + self._saveGroup(); + } + }), + 'back' : new Ui.ButtonIcon({ + icon : 'fa-caret-left', + tooltip : 'Return', + onclick : function() { + self.$el.hide(); + self.app.chart_view.$el.show(); + } + }) + } + }); + this.portlet.append(this.message.$el); + this.portlet.append(this.label.$el); + this.portlet.append(this.table.$el); + + // add element + this.setElement(this.portlet.$el); + + // change + var self = this; + this.chart.on('change:dataset_id', function() { + self._refreshDataset(); + }); + this.chart.on('change:type', function() { + self._refreshType(); + }); + this.group.on('change:label', function() { + self._refreshLabel(); + }); + this.group.on('change', function() { + self._refreshGroup(); + }); + }, + + // show + show: function() { + this.$el.show(); + }, + + // reset + reset: function() { + this.group.reset(); + this.group.set('id', Utils.uuid()); + this.group.set('label', 'Group label'); + }, + + // update dataset + _refreshDataset: function() { + // identify datasets + var dataset_id = this.chart.get('dataset_id'); + + // check if dataset is available + if (!dataset_id) { + return; + } + + // get dataset + var dataset = this.app.datasets.get({id : dataset_id}); + + // check + if (!dataset) { + this.app.log('Config::render()', 'Failed to retrieve dataset.'); + return; + } + + // configure columns + this.columns = []; + var meta = dataset.metadata_column_types; + for (var key in meta){ + this.columns.push({ + 'label' : key + ' [' + meta[key] + ']', + 'value' : key + }); + } + + // update select fields + for (var key in this.list) { + this.list[key].update(this.columns); + } + }, + + // update + _refreshType: function() { + // configure chart type + var self = this; + var chart_type = this.chart.get('type'); + if (chart_type) { + var chart_settings = this.app.types.get(chart_type); + + // table + this.table.removeAll(); + this.list = {}; + for (var id in chart_settings.data) { + // create select field + var data_def = chart_settings.data[id]; + var select = new Ui.Select({ + id : 'select_' + id, + gid : id, + data : this.columns, + onchange : function(value) { + self.group.set(this.gid, value); + } + }); + + // add row to table + this.table.add(data_def.title); + this.table.add(select.$el); + this.table.append(id); + + // add select field to list + this.list[id] = select; + } + } + }, + + // update + _refreshGroup: function() { + // update select fields + for (var id in this.list) { + var col = this.group.get(id); + if (col === undefined) { + col = 0; + } + this.list[id].value(col); + } + }, + + // update label + _refreshLabel: function() { + var label_text = this.group.get('label'); + if (label_text === undefined) { + label_text = ''; + } + this.label.value(label_text); + }, + + // create group + _saveGroup: function() { + // get current chart + var chart = this.chart; + + // update group object + var group = this.group; + for (var key in this.list) { + group.set(key, this.list[key].value()); + } + + // add label + group.set({ + dataset_id : this.chart.get('dataset_id'), + label : this.label.value(), + date : Utils.time() + }); + + // validate + if (!group.get('label')) { + this.message.update({message : 'Please enter a label for your group.'}); + return; + } + + // get groups of current chart + var groups = this.chart.groups; + + // create/update group + var group_update = groups.get(group.id); + if (group_update) { + group_update.set(group.attributes); + } else { + groups.add(group.clone()); + } + + // hide + this.$el.hide(); + + // update main + this.app.chart_view.$el.show(); + } +}); + +}); \ No newline at end of file This diff is so big that we needed to truncate the remainder. Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.