Skip to content

Instantly share code, notes, and snippets.

@alansmithy
Last active June 21, 2019 19:39
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save alansmithy/e984477a741bc56db5a5 to your computer and use it in GitHub Desktop.
d3js - enter(), update() and exit()

This is a simple example of enter/update/exit in d3js.

2 arrays - of differing length - are used to generate alternating sequences of bubbles.

.enter() creates the initial join of data to elements, creating one circle element for every data element in the array.

After the button is clicked, the alternative array is rejoined to the graphical elements.

Because each array is of a different length, this means we must use .exit() to remove any circle elements no longer needed and create any new circle elements by using .enter().

Once all circle elements are properly defined, we can then update the radius of each circle, new and old, according to its value in the new array.

For more details on enter/update/exit, see this useful article by Mike Bostock, creator of d3js.

<!doctype html>
<html>
<head>
<style>
svg {width:500px; height:500px}
button {float:left}
line {stroke:#ddd;shape-rendering: crispEdges;}
text {text-anchor:middle;}
circle {fill:orange;stroke:orange;fill-opacity:0.5;}
.axis line {fill:none;stroke:#ddd;shape-rendering: crispEdges;}
.axis path {fill:none;}
.axis text {font-size:0.7em;fill:#555;font-family:sans-serif}
</style>
<script src="http://d3js.org/d3.v3.js"></script>
</head>
<body>
<script>
//2 different data arrays
var dataArray1 = [30,35,45,55,70];
var dataArray2 = [50,55,45,35,20,25,25,40];
//globals
var dataIndex=1;
var xBuffer=50;
var yBuffer=150;
var lineLength=400;
//create main svg element
var svgDoc = d3.select("body").append("svg")
svgDoc.append("text")
.attr("x",xBuffer+(lineLength/2))
.attr("y",50)
.text("dataset"+dataIndex);
//create axis line
svgDoc.append("line")
.attr("x1",xBuffer)
.attr("y1",yBuffer)
.attr("x1",xBuffer+lineLength)
.attr("y2",yBuffer)
//create basic circles
svgDoc.append("g").selectAll("circle")
.data(eval("dataArray"+dataIndex))
.enter()
.append("circle")
.attr("cx",function(d,i){
var spacing = lineLength/(eval("dataArray"+dataIndex).length);
return xBuffer+(i*spacing)
})
.attr("cy",yBuffer)
.attr("r",function(d,i){return d});
//button to swap over datasets
d3.select("body").append("button")
.text("change data")
.on("click",function(){
//select new data
if (dataIndex==1) {
dataIndex=2;
} else {
dataIndex=1;
}
//rejoin data
var circle = svgDoc.select("g").selectAll("circle")
.data(eval("dataArray"+dataIndex));
circle.exit().remove();//remove unneeded circles
circle.enter().append("circle")
.attr("r",0);//create any new circles needed
//update all circles to new positions
circle.transition()
.duration(500)
.attr("cx",function(d,i){
var spacing = lineLength/(eval("dataArray"+dataIndex).length);
return xBuffer+(i*spacing)
})
.attr("cy",yBuffer)
.attr("r",function(d,i){return d});
d3.select("text").text("dataset"+dataIndex);
});//end click function
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment