Andrew
Andrew

Reputation: 99

d3.js sorting graph by both axes

I'm currently plotting a list of numbers (y-axis) against a list of titles (x-axis). Each number can correspond to multiple websites. Right now I've been using the ascending function provided by d3 to sort them. I've currently got a drop-down menu in which I can pick either number or title and each option individually sorts by the respective choice. However, I was wondering if there was a way so that I could sort alphabetically by title, and then keeping it alphabetical, also sort by number. As of now I can only do one or the other.

Example: My data is stored in a CSV like this:

"id","name"  
1,"youtube"  
1,"google"  
2,"google"  
3,"nike"  
4,"google"  

Then I use

d3.csv("csvTestFile.csv", function (dataset) 

to read in the file and I convert the id number to ints.

To sort I do the following:

data.sort(function(a, b) { return d3.ascending(a.id, b.id)});  

To sort by ID. To sort by name I do this:

data.sort(function(a, b) { return d3.ascending(a.name, b.name)});  

Both of these work properly, however I would like to first sort by ID, then also sort by Name. So the axis would display (starting from the origin) 1, 2, 3, 4 up the y-axis, and google, nike, youtube down the x-axis. Right now if I try to sort it will either be 1, 2, 3, 4 up to the y-axis and youtube, google, nike down the x-axis OR google, youtube, nike down the x-axis with 1, 2, 4, 3 up the y-axis.

What I want is 1, 2, 3, 4 up the y-axis (sorted numerically) and google, nike, youtube down the x-axis (sorted alphabetically) at the same time. Given this is a scatterplot it should be something simply like rearranging the ticks on the axis but I'm not quite sure how to go about doing it.

Upvotes: 0

Views: 2840

Answers (1)

Lars Kotthoff
Lars Kotthoff

Reputation: 109232

The order in which input values are mapped to output values for a categorical scale depends on the order in which they are given to .domain(). All you need to do to achieve what you want is to sort the values accordingly when you create the scale, i.e. something like

var scale = d3.scale.ordinal()
   .domain(data.sort(function(a, b) { return d3.ascending(a.name, b.name); }))
   .range([...]);

Upvotes: 3

Related Questions