-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Box points hover & select #2094
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
Changes from 1 commit
cfc8725
53c446b
581f3fa
e59f283
5c58049
aef61ae
d352fa5
6a878b0
0027b84
a1ea1e8
6bfcbe0
9ca410a
7e44c9c
f228a5e
b4d8044
9e69900
8901528
b66628e
a3ec75a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/** | ||
* Copyright 2012-2017, 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 DESELECTDIM = require('../../constants/interactions').DESELECTDIM; | ||
|
||
module.exports = function selectPoints(searchInfo, polygon) { | ||
var cd = searchInfo.cd; | ||
var xa = searchInfo.xaxis; | ||
var ya = searchInfo.yaxis; | ||
var trace = cd[0].trace; | ||
var node3 = cd[0].node3; | ||
var selection = []; | ||
var i, j; | ||
|
||
if(trace.visible !== true) return []; | ||
|
||
if(polygon === false) { | ||
for(i = 0; i < cd.length; i++) { | ||
for(j = 0; j < (cd[i].pts || []).length; j++) { | ||
// clear selection | ||
cd[i].pts[j].dim = 0; | ||
} | ||
} | ||
} else { | ||
for(i = 0; i < cd.length; i++) { | ||
for(j = 0; j < (cd[i].pts || []).length; j++) { | ||
var pt = cd[i].pts[j]; | ||
var x = xa.c2p(pt.x); | ||
var y = ya.c2p(pt.y); | ||
|
||
if(polygon.contains([x, y])) { | ||
selection.push({ | ||
pointNumber: pt.i, | ||
x: pt.x, | ||
y: pt.y | ||
}); | ||
pt.dim = 0; | ||
} else { | ||
pt.dim = 1; | ||
} | ||
} | ||
} | ||
} | ||
|
||
node3.selectAll('.point').style('opacity', function(d) { | ||
return d.dim ? DESELECTDIM : 1; | ||
}); | ||
|
||
return selection; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -848,7 +848,60 @@ describe('Test select box and lasso per trace:', function() { | |
]); | ||
assertRanges([[1.66, 3.59], [0.69, 2.17]]); | ||
}, | ||
null, BOXEVENTS, 'bar select' | ||
null, BOXEVENTS, 'histogram select' | ||
); | ||
}) | ||
.catch(fail) | ||
.then(done); | ||
}); | ||
|
||
it('should work for box traces', function(done) { | ||
var assertPoints = makeAssertPoints(['curveNumber', 'y']); | ||
var assertRanges = makeAssertRanges(); | ||
var assertLassoPoints = makeAssertLassoPoints(); | ||
|
||
var fig = Lib.extendDeep({}, require('@mocks/box_grouped')); | ||
fig.data.forEach(function(trace) { | ||
trace.boxpoints = 'all'; | ||
}); | ||
fig.layout.dragmode = 'lasso'; | ||
fig.layout.width = 600; | ||
fig.layout.height = 500; | ||
addInvisible(fig); | ||
|
||
Plotly.plot(gd, fig) | ||
.then(function() { | ||
return _run( | ||
[[200, 200], [400, 200], [400, 350], [200, 350], [200, 200]], | ||
function() { | ||
assertPoints([ | ||
[0, 0.2], [0, 0.3], [0, 0.5], [0, 0.7], | ||
[1, 0.2], [1, 0.5], [1, 0.7], [1, 0.7], | ||
[2, 0.3], [2, 0.6], [2, 0.6] | ||
]); | ||
assertLassoPoints([ | ||
['day 1', 'day 2', 'day 2', 'day 1', 'day 1'], | ||
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. @alexcjohnson Is this the desired behavior, or did an extra 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. ... we might have to wait for v2 though. 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. I guess 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. My argument for
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. So do you think the 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.
These values had really better correspond to the actual data, not offset or jittered values... It's not important for category axes, but for non-lossy axes it is, otherwise you'll be pointed to the wrong data value! So in the end I don't think that this conversion is lossy, even though in general you're right.
How do you convert
Good catch - yeah, I guess so. Everything we report back out with events should be 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.
Yeah, I guess that's kinda hard to in general. Put that in the 9am brain-cramp bin.
I think so too. We should at the very least report everything in the same coordinate space. Right now, lasso coords are in 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.
🐞 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. done in 8901528 |
||
[0.71, 0.71, 0.1875, 0.1875, 0.71] | ||
]); | ||
}, | ||
null, LASSOEVENTS, 'box lasso' | ||
); | ||
}) | ||
.then(function() { | ||
return Plotly.relayout(gd, 'dragmode', 'select'); | ||
}) | ||
.then(function() { | ||
return _run( | ||
[[200, 200], [400, 350]], | ||
function() { | ||
assertPoints([ | ||
[0, 0.2], [0, 0.3], [0, 0.5], [0, 0.7], | ||
[1, 0.2], [1, 0.5], [1, 0.7], [1, 0.7], | ||
[2, 0.3], [2, 0.6], [2, 0.6] | ||
]); | ||
assertRanges([['day 1', 'day 2'], [0.1875, 0.71]]); | ||
}, | ||
null, BOXEVENTS, 'box select' | ||
); | ||
}) | ||
.catch(fail) | ||
|
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.
Note that this style update isn't compatible with the current trace attribute set.
To do so, we would need to add arrayOk support for
marker.color
,marker.opacity
andmarker.symbol
would be pretty easy to add after d352fa5Uh oh!
There was an error while loading. Please reload this page.
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.
... that is if no one finds too awkward to have both box-wide (e.g.
marker.outliercolor
) and per-sample-pt attributes in the same trace.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.
Seems reasonable.
outliercolor
is only forboxpoints: 'suspectedoutliers'
, and in that mode selecting would be a bit weird. (side note:outliercolor
should probably be described better inattributes
... and perhaps the logic indefaults
cleaned up or amended so we don't have theoutliercolor
attributes in_fullData
ifboxpoints !== 'suspectedoutliers'
Begs the question though of what selection (or crossfilter) should do in modes other than
boxpoints: 'all'
when at least the points within the box are hidden - what does selection do now? I could imagine it being cool to still be able to select the points, and have them pop into view when you do (likewise for crossfilter)... but that might be too complicated, dunno.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 vote for hiding the lasso and select mode bar buttons whenever
boxpoints !== 'all'
- similar to how we currently hide them from scatter-line-only graphs here. But maybe that's just because I'm lazy. cc @chriddyp @cpsievert any thoughts on this?I believe that's done already.
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.
We can certainly start that way anyhow, that's fine for this PR, we can revisit if there's interest later.
It's messy logic - but that's actually the second coerce of one of them so the easy thing to do would be to delete them from the full trace if they're not needed. I guess the reason it's done this way is so you can set the default
boxpoints
to'suspectedoutliers'
if either of theoutliercolor
values is a real color - stricter than just existing.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.
Ha I see. I've been wanting to replace
Lib.coerce2
withLib.validate
(which doesn't fill infullData
). I'll do this in this PR 🔨Uh oh!
There was an error while loading. Please reload this page.
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.
🔪ing
Lib.coerce2
turned out to be a little trickier than I thought - and than I want to do in this PR. In brief, we can just replacecoerce2
byvalidate
,validate
return false whenever an value isn't set whilecoerce2
returns the default value.So, here's a quick 🛠️ and 🔒 in 9ca410a
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.
that's in b4d8044