Ashitaka
Ashitaka

Reputation: 19203

How can I fix this bar chart sorting?

Here is a JSFiddle of the issue I'm currently facing.

Basically, I have an array of objects that I use to draw some bars. After sorting the array, I try to update the bars' y positions accordingly but that does not work.

So, this is the scale I use to draw the bars:

var yScale = d3.scale.ordinal()
    .domain(d3.range(0, numberOfBars))
    .rangeBands([0, numberOfBars * barHeight]);

So if I have 3 bars and a bar is 40px high, then I'm mapping 0-3 => 0-120px.

Next, I have a function that uses this scale to return the right y position:

var y = function(d, i) {
    return yScale(i);
};

After drawing the bars using this y function, I then sort the data array and try to redraw the bars:

barsContainer.selectAll('.bar')
    .data(chartData.users)
    .transition()
      .duration(750)
      .delay(delay)
      .attr('y', y); // Not working. I thought this would order the bars.
      //.attr('y', 120); // This works though. It moves all the bars to this y.

This is where I'm stumped. Since I reordered the array (chartData.users), and since the bars are "joined" with the data, shouldn't the bars change their y according to the data's new position in the array?

Upvotes: 1

Views: 102

Answers (2)

Ashitaka
Ashitaka

Reputation: 19203

So I figured out what the problem was. Since I was sorting an array of objects, D3.js couldn't figure out by itself which array objects matched which DOM objects. So I had to create a key function to identify the objects:

var key = function(d) { return d.id }

Then, all I had to do was call data() using this key function and then order(), so the DOM order matches the array order:

barsContainer.selectAll('.bar')
  .data(chartData.users, key)
  .order()
  .transition()
    .delay(delay)
    .duration(750)
    .attr('y', y);

Here's the working JSFiddle.

Upvotes: 1

angus l
angus l

Reputation: 1587

Your Fiddle is very long. I'd recommend paring it back to the bare minimum and seeking help with that specific point.

For example, try testing

console.log(chartData.users)

immediately after you've declared chartData. It appears to be identical to the sorted one, so it might not be the sorting that's at fault. If you do some more work yourself and then ask a more specific, concise question, you'll probably get more answers.

Good luck with D3!

Upvotes: 0

Related Questions