blob: d28fa0d91dbe5fef9b217fb9efc3314d49ab405e [file] [log] [blame]
Bri Prebilic Cole093739a2015-01-23 10:22:50 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 ONOS GUI -- Widget -- Table Service
19 */
20(function () {
21 'use strict';
22
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -080023 var $log, $window, fs, is,
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080024 bottomMargin = 200;
Bri Prebilic Cole093739a2015-01-23 10:22:50 -080025
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080026 // Render a plain d3 table by giving it the div, a config file, and data
27
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080028 function renderTable(div, config, data) {
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080029 var table = div.append('table'),
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080030 colIds = config.colIds,
31 colText = config.colText,
32 dataObjects = data[Object.keys(data)[0]],
33 thead, tbody, tRows;
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080034
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080035 thead = table.append('thead');
36 tbody = table.append('tbody');
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080037
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080038 thead.append('tr').selectAll('th')
39 .data(colText)
40 .enter()
41 .append('th')
42 .text(function(d) { return d });
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080043
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080044 tRows = tbody.selectAll('tr')
45 .data(dataObjects)
46 .enter()
47 .append('tr');
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080048
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080049 tRows.selectAll('td')
50 .data(function(row) {
51 return colIds.map(function(headerId) {
52 return {
53 column: headerId, value: row[headerId]
54 };
55 });
56 })
57 .enter()
58 .append('td')
59 .html(function(d) { return d.value });
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080060
Bri Prebilic Cole4c891772015-01-27 11:38:51 -080061 return table;
Bri Prebilic Coleaa8d2ed2015-01-23 16:53:29 -080062 }
63
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080064 // Functions for creating a fixed header on a table (Angular Directive)
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080065
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080066 function setTableWidth(t) {
67 var tHeaders, tdElement, colWidth, numCols,
68 winWidth = fs.windowSize().width;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080069
70 tHeaders = t.selectAll('th');
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080071 numCols = tHeaders[0].length;
72 colWidth = Math.floor(winWidth/numCols);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080073
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080074 tHeaders.each(function(thElement, index) {
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080075 thElement = d3.select(this);
76
77 tdElement = t.select('td:nth-of-type(' + (index + 1) + ')');
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080078
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080079 // if the header has no text in it,
80 // then make the column the width of the td element.
81 // (This looks good for icons)
82 if (!(thElement.html().length)) {
83 var tdSize = tdElement.style('width');
84 thElement.style('width', tdSize + 'px');
85 tdElement.style('width', tdSize + 'px');
86 }
87 else {
88 thElement.style('width', colWidth + 'px');
89 tdElement.style('width', colWidth + 'px');
90 }
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080091 });
92 }
93
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080094 function setTableHeight(thead, tbody) {
95 var winHeight = fs.windowSize().height;
96
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -080097 thead.style('display', 'block');
98 tbody.style({'display': 'block',
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -080099 'height': ((winHeight - bottomMargin) + 'px'),
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800100 'overflow': 'auto'
101 });
102 }
103
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800104 function fixTable(t, th, tb) {
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800105 setTableWidth(t);
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800106 setTableHeight(th, tb);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800107 }
108
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800109 angular.module('onosWidget')
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800110 .factory('TableService', [function () {
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800111 return {
Bri Prebilic Cole4c891772015-01-27 11:38:51 -0800112 renderTable: renderTable
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800113 };
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800114 }])
115
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800116 .directive('onosFixedHeader', ['$window', '$timeout',
117 'MastService', 'FnService',
118 function (_$window_, $timeout, mast, _fs_) {
119 return function (scope, element) {
120 $window = _$window_;
121 fs = _fs_;
122 var w = angular.element($window),
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800123 table = d3.select(element[0]),
124 shouldResize = false;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800125
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800126 scope.$watch(function () {
127 return {
128 h: window.innerHeight,
129 w: window.innerWidth
130 };
131 }, function (newVal) {
132 var thead = table.select('thead'),
133 tbody = table.select('tbody');
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800134
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800135 scope.windowHeight = newVal.h;
136 scope.windowWidth = newVal.w;
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800137
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800138 scope.setTableHW = function () {
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800139 scope.$on('LastElement', function (event) {
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800140 // only adjust the table once it's completely loaded
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800141 fixTable(table, thead, tbody);
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800142 shouldResize = true;
143 });
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800144 };
Bri Prebilic Coleb0e66be2015-02-10 10:53:15 -0800145
146 if (shouldResize) {
147 fixTable(table, thead, tbody);
148 }
149
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800150 }, true);
Bri Prebilic Cole9ca0f9c2015-01-29 15:44:20 -0800151
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800152 w.bind('onos-fixed-header', function () {
153 scope.$apply();
154 });
155 };
156
Bri Prebilic Cole1f93be22015-02-10 17:16:46 -0800157 }])
158
159 .directive('onosSortableHeader', ['$log', 'IconService',
160 function (_$log_, _is_) {
161 return function (scope, element, attrs) {
162 $log = _$log_;
163 is = _is_;
164 var table = d3.select(element[0]),
165 currCol = {},
166 prevCol = {},
167 sortIconAPI = is.createSortIcon();
168
169 // when a header is clicked, change its icon tag and get sorting
170 // order to send to the server.
171 table.selectAll('th').on('click', function () {
172 var thElem = d3.select(this),
173 div;
174
175 currCol.colId = thElem.attr('colId');
176
177 if (currCol.colId === prevCol.colId) {
178 (currCol.icon === 'tableColSortDesc') ?
179 currCol.icon = 'tableColSortAsc' :
180 currCol.icon = 'tableColSortDesc';
181 prevCol.icon = currCol.icon;
182 } else {
183 currCol.icon = 'tableColSortAsc';
184 prevCol.icon = 'tableColSortNone';
185 }
186
187 $log.debug('currCol clicked: ' + currCol.colId +
188 ', with sorting icon: ' + currCol.icon);
189 $log.debug('prevCol clicked: ' + prevCol.colId +
190 ', with its current sorting icon as ' + prevCol.icon);
191
192 div = thElem.select('div');
193 div.remove();
194
195 div = thElem.append('div');
196
197 if (currCol.icon === 'tableColSortAsc') {
198 sortIconAPI.sortAsc(div);
199 } else {
200 sortIconAPI.sortDesc(div);
201 }
202
203 if (prevCol.colId !== undefined &&
204 prevCol.icon === 'tableColSortNone') {
205 sortIconAPI.sortNone(prevCol.elem.select('div'));
206 }
207
208 prevCol.colId = currCol.colId;
209 prevCol.elem = thElem;
210
211 });
212
213 // TODO: send the prev and currCol info to the server to use in sorting table
214
215 // TODO: figure out timing of events:
216 // updating the icon
217 // sending the column sorting info to the server
218 // refreshing the table so that the new rows will be sorted
219
220 }
Bri Prebilic Colee4d5c6c2015-02-02 15:52:45 -0800221 }]);
Bri Prebilic Cole093739a2015-01-23 10:22:50 -0800222
223}());