title: Appending elements to d3 selection
body: <p>In a d3 program, I have a many <code>circle</code> elements with data bound to them. In a callback to an event, I want to filter out most of them and place a larger red circle on top of those that are left. It looks something like this:</p>
  
  <pre><code>svg.selectAll("circle")
    .filter(/* filter function not important */)
    .append("circle")
    .attr("class", "extra")
    .attr("cx", function(){return d3.select(this).attr("cx")})
    .attr("cy", function(){return d3.select(this).attr("cy")})
    .attr("r", 5);
  </code></pre>
  
  <p>And the result is this (the first line is the original circle):</p>
  
  <pre><code>&lt;circle cx="55.41208075590415" cy="279.3650793650794" r="1"&gt;
    &lt;circle class="extra" r="5"&gt;&lt;/circle&gt;
  &lt;/circle&gt;
  </code></pre>
  
  <p>So I have two problems. One, it's inserting as a child of the old element, rather than a sibling. Ideally it would be inserted as the last child of <code>svg</code>. Second, <code>cx</code> and <code>cy</code> aren't getting copied over. What magic do I have to utter to make this work?</p>
  
  <hr>
  
  <p>If you are okay overwriting existing elements, see the answer below. To create new ones, here's how.</p>
  
  <pre><code>svg.selectAll("circle")
    .filter(/* filter function not important */)
    .each(function(d){
        svg.append("circle")
           .attr("class", "extra")
           .attr("cx", function() { return x(d.fop) })
           .attr("cy", function() { return y(d.bar) })
           .attr("r", 5);
     })
  </code></pre>
  
  <p>Notice two things. One, the inner functions do not take parameters, because there is no data bound to the extra circle. Use the <code>d</code> from the existing circle instead. Two, I couldn't figure out how to access the <code>cx</code> and <code>cy</code> of the existing circle, so I had to recompute them instead, which means the scales <code>x</code> and <code>y</code> must remain unchanged. I'll change the accepted answer if anyone can improve on this.</p>