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

Custom Layouts - Edges Removed #547

Open
Wu-Li opened this issue May 19, 2024 · 1 comment
Open

Custom Layouts - Edges Removed #547

Wu-Li opened this issue May 19, 2024 · 1 comment
Labels

Comments

@Wu-Li
Copy link

Wu-Li commented May 19, 2024

Describe the bug
When creating a custom layout according to the interface found in the Layout model, all of the edges are removed from the graph that is returned by the run function.

To Reproduce
Steps to reproduce the behavior:

  1. Set up a test component that imports ngx-graph.
  2. Create your own custom layout that extends Layout.
  3. Implement only the required functions: run(graph: Graph) => Graph AND updateEdge(graph: Graph, edge: Edge) => Graph
  4. Provide some input nodes and edges, also according to the Node and Edge models.
  5. At a minimum the run() function should process the edges to create the points array ([source: NodePosition, target: NodePosition]).
  6. Optionally, you might implement the updateEdge function similar to how it is implemented in dagre, or just return the input graph without any processing, I don't think it matters, the bug is present in either case. Unless you call updateEdge from run, I think it is only used when dragging nodes, so I don't believe this function is the culprit.
  7. Finally, in your run() function, use console.log (or you preferred logger) to log both the output graph and the graph.edges.
  8. You can see that while the graph.edges are present just before the graph is returned from run(), that when you look into the printed graph object, which if printed as an object will show its modified state even if those modifications occur after run is complete. This object will have an empty array of edges.
  9. If you use Object.freeze(graph) on the graph which is returned from run before you return it. Voila! You have your edges. If you've included your own path algorithm and mapped it to the svg:path d attribute of your edge, it will even draw the line just as you've specified. However, and perhaps this goes without saying, using Object.freeze on the graph has some unseemly side effects, you get some flicker, failed change detection, and weird node placement. Freezing just graph.edges doesn't seem to fix it either.

Expected behavior
I would expect that if the interface is implemented as specified, and the positions of the nodes are provided, and the edge.points are calculated from those positions, that this would be a sufficient minimal layout implementation and it should draw the edges. At a minimum, I would hope that the edges are not removed, so the layout could implement its own line drawing algorithm.

Screenshots
Edges

ngx-graph version
(release): 8.3.0 (https://github.com/swimlane/ngx-graph/pull/545[)](https://github.com/swimlane/ngx-graph/commit/6d3c9d3cbc84107a55d95a83f7b037617e0ea062)

Additional context
First off, I just want to add that I have been trying to troubleshoot my custom layout for months before submitting this bug. I have tried modifying the d3force layout, I've tried modifying the dagre layout (several times) and I've tried building my own layout up from scratch perhaps a dozen times or so, looking at the way the other layouts are implemented (https://github.com/swimlane/ngx-graph/tree/master/projects/swimlane/ngx-graph/src/lib/graph/layouts).

I am mainly trying to implement a graph layout that will keep nodes that have been moved by the user in the fixed position that they were dragged to. It hasn't been hard to get the nodes themselves to do this, but getting the edges to draw correctly once the nodes are moved has been extremely difficult. When I say I've been working on this for months, I'm not exaggerating, I started this project a year and a half ago, and have been coming back to this issue off and on over that year and a half, spending a week or so here and there, and giving up to come back to it later. However it is that the edges are calculated or modified by the graph component once they are delivered by the run function of the layout is not documented at all, and is working by some kind of black magic code, because generating edges with exactly identical properties as the ones generated by, for example, the dagre layout, does not produce the same results that you get from the out-of-box dagre layout. I have tried so many variations to get this to work, and whatever it is that the module is looking for from the graph returned by the layout is unclear.

@Wu-Li Wu-Li added the bug label May 19, 2024
@Wu-Li
Copy link
Author

Wu-Li commented May 21, 2024

The issue is within tick(), if you don't have an array of edgeLabels, the loop through the edgeLabels will just skip and newLinks gets assigned to your graph.edges as an empty array.

I would think that edgeLabels were optional, they are certainly treated as such throughout the rest of the module.

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

No branches or pull requests

1 participant