Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.view.js @ 9350

Last change on this file since 9350 was 9350, checked in by fschoepp, 12 years ago

#1888:

  • Added input parameters to the run class. They will be populated by the back-end and returned to the web pages which renders them.
  • Added a ParameterMapper class which converts HL specific model classes to OaaS independent classes. The conversion gets delegated to IParameterHandler which have to be implemented manually and registered for a certain Type before. All parameters which can be converted to IStringConvertible, IStringConvertibleMatrix, IString* will be converted into a OaaS-StringValue instance.
  • Added IParameterHandlers for PathTSPTour and PermutationType (required for TSP).
  • AlgorithmConverter now makes sure that the id of a run is unique. (All runs of a RunList will be shown now.)
  • Web pages are capable of rendering both the results of a run and their input parameters (added a accordion to wrap their content).
  • Renamed "Traveling Salesman Problem" to "Genetic Algorithm - TSP".
  • Changed js-files to render both input and result parameters of a Run.
File size: 9.1 KB
Line 
1var OAAS_VIEW = (function (my, Backbone, _, $) {
2    // ================= VIEWS ===================
3    my.LoadingView = Backbone.View.extend({
4        render: function () {
5            this.$el.empty();
6            this.template = _.template($('#loadingTemplate').html());
7            $(this.template({ text: this.model })).appendTo(this.$el);
8        }
9    });
10
11    my.JobOverView = Backbone.View.extend({
12        events: {
13            'click tr': 'rowClicked',
14            'click button[data-name="DeleteButton"]': 'deleteClicked'
15        },
16        initialize: function () {
17            this.collection.bind('remove', this.render, this);
18        },
19        render: function () {
20            var prevSettings = null;
21            if (this.table) {
22                prevSettings = this.table.fnSettings();
23            }
24            this.$el.empty();
25            // create header
26            var table = $('<table />');
27            this.template = _.template($('#jobHeaderTemplate').html());
28            $(this.template({})).appendTo(table);
29
30            // create content
31            var tbody = $('<tbody />');
32            this.collection.each(function (model) {
33                var row = new my.JobOverViewRow({ model: model });
34                row.render();
35                row.$el.appendTo(tbody);
36            });
37            tbody.appendTo(table);
38            table.appendTo(this.$el);
39            if (prevSettings != null) {
40                this.table = table.dataTable({
41                    'aaSorting': prevSettings.aaSorting,
42                    'iDisplayLength' : prevSettings._iDisplayLength,
43                    'iDisplayStart' : prevSettings._iDisplayStart,
44                });
45                this.table.fnFilter(prevSettings.oPreviousSearch.sSearch);
46            } else {
47                this.table = table.dataTable();
48            }
49            this.highlightSelectedJob();
50        },
51        highlightSelectedJob: function () {
52            $('tr', this.table).removeClass('selectedRow');
53            if (this.selectedJob) {
54                $('tr[data-jobId="' + this.selectedJob + '"]', this.table).addClass('selectedRow');
55            }
56        },
57        rowClicked: function (row) {
58            var jobId = $(row.target).parent("tr").attr("data-jobId");
59            if (jobId) {
60                this.selectedJob = jobId;
61                this.highlightSelectedJob();
62                this.trigger('jobSelected', jobId);
63            }
64        },
65        deleteClicked: function (evt) {
66            var target = $(evt.target);
67            var id = target.attr('data-id');
68            var jobs = this.collection.where({ Id: id });
69            if (jobs.length == 1) {
70                jobs[0].destroy(); // triggers a remove event on this.collection -> DELETE /Job/1 will be called
71            }
72        }
73    });
74
75    my.JobOverViewRow = Backbone.View.extend({
76        render: function () {
77            this.template = _.template($('#jobRowTemplate').html());
78            this.setElement($(this.template(this.model.attributes)));
79        }
80    });
81
82    my.ResultView = Backbone.View.extend({
83        render: function () {
84            this.$el.empty();
85            var div = $('<h3/>').text('Compare with charts').appendTo(this.$el);
86            var div = $('<div/>').appendTo(this.$el);
87            var rcv = new my.RunCollectionView({model: this.model, el: div});
88            rcv.render();
89            for (var i = 0; i < this.model.models.length; i++) {
90                $('<h3></h3>').text(this.model.models[i].get('name')).appendTo(this.$el);
91                var rev = new my.ResultEntryView({ model: this.model.models[i], el: this.$el });
92                rev.render();
93            }
94        }
95    });
96
97    my.AccordionView = Backbone.View.extend({
98        render: function () {
99            this.$el.accordion({
100                heightStyle: 'content',
101                collapsible: true,
102                active: false
103            });
104        },
105        refresh: function () {
106            this.$el.accordtion("refresh");
107        }
108    });
109
110    my.ResizableView = Backbone.View.extend({
111        events: {
112            'resizestop': 'resized'
113        },
114        render: function () {
115            this.$el.resizable();
116        },
117        resized: function (evt) {
118            this.trigger('resized', evt);
119        }
120    });
121
122    my.TabView = Backbone.View.extend({
123        // model structure: [{ name:
124        events: {
125            'tabsactivate': 'tabActivated'
126        },
127        render: function () {
128            this.$el.empty();
129            var header = $('<ul />').appendTo(this.$el);
130            for (var i = 0; i < this.model.length; i++) {
131                var li = $('<li/>').appendTo(header);
132                var id = 'tab_' + my.PlotView.nextId() + '_' + i;
133                $('<a />').attr('href', '#' + id).text(this.model[i].name).appendTo(li);
134
135                var targetDiv = $('<div/>').attr('id', id).appendTo(this.$el);
136                $(this.model[i].content).appendTo(targetDiv);
137            }
138            this.$el.tabs({
139                collapsible: true,
140                active: false
141            });
142        },
143        tabActivated: function (event, ui) {
144            var tabElement = $(ui.newPanel[0]);
145            this.trigger('tab-activated', { name: ui.newTab.text(), element: tabElement });
146        }
147    });
148
149    my.ResultEntryView = Backbone.View.extend({
150        initialize: function () {
151            this.plotted = {};
152            this.plotted['params'] = {};
153            this.plotted['results'] = {};
154        },
155        render: function () {
156            this.template = _.template($('#runTemplate').html());
157            var table = $(this.template(this.model.attributes));
158            var body = $('tbody[class="results"]', table);
159            table.appendTo(this.$el);
160            // render the results of the model
161            var results = this.model.get('results');
162            for (var i = 0; i < results.length; i++) {
163                this.renderModelEntry(results[i], i, body, 'results');
164            }
165
166            var inputs = this.model.get('params');
167            body = $('tbody[class="inputs"]', table);
168            for (var i = 0; i < inputs.length; i++) {
169                this.renderModelEntry(inputs[i], i, body, 'params');
170            }
171
172            var av = new my.AccordionView({el: $(table)});
173            av.render();
174        },
175        renderModelEntry: function(entry, index, body, attribute) {         
176            var row = $('<tr/>').attr('data-index', index).attr('data-attribute', attribute);
177            $('<td/>').text(entry.Name).appendTo(row);
178            if ($.isArray(entry.Value)) {
179                var col = $('<td/>').appendTo(row);
180                var tevDiv = $('<div/>');
181                var plotDiv = $('<div/>').appendTo($('#tmp'));                               
182                this.plotted[attribute][index] = {};
183                var tv = new my.TabView({
184                    model: [
185                        { name: 'Table', content: tevDiv },
186                        { name: 'Plot', content: plotDiv },
187                    ],
188                    el: col
189                });
190                this.listenTo(tv, 'tab-activated', this.tabActivated);
191                tv.render();
192            }
193            else {
194                $('<td/>').text(entry.Value).appendTo(row);
195            }
196            row.appendTo(body);
197        },
198        tabActivated: function (evt) {
199            var index = parseInt(evt.element.parents('tr').attr('data-index'));
200            var attribute = evt.element.parents('tr').attr('data-attribute');
201            if (evt.name == 'Plot' && !this.plotted[attribute][index].Plot) {
202                this.plotted[attribute][index].Plot = true;
203                var plotDiv = $('<div/>').appendTo($('#tmp'));
204                var pv = new my.PlotView({ model: this.model.get(attribute)[index], el: plotDiv, transpose: true });
205                pv.render();
206                plotDiv.appendTo(evt.element);
207                var rv = new my.ResizableView({ el: evt.element });
208
209                this.listenTo(rv, 'resized', function (evt) {
210                    plotDiv.height($(evt.target).height() * 0.96);
211                    plotDiv.width($(evt.target).width() * 0.96);
212                    pv.refresh();
213                });
214                rv.render();
215                plotDiv.width(rv.$el.width());
216                plotDiv.height(rv.$el.height());
217                pv.refresh();
218            } else if (evt.name == 'Table' && !this.plotted[attribute][index].Table) {
219                this.plotted[attribute][index].Table = true;
220                var tevDiv = $('<div/>').css('overflow', 'scroll');
221                var tev = new my.TableEditView({ model: this.model.get(attribute)[index].Value, rowNames: this.model.get(attribute)[index].RowNames, useDatatable: true, el: tevDiv });
222                tev.render();
223                tevDiv.appendTo(evt.element)
224            }
225        }
226    });
227    return my;
228} (OAAS_VIEW || {}, Backbone, _, $));
Note: See TracBrowser for help on using the repository browser.