<!DOCTYPE html>
<html>
<head>
    <script src="http://d3js.org/d3.v3.min.js"></script>
  </head>
  <body>
    <script src="https://intervis-projects.ccs.neu.edu/ssvg/ssvg-auto.js"></script>
  </body>
</html>
html, body {
            width: 100%;
            height: 100%;
            overflow: hidden;
            margin: 0;
            padding: 0;
        }
        circle {
            fill: black;
            stroke: none;
        }
        circle.saved {
            fill: green;
        }
var w = 900,
    h = 500,
    svg = d3.select('body').append('svg')
      .attr('width',w)
      .attr('height',h);

  var data = [],
    removed = [];

  function render() {

    var circles = svg.selectAll('circle')
      .data(data, function(d){
        return d.id;
      });

    // the enter() selection needs representation:
    circles.enter().append('circle')
      .classed('entering',true)
      .attr('cx',function(d){ return d.center.x; })
      .attr('cy',function(d){ return d.center.y; })
      .attr('r',100)
      .style('opacity',1e-6);

    // the exit() selection needs removing
    circles.exit().filter(':not(.exiting)') // but only if we didn't already
      .classed('exiting',true)
      .transition().duration(1000)
      .attr('r',100)
      .style('opacity',1e-6)
      .remove();

    // just for debugging this demo, show which things were saved
    // circles.classed('saved',function(d){ return d.saved; });

    // two things here:
    //  - if something is currently exiting (but in this selection),
    //    we should cancel its exiting transition and restore it
    //  - if something is currently entering (it was *just* added),
    //    we need to trigger a brand new transition
    circles.filter('.exiting, .entering')
      .classed('exiting',false)
      .classed('entering',false)
      .transition().duration(1000)
      .attr('r',function(d){ return d.radius; })
      .style('opacity',1.0);

  }

  setInterval(function(){
    // remove a random element ever other tick (or so)
    if (data.length > 20 && Math.random() > 0.5) {
      var index = Math.floor(Math.random() * data.length);
      var item = data[index];
      data.splice(index,1);
      // save 1 in 4 removed thing for later restoration
      if (Math.random() < 0.25) {
        item.saved = true;
        removed.push(item);
      }
    } else {
      // if we have something to save, save it:
      if (removed.length) {
        data.push(removed.pop());
      } else {
        // otherwise create a new one
        data.push({
          id: new Date().getTime(),
          center: {
            x: Math.random() * w,
            y: Math.random() * h
          },
          radius: 2 + Math.random() * 10
        });
      }
    }
    render();
  }, 30);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.