almende / vis

โš ๏ธ This project is not maintained anymore! Please go to https://github.com/visjs
7.84k stars 1.48k forks source link

Grouping nested nodes together #3293

Closed arunkumarpro1 closed 7 years ago

arunkumarpro1 commented 7 years ago

Hi,

Is there any way to group nested nodes together under a super node in vis.

I want to achieve the following behavior.

design

I want to nest the nodes Node 11, Node 12, Node 13 within Node 1. So, when I click on Node 1 (diagram (A)), I would like to display the nested nodes and also extend the edges to the nested nodes (as shown in (diagram (B)).

Could anyone suggest me an idea to implement the above feature using vis?

Thanks in advance.

wimrijnders commented 7 years ago

Well, at least diagram A can be done. Hiding nodes in a super node is called clustering in vis.Network, see for instance this demo. Clicking the super node to display the contained nodes is also possible.

However, to display them in a way such as diagram B is currently not possible. The official party line would now be 'feel free to implement it yourself', but there appears to be growing interest for this kind of containment; see e.g. the recently reopened #2139 and #3283 from 2 days ago. So it may be worthwhile to seriously consider this functionality.

...but try as I might, I can not think of a way to make this work right now. I've just spent some serious thinking time on this, and all I succeeded doing was stare blankly at the screen. If I have any insights, hackish or otherwise, I will share them here.

wimrijnders commented 7 years ago

Near duplicate of #2139.

arunkumarpro1 commented 7 years ago

@wimrijnders Thanks for your reply and a very good explanation. It is really very helpful. Please let me know if you find any hack to do the above feature.

arunkumarpro1 commented 7 years ago

@wimrijnders But I really could not understand how the issue https://github.com/almende/vis/issues/2319 is related to my problem.

I guess you mean the issue #2139

wimrijnders commented 7 years ago

Oops ๐Ÿ˜Š Typo. It's #2139. Sorry, fixing above links as well.

arunkumarpro1 commented 7 years ago

:-) Yea.. I got it :+1:

arunkumarpro1 commented 7 years ago

@wimrijnders Another question. How to make the label bold by default?

Sorry. I knew that this question is nowhere related to this issue.

bradh commented 7 years ago

@arunkumarpro1 Perhaps you could try this in CSS, independent of vis.js?

arunkumarpro1 commented 7 years ago

@bradh Is it not possible to do that using the font object in vis options?

wimrijnders commented 7 years ago

Setting default bold font is actually not possible. The best way I can think of to do it is set option:

nodes: {
  font: {
    multi: true
  }
}

And then add <b>...</b> tags around all label texts.

@bradh using CSS is not possible here; it's because networks are drawn to canvas, meaning it's converted to a graphic format.

arunkumarpro1 commented 7 years ago

@wimrijnders Thanks a lot. It works.

wimrijnders commented 7 years ago

Coming back to the original issue, I really don't know how to make this work. If you do find a solution, please share.

arunkumarpro1 commented 7 years ago

Even I am not sure about it. I am still working on it. Will let you know once I am able to complete it.

wimrijnders commented 7 years ago

Great. I'll let you know here if I have any insights on this as well.

AndrewMut commented 7 years ago

@arunkumarpro1 That is how I am going to do same thing: 1.Get data of all selected nodes 2.Get all positions of selected 3.Create 2 arrays for X and Y 4.Sort X by biggest number and smallest 5.Repeat for Y 6.Add nessesary value to positions to prevent drawing frame through the nodes 7.Use afterDrawing to draw custom lines to frame them It's not directly what are u looking for, but at least something to start from.

wimrijnders commented 7 years ago

@AndrewMut you know, that might actually work! Is that in the light of a currently open issue here?

Thanks for applying your brainpower on this, I am unable to solve everything put here. I really appreciate it when others take the effort. This is something that can benefit many people.

AndrewMut commented 7 years ago

@wimrijnders Yup, it's in light of it, after You opened my eyes on afterDrawing vis become much more flexible for me.

wimrijnders commented 7 years ago

Glad to be of use!

arunkumarpro1 commented 7 years ago

@AndrewMut Thanks for sharing your insights. I will work on them and share my progress here.

AndrewMut commented 7 years ago

@arunkumarpro1 Thanks, would be interesting to see!

arunkumarpro1 commented 7 years ago

@AndrewMut Also if you have any working code, can you share it here for reference?

AndrewMut commented 7 years ago

@arunkumarpro1 I do not have, but if u would need a help, let me know plz, I'll try to write something to help you with that.

arunkumarpro1 commented 7 years ago

@AndrewMut Thank you very much. I am working on the clustering part right now. I might need some help in drawing the boundaries around the nodes. I will let you know once I start working on that.

wimrijnders commented 7 years ago

Is there any way to cluster a single node? In my requirement even if there is only one node that satisfies the cluster requirement, I have to embed it within a cluster

Yes, there is. Set option clusterNodeProperties.allowSingleNodeCluster: true and then proceed as normal. Update: But I think you found that out for yourself, since the comment with the question has disappeared ๐Ÿ˜„.

arunkumarpro1 commented 7 years ago

@wimrijnders Anyways, thanks a lot for the answer. I totally forgot the that you will be notified by my comment :P

Another question: I could not find the answer this time :) Is there any way to get hold of the canvas context, other than the render events ('beforeDrawing'/'afterDrawing')?

wimrijnders commented 7 years ago

Officially no, it is not exposed in the API. However, this is javascript and nothing whatsoever can stop you from accessing it by force.

If you don't mind doing unsupported things (but this is very unlikely to change), and you really really need direct access, it's at network.canvas.frame.canvas.

Now, please forget that I was the one who told you this ๐Ÿ˜ถ .

arunkumarpro1 commented 7 years ago

@wimrijnders haha. I will never say this to anyone :no_mouth:

Also, I am skeptic about the working of 'afterDrawing' render event. Initially, I assumed that it will be called only once after the drawing is completed on the canvas. But after implementing it, I observed that the event is being triggered multiple times during stabilization.

Is my understanding right?

wimrijnders commented 7 years ago

Ooh that's new for me. Never realized it worked that way. You may have uncovered a bug here. But it will have to wait I'm afraid; vacation is breaking over me.

arunkumarpro1 commented 7 years ago

@wimrijnders Sorry for bugging you. Enjoy your vacation :+1:

We can discuss this once you are back from vacation.

arunkumarpro1 commented 7 years ago

Hi @wimrijnders @AndrewMut I did get a chance to work on this feature this week. This is what I have achieved till now.

Initial layout (with clustered nodes):

image

Cluster opened on node selection:

image

All Clusters opened on zoom:

image

arunkumarpro1 commented 7 years ago

@wimrijnders I am more concerned on the overlapping arrows. I tried a lot of physics configurations (hierarchicalRepulsion) , the layout remains the same every time.

This is my options object:

let options = {
    layout: {
        randomSeed: undefined,
        improvedLayout: true,
        hierarchical: {
            enabled: true,
            levelSeparation: 100,
            nodeSpacing: 100,
            treeSpacing: 200,
            blockShifting: true,
            edgeMinimization: true,
            parentCentralization: true,
            direction: 'UD', // UD, DU, LR, RL
            sortMethod: 'directed' // hubsize, directed
        }
    },
    autoResize: false,
    edges: {
        smooth: false,
        color: '#000000',
        width: 0.5,
        arrows: {
            to: {
                enabled: true,
                scaleFactor: 0.5
            }
        }
    },
    physics: {
        enabled: true,
        hierarchicalRepulsion: {
            centralGravity: 0.0,
            springLength: 75,
            springConstant: 0.01,
            nodeDistance: 120,
            damping: 0.09
        },
        stabilization: {
            enabled: true,
            iterations: 1000 
        }
    }
};
arunkumarpro1 commented 7 years ago

Hi @wimrijnders .. Sorry to bug you again. Do you have any idea about how I can avoid overlapping the edges?

I tried making a lot of changes to the hierarchialRepulsion physics config. I also tried to reduce the length of the edges by adjusting the length field within edges option / spring length with in hierarchialRepulsion physics config. Both of them did not have any effect on the edges.

wimrijnders commented 7 years ago

I'm afraid there's no short-term solution for this. I will need to dive into this code to figure out how to improve this. I've also got other bugs to deal with. Sorry.

wimrijnders commented 7 years ago

I'm still waiting for the brainwave to hit me, that will fix this....

arunkumarpro1 commented 7 years ago

Hi @wimrijnders , right now I will be glad if you could give some ideas about how to avoid those overlapping edges. The graph looks so clumsy as follows

screen shot 2017-08-31 at 2 49 13 pm

Is there anything which I can do for placing the child nodes closer to their parent nodes? If you look into the above picture, most of the child nodes are placed very far away from their parent nodes which ultimately leads to the overlapping of edges.

wimrijnders commented 7 years ago

OK, so the thing to keep in mind, is that currently in the drawing methods, the order is retained for nodes as well as edges. Thus the positioning within the network can be influenced by crafty ordering of nodes/edges within the DataSet.

So for example what you could do in the given image, is to place ALL DAEMONS in front of DROPPED PACKETS. Consecutive use of this should clean up the layout considerably.

If I look at a previous network here above, the network looks quite clean to me. The layout should be handled fine no problem on setup. Strange. Would you mind sharing the node/edge definitions as well? A cut-down version showing the funky edges is perfectly fine.

