visjs / vis-network

:dizzy: Display dynamic, automatically organised, customizable network views.
https://visjs.github.io/vis-network/
Apache License 2.0
3.02k stars 367 forks source link

vis-network hierarchical sortMethod/level/layout issue #100

Open deepanshu11madan opened 5 years ago

deepanshu11madan commented 5 years ago

Screen Shot 2019-08-28 at 7 30 22 PM Does this pull request also fixes this layout issue I am seeing with my graph in the screenshot, it is assigning the 'END' node (shown by the pointer) to it's highest/upper most possible level. A lot of node points to the End node, and it would be good have the lowest position assigned to it.

Also, is there a way I can pass my own sorting method in addition to 'hubsize', 'directed'?

Thomaash commented 5 years ago

Hi @deepanshu11madan,

I don't think it would solve your problem as you have cycles in your “hierarchy”. You can however try it out with the PR version of Vis Network: https://raw.githack.com/Thomaash/vis-network/issues/4/dist/vis-network.js . Also a bigger image would be appreciated.

Custom sorting method is being discussed in #84 but is not yet implemented.

deepanshu11madan commented 5 years ago

Thanks Thomaash for getting back to me. Is there any plans for the custom sorting enhancement discussed in #84?

deepanshu11madan commented 5 years ago

Also, I did try PR version of Vis-network, it didn't make the the graph i added a screenshot for.

Custom sort would really help, i am looking to have something similar to topological sort for cyclic graph, for example, i found this example of a network graph:

Screen Shot 2019-08-30 at 8 49 07 PM

Do you think if anything similar to this screenshot is possible with vis.js?

Thomaash commented 5 years ago

Possible yes. You can always explicitly set the levels or just position your nodes manually. The sharp edge corners can be achieved by using hidden nodes in the corners. However there is no way how to do this automatically at the moment. The sort from #84 is mean to order nodes direct descendants horizontally so that's not helpful to you.

I think that this is not hierarchical layout at all. Different layouting engine should handle your case.

deepanshu11madan commented 5 years ago

yeah sharp edges isn't very important. More like getting the layout like that. I guess i can calculate levels myself, Do you know if there's a library to calculate levels? or do recommend any good efficient ways of traversals? there's d3 graph lib, d3-dag layouts that would work, https://observablehq.com/@erikbrinkman/d3-dag-topological. but I really vis-network, and see if i can find a way to achieve my use case with vis.js

deepanshu11madan commented 4 years ago

@Thomaash I calculated the layers and coordinates for the nodes, and I was trying your suggestion to use hidden nodes for the edge layout, but when i hide the dummy nodes , the edges are also hidden, is that expected?

Thomaash commented 4 years ago

I've never actually used hidden nodes before so I'm not sure how exactly they work. The documentation on these is very short so maybe this is how they're supposed to work. If so we should add it to the docs.

deepanshu11madan commented 4 years ago

yeah I am not sure either, from what I knew or read in a post , dynamic edges work using hidden dummy nodes, but not able find any documentation around it.

Is there any other way you can suggest to have a custom layout for edges like that?

Thomaash commented 4 years ago

The only other thing that comes to my mind is to try regular nodes with zero size or tiny 100 % transparent images.

deepanshu11madan commented 4 years ago

yeah i was thinking that too, but then i will loose the edge click events functionality, there will be multiple edges instead of once edge between two nodes.

Is there an example or something you might be able to point me to draw my own edge on canvas, using the ctx, and that way i can provide coordinates to it. I am assuming library does something similar to draw edges, i am just looking to somehow override it and pass my own coordinates of the control points for the edge.

deepanshu11madan commented 4 years ago

something like exposing this "Compute the additional points the edge passes through" in https://github.com/visjs/vis-network/blob/master/lib/network/modules/components/edges/cubic-bezier-edge.ts

So we can pass the additional points the edge passes through, do you think this is something that can be done on the library side?

Thomaash commented 4 years ago

Sadly the code expects one or two points so it would be pretty inflexible. Making them configurable in user friendly way will likely require some work. However adding this without smooth edges should be quite simple. Though I haven't looked into it yet.

Regarding the edge you can take inspiration from https://thomaash.github.io/me/#/canvas (code: https://github.com/Thomaash/me/blob/02303744befed1aa4bb187eaba6330cb5ab2ea59/src/components/Vis.vue#L652). When you try to drag a computer the ports will move to. The trick is that in the event handler the selection is simply expanded. You can do the same thing in your app to select the whole edge (you can use selectNode and selectEdge events and then network.selectNodes(hiddenNodeIds, true) to select the whole edge) even though it is technically speaking multiple edges with nodes in between (the user will never know).

deepanshu11madan commented 4 years ago

Thanks @Thomaash. Yeah I can try this other way, but it might be very hacky, I'll also have to find a way to show edge label with those multiple edges with hidden nodes, I also have an edge traffic animation and who knows there might be other issues I might have to handle.

And regarding your point of adding this without smooth edges would be simple, how much work do you anticipate? Is that something you have bandwidth to try? Or is that something I can do or will need to be done on the library side?

A little more context: I am using https://github.com/dagrejs/dagre/wiki, is a really good layout for directed graphs based on Sugiyama layered graph algorithm. dagre's focus in on graph layout only, this means that I need something to actually render the graphs with the layout information from dagre, and I am using visjs to render my graph.

deepanshu11madan commented 4 years ago

Sadly the code expects one or two points so it would be pretty inflexible. Making them configurable in user friendly way will likely require some work. However adding this without smooth edges should be quite simple. Though I haven't looked into it yet.

Regarding the edge you can take inspiration from https://thomaash.github.io/me/#/canvas (code: https://github.com/Thomaash/me/blob/02303744befed1aa4bb187eaba6330cb5ab2ea59/src/components/Vis.vue#L652). When you try to drag a computer the ports will move to. The trick is that in the event handler the selection is simply expanded. You can do the same thing in your app to select the whole edge (you can use selectNode and selectEdge events and then network.selectNodes(hiddenNodeIds, true) to select the whole edge) even though it is technically speaking multiple edges with nodes in between (the user will never know).

Actually Rob Spencer describes what might be a way to do it? http://scaledinnovation.com/analytics/splines/aboutSplines.html. Here's the code with a demo https://jsbin.com/ApitIxo/2/edit?html,output

deepanshu11madan commented 4 years ago

or the other way described here https://stackoverflow.com/a/15528789, does any of these sound like something that could allow taking it in array of points and draw an edge? I'll also take a shot and play with the library code to see if i can make it work somehow.

deepanshu11madan commented 4 years ago

@Thomaash I am not able to make it work, you mentioned "However adding this without smooth edges should be quite simple." how would that be ?

Thomaash commented 4 years ago

Well, without smooth edges you can just connect node to node with straight lines. That shouldn't be difficult.

deepanshu11madan commented 4 years ago

it is not the same, so i have basically edge control points calculated using dagre layout which follows Sugiyama layred graph algorithm, and avoids edge overlapping, straight lines would cause edge overlapping