Reputation: 7632
I'm working with D3.js and trying to sort my bars in ascending/descending order when a button is clicked. But I'm having issues having the sortBars function return the correct value from my object.
var sortOrder = false;
var sortBars = function() {
sortOrder = !sortOrder;
svg.selectAll("rect")
.sort(function(a, b) {
if (sortOrder) {
return d3.ascending(a, b);
} else {
return d3.descending(a, b);
}
})
.transition()
.delay(function(d, i) {
return i * 50;
})
.duration(1000)
.attr("x", function(d, i) {
return xScale(i);
});
};
When it returns xScale(i), I know it's not referencing my dataset appropriately. I've tried placing it as i.value (which is what I have it named as in my dataset). I know this isn't correct, but when I change it to that, I at least get the bars to move. How would I access the correct datum?
I've developed a JSFiddle for this. Feel free to play around with it. Currently, the Sort button won't have any effect (as the function is not correctly accessing the data yet).
Upvotes: 1
Views: 213
Reputation: 5834
I think you are pretty close. The xscale should be using i - which here is the position of the datum in the list (not the datum which is in d). However your sort is trying to sort the data objects, not the values. Try this:
.sort(function(a, b) {
if (sortOrder) {
return d3.ascending(a.value, b.value);
} else {
return d3.descending(a.value, b.value);
}
})
I think with two objects it is undefined which one is bigger. And the ascending and descending functions do not take accessors.
Upvotes: 1
Reputation: 8264
Your code was almost good, there are just two details:
The comparator function must return positive, negative or zero. In your code you are comparing data items, not their values:
function sortItems(a, b) {
if (sortOrder) { return a.value - b.value; }
return b.value - a.value;
}
svg.selectAll('rect')
.sort(sortItems)
// update the attributes
The sortBars method wasn't working. I prefer to bind the event using d3:
// Bind the event 'onclick' to the sortBars functions
d3.select('#sort').on('click', sortBars);
I forked your jsFiddle and adapted to make it work: http://jsfiddle.net/pnavarrc/3HL4a/4/
References
Upvotes: 1