Skip to content

Commit e007f73

Browse files
committed
plotly#189 reworking the order code because it converted numbers to strings (with test cases)
1 parent b98bd65 commit e007f73

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

src/plots/cartesian/ordered_categories.js

+10-6
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,27 @@ var d3 = require('d3');
1414
// flattenUnique :: String -> [[String]] -> Object
1515
function flattenUnique(axisLetter, data) {
1616
var traceLines = data.map(function(d) {return d[axisLetter];});
17-
var categoryMap = {}; // hashmap is O(1);
17+
// Can't use a hashmap, which is O(1), because ES5 maps coerce keys to strings. If it ever becomes a bottleneck,
18+
// code can be separated: a hashmap (JS object) based version if all values encountered are strings; and
19+
// downgrading to this O(log(n)) array on the first encounter of a non-string value.
20+
var categoryArray = [];
1821
var i, j, tracePoints, category;
1922
for(i = 0; i < traceLines.length; i++) {
2023
tracePoints = traceLines[i];
2124
for(j = 0; j < tracePoints.length; j++) {
2225
category = tracePoints[j];
23-
if(!categoryMap[category]) {
24-
categoryMap[category] = true;
26+
if(category === null || category === undefined) continue;
27+
if(categoryArray.indexOf(category) === -1) {
28+
categoryArray.push(category);
2529
}
2630
}
2731
}
28-
return categoryMap;
32+
return categoryArray;
2933
}
3034

3135
// flattenUniqueSort :: String -> Function -> [[String]] -> [String]
3236
function flattenUniqueSort(axisLetter, sortFunction, data) {
33-
return Object.keys(flattenUnique(axisLetter, data)).sort(sortFunction);
37+
return flattenUnique(axisLetter, data).sort(sortFunction);
3438
}
3539

3640

@@ -50,7 +54,7 @@ function flattenUniqueSort(axisLetter, sortFunction, data) {
5054
module.exports = function orderedCategories(axisLetter, categorymode, categorylist, data) {
5155

5256
switch(categorymode) {
53-
case 'array': return Array.isArray(categorylist) ? categorylist : [];
57+
case 'array': return Array.isArray(categorylist) ? categorylist.slice() : [];
5458
case 'category ascending': return flattenUniqueSort(axisLetter, d3.ascending, data);
5559
case 'category descending': return flattenUniqueSort(axisLetter, d3.descending, data);
5660
case 'trace': return [];

test/jasmine/tests/calcdata_test.js

+29
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,20 @@ describe('calculated data and points', function() {
9696
expect(gd.calcdata[0][4]).toEqual(jasmine.objectContaining({x: 1, y: 14}));
9797
});
9898

99+
it('should output categories in ascending domain alphanumerical order even if categories are all numbers', function() {
100+
101+
Plotly.plot(gd, [{x: [3,1,5,2,4], y: [15,11,12,13,14]}], { xaxis: {
102+
type: 'category',
103+
categorymode: 'category ascending'
104+
}});
105+
106+
expect(gd.calcdata[0][0]).toEqual(jasmine.objectContaining({x: 2, y: 15}));
107+
expect(gd.calcdata[0][1]).toEqual(jasmine.objectContaining({x: 0, y: 11}));
108+
expect(gd.calcdata[0][2]).toEqual(jasmine.objectContaining({x: 4, y: 12}));
109+
expect(gd.calcdata[0][3]).toEqual(jasmine.objectContaining({x: 1, y: 13}));
110+
expect(gd.calcdata[0][4]).toEqual(jasmine.objectContaining({x: 3, y: 14}));
111+
});
112+
99113
it('should output categories in categorymode order even if category array is defined', function() {
100114

101115
Plotly.plot(gd, [{x: ['c','a','e','b','d'], y: [15,11,12,13,14]}], { xaxis: {
@@ -189,6 +203,21 @@ describe('calculated data and points', function() {
189203
expect(gd.calcdata[0][4]).toEqual(jasmine.objectContaining({x: 2, y: 14}));
190204
});
191205

206+
it('should output categories in explicitly supplied order even if category values are all numbers', function() {
207+
208+
Plotly.plot(gd, [{x: [3,1,5,2,4], y: [15,11,12,13,14]}], { xaxis: {
209+
type: 'category',
210+
categorymode: 'array',
211+
categorylist: [2,1,4,5,3]
212+
}});
213+
214+
expect(gd.calcdata[0][0]).toEqual(jasmine.objectContaining({x: 4, y: 15}));
215+
expect(gd.calcdata[0][1]).toEqual(jasmine.objectContaining({x: 1, y: 11}));
216+
expect(gd.calcdata[0][2]).toEqual(jasmine.objectContaining({x: 3, y: 12}));
217+
expect(gd.calcdata[0][3]).toEqual(jasmine.objectContaining({x: 0, y: 13}));
218+
expect(gd.calcdata[0][4]).toEqual(jasmine.objectContaining({x: 2, y: 14}));
219+
});
220+
192221
it('should output categories in explicitly supplied order, independent of trace order, pruned', function() {
193222

194223
Plotly.plot(gd, [{x: ['c',undefined,'e','b','d'], y: [15,11,12,null,14]}], { xaxis: {

0 commit comments

Comments
 (0)