Reputation: 99
I have a rowchart that currently looks like this:
deltaChart
.width(300)
.height(250)
.dimension(deltaDim)
.group(pointsByDelta)
.xAxis().ticks(4);
In which the deltaDim
dimension is comprised of 11 or so unique string values, pointsByDelta
represents related counts, and deltaChart
is of type rowChart.
Since the deltaDim
values are string and not numeric, the sorting is out of order. I've tried applying what I've found in the wiki as well as on other's posts here to manually reorder, with no luck at all. Regardless of the format I receive a console error: .ordering is not a function()
I've tried just simple ordering like this:
.ordering(function(d){return -d.value})
That results in error. Ideally I'd like to be able to do something like:
.ordering(function(d) {
if(d.value == "5 ft") return 0;
else if(d.value == "4 ft") return 1;
else if(d.value == "3 ft") return 2;
else if(d.value == "2 ft") return 3;
else if(d.value == "1 ft") return 4;
else if(d.value == "0 ft") return 5;
else if(d.value == "-1 ft") return 6;
else if(d.value == "-2 ft") return 7;
else if(d.value == "-3 ft") return 8;
else if(d.value == "-4 ft") return 9;
else if(d.value == "-5 ft") return 10;
else return 11;
})
It looks like most of the posts on this topic are responded to with a way to sort in ascending or descending order. I've not even been able to get that to behave, and in my case, I need to be able to dictate the order if possible.
Any help appreciated. Thank you!
Upvotes: 1
Views: 814
Reputation: 3205
Better to avoid the lengthy if else condition. This can be easily handled through d3 scales
Range can be done with the index by sorting order
var scale = d3.scale.ordinal()
.domain(['C','B','A'])
.range([0,1,2]);
In ordering function
chart.ordering(function(k){
return scale(k.key);
})
Upvotes: 1
Reputation: 99
Combined with Gordon's input from above regarding .xAxis(), the solution that works is as follows.
deltaChart
.width(300)
.height(250)
.dimension(bfeDeltaDim)
.group(pointsByBFEDelta)
.ordering(function(d) {
if(d.key == "5 ft") return 0;
else if(d.key == "4 ft") return 1;
else if(d.key == "3 ft") return 2;
else if(d.key == "2 ft") return 3;
else if(d.key == "1 ft") return 4;
else if(d.key == "0 ft") return 5;
else if(d.key == "-1 ft") return 6;
else if(d.key == "-2 ft") return 7;
else if(d.key == "-3 ft") return 8;
else if(d.key == "-4 ft") return 9;
else if(d.key == "-5 ft") return 10;
else return 11;
})
.xAxis().ticks(4);
Upvotes: 1
Reputation: 6332
If the strings are like they are above you could work with them in the function.
Split:
The split() method splits a String object into an array of strings by separating the string into substrings.
split the string by the space in the string and then return the first item in the array
Then parse this item, which will be 5 to -5 into an int
.ordering(function(d){
return parseInt(d.split(" ")[0]);
})
.ordering()
is available with dc.js - but only on
the dc object
https://github.com/dc-js/dc.js/blob/master/web/docs/api-latest.md#orderingorderfunctionsort()
-
https://github.com/d3/d3-3.x-api-reference/blob/master/Selections.md#sortUpvotes: 1
Reputation: 66228
Are you sure d3.js has an .ordering()
method? Perhaps you are looking for the good old .sort()
. The issue is that you have to replace the unit "ft" when iterating through the array, and we can use the regex pattern \s+ft$
to remove that. The pattern matches the term <any_amount_of_space>ft
at the end of the string. After replacement, simply convert it to a float. I avoid using parseInt()
because you might have non-integer values.
var arr = ["5 ft", "4 ft", "3 ft", "2 ft", "1 ft", "0 ft", "-1 ft", "-2 ft", "-3 ft", "-4 ft", "-5 ft"];
var arr_sorted = arr.sort(function(a, b) {
// Convert to float
var x = parseFloat(a.replace(/\s+ft$/, "")),
y = parseFloat(b.replace(/\s+ft$/, ""));
// Return, sort by descending order
return ((x < y) ? 1 : ((x > y) ? -1 : 0));
// If ascending order is needed, use:
// return ((x > y) ? 1 : ((x < y) ? -1 : 0));
});
console.log(arr_sorted);
Upvotes: 1