Cleaned up Driver Matrix View.
- now implements proper resizing and scrolling.

Change-Id: Ideabb86ed3db44ed1827de15e49216d107053189
diff --git a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.css b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.css
index ae1d403..c5122f2 100644
--- a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.css
+++ b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.css
@@ -5,29 +5,19 @@
 }
 
 #ov-driver-matrix .driver-matrix {
-    /* FIXME: demo only, need a proper scrolling solution */
-    height: 600px;
-    overflow: scroll;
+    background-color: white;
 }
 
 #ov-driver-matrix table {
     margin-left: 20px;
 }
 
-#ov-driver-matrix .table-header-rotated {
+#ov-driver-matrix .table-header-rotated table {
     border-collapse: collapse;
 }
 #ov-driver-matrix .table-header-rotated td {
     width: 24px;
 }
-#ov-driver-matrix .table-header-rotated td.xmark {
-    background-color: rgba(200, 85, 85, 0.5);
-}
-#ov-driver-matrix .table-header-rotated td {
-    text-align: center;
-    padding: 2px 5px;
-    border: 1px solid #ccc;
-}
 #ov-driver-matrix .table-header-rotated th.rotate {
     height: 140px;
     white-space: nowrap;
@@ -36,19 +26,43 @@
 #ov-driver-matrix .table-header-rotated th.rotate > div {
     -webkit-transform: translate(25px, 51px) rotate(-45deg);
     transform: translate(25px, 51px) rotate(-45deg);
-    width: 30px;
+    width: 33px;
 }
 #ov-driver-matrix .table-header-rotated th.rotate > div > span {
     border-bottom: 1px solid #ccc;
     padding: 5px 10px;
+    background-color: rgb(249, 225, 193);
 }
-#ov-driver-matrix .table-header-rotated th.row-header {
+
+#ov-driver-matrix .table-grid {
+    overflow: scroll;
+    color: white;
+}
+#ov-driver-matrix .table-grid table {
+    border-collapse: collapse;
+}
+#ov-driver-matrix .table-grid th.row-header {
     padding: 0 10px;
     border-bottom: 1px solid #ccc;
     text-align: right;
+    color: black;
+    font-size: 10pt;
+    background-color: rgb(249, 225, 193);
+}
+#ov-driver-matrix .table-grid td {
+    width: 24px;
+}
+#ov-driver-matrix .table-grid td.xmark {
+    background-color: rgb(249, 225, 193);
+    color: rgb(88,70,14);
+}
+#ov-driver-matrix .table-grid td {
+    text-align: center;
+    padding: 2px 5px;
+    border: 1px solid #ccc;
 }
 
-
+/* === NOT YET IMPLEMENTED === */
 /* Panel Styling */
 #ov-driver-matrix-item-details-panel.floatpanel {
     position: absolute;
diff --git a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.html b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.html
index 5df2a46..f122938 100644
--- a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.html
+++ b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.html
@@ -11,36 +11,34 @@
         </div>
     </div>
 
-    <!-- TODO: handle resizing / scrolling -->
     <div class="driver-matrix">
-        <table class="table-header-rotated">
-            <thead>
+        <div class="table-header-rotated">
+            <table>
+                <thead>
                 <tr>
                     <!-- first column header is not rotated -->
-                    <th></th>
+                    <th class="first"></th>
                     <!-- following headers are rotated -->
                     <th class="rotate" ng-repeat="beh in behaviours track by $index">
                         <div><span>{{beh}}</span></div>
                     </th>
                 </tr>
