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
Disable Shift key behavior? #20
Comments
Hmm. You can register a brush start event listener that removes the brush’s keydown and keyup event listeners, thereby preventing it from receiving these events: brush.on("start.nokey", function() {
d3.select(window).on("keydown.brush keyup.brush", null);
}); But, it’ll still see event.shiftKey, event.metaKey and event.altKey if they are pressed during mousedown or touchstart, so that won’t really disable the behavior completely. I think the simplest thing would probably be a new feature that lets you disable the event.shiftKey and other key-driven behaviors. Possibly it should let you remap them to different modifier keys, or null to remove the functionality entirely. |
Thanks for the quick reply. As you said the mousedown and touchstart events are still coming through and the A remapping solution would be great 👍 since these are still useful features to have, it's just a bit inflexible currently. I'll likely fork the lib and remove this functionality in the meantime but the customizable solution would be great. |
If anyone stumbles upon this issue and is interested in my solution I did end up forking the lib and removing shifting functionality. As the project developed I also ended up tweaking a few other things about the brush. Namely, I found myself wanting to hook into events which were being blocked by the brush so I ended up removing More customizability in the way the brush binds to keyboard/mouse events would be really cool, but forking the lib is a viable solution for anyone else who runs into similar issues. |
totally agree...maybe it could be improved to a optional feature? |
It's not working to me, also remove keydown.brush and keyup.brush event, but shifting's init value has been true, and always true when brush. |
I just got hit by this as well - FWIW I am trying to develop a view which has zoom, pan and brush - but I only wanted the brush enabled when the "shift" key was pressed. |
Grabbing Shift or Alt key behavior with no possibility to reconfigure it is unsuitable. |
@iansinnott would you mind sharing your fork? The brush behavior is fantastic, but the fact that it takes over the shift and alt keys really makes it difficult to integrate with other functionality like @GordonSmith's example of zooming and brushing. Trying to tie it to another keydown event is tricky because it looks like other keys repeatedly fire the 'keydown' event while held down. The shift and alt keydown events only fire once when the key is held down continuously. |
@pkerpedjiev I would be happy to but it's currently an internal fork so it's not publicly accessible. I am indeed using it for zoom/pan/shift+brush, so what is suggested in this thread is quite possible and didn't take too much work. It was mostly a matter of code removal. I believe I removed everything relating to |
It seems like the main thing blocking this issue is not how to implement it but what the desired API is, both in terms of functionality and name. As context, there are four modes of manipulating the brush. These modes are not exposed in the public API (currently), but here are the internal names that are used:
Separate from the modes, there is also a flag:
Some possible options:
|
Is it possible that all key modifiers start turned off, and we can assign certain keys to the modifiers? Ie: brush.setModifier("CENTER", alt_key); (I love how it works now, but I need to use shift for other functions in my app, so I just had to comment it out from my d3.js) |
I wouldn’t change the default behavior, as that would require a major version change. However I think allowing the key bindings to be reconfigurable could work. We’d need to enumerate the behavioral modifiers, say symbols like this:
It’s a little weird in that we need to know the mapping from key code to key modifier (i.e., keycode 18 means event.altKey). But it’s probably doable? I worry it’s more complex than just an all-on/all-off flag, of course. |
And |
Probably something like this: brush.keyModifier(d3.brushFixSize, null) |
But as I said, that’s just one proposal, and I don’t know if the added complexity of configurable modifiers is justified in comparison to just being able to turn them all off. |
Could you also be able to use the metaKey? or to set no key if we want to disable a function? |
Having the option to just turn them all off is one thing. Very beneficial for those apps, like mine, that have Ctrl, Alt, and Shift mapped to other things and just want basic brush behaviors. In my case, I want to use Shift to be an additive selection like you had in your Draggable Network II example for v3. So just being able to disable them would work in my scenario. Remapping the keys to allow for the same behavior is definitely more beneficial for a larger audience I believe. Maybe creating a shortcut function that performs a blanket disable by remapping each to null would be the solution for both issues I've been trying to think of a way you could tie it into either the
But I can't come up with anything that feels viable. |
I'm personally fine with turning off all of these behaviors at once. But that is also possible if each are individually configurable. So I suppose it depends on how much extra effort it takes to implement the latter option to determine whether it's worth it. @kpaxton If you're interested, I implemented a selectable, draggable, force directed network by forking d3-brush.js and turning off the default shift key behavior. Example is on bl.ocks.org. |
Thansk @pkerpedjiev but I'm in a production situation and don't want to stray from supported packages. I was using your other one initially. http://bl.ocks.org/pkerpedjiev/0389e39fad95e1cf29ce |
Any movement on this yet? I could really use this feature. |
I got hit by this as well, will be there any update regarding this behavior? |
Is anyone going to work on this at all? Looks like this library has been dormant for a long time. @mbostock ? |
+1 |
d3#20 Added modifier behavior "constants" that also hold the default key modifier. d3.brushForceNew (Meta key) <-- unsure on naming d3.brushFixSize (Space key) d3.brushFixCenter (Alt key) d3.brushFixSecondary (Shift key) Default modifier key code can be changed, or the behavior disabled, by calling ``` d3.brushFixSecondary.keyCode(newKeyCode); //change d3.brushFixCenter.keyCode(null); //disable ``` Default modifier key code can be retrieved by calling `.keyCode()` without arguments. Added `brush.keyModifier(behavior, keyCode)` method Modifier keys for an individual brush can be changed or disabled by calling ``` brush.keyModifier(d3.brushFixSecondary, keyCode); //change brush.keyModifier(d3.brushFixCenter, null); //disable ``` The current modifier key code can be retrieved by passing the behavior without an argument for key code. ``` const keyCode = brush.keyModifier(d3.brushFixSecondary); // keyCode === 16 ``` Note: Non-modifier keys can be set as the key code for brushFixCenter, but the behavior will only be applied/stopped for keydown/keyup while brushing is active, since the key code can't be mapped to one of the `modifierKey` properties on MouseEvent.
I could really use this behavior, as well; I need to map the modifiers to match the keys used in another package that I don't have control over. https://github.com/krisdages/d3-brush/tree/issue-20 @mbostock, Wasn't sure what the form of I tried to follow the general pattern where calling a method without the value to set returns the current value. Was not sure about code style or pull request etiquette for this project, so I didn't create a pull request, but please feel free to make any changes to this and pull them in if you want. |
BTW, I noticed that My initial implementation used |
I’ve added |
d3#20 Added modifier behavior "constants" that also hold the default key modifier. d3.brushForceNew (Meta key) <-- unsure on naming d3.brushFixSize (Space key) d3.brushFixCenter (Alt key) d3.brushFixSecondary (Shift key) Default modifier key code can be changed, or the behavior disabled, by calling ``` d3.brushFixSecondary.keyCode(newKeyCode); //change d3.brushFixCenter.keyCode(null); //disable ``` Default modifier key code can be retrieved by calling `.keyCode()` without arguments. Added `brush.keyModifier(behavior, keyCode)` method Modifier keys for an individual brush can be changed or disabled by calling ``` brush.keyModifier(d3.brushFixSecondary, keyCode); //change brush.keyModifier(d3.brushFixCenter, null); //disable ``` The current modifier key code can be retrieved by passing the behavior without an argument for key code. ``` const keyCode = brush.keyModifier(d3.brushFixSecondary); // keyCode === 16 ``` Note: Non-modifier keys can be set as the key code for brushFixCenter, but the behavior will only be applied/stopped for keydown/keyup while brushing is active, since the key code can't be mapped to one of the `modifierKey` properties on MouseEvent.
After reading this thread and seeing examples like this one, I did the following to disable panning/zooming when the shift key is held... zoom.filter(() => !d3.event.shiftKey) and then used the opposite brush.filter(() => d3.event.shiftKey)
brush.keyModifiers(false) This approach worked perfectly! Thanks @iansinnott for the initial thought/research and thanks @mbostock for the |
d3#20 Added modifier behavior "constants" that also hold the default key modifier. d3.brushForceNew (Meta key) <-- unsure on naming d3.brushFixSize (Space key) d3.brushFixCenter (Alt key) d3.brushFixSecondary (Shift key) Default modifier key code can be changed, or the behavior disabled, by calling ``` d3.brushFixSecondary.keyCode(newKeyCode); //change d3.brushFixCenter.keyCode(null); //disable ``` Default modifier key code can be retrieved by calling `.keyCode()` without arguments. Added `brush.keyModifier(behavior, keyCode)` method Modifier keys for an individual brush can be changed or disabled by calling ``` brush.keyModifier(d3.brushFixSecondary, keyCode); //change brush.keyModifier(d3.brushFixCenter, null); //disable ``` The current modifier key code can be retrieved by passing the behavior without an argument for key code. ``` const keyCode = brush.keyModifier(d3.brushFixSecondary); // keyCode === 16 ``` Note: Non-modifier keys can be set as the key code for brushFixCenter, but the behavior will only be applied/stopped for keydown/keyup while brushing is active, since the key code can't be mapped to one of the `modifierKey` properties on MouseEvent.
d3#20 Added modifier behavior "constants" that also hold the default key modifier. d3.brushForceNew (Meta key) <-- unsure on naming d3.brushFixSize (Space key) d3.brushFixCenter (Alt key) d3.brushFixSecondary (Shift key) Default modifier key code can be changed, or the behavior disabled, by calling ``` d3.brushFixSecondary.keyCode(newKeyCode); //change d3.brushFixCenter.keyCode(null); //disable ``` Default modifier key code can be retrieved by calling `.keyCode()` without arguments. Added `brush.keyModifier(behavior, keyCode)` method Modifier keys for an individual brush can be changed or disabled by calling ``` brush.keyModifier(d3.brushFixSecondary, keyCode); //change brush.keyModifier(d3.brushFixCenter, null); //disable ``` The current modifier key code can be retrieved by passing the behavior without an argument for key code. ``` const keyCode = brush.keyModifier(d3.brushFixSecondary); // keyCode === 16 ``` Note: Non-modifier keys can be set as the key code for brushFixCenter, but the behavior will only be applied/stopped for keydown/keyup while brushing is active, since the key code can't be mapped to one of the `modifierKey` properties on MouseEvent.
Is there a best-practices way to disable the shift key behavior?
In my app the brush is enabled only when the user holds shift. I.e. they hold shift and then drag to select nodes in a force layout. This means that
event.shiftKey
is always true during the brush drag. I understand that this is a feature of the brush, but if possible I would like to disable it for this use case.I scanned through the code and saw that if I change this line to the following everything works fine:
But I wasn't sure how I might hook into this functionality without modifying the source. Any suggestions would be much appreciated. Thanks!
The text was updated successfully, but these errors were encountered: