[AETHER-1213] GUI1 enhanced to allow scaling host icons and host text.

Scale is proportional to the current zoom level, but can be toggled in
four increments via SHIFT-[ (text) and SHIFT-] (icon) keyboard shortcuts.

The icon size limit was increased to be min 20 and max 70.

Change-Id: I49e983d34a2465fb12d48395c34c1f22911f4f51
diff --git a/web/gui/src/main/webapp/_doc/view/topo/README.force.md b/web/gui/src/main/webapp/_doc/view/topo/README.force.md
index bbdfc45..55dbad5 100644
--- a/web/gui/src/main/webapp/_doc/view/topo/README.force.md
+++ b/web/gui/src/main/webapp/_doc/view/topo/README.force.md
@@ -62,9 +62,8 @@
 * Will briefly highlight links for which there is only a single backing link
 * Also writes a summary of bad links to the console
 
-`setNodeScale()`
-* `scale`: the scale to use
-* Rescales the nodes and links (and labels) based on the input parameter
+`adjustNodeScale()`
+* Rescales the nodes and links (and labels) based on the current zoomer state
 
 `resetAllLocations()`
 * Resets all nodes (hosts, devices) to the configured positions
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index ab803f6..1348eec 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -83,6 +83,7 @@
         function uiDragTxt() { return topoLion('qh_gest_drag'); }
         function uiCmdScrTxt() { return topoLion('qh_gest_cmd_scroll'); }
         function uiCmdDragTxt() { return topoLion('qh_gest_cmd_drag'); }
+        function quiet() { return ""; }
 
         actionMap = {
             I: [toggleInstances, togInst],
@@ -109,6 +110,9 @@
             dot: [ttbs.toggleToolbar, togtb],
             E: [equalizeMasters, eqmaster],
 
+            "shift-openBracket": [tfs.toggleHostTextSize, quiet],
+            "shift-closeBracket": [tfs.toggleHostIconSize, quiet],
+
             // -- instance color palette debug
             // 9: function () { sus.cat7().testCard(svg); },
 
@@ -305,7 +309,7 @@
         // keep the map lines constant width while zooming
         mapG.style('stroke-width', (2.0 / sc) + 'px');
 
-        tfs.setNodeScale(sc);
+        tfs.adjustNodeScale();
     }
 
     function setUpZoom() {
diff --git a/web/gui/src/main/webapp/app/view/topo/topoForce.js b/web/gui/src/main/webapp/app/view/topo/topoForce.js
index b7cc07c..e648d6d 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoForce.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoForce.js
@@ -71,7 +71,7 @@
         linkNums = [], // array of link number labels
         devIconDim = 36, // node target dimension
         devIconDimMin = 20, // node minimum dimension when zoomed out
-        devIconDimMax = 40, // node maximum dimension when zoomed in
+        devIconDimMax = 70, // node maximum dimension when zoomed in
         portLabelDim = 30;
 
     // SVG elements;
@@ -107,6 +107,7 @@
         },
     };
 
+    var hostScaleFactor = {icon: 1.0, text: 1.0};
 
     // ==========================
     // === EVENT HANDLERS
@@ -626,8 +627,8 @@
         $timeout(updateLinks, 2000);
     }
 
-    function deviceScale() {
-        var scale = uplink.zoomer().scale(),
+    function deviceScale(scaleFactor) {
+        var scale = uplink.zoomer().scale() * scaleFactor,
             dim = devIconDim,
             multiplier = 1;
 
@@ -640,37 +641,54 @@
         return multiplier;
     }
 
-    function linkWidthScale(scale) {
+    function linkWidthScale() {
         var scale = uplink.zoomer().scale();
         return linkScale(widthRatio) / scale;
     }
 
-    function portLabelScale(scale) {
+    function portLabelScale() {
         var scale = uplink.zoomer().scale();
         return portLabelDim / (portLabelDim * scale);
     }
 
-    function setNodeScale(scale) {
+    function adjustNodeScale() {
         // Scale the network nodes
         _.each(network.nodes, function (node) {
             if (node.class === 'host') {
-                node.el.selectAll('g').style('transform', 'scale(' + deviceScale(scale) + ')');
-                node.el.selectAll('text').style('transform', 'scale(' + deviceScale(scale) + ')');
+                node.el.selectAll('g').style('transform', 'scale(' + deviceScale(hostScaleFactor.icon) + ')');
+                node.el.selectAll('text').style('transform', 'scale(' + deviceScale(hostScaleFactor.text) + ')');
                 return;
             }
-            node.el.selectAll('*')
-                .style('transform', 'scale(' + deviceScale(scale) + ')');
+            node.el.selectAll('*').style('transform', 'scale(' + deviceScale(1.0) + ')');
         });
 
         // Scale the network links
         _.each(network.links, function (link) {
-            link.el.style('stroke-width', linkWidthScale(scale) + 'px');
+            link.el.style('stroke-width', linkWidthScale() + 'px');
         });
 
         d3.select('#topo-portLabels')
             .selectAll('.portLabel')
             .selectAll('*')
-            .style('transform', 'scale(' + portLabelScale(scale) + ')');
+            .style('transform', 'scale(' + portLabelScale() + ')');
+    }
+
+
+    function toggleScale(scale) {
+        if (scale < 0.5) {
+            return 1.0
+        }
+        return scale - 0.2;
+    }
+
+    function toggleHostTextSize() {
+        hostScaleFactor.text = toggleScale(hostScaleFactor.text);
+        adjustNodeScale();
+    }
+
+    function toggleHostIconSize() {
+         hostScaleFactor.icon = toggleScale(hostScaleFactor.icon);
+         adjustNodeScale();
     }
 
     function resetAllLocations() {
@@ -1288,7 +1306,10 @@
                 unpin: unpin,
                 showMastership: showMastership,
                 showBadLinks: showBadLinks,
-                setNodeScale: setNodeScale,
+                adjustNodeScale: adjustNodeScale,
+
+                toggleHostTextSize: toggleHostTextSize,
+                toggleHostIconSize: toggleHostIconSize,
 
                 resetAllLocations: resetAllLocations,
                 addDevice: addDevice,
diff --git a/web/gui/src/main/webapp/tests/app/view/topo/topoForce-spec.js b/web/gui/src/main/webapp/tests/app/view/topo/topoForce-spec.js
index 85e2f9e..1d9f63c 100644
--- a/web/gui/src/main/webapp/tests/app/view/topo/topoForce-spec.js
+++ b/web/gui/src/main/webapp/tests/app/view/topo/topoForce-spec.js
@@ -42,7 +42,7 @@
             'updateDeviceColors', 'toggleHosts',
             'togglePorts', 'toggleOffline',
             'cycleDeviceLabels', 'cycleHostLabels', 'unpin',
-            'showMastership', 'showBadLinks', 'setNodeScale',
+            'showMastership', 'showBadLinks', 'adjustNodeScale',
 
             'resetAllLocations', 'addDevice', 'updateDevice', 'removeDevice',
             'addHost', 'updateHost', 'moveHost', 'removeHost',