3d-force-graph icon indicating copy to clipboard operation
3d-force-graph copied to clipboard

Question: For nodes with HTML in them, is there a way for the user to select the HTML elements that are rendered?

Open hughlett opened this issue 2 years ago • 6 comments

I'm 90% sure that the answer is "no" but I wanted to ask here to see if I could get a definite answer.

As seen in the HTML in nodes example, it is possible to render HTML. Is it possible for the user to select the HTML that is rendered on the node, or is what's being rendered only an image?

I tried reading through the documentation of the CSS2DRenderer object that is being used in the example, but it's a little over my head.

Any help or information would be much appreciated, thanks!

hughlett avatar Jun 22 '22 17:06 hughlett

@drewrh thanks for reaching out.

You should be able to do most things that you would otherwise do with regular HTML elements, including text selection, or other interactions.

For this particular example, text selection is explicitly disabled in the CSS, because it was too distracting. But you can set it any way you like. https://github.com/vasturiano/3d-force-graph/blob/fe9a833bc659303d21c8ffa18f2afd01587443ba/example/html-nodes/index.html#L16

vasturiano avatar Jun 22 '22 22:06 vasturiano

@vasturiano I can't believe I didn't notice the CSS! I've been so fixated on the rendering that I totally forgot that CSS exists. Thank you for the reply and sanity check, this helps me out a lot!

Thanks again for answering, and thanks for maintaining this library, it's been a lot of fun to use with React.

hughlett avatar Jun 23 '22 02:06 hughlett

Apologies for reopening the issue but I tried running the example code with the user-select line commented out, as well as changing the value from none to all and I still was unable to select anything within the node. Is there another setting I should change to be able to select the rendered HTML?

hughlett avatar Jun 23 '22 03:06 hughlett

@drewrh thanks for re-opening the issue. I see what the problem is, the DOM container where all of the HTML element nodes are placed has a pointer-events: none CSS rule. You can see that's being set here: https://github.com/vasturiano/three-render-objects/blob/34c768906a89061cdd079ce4def6cbe4371bba60/src/three-render-objects.js#L383

In reality this rule exists because if the pointer events are being caught by the overlayed node elements, they won't by passed through to the force-graph canvas, which will effectively disable all the interactivity such as graph rotation/zooming and node drag/click/hover.

So, what you can do is add a CSS rule in each of your node elements which re-enables the trap on pointer events, like pointer-events: auto. However, keep in mind that this will interfere with the general interactivity of the canvas when the pointer is directly on top of a node DOM element.

vasturiano avatar Jun 26 '22 14:06 vasturiano

@vasturiano Hello, reopening this.

I was able to apply the solution and have added a button using the CSS2D renderer. I'm now able to click the button and run a function, however, one issue that I'm running into is, if I press on an area on the button that overlaps with the node underneath it, I end up clicking both the button and the node, triggering an onNodeClick function.

Is there a way I can prevent this from happening?

2arch avatar Aug 26 '23 13:08 2arch

@atlllas I would suggest to put a verification in your onNodeClick handler for the event.target; if that is your button element instead of the graph canvas you'll know that it's already been taken care of in your button handler and you can safely discard it. The event is in the second argument of that callback.

vasturiano avatar Aug 28 '23 22:08 vasturiano