diff --git a/web/ons-demo/js/topology.js b/web/ons-demo/js/topology.js
new file mode 100644
index 0000000..b7a9112
--- /dev/null
+++ b/web/ons-demo/js/topology.js
@@ -0,0 +1,675 @@
+/***************************************************************************************************
+functions for creating and interacting with the topology view of the webui
+
+flow related topology is in flows.js
+***************************************************************************************************/
+
+function createLinkMap(links) {
+	var linkMap = {};
+	links.forEach(function (link) {
+		var srcDPID = link['src-switch'];
+		var dstDPID = link['dst-switch'];
+
+		var srcMap = linkMap[srcDPID] || {};
+
+		srcMap[dstDPID] = link;
+
+		linkMap[srcDPID]  = srcMap;
+	});
+	return linkMap;
+}
+
+
+// removes links from the pending list that are now in the model
+function reconcilePendingLinks(model) {
+	var links = [];
+	model.links.forEach(function (link) {
+		links.push(link);
+		delete pendingLinks[makeLinkKey(link)]
+	})
+	var linkId;
+	for (linkId in pendingLinks) {
+		links.push(pendingLinks[linkId]);
+	}
+	return links
+}
+
+
+function createTopologyView() {
+
+	window.addEventListener('resize', function () {
+		// this is too slow. instead detect first resize event and hide the paths that have explicit matrix applied
+		// either that or is it possible to position the paths so they get the automatic transform as well?
+//		updateTopology();
+	});
+
+	var svg = d3.select('#svg-container').append('svg:svg');
+
+	svg.append("svg:defs").append("svg:marker")
+	    .attr("id", "arrow")
+	    .attr("viewBox", "0 -5 10 10")
+	    .attr("refX", -1)
+	    .attr("markerWidth", 5)
+	    .attr("markerHeight", 5)
+	    .attr("orient", "auto")
+	  .append("svg:path")
+	    .attr("d", "M0,-3L10,0L0,3");
+
+	return svg.append('svg:svg').attr('id', 'viewBox').attr('viewBox', '0 0 1000 1000').attr('preserveAspectRatio', 'none').
+			attr('id', 'viewbox').append('svg:g').attr('transform', 'translate(500 500)');
+}
+
+// d3.xml("assets/map.svg", "image/svg+xml", function(xml) {
+//   var importedNode = document.importNode(xml.documentElement, true);
+//   var paths = importedNode.querySelectorAll('path');
+//   var i;
+//   for (i=0; i < paths.length; i+=1) {
+//   	svg.append('svg:path')
+//   		.attr('class', 'state')
+//   		.attr('d', d3.select(paths.item(i)).attr('d'))
+//   		.attr('transform', 'translate(-500 -500)scale(1 1.7)')
+//   }
+// });
+
+
+var widths = {
+	edge: 6,
+	aggregation: 12,
+	core: 18
+}
+
+function createRingsFromModel(model) {
+	var rings = [{
+		radius: 3,
+		width: widths.edge,
+		switches: model.edgeSwitches,
+		className: 'edge',
+		angles: []
+	}, {
+		radius: 2.25,
+		width: widths.aggregation,
+		switches: model.aggregationSwitches,
+		className: 'aggregation',
+		angles: []
+	}, {
+		radius: 0.75,
+		width: widths.core,
+		switches: model.coreSwitches,
+		className: 'core',
+		angles: []
+	}];
+
+
+	var aggRanges = {};
+
+	// arrange edge switches at equal increments
+	var k = 360 / rings[0].switches.length;
+	rings[0].switches.forEach(function (s, i) {
+		var angle = k * i;
+
+		rings[0].angles[i] = angle;
+
+		// record the angle for the agg switch layout
+		var dpid = s.dpid.split(':');
+		dpid[7] = '01'; // the last component of the agg switch is always '01'
+		var aggdpid = dpid.join(':');
+		var aggRange = aggRanges[aggdpid];
+		if (!aggRange) {
+			aggRange = aggRanges[aggdpid] = {};
+			aggRange.min = aggRange.max = angle;
+		} else {
+			aggRange.max = angle;
+		}
+	});
+
+	// arrange aggregation switches to "fan out" to edge switches
+	k = 360 / rings[1].switches.length;
+	rings[1].switches.forEach(function (s, i) {
+//		rings[1].angles[i] = k * i;
+		var range = aggRanges[s.dpid];
+
+		rings[1].angles[i] = (range.min + range.max)/2;
+	});
+
+	// find the association between core switches and aggregation switches
+	var aggregationSwitchMap = {};
+	model.aggregationSwitches.forEach(function (s, i) {
+		aggregationSwitchMap[s.dpid] = i;
+	});
+
+	// put core switches next to linked aggregation switches
+	k = 360 / rings[2].switches.length;
+	rings[2].switches.forEach(function (s, i) {
+//		rings[2].angles[i] = k * i;
+		var associatedAggregationSwitches = model.configuration.association[s.dpid];
+		// TODO: go between if there are multiple
+		var index = aggregationSwitchMap[associatedAggregationSwitches[0]];
+
+		rings[2].angles[i] = rings[1].angles[index];
+	});
+
+	// TODO: construct this form initially rather than converting. it works better because
+	// it allows binding by dpid
+	var testRings = [];
+	rings.forEach(function (ring) {
+		var testRing = [];
+		ring.switches.forEach(function (s, i) {
+			var testSwitch = {
+				dpid: s.dpid,
+				state: s.state,
+				radius: ring.radius,
+				width: ring.width,
+				className: ring.className,
+				angle: ring.angles[i],
+				controller: s.controller
+			};
+			testRing.push(testSwitch);
+		});
+
+
+		testRings.push(testRing);
+	});
+
+
+//	return rings;
+	return testRings;
+}
+
+updateTopology = function() {
+
+	// DRAW THE SWITCHES
+	var rings = svg.selectAll('.ring').data(createRingsFromModel(model));
+
+	var links = reconcilePendingLinks(model);
+	var linkMap = createLinkMap(links);
+
+	function mouseOverSwitch(data) {
+
+		d3.event.preventDefault();
+
+		d3.select(document.getElementById(data.dpid + '-label')).classed('nolabel', false);
+
+		if (data.highlighted) {
+			return;
+		}
+
+		// only highlight valid link or flow destination by checking for class of existing highlighted circle
+		var highlighted = svg.selectAll('.highlight')[0];
+		if (highlighted.length == 1) {
+			var s = d3.select(highlighted[0]).select('circle');
+			// only allow links
+			// 	edge->edge (flow)
+			//  aggregation->core
+			//	core->core
+			if (data.className == 'edge' && !s.classed('edge') ||
+				data.className == 'core' && !s.classed('core') && !s.classed('aggregation') ||
+				data.className == 'aggregation' && !s.classed('core')) {
+				return;
+			}
+
+			// don't highlight if there's already a link or flow
+			// var map = linkMap[data.dpid];
+			// console.log(map);
+			// console.log(s.data()[0].dpid);
+			// console.log(map[s.data()[0].dpid]);
+			// if (map && map[s.data()[0].dpid]) {
+			// 	return;
+			// }
+
+			// the second highlighted switch is the target for a link or flow
+			data.target = true;
+		}
+
+		var node = d3.select(document.getElementById(data.dpid));
+		node.classed('highlight', true).select('circle').transition().duration(100).attr("r", widths.core);
+		data.highlighted = true;
+		node.moveToFront();
+	}
+
+	function mouseOutSwitch(data) {
+		d3.select(document.getElementById(data.dpid + '-label')).classed('nolabel', true);
+
+		if (data.mouseDown)
+			return;
+
+		var node = d3.select(document.getElementById(data.dpid));
+		node.classed('highlight', false).select('circle').transition().duration(100).attr("r", widths[data.className]);
+		data.highlighted = false;
+		data.target = false;
+	}
+
+	function mouseDownSwitch(data) {
+		mouseOverSwitch(data);
+		data.mouseDown = true;
+		d3.select('#topology').classed('linking', true);
+
+		d3.select('svg')
+			.append('svg:path')
+			.attr('id', 'linkVector')
+			.attr('d', function () {
+				var s = d3.select(document.getElementById(data.dpid));
+
+				var pt = document.querySelector('svg').createSVGPoint();
+				pt.x = s.attr('x');
+				pt.y = s.attr('y');
+				pt = pt.matrixTransform(s[0][0].getCTM());
+
+				return line([pt, pt]);
+			});
+
+
+		if (data.className === 'core') {
+			d3.selectAll('.edge').classed('nodrop', true);
+		}
+		if (data.className === 'edge') {
+			d3.selectAll('.core').classed('nodrop', true);
+			d3.selectAll('.aggregation').classed('nodrop', true);
+		}
+		if (data.className === 'aggregation') {
+			d3.selectAll('.edge').classed('nodrop', true);
+			d3.selectAll('.aggregation').classed('nodrop', true);
+		}
+	}
+
+	function mouseUpSwitch(data) {
+		if (data.mouseDown) {
+			data.mouseDown = false;
+			d3.select('#topology').classed('linking', false);
+			d3.event.stopPropagation();
+			d3.selectAll('.nodrop').classed('nodrop', false);
+		}
+	}
+
+	function doubleClickSwitch(data) {
+		var circle = d3.select(document.getElementById(data.dpid)).select('circle');
+		if (data.state == 'ACTIVE') {
+			var prompt = 'Deactivate ' + data.dpid + '?';
+			if (confirm(prompt)) {
+				switchDown(data);
+				setPending(circle);
+			}
+		} else {
+			var prompt = 'Activate ' + data.dpid + '?';
+			if (confirm(prompt)) {
+				switchUp(data);
+				setPending(circle);
+			}
+		}
+	}
+
+	function ringEnter(data, i) {
+		if (!data.length) {
+			return;
+		}
+
+		// create the nodes
+		var nodes = d3.select(this).selectAll("g")
+			.data(data, function (data) {
+				return data.dpid;
+			})
+			.enter().append("svg:g")
+			.attr("id", function (data, i) {
+				return data.dpid;
+			})
+			.attr("transform", function(data, i) {
+				return "rotate(" + data.angle+ ")translate(" + data.radius * 150 + ")rotate(" + (-data.angle) + ")";
+			});
+
+		// add the cirles representing the switches
+		nodes.append("svg:circle")
+			.attr("transform", function(data, i) {
+				var m = document.querySelector('#viewbox').getTransformToElement().inverse();
+				if (data.scale) {
+					m = m.scale(data.scale);
+				}
+				return "matrix( " + m.a + " " + m.b + " " + m.c + " " + m.d + " " + m.e + " " + m.f + " )";
+			})
+			.attr("x", function (data) {
+				return -data.width / 2;
+			})
+			.attr("y", function (data) {
+				return -data.width / 2;
+			})
+			.attr("r", function (data) {
+				return data.width;
+			});
+
+		// setup the mouseover behaviors
+		nodes.on('mouseover', mouseOverSwitch);
+		nodes.on('mouseout', mouseOutSwitch);
+		nodes.on('mouseup', mouseUpSwitch);
+		nodes.on('mousedown', mouseDownSwitch);
+
+		// only do switch up/down for core switches
+		if (i == 2) {
+			nodes.on('dblclick', doubleClickSwitch);
+		}
+	}
+
+	// append switches
+	rings.enter().append("svg:g")
+		.attr("class", "ring")
+		.each(ringEnter);
+
+
+	function ringUpdate(data, i) {
+		var nodes = d3.select(this).selectAll("g")
+			.data(data, function (data) {
+				return data.dpid;
+			});
+		nodes.select('circle')
+			.each(function (data) {
+				// if there's a pending state changed and then the state changes, clear the pending class
+				var circle = d3.select(this);
+				if (data.state === 'ACTIVE' && circle.classed('inactive') ||
+					data.state === 'INACTIVE' && circle.classed('active')) {
+					circle.classed('pending', false);
+				}
+			})
+			.attr('class', function (data)  {
+				if (data.state === 'ACTIVE' && data.controller) {
+					return data.className + ' active ' + controllerColorMap[data.controller];
+				} else {
+					return data.className + ' inactive ' + 'colorInactive';
+				}
+			});
+	}
+
+	// update  switches
+	rings.each(ringUpdate);
+
+
+	// Now setup the labels
+	// This is done separately because SVG draws in node order and we want the labels
+	// always on top
+	var labelRings = svg.selectAll('.labelRing').data(createRingsFromModel(model));
+
+	d3.select(document.body).on('mousemove', function () {
+		if (!d3.select('#topology').classed('linking')) {
+			return;
+		}
+		var linkVector = document.getElementById('linkVector');
+		if (!linkVector) {
+			return;
+		}
+		linkVector = d3.select(linkVector);
+
+		var highlighted = svg.selectAll('.highlight')[0];
+		var s1 = null, s2 = null;
+		if (highlighted.length > 1) {
+			var s1 = d3.select(highlighted[0]);
+			var s2 = d3.select(highlighted[1]);
+
+		} else if (highlighted.length > 0) {
+			var s1 = d3.select(highlighted[0]);
+		}
+		var src = s1;
+		if (s2 && !s2.data()[0].target) {
+			src = s2;
+		}
+		if (src) {
+			linkVector.attr('d', function () {
+					var srcPt = document.querySelector('svg').createSVGPoint();
+					srcPt.x = src.attr('x');
+					srcPt.y = src.attr('y');
+					srcPt = srcPt.matrixTransform(src[0][0].getCTM());
+
+					var svg = document.getElementById('topology');
+					var mouse = d3.mouse(viewbox);
+					var dstPt = document.querySelector('svg').createSVGPoint();
+					dstPt.x = mouse[0];
+					dstPt.y = mouse[1];
+					dstPt = dstPt.matrixTransform(viewbox.getCTM());
+
+					return line([srcPt, dstPt]);
+				});
+		}
+	});
+
+	d3.select(document.body).on('mouseup', function () {
+		function clearHighlight() {
+			svg.selectAll('circle').each(function (data) {
+				data.mouseDown = false;
+				d3.select('#topology').classed('linking', false);
+				mouseOutSwitch(data);
+			});
+			d3.select('#linkVector').remove();
+		};
+
+		d3.selectAll('.nodrop').classed('nodrop', false);
+
+		function removeLink(link) {
+			var path1 = document.getElementById(link['src-switch'] + '=>' + link['dst-switch']);
+			var path2 = document.getElementById(link['dst-switch'] + '=>' + link['src-switch']);
+
+			if (path1) {
+				setPending(d3.select(path1));
+			}
+			if (path2) {
+				setPending(d3.select(path2));
+			}
+
+			linkDown(link);
+		}
+
+
+		var highlighted = svg.selectAll('.highlight')[0];
+		if (highlighted.length == 2) {
+			var s1Data = highlighted[0].__data__;
+			var s2Data = highlighted[1].__data__;
+
+			var srcData, dstData;
+			if (s1Data.target) {
+				dstData = s1Data;
+				srcData = s2Data;
+			} else {
+				dstData = s2Data;
+				srcData = s1Data;
+			}
+
+			if (s1Data.className == 'edge' && s2Data.className == 'edge') {
+				var prompt = 'Create flow from ' + srcData.dpid + ' to ' + dstData.dpid + '?';
+				if (confirm(prompt)) {
+					addFlow(srcData, dstData);
+
+					var flow = {
+						dataPath: {
+							srcPort: {
+								dpid: {
+									value: srcData.dpid
+								}
+							},
+							dstPort: {
+								dpid: {
+									value: dstData.dpid
+								}
+							}
+						},
+					        srcDpid: srcData.dpid,
+					        dstDpid: dstData.dpid,
+						createPending: true
+					};
+
+					selectFlow(flow);
+
+					setTimeout(function () {
+						deselectFlowIfCreatePending(flow);
+					}, pendingTimeout);
+				}
+			} else {
+				var map = linkMap[srcData.dpid];
+				if (map && map[dstData.dpid]) {
+					var prompt = 'Remove link between ' + srcData.dpid + ' and ' + dstData.dpid + '?';
+					if (confirm(prompt)) {
+						removeLink(map[dstData.dpid]);
+					}
+				} else {
+					map = linkMap[dstData.dpid];
+					if (map && map[srcData.dpid]) {
+						var prompt = 'Remove link between ' + dstData.dpid + ' and ' + srcData.dpid + '?';
+						if (confirm(prompt)) {
+							removeLink(map[srcData.dpid]);
+						}
+					} else {
+						var prompt = 'Create link between ' + srcData.dpid + ' and ' + dstData.dpid + '?';
+						if (confirm(prompt)) {
+							var link1 = {
+								'src-switch': srcData.dpid,
+								'src-port': 1,
+								'dst-switch': dstData.dpid,
+								'dst-port': 1,
+								pending: true
+							};
+							pendingLinks[makeLinkKey(link1)] = link1;
+							var link2 = {
+								'src-switch': dstData.dpid,
+								'src-port': 1,
+								'dst-switch': srcData.dpid,
+								'dst-port': 1,
+								pending: true
+							};
+							pendingLinks[makeLinkKey(link2)] = link2;
+							updateTopology();
+
+							linkUp(link1);
+
+							// remove the pending links after 10s
+							setTimeout(function () {
+								delete pendingLinks[makeLinkKey(link1)];
+								delete pendingLinks[makeLinkKey(link2)];
+
+								updateTopology();
+							}, pendingTimeout);
+						}
+					}
+				}
+			}
+
+			clearHighlight();
+		} else {
+			clearHighlight();
+		}
+
+	});
+
+	function labelRingEnter(data) {
+		if (!data.length) {
+			return;
+		}
+
+		// create the nodes
+		var nodes = d3.select(this).selectAll("g")
+			.data(data, function (data) {
+				return data.dpid;
+			})
+			.enter().append("svg:g")
+			.classed('nolabel', true)
+			.attr("id", function (data) {
+				return data.dpid + '-label';
+			})
+			.attr("transform", function(data, i) {
+				return "rotate(" + data.angle+ ")translate(" + data.radius * 150 + ")rotate(" + (-data.angle) + ")";
+			})
+
+		// add the text nodes which show on mouse over
+		nodes.append("svg:text")
+				.text(function (data) {return data.dpid;})
+				.attr("x", function (data) {
+					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
+						if (data.className == 'edge') {
+							return - data.width*3 - 4;
+						} else {
+							return - data.width - 4;
+						}
+					} else {
+						if (data.className == 'edge') {
+							return data.width*3 + 4;
+						} else {
+							return data.width + 4;
+						}
+					}
+				})
+				.attr("y", function (data) {
+					var y;
+					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
+						if (data.className == 'edge') {
+							y = data.width*3/2 + 4;
+						} else {
+							y = data.width/2 + 4;
+						}
+					} else {
+						if (data.className == 'edge') {
+							y = data.width*3/2 + 4;
+						} else {
+							y = data.width/2 + 4;
+						}
+					}
+					return y - 6;
+				})
+				.attr("text-anchor", function (data) {
+					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
+						return "end";
+					} else {
+						return "start";
+					}
+				})
+				.attr("transform", function(data) {
+					var m = document.querySelector('#viewbox').getTransformToElement().inverse();
+					if (data.scale) {
+						m = m.scale(data.scale);
+					}
+					return "matrix( " + m.a + " " + m.b + " " + m.c + " " + m.d + " " + m.e + " " + m.f + " )";
+				})
+	}
+
+	labelRings.enter().append("svg:g")
+		.attr("class", "textRing")
+		.each(labelRingEnter);
+
+	// switches should not change during operation of the ui so no
+	// rings.exit()
+
+
+	// DRAW THE LINKS
+
+	// key on link dpids since these will come/go during demo
+	var links = d3.select('svg').selectAll('.link').data(links, function (d) {
+			return d['src-switch']+'->'+d['dst-switch'];
+	});
+
+	// add new links
+	links.enter().append("svg:path")
+	.attr("class", "link");
+
+	links.attr('id', function (d) {
+			return makeLinkKey(d);
+		})
+		.attr("d", function (d) {
+			var src = d3.select(document.getElementById(d['src-switch']));
+			var dst = d3.select(document.getElementById(d['dst-switch']));
+
+			var srcPt = document.querySelector('svg').createSVGPoint();
+			srcPt.x = src.attr('x');
+			srcPt.y = src.attr('y');
+			srcPt = srcPt.matrixTransform(src[0][0].getCTM());
+
+			var dstPt = document.querySelector('svg').createSVGPoint();
+			dstPt.x = dst.attr('x');
+			dstPt.y = dst.attr('y');
+			dstPt = dstPt.matrixTransform(dst[0][0].getCTM());
+
+			var midPt = document.querySelector('svg').createSVGPoint();
+			midPt.x = (srcPt.x + dstPt.x)/2;
+			midPt.y = (srcPt.y + dstPt.y)/2;
+
+			return line([srcPt, midPt, dstPt]);
+		})
+		.attr("marker-mid", function(d) { return "url(#arrow)"; })
+		.classed('pending', function (d) {
+			return d.pending;
+		});
+
+
+	// remove old links
+	links.exit().remove();
+}
\ No newline at end of file
