 
 	onScriptsLoaded: =>
 		@init()
+		setTimeout =>
+			@watcher = scrollMonitor.create @$context
+			@watcher.enterViewport @_onEnterViewport
+			@watcher.exitViewport @_onExitViewport
+			@watcher.recalculateLocation()
+		, 1
 
-	init: =>
+	_onEnterViewport: () =>
+		@run()
+		@watcher.destroy()
 
-		@root = NODES[0]
-		@root.radius = 0
-		@root.fixed = true
-
-		@svg = d3.select( SELECTOR_CONTAINER )
-			 .append("svg")
-			 .attr("preserveAspectRatio", "xMinYMin meet")
-			 .attr("viewBox", "0 0 " + W + " " + H)
-			 .classed("svg-content", true)
-
-		@svg.selectAll("circle")
-			.data( NODES )
-			.enter()
-			.append("svg:circle")
-			.attr("r", (d) -> d.r )
-			.style("fill", (d, i) -> d.fill )
-
+	run: =>
 		@force = d3.layout.force()
 			.gravity(0.05)
-			# .charge( (d, i) -> i ? 0 : -2000 )
 			.nodes( NODES )
 			.size([ W, H])
 

						quad.point.y += y
				x1 > nx2 or x2 < nx1 or y1 > ny2 or y2 < ny1

	destroy: ->
		super()

					x = node.x - (quad.point.x)
					y = node.y - (quad.point.y)
					l = Math.sqrt(x * x + y * y)
					r = node.r + quad.point.r
					if l < r
						l = (l - r) / l * .5
						node.x -= x *= l