-
-            </thead>
-
-            <tbody>
-            <tr ng-repeat="drv in drivers track by $index">
-                <!--ng-click="selectCallback($event, item)"-->
-                <!--ng-class="{selected: item.id === selId}">-->
-                <th class="row-header">
-                    {{drv}}
-                </th>
-                <td ng-repeat="beh in behaviours track by $index"
-                    ng-class="{'xmark':cellMarked(drv, beh)}">
-                    {{cellValue(drv, beh)}}
-                </td>
-            </tr>
-            </tbody>
-        </table>
+                </thead>
+                <tbody></tbody>
+            </table>
+        </div>
+        <div class="table-grid">
+            <table>
+                <thead></thead>
+                <tbody>
+                <tr ng-repeat="drv in drivers track by $index">
+                    <th class="row-header"> {{drv}} </th>
+                    <td ng-repeat="beh in behaviours track by $index"
+                        ng-class="{'xmark':cellMarked(drv, beh)}"
+                        ng-bind-html="checkmark"></td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
     </div>
-
-    <ov-driver-matrix-item-details-panel></ov-driver-matrix-item-details-panel>
 </div>
diff --git a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.js b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.js
index e0a4689..49b41c0 100644
--- a/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.js
+++ b/apps/drivermatrix/src/main/resources/app/view/driverMatrix/driverMatrix.js
@@ -3,48 +3,37 @@
     'use strict';
 
     // injected refs
-    var $log, $scope, fs, wss;
+    var $log, $scope, fs, wss, mast;
 
     // constants
     var detailsReq = 'driverDataRequest',
         detailsResp = 'driverDataResponse',
-        // TODO: deal with details panel
-        pName = 'ov-driver-matrix-item-details-panel',
-        propOrder = ['id', 'label', 'code'],
-        friendlyProps = ['Item ID', 'Item Label', 'Special Code'];
+        topPad = 13,
+        labelFudge = 14;
 
+    // d3 selections
+    var tabular, dMatrix, tabHdRot, tabGrid, first;
 
