cytoscape / cytoscape.js

Graph theory (network) library for visualisation and analysis
https://js.cytoscape.org
MIT License
10.13k stars 1.64k forks source link

Option to pan with wheel and zoom on ctrl+wheel #3287

Open septatrix opened 2 weeks ago

septatrix commented 2 weeks ago

Description of new feature

There should be an option to pan the graph on normal wheel inputs and only zoom when the Ctrl modifier is active.

Motivation for new feature

On large graphs it is often desirable to have a quick way to pan/translate the graph. The scroll event is ideal for that but currently bound to zooming. An option should be added to instead map wheel events to panning. To still have an easy option to zoom, wheel events which have the Ctrl modifier set should still zoom. When pinching on a touchpad this modifier is automatically set.

A good example of this behavior is Excalidraw.

On pages where cytoscape does not fill the whole page the current behavior of capturing and preventing any scroll events can make it annoying to scroll past the element as it eats the wheel input. A popular example which only zooms on Ctrl+Wheel are embedded (Google) maps widgets.

For reviewers

Reviewers should ensure that the following tasks are carried out for incorporated issues:

mikekucera commented 2 weeks ago

I think wheel for zooming makes sense for cy.js. Networks tend to be as wide as they are tall, so unlike a webpage or document it doesn't really make sense to prioritize vertical scroll over horizontal scroll. Also google maps and others use wheel for zoom, so its not an uncommon thing.

The real issue is embedding a small cy.js element in a larger web page, and you are scrolling with the mouse wheel, and the mouse goes over the cy.js canvas, and the events get eaten. If scroll events are treated as panning instead of zooming won't it still eat the scroll events, but just pan the network in stead of zooming it? Perhaps there could be an option to just turn off the eating of scroll events entirely? I think that would address this issue without introducing new behaviours for scrolling.

septatrix commented 2 weeks ago

I think wheel for zooming makes sense for cy.js. Networks tend to be as wide as they are tall, so unlike a webpage or document it doesn't really make sense to prioritize vertical scroll over horizontal scroll.

Especially when zoomed in, dragging to pan becomes very cumbersome. Scrolling is a lot faster in those cases. Also, while force-directed graphs may have a aspect ration of ~1, this is not the case for layered/hierarchical graphs.

With normal mouse wheels one can also press Shift to scroll horizontally but especially for laptops this is not even necessary. I am also not against zooming - just an options that it should only happen when pressing Ctrl.

Also google maps and others use wheel for zoom, so its not an uncommon thing.

For the full applications yes, but not for embeds:

image

The real issue is embedding a small cy.js element in a larger web page, and you are scrolling with the mouse wheel, and the mouse goes over the cy.js canvas, and the events get eaten. If scroll events are treated as panning instead of zooming won't it still eat the scroll events, but just pan the network in stead of zooming it? Perhaps there could be an option to just turn off the eating of scroll events entirely? I think that would address this issue without introducing new behaviours for scrolling.

Yeah I might not have been entirely clear in the issue. Ideally, there would be two new options: One to enable wheel-to-pan and one to disable wheel-to-zoom unless Ctrl is pressed

maxkfranz commented 1 week ago

The custom scroll wheel behaviour looks like a good idea for an extension. It's niche.

Most people are going to expect the wheel to zoom. That's why Google Maps has to have the notification when you try to zoom in the embedded version. They show that message because users are surprised that zooming doesn't work as expected.

On pages where cytoscape does not fill the whole page the current behavior of capturing and preventing any scroll events can make it annoying to scroll past the element as it eats the wheel input.

A better/simpler solution for this problem would be to detect when the page is scrolling and disable the wheel gesture during that set of scroll events. That's easy to monitor for the top-level page, but it might be more complicated if there's nested scrollable areas.