title: d3: Elements move when scale() transform is applied
body: <p>I want SVG elements to appear larger on mouseover. Applying a CSS transform seems to be a convenient way to do this, however it also translates the objects. How do I make the circles in the below example keep their original center point? I've tried applying <code>position: absolute;</code> to no avail.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var dataset = [0, 2345786000, 10000000000];
  
  var svg = d3.select("body").append("svg");
  var w = 500, h = 200;
  var padding = 50;
  svg.attr("width", w)
     .attr("height", h);
  
  // Background pattern 
  var patternSize = 5;
  svg.append("defs")
              .append("pattern")
              .attr("id", "dotPattern")
              .attr("patternUnits", "userSpaceOnUse")
              .attr("width", patternSize)
              .attr("height", patternSize)
              .append("circle")
              .attr("cx", patternSize / 2)
              .attr("cy", patternSize / 2)
              .attr("r", 2)
              .style("stroke", "none")
              .style("fill", "lightgrey")
              .style("opacity", 0.5);
     
  var xScale = d3.time.scale()
      .domain([0, 10000000000])
      .range([padding, w-padding]);
  var xAxis = d3.svg.axis()
      .scale(xScale)
      .ticks(5);
  svg.append("g")
    .attr("class","axis")
      .attr("transform", "translate(0," + (h-padding) + ")")
      .call(xAxis);
      
  var zoom = d3.behavior.zoom()
              .on("zoom", build)
              .scaleExtent([1, 20]);           
  zoom.x(xScale);
  
  var clipPath = svg.append("clipPath")
          .attr("id", "clip")
          .append("rect")
          .attr("x", padding)
          .attr("y", 0)
          .attr("width",w-2*padding)
          .attr("height", h-padding);
  var zoomArea = svg.append("g")
           .attr("class", "zoomArea")
           .style("cursor","move")
           .attr("clip-path", "url(#clip)");
  var zoomRect = zoomArea.append("rect")
       .attr("x", padding)
       .attr("y", 0)
       .attr("width", w-2*padding)
       .attr("height", h-padding)
       .style("fill", "url(#dotPattern)")
       .style("pointer-events", "all")
       .style("cursor","move")
       .call(zoom);
  
  zoomArea.selectAll("circles")          
   .data(dataset)
    .enter()
    .append("circle")
    .attr("cx", function(d){
     return xScale(d);
    })
    .attr("cy", h/2)
    .attr("r",10)
    .attr("fill","grey")
    .on("mouseover", function(){
     d3.select(this)
       .attr("transform", "scale(1.4)")
    })
    .on("mouseout", function(){
     d3.select(this)
       .attr("transform", "scale(1)")
    });
  
  function build(){
       svg.select("g.axis").call(xAxis);
            d3.selectAll("circle")
               .attr("cx", function(d){
           return xScale(d);
          });
  };    </code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"&gt;&lt;/script&gt;</code></pre>
  </div>
  </div>
  </p>