diff --git a/web/gui/src/main/webapp/app/view/topo/topoD3.js b/web/gui/src/main/webapp/app/view/topo/topoD3.js
new file mode 100644
index 0000000..ced1656
--- /dev/null
+++ b/web/gui/src/main/webapp/app/view/topo/topoD3.js
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Topology D3 Module.
+ Functions for manipulating the D3 visualizations of the Topology
+ */
+
+(function () {
+    'use strict';
+
+    // injected refs
+    var $log, fs, sus, is, ts;
+
+    // api to topoForce
+    var api;
+    /*
+     node()                 // get ref to D3 selection of nodes
+     link()                 // get ref to D3 selection of links
+     linkLabel()            // get ref to D3 selection of link labels
+     instVisible()          // true if instances panel is visible
+     posNode()              // position node
+     showHosts()            // true if hosts are to be shown
+     restyleLinkElement()   // update link styles based on backing data
+     updateLinkLabelModel() // update backing data for link labels
+     */
+
+    // configuration
+    var devCfg = {
+            xoff: -20,
+            yoff: -18
+        },
+        labelConfig = {
+            imgPad: 16,
+            padLR: 4,
+            padTB: 3,
+            marginLR: 3,
+            marginTB: 2,
+            port: {
+                gap: 3,
+                width: 18,
+                height: 14
+            }
+        },
+        icfg;
+
+    // internal state
+    var deviceLabelIndex = 0,
+        hostLabelIndex = 0;
+
+
+    var dCol = {
+        black: '#000',
+        paleblue: '#acf',
+        offwhite: '#ddd',
+        darkgrey: '#444',
+        midgrey: '#888',
+        lightgrey: '#bbb',
+        orange: '#f90'
+    };
+
+    // note: these are the device icon colors without affinity
+    var dColTheme = {
+        light: {
+            rfill: dCol.offwhite,
+            online: {
+                glyph: dCol.darkgrey,
+                rect: dCol.paleblue
+            },
+            offline: {
+                glyph: dCol.midgrey,
+                rect: dCol.lightgrey
+            }
+        },
+        dark: {
+            rfill: dCol.midgrey,
+            online: {
+                glyph: dCol.darkgrey,
+                rect: dCol.paleblue
+            },
+            offline: {
+                glyph: dCol.midgrey,
+                rect: dCol.darkgrey
+            }
+        }
+    };
+
+    function devBaseColor(d) {
+        var o = d.online ? 'online' : 'offline';
+        return dColTheme[ts.theme()][o];
+    }
+
+    function setDeviceColor(d) {
+        var o = d.online,
+            s = d.el.classed('selected'),
+            c = devBaseColor(d),
+            a = instColor(d.master, o),
+            icon = d.el.select('g.deviceIcon'),
+            g, r;
+
+        if (s) {
+            g = c.glyph;
+            r = dCol.orange;
+        } else if (api.instVisible()) {
+            g = o ? a : c.glyph;
+            r = o ? c.rfill : a;
+        } else {
+            g = c.glyph;
+            r = c.rect;
+        }
+
+        icon.select('use').style('fill', g);
+        icon.select('rect').style('fill', r);
+    }
+
+    function instColor(id, online) {
+        return sus.cat7().getColor(id, !online, ts.theme());
+    }
+
+    // ====
+
+    function incDevLabIndex() {
+        deviceLabelIndex = (deviceLabelIndex+1) % 3;
+    }
+
+    // Returns the newly computed bounding box of the rectangle
+    function adjustRectToFitText(n) {
+        var text = n.select('text'),
+            box = text.node().getBBox(),
+            lab = labelConfig;
+
+        text.attr('text-anchor', 'middle')
+            .attr('y', '-0.8em')
+            .attr('x', lab.imgPad/2);
+
+        // 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 hostLabel(d) {
+        var idx = (hostLabelIndex < d.labels.length) ? hostLabelIndex : 0;
+        return d.labels[idx];
+    }
+    function deviceLabel(d) {
+        var idx = (deviceLabelIndex < d.labels.length) ? deviceLabelIndex : 0;
+        return d.labels[idx];
+    }
+    function trimLabel(label) {
+        return (label && label.trim()) || '';
+    }
+
+    function emptyBox() {
+        return {
+            x: -2,
+            y: -2,
+            width: 4,
+            height: 4
+        };
+    }
+
+
+    function updateDeviceLabel(d) {
+        var label = trimLabel(deviceLabel(d)),
+            noLabel = !label,
+            node = d.el,
+            dim = icfg.device.dim,
+            box, dx, dy;
+
+        node.select('text')
+            .text(label)
+            .style('opacity', 0)
+            .transition()
+            .style('opacity', 1);
+
+        if (noLabel) {
+            box = emptyBox();
+            dx = -dim/2;
+            dy = -dim/2;
+        } else {
+            box = adjustRectToFitText(node);
+            dx = box.x + devCfg.xoff;
+            dy = box.y + devCfg.yoff;
+        }
+
+        node.select('rect')
+            .transition()
+            .attr(box);
+
+        node.select('g.deviceIcon')
+            .transition()
+            .attr('transform', sus.translate(dx, dy));
+    }
+
+    function updateHostLabel(d) {
+        var label = trimLabel(hostLabel(d));
+        d.el.select('text').text(label);
+    }
+
+    function updateDeviceColors(d) {
+        if (d) {
+            setDeviceColor(d);
+        } else {
+            api.node().filter('.device').each(function (d) {
+                setDeviceColor(d);
+            });
+        }
+    }
+
+
+    // ==========================
+    // updateNodes - subfunctions
+
+    function deviceExisting(d) {
+        var node = d.el;
+        node.classed('online', d.online);
+        updateDeviceLabel(d);
+        api.posNode(d, true);
+    }
+
+    function hostExisting(d) {
+        updateHostLabel(d);
+        api.posNode(d, true);
+    }
+
+    function deviceEnter(d) {
+        var node = d3.select(this),
+            glyphId = d.type || 'unknown',
+            label = trimLabel(deviceLabel(d)),
+            //devCfg = deviceIconConfig,
+            noLabel = !label,
+            box, dx, dy, icon;
+
+        d.el = node;
+
+        node.append('rect').attr({ rx: 5, ry: 5 });
+        node.append('text').text(label).attr('dy', '1.1em');
+        box = adjustRectToFitText(node);
+        node.select('rect').attr(box);
+
+        icon = is.addDeviceIcon(node, glyphId);
+
+        if (noLabel) {
+            dx = -icon.dim/2;
+            dy = -icon.dim/2;
+        } else {
+            box = adjustRectToFitText(node);
+            dx = box.x + devCfg.xoff;
+            dy = box.y + devCfg.yoff;
+        }
+
+        icon.attr('transform', sus.translate(dx, dy));
+    }
+
+    function hostEnter(d) {
+        var node = d3.select(this),
+            gid = d.type || 'unknown',
+            rad = icfg.host.radius,
+            r = d.type ? rad.withGlyph : rad.noGlyph,
+            textDy = r + 10;
+
+        d.el = node;
+        sus.visible(node, api.showHosts());
+
+        is.addHostIcon(node, r, gid);
+
+        node.append('text')
+            .text(hostLabel)
+            .attr('dy', textDy)
+            .attr('text-anchor', 'middle');
+    }
+
+    function hostExit(d) {
+        var node = d.el;
+        node.select('use')
+            .style('opacity', 0.5)
+            .transition()
+            .duration(800)
+            .style('opacity', 0);
+
+        node.select('text')
+            .style('opacity', 0.5)
+            .transition()
+            .duration(800)
+            .style('opacity', 0);
+
+        node.select('circle')
+            .style('stroke-fill', '#555')
+            .style('fill', '#888')
+            .style('opacity', 0.5)
+            .transition()
+            .duration(1500)
+            .attr('r', 0);
+    }
+
+    function deviceExit(d) {
+        var node = d.el;
+        node.select('use')
+            .style('opacity', 0.5)
+            .transition()
+            .duration(800)
+            .style('opacity', 0);
+
+        node.selectAll('rect')
+            .style('stroke-fill', '#555')
+            .style('fill', '#888')
+            .style('opacity', 0.5);
+    }
+
+
+    // ==========================
+    // updateLinks - subfunctions
+
+    function linkExisting(d) {
+        // this is supposed to be an existing link, but we have observed
+        //  occasions (where links are deleted and added rapidly?) where
+        //  the DOM element has not been defined. So protection against that...
+        if (d.el) {
+            api.restyleLinkElement(d, true);
+        }
+    }
+
+    function linkEntering(d) {
+        var link = d3.select(this);
+        d.el = link;
+        api.restyleLinkElement(d);
+        if (d.type() === 'hostLink') {
+            sus.visible(link, api.showHosts());
+        }
+    }
+
+    var linkLabelOffset = '0.3em';
+
+    function applyLinkLabels() {
+        var entering;
+
+        api.updateLinkLabelModel();
+
+        // for elements already existing, we need to update the text
+        // and adjust the rectangle size to fit
+        api.linkLabel().each(function (d) {
+            var el = d3.select(this),
+                rect = el.select('rect'),
+                text = el.select('text');
+            text.text(d.label);
+            rect.attr(rectAroundText(el));
+        });
+
+        entering = api.linkLabel().enter().append('g')
+            .classed('linkLabel', true)
+            .attr('id', function (d) { return d.id; });
+
+        entering.each(function (d) {
+            var el = d3.select(this),
+                rect,
+                text,
+                parms = {
+                    x1: d.ldata.source.x,
+                    y1: d.ldata.source.y,
+                    x2: d.ldata.target.x,
+                    y2: d.ldata.target.y
+                };
+
+            if (d.ldata.type() === 'hostLink') {
+                el.classed('hostLinkLabel', true);
+                sus.visible(el, api.showHosts());
+            }
+
+            d.el = el;
+            rect = el.append('rect');
+            text = el.append('text').text(d.label);
+            rect.attr(rectAroundText(el));
+            text.attr('dy', linkLabelOffset);
+
+            el.attr('transform', transformLabel(parms));
+        });
+
+        // Remove any labels that are no longer required.
+        api.linkLabel().exit().remove();
+    }
+
+    function rectAroundText(el) {
+        var text = el.select('text'),
+            box = text.node().getBBox();
+
+        // 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 -= 1;
+        box.width += 2;
+        return box;
+    }
+
+    function transformLabel(p) {
+        var dx = p.x2 - p.x1,
+            dy = p.y2 - p.y1,
+            xMid = dx/2 + p.x1,
+            yMid = dy/2 + p.y1;
+        return sus.translate(xMid, yMid);
+    }
+
+
+    // ==========================
+    // Module definition
+
+    angular.module('ovTopo')
+    .factory('TopoD3Service',
+        ['$log', 'FnService', 'SvgUtilService', 'IconService', 'ThemeService',
+
+        function (_$log_, _fs_, _sus_, _is_, _ts_) {
+            $log = _$log_;
+            fs = _fs_;
+            sus = _sus_;
+            is = _is_;
+            ts = _ts_;
+
+            icfg = is.iconConfig();
+
+            function initD3(_api_) {
+                api = _api_;
+            }
+
+            function destroyD3() { }
+
+            return {
+                initD3: initD3,
+                destroyD3: destroyD3,
+
+                incDevLabIndex: incDevLabIndex,
+                adjustRectToFitText: adjustRectToFitText,
+                hostLabel: hostLabel,
+                deviceLabel: deviceLabel,
+                trimLabel: trimLabel,
+
+                updateDeviceLabel: updateDeviceLabel,
+                updateHostLabel: updateHostLabel,
+                updateDeviceColors: updateDeviceColors,
+
+                deviceExisting: deviceExisting,
+                hostExisting: hostExisting,
+                deviceEnter: deviceEnter,
+                hostEnter: hostEnter,
+                hostExit: hostExit,
+                deviceExit: deviceExit,
+
+                linkExisting: linkExisting,
+                linkEntering: linkEntering,
+                applyLinkLabels: applyLinkLabels,
+
+                transformLabel: transformLabel
+            };
+        }]);
+}());
