Git Product home page Git Product logo

Comments (27)

kpaxton avatar kpaxton commented on April 27, 2024 6

Any movement on this yet? I could really use this feature.

from d3-brush.

skipjack avatar skipjack commented on April 27, 2024 5

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 filter as well as the new keyModifiers method on the brush...

brush.filter(() => d3.event.shiftKey)
brush.keyModifiers(false)

This approach worked perfectly! Thanks @iansinnott for the initial thought/research and thanks @mbostock for the keyModifiers addition 🎉. For anyone else that stumbles upon this, you may want to add a few more cases to brush.filter to improve the experience or just hide the brush after selection is complete (as done here).

from d3-brush.

mbostock avatar mbostock commented on April 27, 2024 4

I’ve added brush.keyModifiers(false) as a quick way to turn off all keybindings. If we want something fancier, it’ll require further design.

from d3-brush.

bumbeishvili avatar bumbeishvili commented on April 27, 2024 3

I got hit by this as well, will be there any update regarding this behavior?

from d3-brush.

mbostock avatar mbostock commented on April 27, 2024 2

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.

from d3-brush.

mbostock avatar mbostock commented on April 27, 2024 1

Probably something like this:

brush.keyModifier(d3.brushFixSize, null)

from d3-brush.

pkerpedjiev avatar pkerpedjiev commented on April 27, 2024 1

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.

from d3-brush.

iansinnott avatar iansinnott commented on April 27, 2024

Thanks for the quick reply. As you said the mousedown and touchstart events are still coming through and the event.shiftKey is true when that event fires.

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.

from d3-brush.

iansinnott avatar iansinnott commented on April 27, 2024

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 nopropagation and noevent in some places.

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.

from d3-brush.

geekplux avatar geekplux commented on April 27, 2024

these are still useful features to have, it's just a bit inflexible currently

totally agree...maybe it could be improved to a optional feature?

from d3-brush.

yandongCoder avatar yandongCoder commented on April 27, 2024

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.

from d3-brush.

GordonSmith avatar GordonSmith commented on April 27, 2024

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.

from d3-brush.

Krzysztof-FF avatar Krzysztof-FF commented on April 27, 2024

Grabbing Shift or Alt key behavior with no possibility to reconfigure it is unsuitable.
In my application, I'm using Brush behavior to select several geometrical entities, I'm using Ctrl key to activate Brush behavior over standard Zoom-Pan behavior. Successive Brush selects new set of entities. With e.g. Shift or Alt pressed, I would like to activate other logical operations between successive selections, e.g. by adding or subtracting them.
Built-in behavior of Shift and Alt are in my application of minor significance and I would like to have them removable / reconfigurable.

from d3-brush.

pkerpedjiev avatar pkerpedjiev commented on April 27, 2024

@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.

from d3-brush.

iansinnott avatar iansinnott commented on April 27, 2024

@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 shifting (source) as well as noevent and nopropagation. The shifting behavior is simply undesirable if you want to use shift to activate the brush, and the event related stuff allows DOM events to bubble up and be caught by your app code instead of the brush internal handlers.

from d3-brush.

mbostock avatar mbostock commented on April 27, 2024

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:

  • MODE_DRAG - Translates the brush selection, maintaining its current size. This typically happens when you click and drag in the main area of an existing brush selection.

  • MODE_SPACE - Like MODE_DRAG, translates the brush selection, maintaining its current size. The only difference is that this is enabled temporarily by holding down the SPACE key when in another mode, such as MODE_HANDLE.

  • MODE_HANDLE - Resizes one or two edges of the brush selection, maintaining the position of the other edges. This typically happens when you click and drag on an edge (or a corner) of an existing brush selection, or when you click outside the existing brush selection and drag to create a new brush selection.

  • MODE_CENTER - Like MODE_HANDLE, except it resizes two or four edges of the brush selection, maintaining the current center of the brush selection. This mode is temporarily enabled from MODE_HANDLE by holding down the ALT key. Also note that the SPACE key takes priority, so holding down ALT and SPACE will use MODE_SPACE.

Separate from the modes, there is also a flag:

  • shifting - Allow the brush selection to change in only one dimension. The dimension is determined by the first pointer movement after SHIFT is depressed. For example, if you hold down SHIFT and move the pointer to the right, the y-position of the brush selection becomes locked at its current values until the SHIFT key is released.

Some possible options:

  1. The simplest API would be to disable all key modifiers. This would allow you to use MODE_DRAG and MODE_HANDLE, depending on where the initial click landed, but would not allow you to change modes during a brush gesture, and would effectively disable MODE_SPACE, MODE_CENTER, and the shifting flag.

  2. An alternative API might allow disabling of specific modes. If you disabled MODE_SPACE, for instance, it would not listen for the SPACE key, but it might still listen for the ALT key to enable MODE_CENTER. Likewise you could disable MODE_CENTER to avoid listening for ALT. On the other hand since the shifting flag is orthogonal to the modes, I don’t see how this could disable listening for SHIFT, which is the original motivation for this issue.

  3. Another alternative would be to continue to observe key modifiers, but disable key listeners. This would allow you to use a key modifier at the start of a gesture; for example, holding down SHIFT on brush start could still lock the selection position on one dimension, but there would be no keydown and keyup listener, so if the SHIFT key were released while brushing, it would not affect the current brush gesture. Thus the brush would not interfere with external event listeners that want to do something with these key events.

from d3-brush.

Frazer avatar Frazer commented on April 27, 2024

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)

from d3-brush.

mbostock avatar mbostock commented on April 27, 2024

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:

  • d3.brushFixSize - defaults to SPACE (32)
  • d3.brushFixCenter - defaults to ALT (18)
  • d3.brushFixSecondary - defaults to SHIFT (16)

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.

from d3-brush.

pkerpedjiev avatar pkerpedjiev commented on April 27, 2024

And d3.brushFixSize(null) would disable that behavior?

from d3-brush.

mbostock avatar mbostock commented on April 27, 2024

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.

from d3-brush.

Frazer avatar Frazer commented on April 27, 2024

Could you also be able to use the metaKey? or to set no key if we want to disable a function?

from d3-brush.

kpaxton avatar kpaxton commented on April 27, 2024

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 brush.disableKeyModifiers(). What @mbostock suggested above brush.keyModifier(d3.brushFixSize, null) I think is fine. As long as what brushFixSize, brushFixCenter, and brushFixSecondary are documented well so that everyone knows what they mean. I also think @Frazer's suggestion of just using 'CENTER', 'SIZE', or 'SECONDARY' are viable as well. I would expect almost all users of D3 who are trying to set keydown functions would understand the mapping between keycodes and key modifiers. So I don't necessarily see that as a blocker to moving forward with this.

I've been trying to think of a way you could tie it into either the brush.on() functions or some other type of event override similar to your example above.

brush.on("start.nokey", function() {
  d3.select(window).on("keydown.brush keyup.brush", null);
});

But I can't come up with anything that feels viable.

from d3-brush.

kpaxton avatar kpaxton commented on April 27, 2024

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

from d3-brush.

kpaxton avatar kpaxton commented on April 27, 2024

Is anyone going to work on this at all? Looks like this library has been dormant for a long time. @mbostock ?

from d3-brush.

heyitaki avatar heyitaki commented on April 27, 2024

+1

from d3-brush.

krisdages avatar krisdages commented on April 27, 2024

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,
I implemented according to the spec above, with the addition of adding another behavior "constant" for the meta key behavior.

Wasn't sure what the form of d3.brushFixSize etc, should take; I went ahead and made them objects that hold the default key code, and allow it to be changed with, e,g. d3.brushFixSize.keyCode(18).

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.

from d3-brush.

krisdages avatar krisdages commented on April 27, 2024

BTW, I noticed that event.keyCode is marked as deprecated on MDN. My initial plan was to recognize the modifier keys with event.code, event.char, and/or event.key instead of switch (event.keyCode) {}, but I didn't want to make too many changes.

My initial implementation used event.key alone, but it was problematic on my Linux system because
Shift + Alt emitted "Meta".

from d3-brush.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.