-    function addProp(tbody, index, value) {
-        var tr = tbody.append('tr');
+    function fixSizes() {
+        var dy = fs.noPxStyle(tabular, 'height') +
+                fs.noPxStyle(tabHdRot, 'height') + mast.mastHeight() + topPad,
+            tHeight = fs.windowSize(dy).height + 'px',
+            rowHdr = tabGrid.select('.row-header'),
+            w;
 
-        function addCell(cls, txt) {
-            tr.append('td').attr('class', cls).html(txt);
+        tabGrid.style('height', tHeight);
+        if (!rowHdr.empty()) {
+            w = fs.noPxStyle(rowHdr, 'width') + labelFudge;
+            first.style('width', w + 'px');
         }
-        addCell('label', friendlyProps[index] + ' :');
-        addCell('value', value);
-    }
-
-    function populatePanel(panel) {
-        var title = panel.append('h3'),
-            tbody = panel.append('table').append('tbody');
-
-        title.text('Item Details');
-
-        propOrder.forEach(function (prop, i) {
-            addProp(tbody, i, $scope.panelDetails[prop]);
-        });
-
-        panel.append('hr');
-        panel.append('h4').text('Comments');
-        panel.append('p').text($scope.panelDetails.comment);
     }
 
     function respDetailsCb(data) {
-        //$log.debug('Matrix Data', data);
         $scope.behaviours = data.behaviours;
         $scope.drivers = data.drivers;
         $scope.matrix = data.matrix;
         $scope.$apply();
+        fixSizes();
     }
 
     angular.module('ovDriverMatrix', [])
@@ -53,106 +42,60 @@
             is.registerIconMapping('nav_drivers', 'cog');
         }])
         .controller('OvDriverMatrixCtrl',
-        ['$log', '$scope', 'TableBuilderService',
-            'FnService', 'WebSocketService',
+            ['$rootScope', '$window', '$log', '$scope', '$sce',
+                'FnService', 'WebSocketService', 'MastService',
 
-            function (_$log_, _$scope_, tbs, _fs_, _wss_) {
-                $log = _$log_;
-                $scope = _$scope_;
-                fs = _fs_;
-                wss = _wss_;
+        function ($rootScope, $window, _$log_, _$scope_, $sce,
+                  _fs_, _wss_, _mast_) {
+            $log = _$log_;
+            $scope = _$scope_;
+            fs = _fs_;
+            wss = _wss_;
+            mast = _mast_;
 
-                var handlers = {};
-                $scope.behaviours = [];
-                $scope.drivers = [];
-                $scope.matrix = {};
+            var handlers = {},
+                unbindWatch;
 
-                // details response handler
-                handlers[detailsResp] = respDetailsCb;
-                wss.bindHandlers(handlers);
+            tabular = d3.select('.tabular-header');
+            dMatrix = d3.select('.driver-matrix');
+            tabHdRot = d3.select('.table-header-rotated');
+            tabGrid = d3.select('.table-grid');
+            first = tabHdRot.select('.first');
 
-                wss.sendEvent(detailsReq);
+            unbindWatch = $rootScope.$watchCollection(
+                function () {
+                    return {
+                        h: $window.innerHeight,
+                        w: $window.innerWidth
+                    };
+                }, fixSizes
+            );
 
-                //// custom selection callback
-                //function selCb($event, row) {
-                //    if ($scope.selId) {
-                //        wss.sendEvent(detailsReq, { id: row.id });
-                //    } else {
-                //        $scope.hidePanel();
-                //    }
-                //    $log.debug('Got a click on:', row);
-                //}
+            $scope.behaviours = [];
+            $scope.drivers = [];
+            $scope.matrix = {};
 
-                function cellHit(d, b) {
-                    var drec = $scope.matrix[d],
-                        brec = drec && drec[b];
-                    return !!brec;
-                }
+            handlers[detailsResp] = respDetailsCb;
+            wss.bindHandlers(handlers);
 
-                $scope.cellMarked = cellHit;
+            wss.sendEvent(detailsReq);
 
-                $scope.cellValue = function(d, b) {
-                    return cellHit(d, b) ? 'x' : '';
-                };
+            function cellHit(d, b) {
+                var drec = $scope.matrix[d],
+                    brec = drec && drec[b];
+                return !!brec;
+            }
 
-                // cleanup
-                $scope.$on('$destroy', function () {
-                    wss.unbindHandlers(handlers);
-                    $log.log('OvDriverMatrixCtrl has been destroyed');
-                });
+            $scope.cellMarked = cellHit;
+            $scope.checkmark = $sce.trustAsHtml("&check;");
 
-                $log.log('OvDriverMatrixCtrl has been created');
-            }])
+            // cleanup
+            $scope.$on('$destroy', function () {
+                unbindWatch();
+                wss.unbindHandlers(handlers);
+                $log.log('OvDriverMatrixCtrl has been destroyed');
+            });
 
-        // TODO: implement row selection to show details panel
-        .directive('ovDriverMatrixItemDetailsPanel', ['PanelService', 'KeyService',
-            function (ps, ks) {
-            return {
-                restrict: 'E',
-                link: function (scope, element, attrs) {
-                    // insert details panel with PanelService
-                    // create the panel
-                    var panel = ps.createPanel(pName, {
-                        width: 200,
-                        margin: 20,
-                        hideMargin: 0
-                    });
-                    panel.hide();
-                    scope.hidePanel = function () { panel.hide(); };
-
-                    function closePanel() {
-                        if (panel.isVisible()) {
-                            $scope.selId = null;
-                            panel.hide();
-                            return true;
-                        }
-                        return false;
-                    }
-
-                    // create key bindings to handle panel
-                    ks.keyBindings({
-                        esc: [closePanel, 'Close the details panel'],
-                        _helpFormat: ['esc']
-                    });
-                    ks.gestureNotes([
-                        ['click', 'Select a row to show item details']
-                    ]);
-
-                    // update the panel's contents when the data is changed
-                    scope.$watch('panelDetails', function () {
-                        if (!fs.isEmptyObject(scope.panelDetails)) {
-                            panel.empty();
-                            populatePanel(panel);
-                            panel.show();
-                        }
-                    });
-
-                    // cleanup on destroyed scope
-                    scope.$on('$destroy', function () {
-                        ks.unbindKeys();
-                        ps.destroyPanel(pName);
-                    });
-                }
-            };
+            $log.log('OvDriverMatrixCtrl has been created');
         }]);
 }());