(function() { var height, svg, width, zoom, zoomable_layer; 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() { zoomable_layer.attr({ transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")" }); return zoomable_layer.selectAll('.semantic_zoom').attr({ transform: "scale(" + (1 / zoom.scale()) + ")" }); }); svg.call(zoom); zoomable_layer.append('circle').attr({ r: 60, fill: 'orange' }); zoomable_layer.append('rect').attr({ x: -60, y: -160, width: 120, height: 60, fill: 'orange' }); zoomable_layer.append('rect').attr({ x: -60, y: 100, width: 120, height: 60, fill: 'orange' }); zoomable_layer.append('g').attr({ transform: "translate(" + 120 + "," + 0 + ")" }).append('circle').attr({ "class": 'semantic_zoom', r: 20, fill: 'purple' }); zoomable_layer.append('g').attr({ transform: "translate(" + (-120) + "," + 0 + ")" }).append('rect').attr({ "class": 'semantic_zoom', x: -20, y: -20, width: 40, height: 40, fill: 'purple' }); svg.append('circle').attr({ r: 40, cx: 400, cy: 180, fill: 'teal' }); svg.append('rect').attr({ x: -444, y: -220, width: 80, height: 80, fill: 'teal' }); }).call(this);