We want to make it possible to click on a section of the pie to remove it. First, let's add IDs to our data, to make the removal easier. Adjust the var dataset code at the top of app.js:
var dataset = [
{ id: 1, label: 'Bob', count: 10 }, //add id property
{ id: 2, label: 'Sally', count: 20 }, //add id property
{ id: 3, label: 'Matt', count: 30 }, //add id property
{ id: 4, label: 'Jane', count: 40 } //add id property
];
Now, let's use those IDs when we map data to paths. Adjust the .data() portion of our var path =d3.select('g').selectAll('path')code at the bottom of app.js, as follows:
var path = d3.select('g').selectAll('path')
.data(pie(dataset), function(datum){ //attach datum.data.id to each element
return datum.data.id
})
Let's save a record of the current data for each element by adding a _current property to each element (we'll use this later). Add .each(function(d) { this._current = d; });to the end of our var path =d3.select('g') code, at the bottom of app.js:
var path = d3.select('g').selectAll('path')
.data(pie(dataset), function(datum){
return datum.data.id
})
.enter()
.append('path')
.attr('d', arc)
.attr('fill', function(d) {
return colorScale(d.data.label);
})//watch out! remove the semicolon here
.each(function(d) { this._current = d; }); //add this
Create the click handler by adding the following code to the bottom of app.js:
path.on('click', function(clickedDatum, clickedIndex){
});
Remove the selected data from the dataset array, using JavaScript's native filter function. Adjust the code that we just added, as follows:
path.on('click', function(clickedDatum, clickedIndex){
dataset = dataset.filter(function(currentDatum, currentIndex){ //new
return clickedDatum.data.id !== currentDatum.id //new
}); //new
});
Remove the path elements from the SVG by adding the following to our click handler function:
path.on('click', function(clickedDatum, clickedIndex){
dataset = dataset.filter(function(currentDatum, currentIndex){
return clickedDatum.data.id !== currentDatum.id
});
path //new
.data(pie(dataset), function(datum){ //new
return datum.data.id //new
}) //new
.exit().remove(); //new
});
Now, if we click on the orange segment, we should get the following result:
Let's close the donut and add a transition. Add the following to the bottom of our click handler. Check out the comments in the following code to see what each line does:
path.on('click', function(clickedDatum, clickedIndex){
dataset = dataset.filter(function(currentDatum, currentIndex){
return clickedDatum.data.id !== currentDatum.id
});
path
.data(pie(dataset), function(datum){
return datum.data.id
})
.exit().remove();
path.transition() //create the transition
.duration(750) //add how long the transition takes
.attrTween('d', function(d) { //tween the d attribute
var interpolate = d3.interpolate(this._current, d);
//interpolate
from what the d attribute was and what it is now
this._current = interpolate(0); //save new value of data
return function(t) { //re-run the arc function:
return arc(interpolate(t));
};
});
});
Now, when we click on the orange segment, the donut closes smoothly, as follows: