Skip to content

Instantly share code, notes, and snippets.

@ngminhtrung
Last active May 9, 2018 08:49
Show Gist options
  • Save ngminhtrung/5276679664ac9e82f1d6e51c68ca0c71 to your computer and use it in GitHub Desktop.
Save ngminhtrung/5276679664ac9e82f1d6e51c68ca0c71 to your computer and use it in GitHub Desktop.
D3 v4 - Enter - Update - Exit

Original block: http://bl.ocks.org/alansmithy/e984477a741bc56db5a5

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