Simon Hunt

Cleaned up Driver Matrix View.

- now implements proper resizing and scrolling.

Change-Id: Ideabb86ed3db44ed1827de15e49216d107053189
...@@ -5,29 +5,19 @@ ...@@ -5,29 +5,19 @@
5 } 5 }
6 6
7 #ov-driver-matrix .driver-matrix { 7 #ov-driver-matrix .driver-matrix {
8 - /* FIXME: demo only, need a proper scrolling solution */ 8 + background-color: white;
9 - height: 600px;
10 - overflow: scroll;
11 } 9 }
12 10
13 #ov-driver-matrix table { 11 #ov-driver-matrix table {
14 margin-left: 20px; 12 margin-left: 20px;
15 } 13 }
16 14
17 -#ov-driver-matrix .table-header-rotated { 15 +#ov-driver-matrix .table-header-rotated table {
18 border-collapse: collapse; 16 border-collapse: collapse;
19 } 17 }
20 #ov-driver-matrix .table-header-rotated td { 18 #ov-driver-matrix .table-header-rotated td {
21 width: 24px; 19 width: 24px;
22 } 20 }
23 -#ov-driver-matrix .table-header-rotated td.xmark {
24 - background-color: rgba(200, 85, 85, 0.5);
25 -}
26 -#ov-driver-matrix .table-header-rotated td {
27 - text-align: center;
28 - padding: 2px 5px;
29 - border: 1px solid #ccc;
30 -}
31 #ov-driver-matrix .table-header-rotated th.rotate { 21 #ov-driver-matrix .table-header-rotated th.rotate {
32 height: 140px; 22 height: 140px;
33 white-space: nowrap; 23 white-space: nowrap;
...@@ -36,19 +26,43 @@ ...@@ -36,19 +26,43 @@
36 #ov-driver-matrix .table-header-rotated th.rotate > div { 26 #ov-driver-matrix .table-header-rotated th.rotate > div {
37 -webkit-transform: translate(25px, 51px) rotate(-45deg); 27 -webkit-transform: translate(25px, 51px) rotate(-45deg);
38 transform: translate(25px, 51px) rotate(-45deg); 28 transform: translate(25px, 51px) rotate(-45deg);
39 - width: 30px; 29 + width: 33px;
40 } 30 }
41 #ov-driver-matrix .table-header-rotated th.rotate > div > span { 31 #ov-driver-matrix .table-header-rotated th.rotate > div > span {
42 border-bottom: 1px solid #ccc; 32 border-bottom: 1px solid #ccc;
43 padding: 5px 10px; 33 padding: 5px 10px;
34 + background-color: rgb(249, 225, 193);
44 } 35 }
45 -#ov-driver-matrix .table-header-rotated th.row-header { 36 +
37 +#ov-driver-matrix .table-grid {
38 + overflow: scroll;
39 + color: white;
40 +}
41 +#ov-driver-matrix .table-grid table {
42 + border-collapse: collapse;
43 +}
44 +#ov-driver-matrix .table-grid th.row-header {
46 padding: 0 10px; 45 padding: 0 10px;
47 border-bottom: 1px solid #ccc; 46 border-bottom: 1px solid #ccc;
48 text-align: right; 47 text-align: right;
48 + color: black;
49 + font-size: 10pt;
50 + background-color: rgb(249, 225, 193);
51 +}
52 +#ov-driver-matrix .table-grid td {
53 + width: 24px;
54 +}
55 +#ov-driver-matrix .table-grid td.xmark {
56 + background-color: rgb(249, 225, 193);
57 + color: rgb(88,70,14);
58 +}
59 +#ov-driver-matrix .table-grid td {
60 + text-align: center;
61 + padding: 2px 5px;
62 + border: 1px solid #ccc;
49 } 63 }
50 64
51 - 65 +/* === NOT YET IMPLEMENTED === */
52 /* Panel Styling */ 66 /* Panel Styling */
53 #ov-driver-matrix-item-details-panel.floatpanel { 67 #ov-driver-matrix-item-details-panel.floatpanel {
54 position: absolute; 68 position: absolute;
......
...@@ -11,36 +11,34 @@ ...@@ -11,36 +11,34 @@
11 </div> 11 </div>
12 </div> 12 </div>
13 13
14 - <!-- TODO: handle resizing / scrolling -->
15 <div class="driver-matrix"> 14 <div class="driver-matrix">
16 - <table class="table-header-rotated"> 15 + <div class="table-header-rotated">
16 + <table>
17 <thead> 17 <thead>
18 <tr> 18 <tr>
19 <!-- first column header is not rotated --> 19 <!-- first column header is not rotated -->
20 - <th></th> 20 + <th class="first"></th>
21 <!-- following headers are rotated --> 21 <!-- following headers are rotated -->
22 <th class="rotate" ng-repeat="beh in behaviours track by $index"> 22 <th class="rotate" ng-repeat="beh in behaviours track by $index">
23 <div><span>{{beh}}</span></div> 23 <div><span>{{beh}}</span></div>
24 </th> 24 </th>
25 </tr> 25 </tr>
26 -
27 </thead> 26 </thead>
28 - 27 + <tbody></tbody>
28 + </table>
29 + </div>
30 + <div class="table-grid">
31 + <table>
32 + <thead></thead>
29 <tbody> 33 <tbody>
30 <tr ng-repeat="drv in drivers track by $index"> 34 <tr ng-repeat="drv in drivers track by $index">
31 - <!--ng-click="selectCallback($event, item)"--> 35 + <th class="row-header"> {{drv}} </th>
32 - <!--ng-class="{selected: item.id === selId}">-->
33 - <th class="row-header">
34 - {{drv}}
35 - </th>
36 <td ng-repeat="beh in behaviours track by $index" 36 <td ng-repeat="beh in behaviours track by $index"
37 - ng-class="{'xmark':cellMarked(drv, beh)}"> 37 + ng-class="{'xmark':cellMarked(drv, beh)}"
38 - {{cellValue(drv, beh)}} 38 + ng-bind-html="checkmark"></td>
39 - </td>
40 </tr> 39 </tr>
41 </tbody> 40 </tbody>
42 </table> 41 </table>
43 </div> 42 </div>
44 - 43 + </div>
45 - <ov-driver-matrix-item-details-panel></ov-driver-matrix-item-details-panel>
46 </div> 44 </div>
......
...@@ -3,48 +3,37 @@ ...@@ -3,48 +3,37 @@
3 'use strict'; 3 'use strict';
4 4
5 // injected refs 5 // injected refs
6 - var $log, $scope, fs, wss; 6 + var $log, $scope, fs, wss, mast;
7 7
8 // constants 8 // constants
9 var detailsReq = 'driverDataRequest', 9 var detailsReq = 'driverDataRequest',
10 detailsResp = 'driverDataResponse', 10 detailsResp = 'driverDataResponse',
11 - // TODO: deal with details panel 11 + topPad = 13,
12 - pName = 'ov-driver-matrix-item-details-panel', 12 + labelFudge = 14;
13 - propOrder = ['id', 'label', 'code'], 13 +
14 - friendlyProps = ['Item ID', 'Item Label', 'Special Code']; 14 + // d3 selections
15 - 15 + var tabular, dMatrix, tabHdRot, tabGrid, first;
16 - 16 +
17 - function addProp(tbody, index, value) { 17 + function fixSizes() {
18 - var tr = tbody.append('tr'); 18 + var dy = fs.noPxStyle(tabular, 'height') +
19 - 19 + fs.noPxStyle(tabHdRot, 'height') + mast.mastHeight() + topPad,
20 - function addCell(cls, txt) { 20 + tHeight = fs.windowSize(dy).height + 'px',
21 - tr.append('td').attr('class', cls).html(txt); 21 + rowHdr = tabGrid.select('.row-header'),
22 - } 22 + w;
23 - addCell('label', friendlyProps[index] + ' :'); 23 +
24 - addCell('value', value); 24 + tabGrid.style('height', tHeight);
25 + if (!rowHdr.empty()) {
26 + w = fs.noPxStyle(rowHdr, 'width') + labelFudge;
27 + first.style('width', w + 'px');
25 } 28 }
26 -
27 - function populatePanel(panel) {
28 - var title = panel.append('h3'),
29 - tbody = panel.append('table').append('tbody');
30 -
31 - title.text('Item Details');
32 -
33 - propOrder.forEach(function (prop, i) {
34 - addProp(tbody, i, $scope.panelDetails[prop]);
35 - });
36 -
37 - panel.append('hr');
38 - panel.append('h4').text('Comments');
39 - panel.append('p').text($scope.panelDetails.comment);
40 } 29 }
41 30
42 function respDetailsCb(data) { 31 function respDetailsCb(data) {
43 - //$log.debug('Matrix Data', data);
44 $scope.behaviours = data.behaviours; 32 $scope.behaviours = data.behaviours;
45 $scope.drivers = data.drivers; 33 $scope.drivers = data.drivers;
46 $scope.matrix = data.matrix; 34 $scope.matrix = data.matrix;
47 $scope.$apply(); 35 $scope.$apply();
36 + fixSizes();
48 } 37 }
49 38
50 angular.module('ovDriverMatrix', []) 39 angular.module('ovDriverMatrix', [])
...@@ -53,36 +42,44 @@ ...@@ -53,36 +42,44 @@
53 is.registerIconMapping('nav_drivers', 'cog'); 42 is.registerIconMapping('nav_drivers', 'cog');
54 }]) 43 }])
55 .controller('OvDriverMatrixCtrl', 44 .controller('OvDriverMatrixCtrl',
56 - ['$log', '$scope', 'TableBuilderService', 45 + ['$rootScope', '$window', '$log', '$scope', '$sce',
57 - 'FnService', 'WebSocketService', 46 + 'FnService', 'WebSocketService', 'MastService',
58 47
59 - function (_$log_, _$scope_, tbs, _fs_, _wss_) { 48 + function ($rootScope, $window, _$log_, _$scope_, $sce,
49 + _fs_, _wss_, _mast_) {
60 $log = _$log_; 50 $log = _$log_;
61 $scope = _$scope_; 51 $scope = _$scope_;
62 fs = _fs_; 52 fs = _fs_;
63 wss = _wss_; 53 wss = _wss_;
54 + mast = _mast_;
55 +
56 + var handlers = {},
57 + unbindWatch;
58 +
59 + tabular = d3.select('.tabular-header');
60 + dMatrix = d3.select('.driver-matrix');
61 + tabHdRot = d3.select('.table-header-rotated');
62 + tabGrid = d3.select('.table-grid');
63 + first = tabHdRot.select('.first');
64 +
65 + unbindWatch = $rootScope.$watchCollection(
66 + function () {
67 + return {
68 + h: $window.innerHeight,
69 + w: $window.innerWidth
70 + };
71 + }, fixSizes
72 + );
64 73
65 - var handlers = {};
66 $scope.behaviours = []; 74 $scope.behaviours = [];
67 $scope.drivers = []; 75 $scope.drivers = [];
68 $scope.matrix = {}; 76 $scope.matrix = {};
69 77
70 - // details response handler
71 handlers[detailsResp] = respDetailsCb; 78 handlers[detailsResp] = respDetailsCb;
72 wss.bindHandlers(handlers); 79 wss.bindHandlers(handlers);
73 80
74 wss.sendEvent(detailsReq); 81 wss.sendEvent(detailsReq);
75 82
76 - //// custom selection callback
77 - //function selCb($event, row) {
78 - // if ($scope.selId) {
79 - // wss.sendEvent(detailsReq, { id: row.id });
80 - // } else {
81 - // $scope.hidePanel();
82 - // }
83 - // $log.debug('Got a click on:', row);
84 - //}
85 -
86 function cellHit(d, b) { 83 function cellHit(d, b) {
87 var drec = $scope.matrix[d], 84 var drec = $scope.matrix[d],
88 brec = drec && drec[b]; 85 brec = drec && drec[b];
...@@ -90,69 +87,15 @@ ...@@ -90,69 +87,15 @@
90 } 87 }
91 88
92 $scope.cellMarked = cellHit; 89 $scope.cellMarked = cellHit;
93 - 90 + $scope.checkmark = $sce.trustAsHtml("&check;");
94 - $scope.cellValue = function(d, b) {
95 - return cellHit(d, b) ? 'x' : '';
96 - };
97 91
98 // cleanup 92 // cleanup
99 $scope.$on('$destroy', function () { 93 $scope.$on('$destroy', function () {
94 + unbindWatch();
100 wss.unbindHandlers(handlers); 95 wss.unbindHandlers(handlers);
101 $log.log('OvDriverMatrixCtrl has been destroyed'); 96 $log.log('OvDriverMatrixCtrl has been destroyed');
102 }); 97 });
103 98
104 $log.log('OvDriverMatrixCtrl has been created'); 99 $log.log('OvDriverMatrixCtrl has been created');
105 - }])
106 -
107 - // TODO: implement row selection to show details panel
108 - .directive('ovDriverMatrixItemDetailsPanel', ['PanelService', 'KeyService',
109 - function (ps, ks) {
110 - return {
111 - restrict: 'E',
112 - link: function (scope, element, attrs) {
113 - // insert details panel with PanelService
114 - // create the panel
115 - var panel = ps.createPanel(pName, {
116 - width: 200,
117 - margin: 20,
118 - hideMargin: 0
119 - });
120 - panel.hide();
121 - scope.hidePanel = function () { panel.hide(); };
122 -
123 - function closePanel() {
124 - if (panel.isVisible()) {
125 - $scope.selId = null;
126 - panel.hide();
127 - return true;
128 - }
129 - return false;
130 - }
131 -
132 - // create key bindings to handle panel
133 - ks.keyBindings({
134 - esc: [closePanel, 'Close the details panel'],
135 - _helpFormat: ['esc']
136 - });
137 - ks.gestureNotes([
138 - ['click', 'Select a row to show item details']
139 - ]);
140 -
141 - // update the panel's contents when the data is changed
142 - scope.$watch('panelDetails', function () {
143 - if (!fs.isEmptyObject(scope.panelDetails)) {
144 - panel.empty();
145 - populatePanel(panel);
146 - panel.show();
147 - }
148 - });
149 -
150 - // cleanup on destroyed scope
151 - scope.$on('$destroy', function () {
152 - ks.unbindKeys();
153 - ps.destroyPanel(pName);
154 - });
155 - }
156 - };
157 }]); 100 }]);
158 }()); 101 }());
......