Skip to content

Instantly share code, notes, and snippets.

@ZJONSSON
Created October 1, 2011 19:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ZJONSSON/1256534 to your computer and use it in GitHub Desktop.
Save ZJONSSON/1256534 to your computer and use it in GitHub Desktop.
Using data() enter and exit in D3
<!DOCTYPE html>
<html>
<head></head>
<body></body>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript">
// Define the SVG domain in a viewbox to get automatic resize to
// window. This is a good alternative to d3.scale for simple stuff
svg=d3.select("body")
.append("svg:svg")
.attr("height","100%")
.attr("width","100%")
.attr("viewBox","0 0 50 50");
// define an arbitrary initial dataset
dataset=[{id:1,x:10,y:10},
{id:23,x:20,y:20},
{id:44,x:30,y:30},
{id:13,x:40,y:40}];
// This helper function defines the initial shape of any new datapoints
function circle_factory(selection) {
selection.attr("class","series")
.attr("cx",function(d) {return d.x})
.attr("cy",function(d) {return d.y})
.attr("ObjectID",function(d) {return d.id;}) // for easy debugging/monitoring
.attr("r",5)
.style("fill","blue");
}
// enter() passes on all data not reflected already (by key) in the selection
// here all data points are passed on, and we append a circle for each
c=svg.selectAll(".series").data(dataset)
.enter().append("svg:circle").call(circle_factory);
// Subsequently the y value of #44 changes to 10
// notice we only need to supply the y value and the id
c.data([{id:44,y:10}],function(d) {return d.id;})
.transition().delay(500).duration(1000).style("fill","red").style("fill","red")
.attr("cy",function(d) {return d.y;});
// Both x & y of #23 change
c.data( [ {id:23,x:10,y:40} ], function(d) {return d.id;})
.transition().delay(2000).duration(1000).style("fill","yellow")
.style("fill","yellow")
.attr("cy",function(d) {return d.y;})
.attr("cx",function(d) {return d.x;});
// Now remove #13 by supplying just the key
c.data( [ {id:13} ], function(d) {return d.id;})
.attr("opacity",1).transition().delay(3500).duration(1000).attr("opacity",0)
.remove();
// finally we go back to initial data without #23
function get_back() {
dataset = [dataset[0],dataset[2],dataset[3]];
c=c.data(dataset,function(d) {return d.key;});
c.exit().remove(); // remove any existing objects not in the dataset
c.call(circle_factory) // move existing matching object to data specs
c.enter().append("svg:circle").call(circle_factory); // Finally add the non-existing objects
}
setTimeout(get_back,5000) // create any missing circles (from id)
</SCRIPT>
</html>
@enthal
Copy link

enthal commented Mar 28, 2012

Why do you repeat .style("fill","red")

in

.transition().delay(500).duration(1000).style("fill","red").style("fill","red")

?

@ZJONSSON
Copy link
Author

This is a minor slip on my behalf. While it does no damage (i.e. fill is most certainly set to red) , there is no reason why this should be repeated.

@enthal
Copy link

enthal commented Mar 28, 2012

So it's not related to the delay/duration. Thanks. (Same thing with yellow actually.)

Thanks for this nice example!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment