Emile
Emile

Reputation: 197

D3 bar chart sorting not working

I created a bar chart with a simple .csv data. The first column is "Team", which contains team names as text; The second column is "Goals", which contains number of goals scored.
But then I want to sort the bars so that Teams with more goals comes first. I tried everything I can find on the web but none of them works in my case. I was very confused...


The code:

var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom;

var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
    y = d3.scaleLinear().rangeRound([height, 0]);

svg = svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.csv("StatsByClub1.csv", function(d) {
  d.Goals = +d.Goals;
  return d;
}, function(error, data) {
  if (error) throw error;

  x.domain(data.map(function(d) { return d.Team; }));
  y.domain([0, d3.max(data, function(d) { return d.Goals; })]);

  svg.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x));

  svg.append("g")
      .attr("class", "axis axis--y")
      .call(d3.axisLeft(y))
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", "0.71em")
      .attr("text-anchor", "end")
      .text("Goals");

  svg.selectAll(".bar")
      .data(data)
      .enter().append("rect")
  // sorting does not work!
      .sort(function(a, b) {d3.descending(a.Goals, b.Goals)})
        .attr("class", "bar")
        .attr("x", function(d) { return x(d.Team); })
        .attr("y", function(d) { return y(d.Goals); })
        .attr("width", x.bandwidth())
        .attr("height", function(d) { return height - y(d.Goals); });

The data looks like:

Team    Goals
Man. United 49
Man. City   71
Arsenal 65
Hotspur 69
Liverpool   63
Chelsea 59
Everton 59
Swansea 48
Stoke City  41
Sunderland  42

Upvotes: 0

Views: 1469

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102174

Sort the data array using d3.descending, which:

Returns -1 if a is greater than b, or 1 if a is less than b, or 0. This is the comparator function for reverse natural order, and can be used in conjunction with the built-in array sort method to arrange elements in descending order.

So, put this right after you load the data, before setting the domains:

data.sort((a, b) => d3.descending(a.Goals, b.Goals));

Upvotes: 4

Related Questions