diff --git a/client/src/components/categorical/category.js b/client/src/components/categorical/category.js index 2e103b43..24395911 100644 --- a/client/src/components/categorical/category.js +++ b/client/src/components/categorical/category.js @@ -208,7 +208,9 @@ class Category extends React.Component { const { isTruncated } = categoricalSelection[metadataField]; const cat = categoricalSelection[metadataField]; - const optTuples = sortedCategoryValues([...cat.categoryValueIndices]); + const optTuples = sortedCategoryValues(isUserAnno, [ + ...cat.categoryValueIndices + ]); const optTuplesAsKey = _.map(optTuples, t => t[0]).join(""); // animation return ( diff --git a/client/src/components/categorical/util.js b/client/src/components/categorical/util.js index 086f2f65..b05dfdf6 100644 --- a/client/src/components/categorical/util.js +++ b/client/src/components/categorical/util.js @@ -4,16 +4,29 @@ // index is range array // return sorted index -import isNumber from "is-number"; +/* +Sort category values (labels) in the order we want for presentation. -const sortedCategoryValues = values => { +TL;DR: numeric sort for number-like strings, then strings in case-ignoring alpha +order. Except, when isUserAnno is true, pin globals.unassignedCategoryLabel +to the end. + +*/ + +import isNumber from "is-number"; +import * as globals from "../../globals"; + +const sortedCategoryValues = (isUserAnno, values) => { /* this sort could be memoized for perf */ const strings = []; const ints = []; + const unassigned = []; values.forEach(v => { - if (isNumber(v[0])) { + if (isUserAnno && v[0] === globals.unassignedCategoryLabel) { + unassigned.push(v); + } else if (isNumber(v[0])) { ints.push(v); } else { strings.push(v); @@ -28,7 +41,7 @@ const sortedCategoryValues = values => { ints.sort((a, b) => +a[0] - +b[0]); - return ints.concat(strings); + return ints.concat(strings, unassigned); }; export default sortedCategoryValues;