(function() { var drag, height, nodes, nodes_data, svg, width, zoom, zoomable_layer; nodes_data = [ { x: 0, y: 0 }, { x: 80, y: 80 }, { x: -80, y: 80 }, { x: -80, y: -80 }, { x: 80, y: -80 } ]; svg = d3.select('svg'); width = svg.node().getBoundingClientRect().width; height = svg.node().getBoundingClientRect().height; svg.attr({ viewBox: "" + (-width / 2) + " " + (-height / 2) + " " + width + " " + height }); zoomable_layer = svg.append('g'); zoom = d3.behavior.zoom().scaleExtent([0.5, 4]).on('zoom', function() { return zoomable_layer.attr({ transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")" }); }); svg.call(zoom); drag = d3.behavior.drag().origin(function(d) { return d; }); drag.on('dragstart', function() { return d3.event.sourceEvent.stopPropagation(); }); drag.on('drag', function(d) { d.x = d3.event.x; d.y = d3.event.y; return d3.select(this).attr({ transform: "translate(" + d.x + "," + d.y + ")" }); }); nodes = zoomable_layer.selectAll('.node').data(nodes_data); nodes.enter().append('circle').call(drag).attr({ "class": 'node', r: 20, fill: 'orange', transform: function(d) { return "translate(" + d.x + "," + d.y + ")"; } }); }).call(this);