diff --git a/src/plots/cartesian/ordered_categories.js b/src/plots/cartesian/ordered_categories.js index 49eb6a3dbb0..d50c6b195ce 100644 --- a/src/plots/cartesian/ordered_categories.js +++ b/src/plots/cartesian/ordered_categories.js @@ -13,32 +13,25 @@ var d3 = require('d3'); // flattenUniqueSort :: String -> Function -> [[String]] -> [String] function flattenUniqueSort(axisLetter, sortFunction, data) { - // Bisection based insertion sort of distinct values for logarithmic time complexity. // Can't use a hashmap, which is O(1), because ES5 maps coerce keys to strings. If it ever becomes a bottleneck, // code can be separated: a hashmap (JS object) based version if all values encountered are strings; and // downgrading to this O(log(n)) array on the first encounter of a non-string value. var categoryArray = []; - var traceLines = data.map(function(d) {return d[axisLetter];}); - - var i, j, tracePoints, category, insertionIndex; - var bisector = d3.bisector(sortFunction).left; - for(i = 0; i < traceLines.length; i++) { - - tracePoints = traceLines[i]; - - for(j = 0; j < tracePoints.length; j++) { + for(var i = 0; i < traceLines.length; i++) { + var tracePoints = traceLines[i] || []; - category = tracePoints[j]; + for(var j = 0; j < tracePoints.length; j++) { + var category = tracePoints[j]; // skip loop: ignore null and undefined categories if(category === null || category === undefined) continue; - insertionIndex = bisector(categoryArray, category); + var insertionIndex = bisector(categoryArray, category); // skip loop on already encountered values if(insertionIndex < categoryArray.length && categoryArray[insertionIndex] === category) continue; diff --git a/test/jasmine/tests/calcdata_test.js b/test/jasmine/tests/calcdata_test.js index 2f1ef1f2f59..a7c7b103b46 100644 --- a/test/jasmine/tests/calcdata_test.js +++ b/test/jasmine/tests/calcdata_test.js @@ -150,6 +150,27 @@ describe('calculated data and points', function() { expect(gd._fullLayout.xaxis._categories).toEqual(['1']); }); + + it('should skip over visible-false traces', function() { + Plotly.plot(gd, [{ + x: [1, 2, 3], + y: [7, 6, 5], + visible: false + }, { + x: [10, 9, 8], + y: ['A', 'B', 'C'], + yaxis: 'y2' + }], { + yaxis2: { + categoryorder: 'category descending' + } + }); + + expect(gd.calcdata[1][0]).toEqual(jasmine.objectContaining({x: 10, y: 2})); + expect(gd.calcdata[1][1]).toEqual(jasmine.objectContaining({x: 9, y: 1})); + expect(gd.calcdata[1][2]).toEqual(jasmine.objectContaining({x: 8, y: 0})); + expect(gd._fullLayout.yaxis2._categories).toEqual(['C', 'B', 'A']); + }); }); describe('explicit category ordering', function() {