jacomyal / sigma.js

A JavaScript library aimed at visualizing graphs of thousands of nodes and edges
https://www.sigmajs.org/
MIT License
11.25k stars 1.59k forks source link

Label events (enterLabel and clickLabel) #1319

Open cyclecycle opened 1 year ago

cyclecycle commented 1 year ago

We would like to implement hover and click event listeners for labels, because we have found that users often try to click on labels instead of nodes.

If you agree this should be a feature, we would be happy to put in a PR for it. If this is already achievable without any feature additions, please guide me on how to do this.

Thanks!

jacomyal commented 1 year ago

Hi @cyclecycle,

I see the usecase and I actually have seen multiple times people trying to interact with labels indeed. I think as long as it does not bring too much complexity and performance issues, it would be a great new feature!

However, this feature would have to handle the fact that labels are now always drawn with the same shapes and dimensions, since the labelRenderer and hoverRenderer are overridable:

https://github.com/jacomyal/sigma.js/blob/7b3a5ead355f7c54449002e6909a9af2eecae6db/src/settings.ts#L60-L61

Here is a real life example of an app that uses a custom hoverRenderer (source code here):

image

Also, since some features in the pipe require breaking changes, we are starting to work on a v3, and this might be a good time to improve the labelRenderer / hoverRenderer APIs, to integrate the possibility to customize the labels interactive area. Any idea on this @Yomguithereal?

cyclecycle commented 1 year ago

Hi @jacomyal,

I see what you mean. The custom labelRenderer can change the coordinates and size of the label, but Sigma does not record them, so we will not know the exact location and size of the label. It seems the question is how to get the new coordinates and size back from custom labelRenderer and store them.

A solution might be for labelRenderer to return data containing the new coordinates and size (of a new type LabelDisplayData). This could be saved in a variable on the class e.g., this.labelDataCache. We can then implement this.getLabelAtPosition(position: Coordinates) etc. similar to existing node/edge mouse events implementation. As far as I can tell this would be a non-breaking change.

cyclecycle commented 1 year ago

Here's a demo of the above suggestion:

https://github.com/jacomyal/sigma.js/compare/main...cyclecycle:sigma.js:label-events

It kind of works: When running the 'events' example, I am able to trigger downLabel and clickLabel events correctly some of the time, depending on the exact position I click.

Let me know what you think. Cheers

gaardhus commented 7 months ago

What happened to this brilliant idea? :eyes:

jacomyal commented 1 month ago

Hi all,

Sorry about my silence on that topic. Basically, I understand that it would be very useful for many people. Here are some insights about labels management in sigma and why making them interactive is challenging:

The main solutions I have in mind to implement this are:

  1. Add a canvas picking layer. This will have some cost when writing custom labels and hover renderers for people who want to detect these events, though.
  2. Rewrite labels rendering using DOM. This will make interacting with labels much easier, as well as customizing labels and hovered nodes appearance. But it has to be done with much attention, since handling too much DOM labels at once might slow applications a lot.

Since both solutions are impactful, I'll flag this feature for version 4.