Changed hosts to small circles (rather than labeled rectangles), and updated collision prevention code appropriately.
Removed hover-selection mode (will replace with tooltips later).
Added flyout div (hidden for now).
diff --git a/web/gui/src/main/webapp/index.html b/web/gui/src/main/webapp/index.html
index 0b73731..9e91669 100644
--- a/web/gui/src/main/webapp/index.html
+++ b/web/gui/src/main/webapp/index.html
@@ -47,7 +47,10 @@
                 <span id="showOpt" class="radio">Optical Only</span>
             </span>
         </div>
-        <div id="view"></div>
+        <div id="view">
+            <!-- NOTE: svg layer injected here -->
+        </div>
+        <div id="flyout"></div>
     </div>
 
     <!-- Initialize the UI...-->
diff --git a/web/gui/src/main/webapp/network.js b/web/gui/src/main/webapp/network.js
index a72ddec..35a62bf 100644
--- a/web/gui/src/main/webapp/network.js
+++ b/web/gui/src/main/webapp/network.js
@@ -49,12 +49,12 @@
             force: {
                 note: 'node.class or link.class is used to differentiate',
                 linkDistance: {
-                    infra: 240,
-                    host: 100
+                    infra: 200,
+                    host: 20
                 },
                 linkStrength: {
                     infra: 1.0,
-                    host: 0.4
+                    host: 1.0
                 },
                 charge: {
                     device: -800,
@@ -90,6 +90,7 @@
                 }
             },
             hostLinkWidth: 1.0,
+            hostRadius: 7,
             mouseOutTimerDelayMs: 120
         };
 
@@ -279,16 +280,16 @@
 
 
         // now, process the explicit links...
