-
Notifications
You must be signed in to change notification settings - Fork 603
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
Add support for clearing selection #4720
Conversation
Nice to see this coming along! Some suggestions:
(Learn I hope this is helpful. I'm excited about your contribution. :) |
added test suite for clear on multi adding single and interval clear adding test cases for single + interval clearing merge + squash + rebase
…ag as true at least modified default behavior and updated tests appropriately clear tx and modified dependent files testing editor linking clear tx working but slow removing unnecssary type updating tx type to modify existing signal added test suite and modified clear to not occur on default - must flag as true at least modified default behavior and updated tests appropriately readding schema file found in master branch
interval selection
adding single type support [Travis] Update schema (build: 22277) [Travis] Update examples (build: 22277) interval selection adding test cases for single + interval clearing
@kanitw How do I merge into a feature branch? |
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.
Hi @allenjlee, this is great work! You're very close to wrapping this up. I've left you some minor comments throughout the code. But there are also a couple of more major/general ones:
-
If you test with the first example (the tabular heatmap) in Add support for clearing selection #4306, you may notice that double clicking with the shift-key pressed doesn't seem to work (i.e., doesn't clear the selection any more). Double clicking w/o the shift does work. Let me know if you need help figuring out why (hint: is there logic kicking in when the
shiftKey
is pressed?). -
Try testing this spec out which is a modified version of our interactive scatterplot matrix example. You can drag out a brush when you have the
shiftKey
depressed. When you double click, you'll notice that all points are colored (i.e., the selection is being cleared out correctly) but the rectangle of the brush extents persists. When we double click, we should make sure the rectangle disappears too.
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"repeat": {
"row": ["Horsepower", "Acceleration", "Miles_per_Gallon"],
"column": ["Miles_per_Gallon", "Acceleration", "Horsepower"]
},
"spec": {
"data": {"url": "data/cars.json"},
"mark": "point",
"selection": {
"brush": {
"type": "interval",
"resolve": "union",
"on": "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!",
"translate": "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!",
"zoom": "wheel![event.shiftKey]"
}
},
"encoding": {
"x": {"field": {"repeat": "column"},"type": "quantitative"},
"y": {"field": {"repeat": "row"},"type": "quantitative"},
"color": {
"condition": {
"selection": "brush",
"field": "Origin",
"type": "nominal"
},
"value": "grey"
}
}
}
}
Note, the above behavior also occurs with this modified version of our interactive brush in a single scatterplot:
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"description": "Drag out a rectangular brush to highlight points.",
"data": {"url": "data/cars.json"},
"selection": {
"brush": {
"type": "interval",
"resolve": "union",
"on": "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!",
"translate": "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!",
"zoom": "wheel![event.shiftKey]"
}
},
"mark": "point",
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"},
"color": {
"condition": {"selection": "brush", "field": "Cylinders", "type": "ordinal"},
"value": "grey"
}
}
}
src/selection.ts
Outdated
* | ||
* See the [TODO: clear] documentation for more information. | ||
*/ | ||
clear?: string | boolean; |
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.
Let's set clear
to be an EventStream | boolean
. Even though EventStream
is aliased to any
, we prefer more specific typings wherever possible both as a self-documenting mechanism and for when we make the types more specific in the future.
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.
Should EventStream
be string
or any
?
src/selection.ts
Outdated
@@ -247,13 +278,15 @@ export const defaultConfig: SelectionConfig = { | |||
multi: { | |||
on: 'click', | |||
fields: [SELECTION_ID], | |||
clear: 'dblclick', |
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.
Not sure why multi
and interval
selections have a clear
set by default but single
doesn't? Recall that in #4306, the second example motivated the need for clearing selections using a single
selection. Let's have clear: 'dblclick'
on all selection types.
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 had a quick question related to this that I wanted to follow up about. What should the signals
array contain when I call it from the transform? I had thought it would contain all signals
in the given selCmpt
, but when I try to iterate through it appears some are missing. I haven't been able to figure out why this is happening.
Are transforms compiled further upstream before other parts?
signals: (model, selCmpt, signals) => { | ||
const tupleIdx = signals.findIndex(i => i.name === selCmpt.name + TUPLE); | ||
signals[tupleIdx].on.push({ | ||
events: [{source: 'scope', type: selCmpt.clear}], |
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.
Wrap selCmpt.clear
with a call to parseSelector
(like in translate.ts
or zoom.ts
). This is important to making sure that, in multi-view visualizations, clearing only fires if the user double-clicks within the same view as the selection was defined in (scope
).
…orking with all example interactive visualizations
…clear off for those tests
added test suite for clear on multi adding single and interval clear adding test cases for single + interval clearing merge + squash + rebase
…ag as true at least modified default behavior and updated tests appropriately clear tx and modified dependent files testing editor linking clear tx working but slow removing unnecssary type updating tx type to modify existing signal added test suite and modified clear to not occur on default - must flag as true at least modified default behavior and updated tests appropriately readding schema file found in master branch
interval selection
adding single type support [Travis] Update schema (build: 22277) [Travis] Update examples (build: 22277) interval selection adding test cases for single + interval clearing
…orking with all example interactive visualizations
…clear off for those tests
src/selection.ts
Outdated
@@ -272,6 +269,7 @@ export const defaultConfig: SelectionConfig = { | |||
single: { | |||
on: 'click', | |||
fields: [SELECTION_ID], | |||
clear: 'dblclick', |
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.
The default clear should be mouseout
if on
is mouseover
.
(But dblclick
is good otherwise. Thus, I don't think dblclick
should be defined here in config.) .
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.
Also, I don't think "interval"
needs default "clear" given that click would be the default clear without an additional signal anyway. (Click triggers brush, and if you don't drag, that's equivalent to clearing.)
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.
But dblclick is good otherwise. Thus, I don't think dblclick should be defined here in config.
Hmm, this is an interesting point. The default "on": "click"
is defined in the configuration, so it seems to make sense to define clear consistently as well. But I see your point that if the user changed to "on": "mouseover"
we might want to detect that and reflect it. If that's the only exception we can think of, I'd rather handle it separately, when we parse defaults, rather than not have clear
defined in our SelectionConfig
whatsoever.
Also, I don't think "interval" needs default "clear" given that click would be the default clear without an additional signal anyway.
I disagree. When an interval selection is bound to scales, it would be helpful to clear it to return to the original scale domains (so too if we had brush-to-zoom functionality as in #4742). Moreover, as much as possible, I would like to keep all selection types working consistently (that is, after all, our original vision of a grammar of interaction rather than a typology of selections).
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.
Hmm, this is an interesting point. The default "on": "click" is defined in the configuration, so it seems to make sense to define clear consistently as well. But I see your point that if the user changed to "on": "mouseover" we might want to detect that and reflect it. If that's the only exception we can think of, I'd rather handle it separately, when we parse defaults, rather than not have clear defined in our SelectionConfig whatsoever.
In the rest of the language, we make the config undefined
if the default value has condition rule. For example, we don't set opacity
in mark config. Same for axis labelAngle
.
When we want users to be able to customize config for each case, we then introduce a more specific version of config. For example, bandPaddingInner
scale config is undefined
(automatic) by default, but the automatic rule will draw value from barBandPaddingInner
and rectBandPaddingInner
scale configs. If users set bandPaddingInner
scale config to a specific value, then the default value is fixed and barBandPaddingInner
and rectBandPaddingInner
are ignored.
So I think we should have consistent config design here.
When an interval selection is bound to scales, it would be helpful to clear it to return to the original scale domains
Good point. I agree.
Note that as I mentioned previously, I see the benefit of interaction typologies as a macro level on top of selection grammar and have started prototyping it a bit, but that's a different issue separate from this. :)
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.
Sorry for the late reply, I just got back to the US.
Is the intention to have clear non-conditionally defined, i.e. set default configs to dblclick
and in cases where user changed to "on: "mouseover"
they also need to change "clear": "mouseout"
. Or have it conditionally defined, making the config undefined
and conditionally choosing the EventStream trigger based off of the on
config?
If the latter, should I make these changes in this PR or in a follow-up?
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.
No worries at all.
I mean the latter:
making the config undefined and conditionally choosing the EventStream trigger based on the
on
config
Since it's a simple change, let's do in this PR?
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.
Also, don't forget to add clear
to the docs. :)
Hi @allenjlee, nice job refactoring the code and making a first pass at the documentation! Things looked good, and I made a few updates to:
Finally, in the future, I recommend you use But overall, this was an excellent first PR and I'm excited to land this functionality in the next Vega-Lite release!! I'll hand off to @kanitw to merge, in case he has any final comments. |
Thanks for the comments, will remember in the future! |
… include explicit clear property
Adjust the size, remove unnecessary configs, make rangeSteep larger
Is it ok to squash and merge this in now? |
Yeah, let's do it. I found some problem when I tried to replicate the stock example, but it might be a different problem somewhere else. Given this is working well for basic functionality already, let's get this in. |
@allenjlee Congrats on your PR. 🎉 ps. I'll create the example and file an issue later. |
🎉 Congratulations on this PR @allenjlee. This is a great improvement. |
This PR adds support clearing selections in Vega-Lite (#4306) for single, multi, and interval types.
In summary: there is now a
clear
selection transform that will clear all selected points as well as clear all panning and zooming in the visualization. Theclear
EventStream
ismouseout
foron: mouseover
, anddblclick
for everything else by default. Users can also specify whatEventStream
they wantclear
to be.Here is a table of the behavior:
Files created:
Files modified:
TESTING: