Dynamic/scrollable container size in Cytoscape (+ cy.fit() issues) - cytoscape.js

So I've been giving Cytoscape a try recently. My project's goal is basically a collaborative graph that people will be able to add/remove nodes to/from, making it grow in the process. The graph will include many compound nodes.
Most of the examples I've seen use container div that takes 100% of the screen space. This is fine for "controlled" graphs but won't work in my case because its size is intended to be dynamic.
Here's a JSFiddle using the circle layout within a fixed 3000px/3000px container:
https://jsfiddle.net/Jeto143/zj8ed82a/5/
Is there any way to have the container size be dynamic as opposed to stating it explicitly? Or do I have to compute the new optimal container size each time somehow, and then call cy.resize()?
edit: actually, using 100%/100% into cy.fit() might just work no matter how large the network is gonna be, so please ignore this question is this is the case.
Is there a recommended layout for displaying large/unknown amounts of data in a non-hierarchical way that would "smartly" place nodes (including compound ones) in the most efficient way possible, all the while avoiding any overlap? (I guess that's a lot to ask...)
Why doesn't cy.fit() seem to be working in my example? I'm using it both at graph initialization and when CTRL+clicking nodes (to show closed neighborhood), but it doesn't seem to like the 3000x3000px container (seems better with 100%x100%).
edit: also ignore this question if you ignored 1., as again it seems fine with 100%/100%.
Any help/suggestions would be greatly appreciated.
Thank you very much in advance.

TLDR: It's (1).
Cytoscape has a pannable viewport, like a map. You can define the dimensions of the viewport (div) in CSS. What's displayed in the viewport is a function of the positions of the nodes, the zoom level, and the pan level -- just like what is visible in a map's viewport is a function of zoom, pan, and positions of points of interest.
So either you have to
(a) rethink your UI in terms of zoom and pan and use those in-built facilities in Cytoscape, or
(b) disable zoom and pan in Cytoscape (probably stay at (0, 0) at zoom 1) and let the user scroll the page as you add content to the graph and resize its container div to accommodate the new content.

Related

Cytoscape with Haystack or Bezier Layout: How to Shorten Edge Length

I am new to Cytoscape, and I have a working graph, but my nodes are very far apart. While I realize Cytoscape generates everything dynamically, it seems like it should be possible to say "use half as much space between nodes".
This demo:
http://js.cytoscape.org/demos/2ebdc40f1c2540de6cf0
seems to show that you can dynamically change the lengths of edges. However, when I look at the source code (https://gist.github.com/maxkfranz/2ebdc40f1c2540de6cf0), I can't figure out how it works.
It seems like the demo is passing a edgeLength option to makeLayout, but the Cytoscape documentation doesn't even mention edgeLength as a valid option.
Can anyone more experienced with Cytoscape point me to how I can shorten the edges between my nodes?
Each layout is different, and the combination of values you use depends on what effect you're trying to create.
Force-directed layouts usually have a weight that affects edge length by spring forces.
In general, the bounding box can affect the length.
Some layouts have spacing adjustment multipliers.
Some layouts have other, miscellaneous options that affect edge length.
You have to look at the options for the layout you're interested in and experiment with them to get the effect you're looking for. That holds true for every layout for every graph theory lib, Cytoscape included.

Cytoscape.js - not adding all "ele" at startup

Situation:
I have a graph with 500 nodes (say 1000 edges), with a root.
Goal:
I want the user able to progress in the graph, by cliking on nodes, showing the edges and new nodes around.
Way I do for now:
I first load all elements in memory (the entire json), then use ele.remove() for each nodes/edges. And just keep visible the root and around.
Question 1)
Is there any solution to choose the element to display at startup.(and not removing them later)
Question 3)
Removing the element does not free memory. Is there a solution to use memory for only elements that are not removed ?
Question 2)
Are there a smarter/better approach to do the trick ?
Thanks a lot
Using classes with visibility-related properties, as mentioned, would work.
You can also animate elements and animate the viewport to highlight parts of the graph.

position edge labels using cytoscape.js

Due to the nodes and edges between nodes, the breadthfirst algorithm is positioning nodes in such a way that labels on the nodes are overlapping one another. Is it possible to have the algorithm either position the nodes or the edge labels so they don't overlap, or attempt to minimize overlap?
You may be interested in label autorotation for edges, planned for 2.4 and implemented in unstable. As for the logic you'd like in the layout itself, it may be a too tight coupling of implied rendering behaviour to the layout. Whereas things like node.outerHeight() can be taken into consideration directly and explicitly in layouts, this would rely on the layout assuming certain rendering behaviour.
I think there's a factor option for spacing the nodes farther apart in the breadthfirst layout, and if you want to discuss other new ideas like it I would be happy to discuss it in a ticket in the tracker.
Thanks

cytoscape.js redraw after hiding nodes

I'm using Cytoscape JS to create a network. This is a large network and I need to hide some nodes to be more readable, but I can't redraw my network not including the hiding nodes.
How can I redraw using auto-layout after hiding some nodes?
It's not clear to me exactly what you mean. An example would probably help. There are different semantics for hidden versus removed elements, and it sounds like perhaps you want the elements removed.
I ended up solving similar problem by just having two instances of Cytoscape.js on a page. First is headless one (invisible, with no HTML-representation) that stores all data I have. Second one is visible and has a subset of objects I want to be visible and layouted at the moment.
Copying elements between instances is extremely easy, like:
cy.add(datacy.$('#elem1'));

Displaying large networks with cytoscape.js

I'm trying to use cytoscape.js to display large networks with hundreds of nodes. However, cytoscape.js seems to always want to constrain everything to the viewport, which can be problematic if there are too many nodes crowding up the viewport. I'm using the "arbor" layout and during the force-directed simulation the nodes don't seem to exit the viewport's initial boundaries, even if I zoom out at initialization. Setting arbor's fit option to false also doesn't seem to do anything. What is the preferred way to go about displaying large networks in cytoscape.js?
There are other layouts you can use. I'll look into the issue with arbor, though https://github.com/cytoscape/cytoscape.js/issues/307