Reputation: 2931
This demo (not my code) compares two different categories of items to each other, so -- unlike a chord diagram where any item can be connected to any other item -- coffee shops can't be connected to coffee shops and states can't be connected to states.
Some wedges look like this, if Dunkin' Donuts come first:
But other wedges look like this, if Starbucks has a higher value in the state:
Unnecessary overlap, in my opinion. The order of the elements shouldn't be determined by their value, but instead by the order of the elements on the left side -- that is, always Dunkin' first.
I see a sort happening in
var chord = d3.layout.chord()
.padding(.02)
.sortSubgroups(d3.descending)
but I'm not sure how I can specify a custom sort for the state elements. It makes sense to have the coffee shop subgroups sorted desc (or asc) but the states shouldn't get the same treatment.
How do we know if a chord is a state or not? It seems that information can be pulled by passing a chord to the rdr
instance of the chordRdr
function, which ties the matrix
, which is what's being sorted, to meta-information from the mmap
object.
How can I create a conditional subgroup sort?
Upvotes: 3
Views: 757
Reputation: 9293
I would not recommend actually using this solution:
//all the values in matrix are integers
//we can track the numbers that are starbucks stores
//by adding a small decimal to them
matrix = matrix.map(function(row){
return row.map(function(d, i){
return d + (i == row.length - 1 ? 1e-7 : 0) })
})
//now we can do a lexicographic sort
//first checking for the presence of a decimal and then size
var chord = d3.layout.chord()
.sortSubgroups(function(a, b){
if (a != Math.round(a)) return false
if (b != Math.round(b)) return true
return b < a ? -1 : b > a ? 1 : 0;
})
Modifying d3.layout.chord
or starting fresh with something simpler that doesn't require a redundant matrix of values would probably work better in most situations.
Upvotes: 1
Reputation: 4218
Short answer: you can't do it in d3.
This is how d3 performs the sort:
// Sort subgroups…
if (sortSubgroups) {
subgroupIndex.forEach(function(d, i) {
d.sort(function(a, b) {
return sortSubgroups(matrix[i][a], matrix[i][b]);
});
});
}
It will perform the sort for every subgroup.
The only way I can think of to make this work legitimately would be to have a custom copy of d3.chord.layout()
, which can be found at the above link, if you want to toy with it.
Upvotes: 2