Skip to content
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

User-defined links do not provide access to link source & target until user interacts with the graph #471

Open
alico-cra opened this issue Nov 22, 2023 · 5 comments

Comments

@alico-cra
Copy link

Describe the bug
In 3D-Force-Graph, when using linkThreeObject and linkThreeObjectExtend, the user does not have access to the converted link object (and properties such as target & source) from string until interaction with the component occurs. This is limiting as it prevents the user from displaying custom-defined links until the cursor interacts with the graph.

This appears to be due to the behavior defined here: https://github.com/vasturiano/d3-force-3d#link_links
It requires that the graph be initialized before custom links are made visible.

To Reproduce
Steps to reproduce the behavior:

  1. Define a custom link object using linkThreeObject
  2. Reload your project
  3. Before interacting with the graph, notice that no links appear
  4. Now, drag your cursor across the graph.
  5. Now notice that the graph initializes with the links.

Expected behavior
When loading the page for the first time, I would expect both custom nodes and custom links to be defined & visible on first load.

Desktop (please complete the following information):

  • OS: MacOS
  • Browser chrome
  • Version 119.0.6045.123
@vasturiano
Copy link
Owner

vasturiano commented Nov 23, 2023

@alico-cra I'm unable to reproduce your issue. Could you make a simple example on https://codesandbox.io/ that clearly shows the problem you're describing?

And if you try this example you'll notice that the custom links are visible immediately, not when the user interacts with the graph. Do you observe a different behaviour?

@alico-cra
Copy link
Author

@vasturiano Here is the link to an example codesandbox displaying the issue.
Essentially, the issue is present when I am rendering some default data that is not fetched, then once the data I wish to display has been fetched, the UI is re-rendered with said new graph. In this example, there is a "Load Data" button which will simulate fetching data that is not initially rendered.

  • Click on the Load Data button
  • Next, you should see 4 nodes present. Notice that there are NO VISIBLE LINKS between them.
  • Now, move your cursor in the area between 2 nodes.
  • Only once the cursor hovers across a non-visible link do all the links become visible.
  • Once the links become interacted with/visible, they follow the appropriate hover opacity & color logic I have set up in this example.

This only occurs when defining linkThreeObject. I would expect that as soon as the button is pressed & refresh occurs, the links would be present along with the nodes. However, it seems like something is conflicting between the initial linkOpacity={0} and the opacity for links set in linkThreeObject. A link must be physically interacted with by the mouse in order to be rendered visible with linkThreeObject in this example.
Am I missing something simple? Thanks in advance for the input.

@cramatt
Copy link

cramatt commented Nov 29, 2023

As @alico-cra noted, I'm able to recreate this issue if I define a custom node AND link. With link only example (the text-label @vasturiano pointed to) I don't see the issue.

I do notice that @vasturiano uses linkPositionUpdate to set link position while @alico-cra we are setting it in the linkThreeObject code - maybe this change would help?

I started a new sandbox but was not able to fully replicate, although I do have other issues with the links not positioning correctly which are maybe related?

https://codesandbox.io/p/sandbox/purple-morning-ntr2zf?file=%2Fsrc%2FForceGraph.jsx%3A57%2C9

@alico-cra
Copy link
Author

@cramatt Yes that is a good point worth clarifying. The text-label example does work for me as well.

However the difference in that example vs what I noted in this bug is that the issue seems to be present when newer content is present after initial render, and after a refresh occurs, the new links are present in the canvas but not visible. They almost seem to be defaulting to the linkOpacity={0} rather than the styling dictated in linkThreeObject.

@vasturiano
Copy link
Owner

Thanks for creating those examples.

Like @cramatt already mentioned, the issue is that you're not implementing the linkPositionUpdate method. This method is essential when you have custom links because the module has no way to know how to generically do that. The method linkThreeObject gets invoked only at object creation, but linkPositionUpdate gets invoked at every frame in which there is node movement.

You can see an example of that implementation here:

linkPositionUpdate={(sprite, { start, end }) => {
const middlePos = Object.assign(...['x', 'y', 'z'].map(c => ({
[c]: start[c] + (end[c] - start[c]) / 2 // calc middle point
})));
// Position sprite
Object.assign(sprite.position, middlePos);
}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants