diff --git a/web/gui/src/main/webapp/_sdh/oblique.html b/web/gui/src/main/webapp/_sdh/oblique.html
new file mode 100644
index 0000000..868ba33
--- /dev/null
+++ b/web/gui/src/main/webapp/_sdh/oblique.html
@@ -0,0 +1,460 @@
+<!DOCTYPE html>
+<!--
+  Testing transformations for transitioning between overhead and
+  perspective projections of two layers.
+
+  @author Simon Hunt
+  -->
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Layer Transformations</title>
+
+    <script src="../tp/d3.js"></script>
+    <script src="../tp/topojson.v1.min.js"></script>
+    <script src="../tp/jquery-2.1.1.min.js"></script>
+
+    <style>
+        html,
+        body {
+            background-color: #ccc;
+            font-family: Arial, Helvetica, sans-serif;
+            font-size: 9pt;
+        }
+
+        svg {
+            position: absolute;
+            background-color: #fff;
+            top: 30px;
+            left: 60px;
+        }
+
+        svg text {
+            font-size: 3pt;
+        }
+
+    </style>
+</head>
+<body>
+    <svg width="1000px" height="600px" viewBox="0 0 160 120"></svg>
+
+    <script>
+        (function (){
+
+            // Configuration...
+            var w = 160,
+                h = 120,
+                time = 1500;
+
+            var pktData = [
+                    [20,60,'a'],
+                    [60,20,'b'],
+                    [100,20,'c'],
+                    [140,60,'d'],
+                    [100,100,'e'],
+                    [60,100,'f'],
+                    [20,20,'w'],
+                    [140,20,'x'],
+                    [20,100,'y'],
+                    [140,100,'z']
+                ],
+                optData = [
+                    [40,40,'p'],
+                    [120,40,'q'],
+                    [120,80,'r'],
+                    [40,80,'s'],
+                    [20,20,'j'],
+                    [140,20,'k'],
+                    [20,100,'l'],
+                    [140,100,'m']
+                ],
+                linkData = [
+                    ['a','p'],
+                    ['p','b'],
+                    ['b','c'],
+                    ['c','q'],
+                    ['q','d'],
+                    ['d','r'],
+                    ['r','e'],
+                    ['e','f'],
+                    ['f','s'],
+                    ['s','a'],
+                    ['s','q'],
+                    ['p','r'],
+                    ['b','f'],
+                    ['c','e'],
+                    ['w','j'],
+                    ['x','k'],
+                    ['z','m'],
+                    ['y','l']
+                ];
+
+            // Transform parameters
+            var tf = {
+                    tt:  -.7,     // x skew y factor
+                    xsk: -35,     // x skew angle
+                    ysc: 0.5,     // y scale
+                    ytr: 50,      // y translate
+                    pad: 5
+                },
+                rectFill = {
+                    pkt: 'rgba(130,130,170,0.3)',
+                    opt: 'rgba(170,130,170,0.3)'
+                };
+
+            // Internal state...
+            var nodes = [],
+                links = [],
+                overhead = true,
+                xffn;
+
+            // D3/DOM magic...
+            var svg = d3.select('svg'),
+                nodeG,
+                linkG,
+                node,
+                link,
+                force,
+                pktLayer,
+                optLayer;
+
+
+            // General functions ...
+            function isF(f) {
+                return $.isFunction(f) ? f : null;
+            }
+
+            function translate(x,y) {
+                return 'translate(' + x + ',' + y + ')';
+            }
+
+            function scale(x,y) {
+                return 'scale(' + x + ',' + y + ')';
+            }
+            function skewX(x) {
+                return 'skewX(' + x + ')';
+            }
+
+
+            // Key Bindings...
+            var keyHandler = {
+                T: transform
+            };
+
+            function whatKey(code) {
+                switch (code) {
+                    case 13: return 'enter';
+                    case 16: return 'shift';
+                    case 17: return 'ctrl';
+                    case 18: return 'alt';
+                    case 27: return 'esc';
+                    case 32: return 'space';
+                    case 37: return 'leftArrow';
+                    case 38: return 'upArrow';
+                    case 39: return 'rightArrow';
+                    case 40: return 'downArrow';
+                    case 91: return 'cmdLeft';
+                    case 93: return 'cmdRight';
+                    case 187: return 'equals';
+                    case 189: return 'dash';
+                    case 191: return 'slash';
+                    default:
+                        if ((code >= 48 && code <= 57) ||
+                                (code >= 65 && code <= 90)) {
+                            return String.fromCharCode(code);
+                        } else if (code >= 112 && code <= 123) {
+                            return 'F' + (code - 111);
+                        }
+                        return '.';
+                }
+            }
+
+            function keyIn() {
+                var event = d3.event,
+                        keyCode = event.keyCode,
+                        key = whatKey(keyCode),
+                        fn = isF(keyHandler[key]);
+                if (fn) {
+                    fn(key, keyCode, event);
+                }
+            }
+
+            // Key events....
+            function transform() {
+                overhead = !overhead;
+                if (overhead) {
+                    toOverhead();
+                } else {
+                    toOblique();
+                }
+            }
+
+            function toOverhead() {
+                xffn = null;
+                hidePlane(pktLayer);
+                hidePlane(optLayer);
+                transitionNodes();
+            }
+
+            function padBox(box, p) {
+                box.x -= p;
+                box.y -= p;
+                box.width += p*2;
+                box.height += p*2;
+            }
+
+            function toOblique() {
+                var box = nodeG.node().getBBox();
+                padBox(box, tf.pad);
+
+                xffn = function (xy, dir) {
+                    var x = xy.x + xy.y*tf.tt,
+                        y = xy.y*tf.ysc + tf.ysc*tf.ytr*dir;
+                    return { x: x, y: y};
+                };
+
+                showPlane(pktLayer, box, -1);
+                showPlane(optLayer, box, 1);
+                transitionNodes();
+            }
+
+            function transitionNodes() {
+            // note: turn off force layout while transitioning.. if it is on
+//                force.stop();
+
+                if (xffn) {
+                    nodes.forEach(function (d) {
+                        var dir = d.type === 'pkt' ? -1 : 1,
+                            oldxy = {x: d.x, y: d.y},
+                            coords = xffn(oldxy, dir);
+                        d.oldxy = oldxy;
+                        d.x = coords.x;
+                        d.y = coords.y;
+                    });
+                } else {
+                    nodes.forEach(function (d) {
+                        d.x = d.oldxy.x;
+                        d.y = d.oldxy.y;
+                        delete d.oldxy;
+                    });
+                }
+
+                nodeG.selectAll('.node')
+                        .transition()
+                        .duration(time)
+                        .attr({
+                            transform: function (d) {
+                                return translate(d.x, d.y);
+                            }
+                        });
+
+                linkG.selectAll('.link')
+                        .transition()
+                        .duration(time)
+                        .attr({
+                            x1: function (d) { return d.source.x; },
+                            y1: function (d) { return d.source.y; },
+                            x2: function (d) { return d.target.x; },
+                            y2: function (d) { return d.target.y; }
+                        });
+            }
+
+            function showPlane(layer, box, dir) {
+                layer.select('rect')
+                    .attr(box)
+                    .attr('opacity', 0)
+                    .transition()
+                        .duration(time)
+                        .attr('opacity', 1)
+                        .attr('transform', obliqueXform(dir));
+            }
+
+            function hidePlane(layer) {
+                var rect = layer.select('rect');
+                rect.transition()
+                        .duration(time)
+                        .attr('opacity', 0)
+                        .attr('transform', overheadXform());
+
+            }
+
+            function obliqueXform(dir) {
+                return scale(1, tf.ysc) + translate(0, dir * tf.ytr) + skewX(tf.xsk);
+            }
+
+
+            function overheadXform() {
+                return skewX(0) + translate(0,0) + scale(1,1);
+            }
+
+            // Nodes and Links...
+            function prepareNodes() {
+                var hw = w/2,
+                    hh = h/2;
+
+                function addNode(t, d) {
+                    nodes.push({
+                        type: t,
+                        x: d[0] - hw,
+                        y: d[1] - hh,
+                        id: d[2],
+                        fixed: true
+                    });
+                }
+
+                optData.forEach(function (d) {
+                    addNode('opt', d);
+                });
+                pktData.forEach(function (d) {
+                    addNode('pkt', d);
+                });
+            }
+
+            function findNode(id) {
+                for (var i=0,n=nodes.length; i<n; i++) {
+                    if (nodes[i].id === id) {
+                        return nodes[i];
+                    }
+                }
+                return null;
+            }
+
+            function prepareLinks() {
+                linkData.forEach(function (d) {
+                    var src = d[0],
+                        dst = d[1];
+                    links.push({
+                        id: src + '-' + dst,
+                        source: findNode(src),
+                        target: findNode(dst)
+                    });
+                });
+
+            }
+
+            function updateNodes() {
+                node = nodeG.selectAll('.node')
+                        .data(nodes, function (d) { return d.id; });
+
+                var entering = node.enter()
+                        .append('g').attr({
+                            id: function (d) { return d.id; },
+                            'class': function (d) { return 'node ' + d.type; }
+                        });
+
+                entering.each(function (d) {
+                    var el = d3.select(this);
+                    d.el = el;
+
+                    el.append('rect').attr({
+                        width: 5,
+                        height: 5,
+                        fill: function (d) {
+                            return d.type === 'pkt' ? '#669' : '#969';
+                        },
+                        rx: 1,
+                        transform: 'translate(-2.5,-2.5)'
+                    });
+                    el.append('text')
+                            .text(d.id)
+                            .attr({
+                                dy: '0.9em',
+                                'text-anchor': 'middle',
+                                transform: 'translate(0,-2.5)',
+                                fill: 'white'
+                            });
+                });
+            }
+
+            function updateLinks() {
+                link = linkG.selectAll('.link')
+                        .data(links, function (d) { return d.id; });
+
+                var entering = link.enter()
+                        .append('line').attr({
+                            id: function (d) { return d.id; },
+                            class: 'link',
+                            stroke: '#888',
+                            'stroke-width': 0.4,
+                            opacity: 0.7
+                        });
+
+                entering.each(function (d) {
+                    d.el = d3.select(this);
+
+                });
+            }
+
+            function update() {
+                updateNodes();
+                updateLinks();
+            }
+
+            var ntick = 0;
+            function tick() {
+                console.log('tick ' + (++ntick));
+                node.attr({
+                    transform: function (d) { return translate(d.x, d.y); }
+                });
+
+                link.attr({
+                    x1: function (d) { return d.source.x; },
+                    y1: function (d) { return d.source.y; },
+                    x2: function (d) { return d.target.x; },
+                    y2: function (d) { return d.target.y; }
+                });
+            }
+
+            function setOrigin(/*varargs*/) {
+                var i, n, g;
+                for (i= 0,n=arguments.length; i< n; i++) {
+                     g = arguments[i];
+                    g.attr('transform', translate(w/2, h/2));
+                }
+            }
+
+            function initLayers() {
+                optLayer.attr('class', 'layer').append('rect')
+                        .attr('fill', rectFill.opt);
+                pktLayer.attr('class', 'layer').append('rect')
+                        .attr('fill', rectFill.pkt);
+            }
+
+            function init() {
+                svg.append('text')
+                        .text('Press the "T" key....')
+                        .attr({ dy: '1.2em', fill: '#999'})
+                        .style('font-size', '2.4pt')
+                        .style('font-style', 'italic');
+
+                optLayer = svg.append('g').attr('id', 'optLayer');
+                pktLayer = svg.append('g').attr('id', 'pktLayer');
+                linkG = svg.append('g').attr('id', 'links');
+                nodeG = svg.append('g').attr('id', 'nodes');
+
+                setOrigin(optLayer, pktLayer, linkG, nodeG);
+
+                node = nodeG.selectAll('.node');
+                link = linkG.selectAll('.link');
+
+                initLayers();
+                prepareNodes();
+                prepareLinks();
+
+                force = d3.layout.force()
+                        .size([w,h])
+                        .nodes(nodes)
+                        .links(links)
+                        .gravity(0.4)
+                        .friction(0.7)
+                        .on('tick', tick);
+                update();
+                tick();
+                d3.select('body').on('keydown', keyIn);
+            }
+
+            init();
+        })();
+    </script>
+</body>
+</html>