Sorry about the lack of interaction, I'm back on a project and have much less time available.


Update: Ah, wait, I think I get it. The nodes in the given graph are all clusters, correct? There might be some interaction issues with that. In any case, a demo network would be appreciated.

arunkumarpro1 commented 7 years ago

@wimrijnders By any chance are you planning to implement this feature in the library?

The method which I used above leads to a lot of problems. For example: If there is a node which does not have any edges, it is placed somewhere far from the graph and rectangular boundary is being extended till there.

nfigay commented 6 years ago

Hi @arunkumarpro1 ,

I'm trying doing similar thing.

Some rough ideas:

Did you explore the way cola.js is doing similar thing, in particular looking at http://marvl.infotech.monash.edu/webcola/examples/SucroseBreakdown.html? So far I understood, cola.js performance are below vis.js, in particular with huge graphs. But may be something can be imagine from their way of doing for nesting nodes of a cluster in a container, preventing the nodes to be too far away.

Other idea: can it be envisage to consider a nested box as something being able to have some attraction on the nodes of the cluster (considering the centre of the nested box), and being consider by the attraction algorithm. Unlike a traditional node, its shape will be draw dynamically using you algorithm, but it will be able to attract it's content, being as a consequence more "contracted". Can it be done creating "containing" edges which will not be displayed?

I'm interest to know how you draw the boxes of the clusters: Dynamic SVG? Other?

arunkumarpro1 commented 6 years ago

Hi @nfigay. Thanks for your comment. I will have a look at the features provided by cola.js.

I don't use SVG to draw boxes. I use canvas draw methods to draw lines surrounding the nodes of the same cluster.

nfigay commented 6 years ago

Hi @arunkumarpro1 , thanks for you feedback. Let me know if you find what you need in cola.js ;)

alanchenchen commented 6 years ago

@arunkumarpro1 Hi ! I have met the same problem as yours, would you please tell me how you show multiple nodes in a group? emmm,i wanna show multiple nodes in a moveable group.

arunkumarpro1 commented 6 years ago

Hi @alanchenchen,

The steps have been clearly explained by @AndrewMut in the previous comments. I have just implemented the same idea.

Let me know if you need anything else.

alanchenchen commented 6 years ago

Thanks for your fast reply. @arunkumarpro1

Should i have to use the canvas to draw lines to frame multiple nodes by myself? Well,the group nodes could be moved ? I wanna to move the group but not move the nodes one by one.

arunkumarpro1 commented 6 years ago

Yes, I have used canvas draw methods to draw lines surrounding the nodes within a group. Before that, we have to find out leftmost and the rightmost nodes of the group to define the x and y co-ordinates of the line that we are going to draw.

By default, both the group (cluster) nodes and the individual nested nodes can be moved. In order to curb the movement of the individual nodes, you might have to change the options. Right now, I am not sure how achieve this. I will let you know once I have time to go through my code.

All the best.

alanchenchen commented 6 years ago

Thanks so much! I'm very surprised that you reponse to me at the same time while i'm asking for help .:stuck_out_tongue_closed_eyes: Please don't mind my poor English.:rofl: since of i'm a Chinese graduate..

alanchenchen commented 6 years ago

@arunkumarpro1 Hi! I'm sorry to bother you .I'm in need now that i've implemented the lines surrounding selected nodes. But i have no idea how to set the group move together if i drag the group...Could i have to set the option 'Cluster'?

ghost commented 6 years ago

Hi I was wondering if visNetwork would be able to replicate the layout like http://marvl.infotech.monash.edu/webcola/examples/SucroseBreakdown.html without the collapsing nodes feature?

AndrewMut commented 6 years ago

Seems like its vis under the hood of that graph

ัั€, 25 ะธัŽะป. 2018 ะณ., 4:20 KC notifications@github.com:

Hi I was wondering if visNetwork would be able to replicate the layout like http://marvl.infotech.monash.edu/webcola/examples/SucroseBreakdown.html without the collapsing nodes feature?

โ€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/almende/vis/issues/3293#issuecomment-407601916, or mute the thread https://github.com/notifications/unsubscribe-auth/AcZrI0xO1Ohm053ouCbFHSBTWqihcaxVks5uJ8ffgaJpZM4OjNf2 .

Vincent-CIRCL commented 5 years ago

It's probably not vis under the hood, as it is largely mentioned on the given page that this is the output of a research project : http://users.monash.edu/~mwybrow/dunnart/ Given available client-side code, it's seems largely based on D3.

Vincent-CIRCL commented 5 years ago

If you want a similiar feature as requested by OP, you may look there. I implemented a similar idea : https://github.com/Vincent-CIRCL/visjs_classificator/commit/73d7b73db0f5b667e3bfd3eff99cd357d468fad5

image