diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js b/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js
index 6e5df6c..9849393 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js
@@ -22,10 +22,7 @@
 (function () {
     'use strict';
 
-    var $log, wss, sus, t2rs, t2d3, t2vs, t2ss;
-
-    var linkG, linkLabelG, nodeG;
-    var link, node, zoomer;
+    var instance;
 
     // default settings for force layout
     var defaultSettings = {
@@ -73,246 +70,14 @@
     };
 
     // internal state
-    var settings,               // merged default settings and options
-        force,                  // force layout object
-        drag,                   // drag behavior handler
-        previousNearestLink,    // previous link to mouse position
-        nodeLock = false;       // whether nodes can be dragged or not (locked)
-
-
-    function init(_svg_, forceG, _uplink_, _dim_, _zoomer_, opts) {
-
-        $log.debug("Initialising Topology Layout");
-        settings = angular.extend({}, defaultSettings, opts);
-
-        linkG = forceG.append('g').attr('id', 'topo-links');
-        linkLabelG = forceG.append('g').attr('id', 'topo-linkLabels');
-        forceG.append('g').attr('id', 'topo-numLinkLabels');
-        nodeG = forceG.append('g').attr('id', 'topo-nodes');
-        forceG.append('g').attr('id', 'topo-portLabels');
-
-        link = linkG.selectAll('.link');
-        linkLabelG.selectAll('.linkLabel');
-        node = nodeG.selectAll('.node');
-
-        zoomer = _zoomer_;
-        _svg_.on('mousemove', mouseMoveHandler);
-        _svg_.on('click', mouseClickHandler);
-    }
-
-    function getDeviceChargeForType(node) {
-
-        var nodeType = node.get('nodeType');
-
-        return settings.charge[nodeType] ||
-            settings.charge._def_;
-    }
-
-    function getLinkDistanceForLinkType(node) {
-        var nodeType = node.get('type');
-
-        return settings.linkDistance[nodeType] ||
-            settings.linkDistance._def_;
-    }
-
-    function getLinkStrenghForLinkType(node) {
-        var nodeType = node.get('type');
-
-        return settings.linkStrength[nodeType] ||
-            settings.linkStrength._def_;
-    }
-
-    function createForceLayout() {
-
-        var regionLinks = t2rs.regionLinks(),
-            regionNodes = t2rs.regionNodes();
-
-        force = d3.layout.force()
-            .size(t2vs.getDimensions())
-            .gravity(settings.gravity)
-            .friction(settings.friction)
-            .charge(getDeviceChargeForType)
-            .linkDistance(getLinkDistanceForLinkType)
-            .linkStrength(getLinkStrenghForLinkType)
-            .on("tick", tick);
-
-        force
-            .nodes(t2rs.regionNodes())
-            .links(regionLinks)
-            .start();
-
-        link = linkG.selectAll('.link')
-            .data(regionLinks, function (d) { return d.get('key'); });
-
-        node = nodeG.selectAll('.node')
-            .data(regionNodes, function (d) { return d.get('id'); });
-
-        drag = sus.createDragBehavior(force,
-          t2ss.selectObject, atDragEnd, dragEnabled, clickEnabled);
-
-        update();
-    }
+    var nodeLock = false;       // whether nodes can be dragged or not (locked)
 
     // predicate that indicates when clicking is active
     function clickEnabled() {
         return true;
     }
 
-    function zoomingOrPanning(ev) {
-        return ev.metaKey || ev.altKey;
-    }
-
-    function atDragEnd(d) {
-        // once we've finished moving, pin the node in position
-        d.fixed = true;
-        d3.select(this).classed('fixed', true);
-        sendUpdateMeta(d);
-        $log.debug(d);
-        t2ss.clickConsumed(true);
-    }
-
-    // predicate that indicates when dragging is active
-    function dragEnabled() {
-        var ev = d3.event.sourceEvent;
-        // nodeLock means we aren't allowing nodes to be dragged...
-        return !nodeLock && !zoomingOrPanning(ev);
-    }
-
-    function sendUpdateMeta(d, clearPos) {
-        var metaUi = {},
-            ll;
-
-        // if we are not clearing the position data (unpinning),
-        // attach the x, y, (and equivalent longitude, latitude)...
-        if (!clearPos) {
-            ll = d.lngLatFromCoord([d.x, d.y]);
-            metaUi = {
-                x: d.x,
-                y: d.y,
-                equivLoc: {
-                    lng: ll[0],
-                    lat: ll[1]
-                }
-            };
-        }
-        d.metaUi = metaUi;
-        wss.sendEvent('updateMeta2', {
-            id: d.get('id'),
-            class: d.get('class'),
-            memento: metaUi
-        });
-    }
-
-    function tick() {
-        link
-            .attr("x1", function (d) { return d.source.x; })
-            .attr("y1", function (d) { return d.source.y; })
-            .attr("x2", function (d) { return d.target.x; })
-            .attr("y2", function (d) { return d.target.y; });
-
-        node
-            .attr({
-                transform: function (d) {
-                    var dx = isNaN(d.x) ? 0 : d.x,
-                        dy = isNaN(d.y) ? 0 : d.y;
-                    return sus.translate(dx, dy);
-                }
-            });
-    }
-
-    function update() {
-        _updateNodes();
-        _updateLinks();
-    }
-
-    function _updateNodes() {
-
-        var regionNodes = t2rs.regionNodes();
-
-        // select all the nodes in the layout:
-        node = nodeG.selectAll('.node')
-            .data(regionNodes, function (d) { return d.get('id'); });
-
-        var entering = node.enter()
-            .append('g')
-            .attr({
-                id: function (d) { return sus.safeId(d.get('id')); },
-                class: function (d) { return d.svgClassName(); },
-                transform: function (d) {
-                    // Need to guard against NaN here ??
-                    return sus.translate(d.node.x, d.node.y);
-                },
-                opacity: 0
-            })
-            .call(drag)
-            .transition()
-            .attr('opacity', 1);
-
-        entering.filter('.device').each(t2d3.nodeEnter);
-        entering.filter('.sub-region').each(t2d3.nodeEnter);
-        entering.filter('.host').each(t2d3.hostEnter);
-
-        // operate on exiting nodes:
-        // Note that the node is removed after 2 seconds.
-        // Sub element animations should be shorter than 2 seconds.
-        var exiting = node.exit()
-            .transition()
-            .duration(300)
-            .style('opacity', 0)
-            .remove();
-
-        // exiting node specifics:
-        // exiting.filter('.host').each(t2d3.hostExit);
-        exiting.filter('.device').each(t2d3.nodeExit);
-    }
-
-    function _updateLinks() {
-
-        // var th = ts.theme();
-        var regionLinks = t2rs.regionLinks();
-
-        link = linkG.selectAll('.link')
-            .data(regionLinks, function (d) { return d.get('key'); });
-
-        // operate on entering links:
-        var entering = link.enter()
-            .append('line')
-            .call(calcPosition)
-            .attr({
-                x1: function (d) { return d.get('position').x1; },
-                y1: function (d) { return d.get('position').y1; },
-                x2: function (d) { return d.get('position').x2; },
-                y2: function (d) { return d.get('position').y2; },
-                stroke: linkConfig.light.inColor,
-                'stroke-width': linkConfig.inWidth
-            });
-
-        entering.each(t2d3.linkEntering);
-
-        // operate on exiting links:
-        link.exit()
-            .style('opacity', 1)
-            .transition()
-            .duration(300)
-            .style('opacity', 0.0)
-            .remove();
-    }
-
-    function calcPosition() {
-        var lines = this;
-
-        lines.each(function (d) {
-            if (d.get('type') === 'hostLink') {
-                d.set('position', getDefaultPos(d));
-            }
-        });
-
-        lines.each(function (d) {
-            d.set('position', getDefaultPos(d));
-        });
-    }
-
-    function getDefaultPos(link) {
+    function getDefaultPosition(link) {
         return {
             x1: link.get('source').x,
             y1: link.get('source').y,
@@ -321,156 +86,293 @@
         };
     }
 
-    function setDimensions() {
-        if (force) {
-            force.size(t2vs.getDimensions());
-        }
-    }
-
-    function start() {
-        force.start();
-    }
-
-    function mouseClickHandler() {
-
-        if (!d3.event.shiftKey) {
-            t2rs.deselectLink();
-        }
-
-        if (!t2ss.clickConsumed()) {
-            if (previousNearestLink) {
-                previousNearestLink.select();
-            }
-        }
-
-    }
-
-    // Select Links
-    function mouseMoveHandler() {
-        var mp = getLogicalMousePosition(this),
-            link = computeNearestLink(mp);
-
-        // link.enhance();
-        if (link) {
-            if (previousNearestLink && previousNearestLink != link) {
-                previousNearestLink.unenhance();
-            }
-            link.enhance();
-        } else {
-            if (previousNearestLink) {
-                previousNearestLink.unenhance();
-            }
-        }
-
-        previousNearestLink = link;
-    }
-
-
-    function getLogicalMousePosition(container) {
-        var m = d3.mouse(container),
-            sc = zoomer.scale(),
-            tr = zoomer.translate(),
-            mx = (m[0] - tr[0]) / sc,
-            my = (m[1] - tr[1]) / sc;
-        return {x: mx, y: my};
-    }
-
-    function sq(x) { return x * x; }
-
-    function mdist(p, m) {
-        return Math.sqrt(sq(p.x - m.x) + sq(p.y - m.y));
-    }
-
-    function prox(dist) {
-        return dist / zoomer.scale();
-    }
-
-    function computeNearestLink(mouse) {
-        var proximity = prox(30),
-            nearest = null,
-            minDist;
-
-        function pdrop(line, mouse) {
-            var x1 = line.x1,
-                y1 = line.y1,
-                x2 = line.x2,
-                y2 = line.y2,
-                x3 = mouse.x,
-                y3 = mouse.y,
-                k = ((y2-y1) * (x3-x1) - (x2-x1) * (y3-y1)) /
-                    (sq(y2-y1) + sq(x2-x1)),
-                x4 = x3 - k * (y2-y1),
-                y4 = y3 + k * (x2-x1);
-            return {x:x4, y:y4};
-        }
-
-        function lineHit(line, p, m) {
-            if (p.x < line.x1 && p.x < line.x2) return false;
-            if (p.x > line.x1 && p.x > line.x2) return false;
-            if (p.y < line.y1 && p.y < line.y2) return false;
-            if (p.y > line.y1 && p.y > line.y2) return false;
-            // line intersects, but are we close enough?
-            return mdist(p, m) <= proximity;
-        }
-
-        var links = t2rs.regionLinks();
-
-        if (links.length) {
-            minDist = proximity * 2;
-
-            links.forEach(function (d) {
-                var line = d.get('position'),
-                    point,
-                    hit,
-                    dist;
-
-                // TODO: Reinstate when showHost() is implemented
-                // if (!api.showHosts() && d.type() === 'hostLink') {
-                //     return; // skip hidden host links
-                // }
-
-                if (line) {
-                    point = pdrop(line, mouse);
-                    hit = lineHit(line, point, mouse);
-                    if (hit) {
-                        dist = mdist(point, mouse);
-                        if (dist < minDist) {
-                            minDist = dist;
-                            nearest = d;
-                        }
-                    }
-                }
-            });
-        }
-
-        return nearest;
-    }
-
     angular.module('ovTopo2')
     .factory('Topo2LayoutService',
         [
             '$log', 'WebSocketService', 'SvgUtilService', 'Topo2RegionService',
-            'Topo2D3Service', 'Topo2ViewService', 'Topo2SelectService',
+            'Topo2D3Service', 'Topo2ViewService', 'Topo2SelectService', 'Topo2ZoomService',
+            'Topo2ViewController',
+            function ($log, wss, sus, t2rs, t2d3, t2vs, t2ss, t2zs,
+                      ViewController) {
 
-            function (_$log_, _wss_, _sus_, _t2rs_, _t2d3_, _t2vs_, _t2ss_) {
+                var Layout = ViewController.extend({
+                    initialize: function (svg, forceG, uplink, dim, zoomer, opts) {
 
-                $log = _$log_;
-                wss = _wss_;
-                t2rs = _t2rs_;
-                t2d3 = _t2d3_;
-                t2vs = _t2vs_;
-                t2ss = _t2ss_;
-                sus = _sus_;
+                        $log.debug('initialize Layout');
+                        instance = this;
 
-                return {
-                    init: init,
-                    createForceLayout: createForceLayout,
-                    update: update,
-                    tick: tick,
-                    start: start,
+                        this.svg = svg;
 
-                    setDimensions: setDimensions
-                };
+                        // Append all the SVG Group elements to the forceG object
+                        this.createForceElements();
+
+                        this.uplink = uplink;
+                        this.dim = dim;
+                        this.zoomer = zoomer;
+
+                        this.settings = angular.extend({}, defaultSettings, opts);
+
+                        this.link = this.elements.linkG.selectAll('.link');
+                        this.elements.linkLabelG.selectAll('.linkLabel');
+                        this.node = this.elements.nodeG.selectAll('.node');
+                    },
+                    createForceElements: function () {
+
+                        this.prevForce = this.forceG;
+
+                        this.forceG = d3.select('#topo-zoomlayer')
+                            .append('g').attr('class', 'topo-force');
+
+                        this.elements = {
+                            linkG: this.addElement(this.forceG, 'topo-links'),
+                            linkLabelG: this.addElement(this.forceG, 'topo-linkLabels'),
+                            numLinksLabels: this.addElement(this.forceG, 'topo-numLinkLabels'),
+                            nodeG: this.addElement(this.forceG, 'topo-nodes'),
+                            portLabels: this.addElement(this.forceG, 'topo-portLabels')
+                        };
+                    },
+                    addElement: function (parent, className) {
+                        return parent.append('g').attr('class', className);
+                    },
+                    settingOrDefault: function (settingName, node) {
+                        var nodeType = node.get('nodeType');
+                        return this.settings[settingName][nodeType] || this.settings[settingName]._def_;
+                    },
+                    createForceLayout: function () {
+                        var _this = this,
+                            regionLinks = t2rs.regionLinks(),
+                            regionNodes = t2rs.regionNodes();
+
+                        this.force = d3.layout.force()
+                            .size(t2vs.getDimensions())
+                            .gravity(this.settings.gravity)
+                            .friction(this.settings.friction)
+                            .charge(this.settingOrDefault.bind(this, 'charge'))
+                            .linkDistance(this.settingOrDefault.bind(this, 'linkDistance'))
+                            .linkStrength(this.settingOrDefault.bind(this, 'linkStrength'))
+                            .nodes(regionNodes)
+                            .links(regionLinks)
+                            .on("tick", this.tick.bind(this))
+                            .on("start", function () {
+
+                                // TODO: Find a better way to do this
+                                setTimeout(function () {
+                                    _this.centerLayout();
+                                }, 500);
+                            })
+                            .start();
+
+                        this.link = this.elements.linkG.selectAll('.link')
+                            .data(regionLinks, function (d) { return d.get('key'); });
+
+                        this.node = this.elements.nodeG.selectAll('.node')
+                            .data(regionNodes, function (d) { return d.get('id'); });
+
+                        this.drag = sus.createDragBehavior(this.force,
+                            t2ss.selectObject,
+                            this.atDragEnd,
+                            this.dragEnabled.bind(this),
+                            clickEnabled
+                        );
+
+                        this.update();
+                    },
+                    centerLayout: function () {
+                        d3.select('#topo-zoomlayer').attr('data-layout', t2rs.model.get('id'));
+
+                        var zoomer = d3.select('#topo-zoomlayer').node().getBBox(),
+                            layoutBBox = this.forceG.node().getBBox(),
+                            scale = (zoomer.height - 150) / layoutBBox.height,
+                            x = (zoomer.width / 2) - ((layoutBBox.x + layoutBBox.width / 2) * scale),
+                            y = (zoomer.height / 2) - ((layoutBBox.y + layoutBBox.height / 2) * scale);
+
+                        t2zs.panAndZoom([x, y], scale, 1000);
+                    },
+                    tick: function () {
+                        this.link
+                            .attr("x1", function (d) { return d.source.x; })
+                            .attr("y1", function (d) { return d.source.y; })
+                            .attr("x2", function (d) { return d.target.x; })
+                            .attr("y2", function (d) { return d.target.y; });
+
+                        this.node
+                            .attr({
+                                transform: function (d) {
+                                    var dx = isNaN(d.x) ? 0 : d.x,
+                                        dy = isNaN(d.y) ? 0 : d.y;
+                                    return sus.translate(dx, dy);
+                                }
+                            });
+                    },
+
+                    start: function () {
+                        this.force.start();
+                    },
+                    update: function () {
+                        this.updateNodes();
+                        this.updateLinks();
+                    },
+                    updateNodes: function () {
+                        var regionNodes = t2rs.regionNodes();
+
+                        // select all the nodes in the layout:
+                        this.node = this.elements.nodeG.selectAll('.node')
+                            .data(regionNodes, function (d) { return d.get('id'); });
+
+                        var entering = this.node.enter()
+                            .append('g')
+                            .attr({
+                                id: function (d) { return sus.safeId(d.get('id')); },
+                                class: function (d) { return d.svgClassName(); },
+                                transform: function (d) {
+                                    // Need to guard against NaN here ??
+                                    return sus.translate(d.node.x, d.node.y);
+                                },
+                                opacity: 0
+                            })
+                            .call(this.drag)
+                            .transition()
+                            .attr('opacity', 1);
+
+                        entering.filter('.device').each(t2d3.nodeEnter);
+                        entering.filter('.sub-region').each(t2d3.nodeEnter);
+                        entering.filter('.host').each(t2d3.hostEnter);
+
+                        // operate on exiting nodes:
+                        // Note that the node is removed after 2 seconds.
+                        // Sub element animations should be shorter than 2 seconds.
+                        // var exiting = this.node.exit()
+                        //     .transition()
+                        //     .duration(300)
+                        //     .style('opacity', 0)
+                        //     .remove();
+
+                        // exiting node specifics:
+                        // exiting.filter('.host').each(t2d3.hostExit);
+                        // exiting.filter('.device').each(t2d3.nodeExit);
+                    },
+                    updateLinks: function () {
+
+                        var regionLinks = t2rs.regionLinks();
+
+                        this.link = this.elements.linkG.selectAll('.link')
+                            .data(regionLinks, function (d) { return d.get('key'); });
+
+                        // operate on entering links:
+                        var entering = this.link.enter()
+                            .append('line')
+                            .call(this.calcPosition)
+                            .attr({
+                                x1: function (d) { return d.get('position').x1; },
+                                y1: function (d) { return d.get('position').y1; },
+                                x2: function (d) { return d.get('position').x2; },
+                                y2: function (d) { return d.get('position').y2; },
+                                stroke: linkConfig.light.inColor,
+                                'stroke-width': linkConfig.inWidth
+                            });
+
+                        entering.each(t2d3.linkEntering);
+
+                        // operate on exiting links:
+                        this.link.exit()
+                            .style('opacity', 1)
+                            .transition()
+                            .duration(300)
+                            .style('opacity', 0.0)
+                            .remove();
+                    },
+                    calcPosition: function () {
+                        var lines = this;
+
+                        lines.each(function (d) {
+                            if (d.get('type') === 'hostLink') {
+                                d.set('position', getDefaultPosition(d));
+                            }
+                        });
+
+                        lines.each(function (d) {
+                            d.set('position', getDefaultPosition(d));
+                        });
+                    },
+                    sendUpdateMeta: function (d, clearPos) {
+                        var metaUi = {},
+                            ll;
+
+                        // if we are not clearing the position data (unpinning),
+                        // attach the x, y, (and equivalent longitude, latitude)...
+                        if (!clearPos) {
+                            ll = d.lngLatFromCoord([d.x, d.y]);
+                            metaUi = {
+                                x: d.x,
+                                y: d.y,
+                                equivLoc: {
+                                    lng: ll[0],
+                                    lat: ll[1]
+                                }
+                            };
+                        }
+                        d.metaUi = metaUi;
+                        wss.sendEvent('updateMeta2', {
+                            id: d.get('id'),
+                            class: d.get('class'),
+                            memento: metaUi
+                        });
+                    },
+                    setDimensions: function () {
+                        if (this.force) {
+                            this.force.size(t2vs.getDimensions());
+                        }
+                    },
+                    dragEnabled: function () {
+                        var ev = d3.event.sourceEvent;
+                        // nodeLock means we aren't allowing nodes to be dragged...
+                        return !nodeLock && !this.zoomingOrPanning(ev);
+                    },
+                    zoomingOrPanning: function (ev) {
+                        return ev.metaKey || ev.altKey;
+                    },
+                    atDragEnd: function (d) {
+                        // once we've finished moving, pin the node in position
+                        d.fixed = true;
+                        d3.select(this).classed('fixed', true);
+                        instance.sendUpdateMeta(d);
+                        $log.debug(d);
+                        t2ss.clickConsumed(true);
+                    },
+                    transitionDownRegion: function () {
+
+                        this.prevForce.transition()
+                            .duration(1500)
+                            .style('opacity', 0)
+                            .remove();
+
+                        this.forceG
+                            .style('opacity', 0)
+                            .transition()
+                            .delay(500)
+                            .duration(500)
+                            .style('opacity', 1);
+                    },
+                    transitionUpRegion: function () {
+                        this.prevForce.transition()
+                            .duration(1000)
+                            .style('opacity', 0)
+                            .remove();
+
+                        this.forceG
+                            .style('opacity', 0)
+                            .transition()
+                            .delay(500)
+                            .duration(500)
+                            .style('opacity', 1);
+                    }
+                });
+
+                function getInstance(svg, forceG, uplink, dim, zoomer, opts) {
+                    return instance || new Layout(svg, forceG, uplink, dim, zoomer, opts);
+                }
+
+                return getInstance;
             }
         ]
     );