-        network.data.links.forEach(function(n) {
-            var src = network.lookup[n.src],
-                dst = network.lookup[n.dst],
+        network.data.links.forEach(function(lnk) {
+            var src = network.lookup[lnk.src],
+                dst = network.lookup[lnk.dst],
                 id = src.id + "~" + dst.id;
 
             var link = {
                 class: 'infra',
                 id: id,
-                type: n.type,
-                width: n.linkWidth,
+                type: lnk.type,
+                width: lnk.linkWidth,
                 source: src,
                 target: dst,
                 strength: config.force.linkStrength.infra
@@ -379,6 +380,7 @@
             .attr('class', function(d) {return 'link ' + d.class});
 
 
+        // TODO: move drag behavior into separate method.
         // == define node drag behavior...
         network.draggedThreshold = d3.scale.linear()
             .domain([0, 0.1])
@@ -442,6 +444,8 @@
             })
             .call(network.drag)
             .on('mouseover', function(d) {
+                // TODO: show tooltip
+/*
                 if (!selected.obj) {
                     if (network.mouseoutTimeout) {
                         clearTimeout(network.mouseoutTimeout);
@@ -449,8 +453,11 @@
                     }
                     highlightObject(d);
                 }
+*/
             })
             .on('mouseout', function(d) {
+                // TODO: hide tooltip
+/*
                 if (!selected.obj) {
                     if (network.mouseoutTimeout) {
                         clearTimeout(network.mouseoutTimeout);
@@ -460,9 +467,13 @@
                         highlightObject(null);
                     }, config.mouseOutTimerDelayMs);
                 }
+*/
             });
 
-        network.nodeRect = network.node.append('rect')
+
+        // deal with device nodes first
+        network.nodeRect = network.node.filter('.device')
+            .append('rect')
             .attr({
                 rx: 5,
                 ry: 5,
@@ -470,8 +481,9 @@
                 height: 12
             });
             // note that width/height are adjusted to fit the label text
+            // then padded, and space made for the icon.
 
-        network.node.each(function(d) {
+        network.node.filter('.device').each(function(d) {
             var node = d3.select(this),
                 icon = iconUrl(d);
 
@@ -505,47 +517,35 @@
             }
         });
 
+        // now process host nodes
+        network.nodeCircle = network.node.filter('.host')
+            .append('circle')
+            .attr({
+                r: config.hostRadius
+            });
 
-        // returns the newly computed bounding box
-        function adjustRectToFitText(n) {
-            var text = n.select('text'),
-                box = text.node().getBBox(),
-                lab = config.labels;
+        network.node.filter('.host').each(function(d) {
+            var node = d3.select(this),
+                icon = iconUrl(d);
 
-            text.attr('text-anchor', 'middle')
-                .attr('y', '-0.8em')
-                .attr('x', lab.imgPad/2)
-            ;
-
-            // TODO: figure out how to access the data on selection
-            console.log("\nadjust rect for " + n.data().id);
-            console.log(box);
-
-            // translate the bbox so that it is centered on [x,y]
-            box.x = -box.width / 2;
-            box.y = -box.height / 2;
-
-            // add padding
-            box.x -= (lab.padLR + lab.imgPad/2);
-            box.width += lab.padLR * 2 + lab.imgPad;
-            box.y -= lab.padTB;
-            box.height += lab.padTB * 2;
-
-            return box;
-        }
-
-        function boundsFromBox(box) {
-            return {
-                x1: box.x,
-                y1: box.y,
-                x2: box.x + box.width,
-                y2: box.y + box.height
-            };
-        }
+            // debug function to show the modelled x,y coordinates of nodes...
+            if (debug('showNodeXY')) {
+                node.select('circle').attr('fill-opacity', 0.5);
+                node.append('circle')
+                    .attr({
+                        class: 'debug',
+                        cx: 0,
+                        cy: 0,
+                        r: '3px'
+                    });
+            }
+        });
 
         // this function is scheduled to happen soon after the given thread ends
         setTimeout(function() {
-            network.node.each(function(d) {
+            // post process the device nodes, to pad their size to fit the
+            // label text and attach the icon to the right location.
+            network.node.filter('.device').each(function(d) {
                 // for every node, recompute size, padding, etc. so text fits
                 var node = d3.select(this),
                     text = node.select('text'),
@@ -589,6 +589,44 @@
             $('#view').css('visibility', 'visible');
         });
 
+
+        // returns the newly computed bounding box of the rectangle
+        function adjustRectToFitText(n) {
+            var text = n.select('text'),
+                box = text.node().getBBox(),
+                lab = config.labels;
+
+            text.attr('text-anchor', 'middle')
+                .attr('y', '-0.8em')
+                .attr('x', lab.imgPad/2)
+            ;
+
+            // TODO: figure out how to access the data on selection
+            console.log("\nadjust rect for " + n.data().id);
+            console.log(box);
+
+            // translate the bbox so that it is centered on [x,y]
+            box.x = -box.width / 2;
+            box.y = -box.height / 2;
+
+            // add padding
+            box.x -= (lab.padLR + lab.imgPad/2);
+            box.width += lab.padLR * 2 + lab.imgPad;
+            box.y -= lab.padTB;
+            box.height += lab.padTB * 2;
+
+            return box;
+        }
+
+        function boundsFromBox(box) {
+            return {
+                x1: box.x,
+                y1: box.y,
+                x2: box.x + box.width,
+                y2: box.y + box.height
+            };
+        }
+
     }
 
     function iconUrl(d) {
@@ -599,24 +637,48 @@
         return 'translate(' + x + ',' + y + ')';
     }
 
+    // prevents collisions amongst device nodes
     function preventCollisions() {
-        var quadtree = d3.geom.quadtree(network.nodes);
+        var quadtree = d3.geom.quadtree(network.nodes),
+            hrad = config.hostRadius;
 
         network.nodes.forEach(function(n) {
-            var nx1 = n.x + n.extent.left,
-                nx2 = n.x + n.extent.right,
-                ny1 = n.y + n.extent.top,
+            var nx1, nx2, ny1, ny2;
+
+            if (n.class === 'device') {
+                nx1 = n.x + n.extent.left;
+                nx2 = n.x + n.extent.right;
+                ny1 = n.y + n.extent.top;
                 ny2 = n.y + n.extent.bottom;
 
+            } else {
+                nx1 = n.x - hrad;
+                nx2 = n.x + hrad;
+                ny1 = n.y - hrad;
+                ny2 = n.y + hrad;
+            }
+
             quadtree.visit(function(quad, x1, y1, x2, y2) {
                 if (quad.point && quad.point !== n) {
-                    // check if the rectangles intersect
+                    // check if the rectangles/circles intersect
                     var p = quad.point,
-                        px1 = p.x + p.extent.left,
-                        px2 = p.x + p.extent.right,
-                        py1 = p.y + p.extent.top,
-                        py2 = p.y + p.extent.bottom,
-                        ix = (px1 <= nx2 && nx1 <= px2 && py1 <= ny2 && ny1 <= py2);
+                        px1, px2, py1, py2, ix;
+
+                    if (p.class === 'device') {
+                        px1 = p.x + p.extent.left;
+                        px2 = p.x + p.extent.right;
+                        py1 = p.y + p.extent.top;
+                        py2 = p.y + p.extent.bottom;
+
+                    } else {
+                        px1 = p.x - hrad;
+                        px2 = p.x + hrad;
+                        py1 = p.y - hrad;
+                        py2 = p.y + hrad;
+                    }
+
+                    ix = (px1 <= nx2 && nx1 <= px2 && py1 <= ny2 && ny1 <= py2);
+
                     if (ix) {
                         var xa1 = nx2 - px1, // shift n left , p right
                             xa2 = px2 - nx1, // shift n right, p left
@@ -717,6 +779,16 @@
     //        return false;
     //    });
 
+    function findNodeFromData(d) {
+        var el = null;
+        network.node.filter('.' + d.class).each(function(n) {
+            if (n.id === d.id) {
+                el = d3.select(this);
+            }
+        });
+        return el;
+    }
+
     function selectObject(obj, el) {
         var node;
         if (el) {
diff --git a/web/gui/src/main/webapp/onos.css b/web/gui/src/main/webapp/onos.css
index 5cd75e6..baa00a3 100644
--- a/web/gui/src/main/webapp/onos.css
+++ b/web/gui/src/main/webapp/onos.css
@@ -88,7 +88,12 @@
     -moz-transition: opacity 250ms;
 }
 
-svg .node rect {
+svg .link.host {
+    stroke: #6a6;
+    stroke-dasharray: 3,3;
+}
+
+svg .node.device rect {
     stroke-width: 1.5px;
 
     transition: opacity 250ms;
@@ -104,8 +109,9 @@
     fill: #55f;
 }
 
-svg .node.host rect {
-    fill: #787;
+svg .node.host circle {
+    fill: #898;
+    stroke: #000;
 }
 
 svg .node text {
@@ -132,6 +138,7 @@
 
 svg .link.inactive,
 svg .node.inactive rect,
+svg .node.inactive circle,
 svg .node.inactive text,
 svg .node.inactive image {
     opacity: .2;
@@ -175,16 +182,28 @@
  * Specific structural elements
  */
 
+#mast {
+    height: 36px;
+    padding: 4px;
+    background-color: #ccc;
+    vertical-align: baseline;
+}
+
 #frame {
     width: 100%;
     height: 100%;
     background-color: #fff;
 }
 
-#mast {
-    height: 36px;
-    padding: 4px;
-    background-color: #ccc;
-    vertical-align: baseline;
+#flyout {
+    width: 300px;
+    height: 80%;
+    top: 10%;
+    right: 2%;
+    background-color: rgba(0,0,0,0.5);
+
+    position: absolute;
+    z-index: 100;
+    display: none;
 }