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
Related
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.
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.
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
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'));
I've noticed that when dynamically creating a large canvas (6400x6400) that quite alot of the time nothing will be drawn on it, and when setting the canvas to a small size it works 100% of the time, however as I don't know any better, I have no other choice than to try and get the large canvas working correctly.
thisObj.oMapCanvas = jQuery( document.createElement('canvas') ).attr('width', 6400).attr('height', 6400).css('border','1px solid green').prependTo( thisObj.oMapLayer ).get(0);
// getContext and then drawing stuff here...
The purpose of the canvas is to simply draw a line between two nodes (images), which are within a div container that can be dragged around (viewport I think people call them).
What I "think" may be happening is that on a canvas resize it emptys the canvas, and that is interfering with the context drawing, as like I said previously it works all the time when the canvas is alot smaller.
Has anyone experienced this before and/or know any possible solutions?
That is an enormous sized canvas. 6400 x 6400 x 4 bytes per pixel is 156 MB, and your implementation may need to allocate two or more buffers of that size, for double buffering, or need to allocate video memory of that size as well. It's going to take a while to allocate and clear all that memory, and you may not be guaranteed to succeed at such an allocation. Is there a reason you need such an enormous canvas? You could instead try sizing your canvas to be only as large as necessary to draw the line between those two divs, or you could try using SVG instead of a canvas.
Another possibility would be to try dividing your canvas up into large tiles, and only rendering those tiles that are actually visible on the screen. Google Maps does this with images, to only load images for the portion of the map that is currently visible (plus some extra one each side of the screen to make sure that when you scroll you won't need to wait for it to render), maintaining an illusion that there is an enormous canvas while really only rendering something a bit bigger than the window.
Most browsers that implement HTML5 are still in early beta - so it's quite likely they are still working the bugs out.
However, the resolution of the canvas you are trying to create is very high .. much higher than what most people's monitors can even display. Is there are reason you need it quite so large? Why not restrict the draggable area to something more in line with typical display resolutions?
I had the same problem! I was trtying to use a big canvas to connect some divs. Eventually I gave up and drew a line using javascript (I drew my line using little images as pixels- I did it with divs first, but in IE the divs came out too big).