-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Axis category ordering - adds feature #189 #419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
etpinard
merged 9 commits into
plotly:master
from
monfera:189-axis-category-ordering-squashed
Apr 18, 2016
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
94e0133
#189 adding axis attributes to cartesian plots and gl3d plots
monfera e36d163
#189 category ordering - final, bisecting version
monfera df9ee94
#189 categorymode defaults
monfera eb499d4
#189 putting categorymode, categorylist and coercion into use
monfera c7fb84b
#189 jasmine tests
monfera 02ed858
#189 image test mocks and baseline images
monfera 53f12da
#189 PR feedback
monfera 14908d0
#189 Renaming attributes
monfera b21ebb2
#189 Renamings in image plot titles and image test filenames
monfera File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* Copyright 2012-2016, Plotly, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
var layoutAttributes = require('./layout_attributes'); | ||
|
||
module.exports = function handleCategoryOrderDefaults(containerIn, containerOut, coerce) { | ||
|
||
if(containerIn.type !== 'category') return; | ||
|
||
var validCategories = layoutAttributes.categoryorder.values; | ||
|
||
var propercategoryarray = Array.isArray(containerIn.categoryarray) && containerIn.categoryarray.length > 0; | ||
|
||
if(validCategories.indexOf(containerIn.categoryorder) === -1 && propercategoryarray) { | ||
|
||
// when unspecified or invalid, use the default, unless categoryarray implies 'array' | ||
coerce('categoryorder', 'array'); // promote to 'array' | ||
|
||
} else if(containerIn.categoryorder === 'array' && !propercategoryarray) { | ||
|
||
// when mode is 'array' but no list is given, revert to default | ||
|
||
containerIn.categoryorder = 'trace'; // revert to default | ||
coerce('categoryorder'); | ||
|
||
} else { | ||
|
||
// otherwise use the supplied mode, or the default one if unsupplied or invalid | ||
coerce('categoryorder'); | ||
|
||
} | ||
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/** | ||
* Copyright 2012-2016, Plotly, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
|
||
'use strict'; | ||
|
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great comment. Thanks! |
||
|
||
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++) { | ||
|
||
category = tracePoints[j]; | ||
|
||
// skip loop: ignore null and undefined categories | ||
if(category === null || category === undefined) continue; | ||
|
||
insertionIndex = bisector(categoryArray, category); | ||
|
||
// skip loop on already encountered values | ||
if(insertionIndex < categoryArray.length - 1 && categoryArray[insertionIndex] === category) continue; | ||
|
||
// insert value | ||
categoryArray.splice(insertionIndex, 0, category); | ||
} | ||
} | ||
|
||
return categoryArray; | ||
} | ||
|
||
|
||
/** | ||
* This pure function returns the ordered categories for specified axisLetter, categoryorder, categoryarray and data. | ||
* | ||
* If categoryorder is 'array', the result is a fresh copy of categoryarray, or if unspecified, an empty array. | ||
* | ||
* If categoryorder is 'category ascending' or 'category descending', the result is an array of ascending or descending | ||
* order of the unique categories encountered in the data for specified axisLetter. | ||
* | ||
* See cartesian/layout_attributes.js for the definition of categoryorder and categoryarray | ||
* | ||
*/ | ||
|
||
// orderedCategories :: String -> String -> [String] -> [[String]] -> [String] | ||
module.exports = function orderedCategories(axisLetter, categoryorder, categoryarray, data) { | ||
|
||
switch(categoryorder) { | ||
case 'array': return Array.isArray(categoryarray) ? categoryarray.slice() : []; | ||
case 'category ascending': return flattenUniqueSort(axisLetter, d3.ascending, data); | ||
case 'category descending': return flattenUniqueSort(axisLetter, d3.descending, data); | ||
case 'trace': return []; | ||
default: return []; | ||
} | ||
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"data": [{ | ||
"x": ["c","a","e","b","d"], | ||
"y": [15,11,12,13,14]} | ||
], | ||
"layout": { | ||
"xaxis": { | ||
"title": "category ascending", | ||
"type": "category", | ||
"categoryorder": "category ascending", | ||
"categoryarray": ["y","b","x","a","d","z","e","c", "q", "k"] | ||
}} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{ | ||
"data": [ | ||
{ | ||
"x": [ | ||
1, | ||
2, | ||
null, | ||
4, | ||
5 | ||
], | ||
"y": [ | ||
1, | ||
2, | ||
3, | ||
4, | ||
5 | ||
], | ||
"connectgaps": false, | ||
"uid": "8ac13a" | ||
} | ||
], | ||
"layout": { | ||
"title": "categoryarray", | ||
"xaxis": { | ||
"type": "category", | ||
"range": [ | ||
-0.18336673346693386, | ||
3.1833667334669338 | ||
], | ||
"autorange": true, | ||
"categoryorder": "array", | ||
"categoryarray": [2,4,5,1] | ||
}, | ||
"yaxis": { | ||
"type": "linear", | ||
"range": [ | ||
0.7070063694267517, | ||
5.292993630573249 | ||
], | ||
"autorange": true | ||
}, | ||
"height": 450, | ||
"width": 1000, | ||
"autosize": true | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
test/image/mocks/axes_category_categoryarray_truncated_tails.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"data": [{ | ||
"x": ["c","a","e","b","d"], | ||
"y": [15,11,12,13,14]} | ||
], | ||
"layout": { | ||
"title": "categoryarray with truncated tails (y, q, k not plotted)", | ||
"xaxis": { | ||
"type": "category", | ||
"categoryorder": "array", | ||
"categoryarray": ["y","b","x","a","d","z","e","c", "q", "k"] | ||
}} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"data": [ | ||
{ | ||
"x": [ | ||
5, | ||
1, | ||
3, | ||
2, | ||
4 | ||
], | ||
"y": [ | ||
1, | ||
2, | ||
3, | ||
4, | ||
5 | ||
], | ||
"connectgaps": false, | ||
"uid": "8ac13a" | ||
} | ||
], | ||
"layout": { | ||
"title": "category descending", | ||
"xaxis": { | ||
"type": "category", | ||
"categoryorder": "category descending", | ||
"categoryarray": [2,4,5,1] | ||
}, | ||
"yaxis": { | ||
"type": "linear", | ||
"range": [ | ||
0.7070063694267517, | ||
5.292993630573249 | ||
], | ||
"autorange": true | ||
}, | ||
"height": 450, | ||
"width": 1000, | ||
"autosize": true | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"data": [ | ||
{ | ||
"x": [ | ||
5, | ||
null, | ||
3, | ||
2, | ||
4 | ||
], | ||
"y": [ | ||
1, | ||
2, | ||
3, | ||
null, | ||
5 | ||
], | ||
"connectgaps": false, | ||
"uid": "8ac13a" | ||
} | ||
], | ||
"layout": { | ||
"title": "category descending", | ||
"xaxis": { | ||
"type": "category", | ||
"categoryorder": "category descending", | ||
"categoryarray": [2,4,5,1] | ||
}, | ||
"yaxis": { | ||
"type": "linear", | ||
"range": [ | ||
0.7070063694267517, | ||
5.292993630573249 | ||
], | ||
"autorange": true | ||
}, | ||
"height": 450, | ||
"width": 1000, | ||
"autosize": true | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cldougl @chriddyp does ⏫ look ok to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 for me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should include truncated versions of those values as well e.g.
'cat asc'
,'cat des'
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest avoiding muti-word strings. Maybe just
ascending
anddescending
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for me just
ascending
`descendingdoesn't have a clear relation to _alpha_numeric ordering. I definitely understand the aversion to multi-word strings, but I would vote for more description than
ascending\
descending`plus if
'value ascending'
\'value descending'
are going to be implemented eventuallyThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but I gotta say,
catergoryorder
doesn't sound bad at all.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can add them as labels to the axes (currently described as
ticktext
) or use them as data (currently described asx
). Given that theaxis.type
iscategory
, one might think thatcategories
is how you would add data to that axis.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and maybe
categoryarray
instead ofcategorylist
@chriddyp we're already using the value
'array'
fortickmode
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More like: categories are added automatically. Categories have no effect on
ticktext
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great point 👍
That's why I'm thinking that
categoryorder
might be the winner here.