I have a d3 map with a number of circles and squares appended. The shapes represent data from different years, and I have a selector to allow users to choose the year, which makes that year's shapes more prominent via a function that (among other things) gives them the class '.currentYear'. There's a live version here.
I need to re-append the circles and rects with class '.currentYear' after the others so that they appear on top. My (rather verbose) function for updating when the selector changes is:
d3.select("#yearSelector").on('change', yearTrans);
function yearTrans() {
selected = this.value;
rec.selectAll('.grant')
.filter('.currentYear')
.classed('currentYear', false)
.on('mouseover', tip.hide)
.transition().duration(1000)
.attr("r", rad/2)
.style("opacity", 0.8);
rec.selectAll('.grant')
.filter('.' + selected)
.classed('currentYear', true)
.transition().duration(1000)
.attr("r", rad)
.style("opacity", 1);
rec.selectAll('.award')
.filter('.currentYear')
.classed('currentYear', false)
.on('mouseover', tip.hide)
.transition().duration(1000)
.attr("x", function(d) { return proj([d.custom_fields.longitude - 40, d.custom_fields.latitude])[0] - (rad/2); })
.attr("y", function(d) { return proj([d.custom_fields.longitude, d.custom_fields.latitude])[1] - (rad/2); })
.attr("width", rad)
.attr("height", rad)
.style("opacity", 0.8);
rec.selectAll('.award')
.filter('.' + selected)
.classed('currentYear', true)
.transition().duration(1000)
.attr("x", function(d) { return proj([d.custom_fields.longitude - 40, d.custom_fields.latitude])[0] - (rad); })
.attr("y", function(d) { return proj([d.custom_fields.longitude, d.custom_fields.latitude])[1] - (rad); })
.attr("width", rad * 2)
.attr("height", rad * 2)
.style("opacity", 1);
rec.selectAll(".grant, .award")
.sort(function(a, b) {
if(a.memberOfClass(".currentYear") && !b.memberOfClass(".currentYear")) {
return -1;
} else if(b.memberOfClass(".currentYear")) {
return 1;
} else {
return 0;
}
});
rec.selectAll(".currentYear")
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
};
One way is to select their parentNode and re-append them. I've come across a number of solutions with this approach such as this one, but they are always on mouseover and I can't seem to make it work in the function.
Another approach is to sort them. I've come across what seems to be the solution here, but I don't understand where to include my class in the sort – I've tried every combination I can think of. The relevant code for the sort is
rec.selectAll(".grant, .award")
.sort(function(a, b) {
if(a.memberOfClass() && !b.memberOfClass()) {
return -1;
} else if(b.memberOfClass()) {
return 1;
} else {
return 0;
}
});
How do I apply my class of .currentYear to have it sort correctly?
I feel like I should be able to figure it out from what I've found, but I obviously lack the knowledge right now. Thanks in advance for any help.