cytoscape / cytoscape.js

Graph theory (network) library for visualisation and analysis
https://js.cytoscape.org
MIT License
10k stars 1.64k forks source link

Straight line of connecting nodes (more than 350 nodes) disappears at a certain step when zooming in and out continuously #3258

Open brucenguyen1 opened 1 month ago

brucenguyen1 commented 1 month ago

Before you post

A request for help or a request for a how-to should be directed to Phind.

If your issue pertains to an extension, your issue should be filed in that extension's repository -- not here.

Environment info

Current (buggy) behaviour

I used Cytoscape.us to visualize a map which is a very long straight line of connecting nodes (about 900 nodes with edges between consecutive nodes), it is a sequence of activities in our process analysis tool. When zooming in and out continously, at some step, the whole map disappears, and then it appears again at the next zooming step. This happens either using mouse wheel or two buttons Zoom Out/Zoom In. It happens with default wheelSensitivity option (no setting) or setting a custom value for it (we tried 0.1, 0.2, 0.5, 1, etc.).

I debugged the code and found the issue happens in the getLayers method call, drawLayeredElements() in drawing-elements.js. At one zooming step, (usually this step has level = -1), if it returns a non-null layer and then draws the layer's offscreen canvas, it only shows an empty screen (the map disappears). If it doesn't use the layer's offscreen canvas but instead calling drawCachedElements to draw, this issue doesn't happen, and the redraw between zooming steps is smoother.

Another note is this issue only happens when the number of nodes is about 350 or more. It doesn't when the number of nodes is less than 300, but the zooming is notably not smooth, we noted a little bit interruption between zooming steps.

Please see the two videos attached, one with the original code causing the disappearing issue, and one experimenting with the fix by commenting out the code using layer's offscreen canvas to draw. The number of nodes in the video is about 900.

Disappear video: https://github.com/cytoscape/cytoscape.js/assets/12888841/d6397e16-b115-4646-b013-f4d97456294d

Smooth, no disappearing issue video: https://github.com/cytoscape/cytoscape.js/assets/12888841/8142aee2-b530-4b95-acef-81f3881b3955

Here is a screenshot of the temporary fix for this issue (drawLayeredElements in drawing-elements.js): image

At the moment, we have to use the temporary fix above. Do you think it might cause any other issues? Are there any setting or option that we can turn off offscreen canvas, we didn't want to modify directly in the code?

Desired behaviour

What do you expect Cytoscape.js to do instead?

Zooming smoothly and the map is fully displayed throught out all the zooming steps.

Minimum steps to reproduce

What do you need to do to reproduce the issue?

Create a straight line of connecting nodes with large number of nodes, usually more than 350 nodes. Visualize it, the using the mouse wheel to scroll from the lowest to the highest step.

Fork/clone this JSBin demo and reproduce your issue so that your issue can be addressed quickly and effectively:

JSBin can't save because the data used to create this issue is too big.

I attached here the HTML source used to create the issue. The file extension is changed to TXT because Github issue doesn't accept HTML.

cytoscape_test.txt

For reviewers

Reviewers should ensure that the following tasks are carried out for incorporated issues:

maxkfranz commented 1 month ago

(1) In the code you commented out in your temporary fix, if you uncomment the lines so the original code runs, what are the dimensions of the layers (bb)?

(2) Can you reproduce this if you put the nodes in a NxN-pixel grid layout?

brucenguyen1 commented 1 month ago

(1) Run the original code: layer.bb is always the below (there is only one layer): { "x1": -5.5, "y1": 94.5, "x2": 184779.5, "y2": 204.91973244869826, "w": 184785, "h": 110.41973244869826 } This issue only happens at the last zooming result when the result of getLayers is not null. In the next larger zooming result and onwards, getLayers returns null and so the offscreen canvas is not used.

image

The drawing disappears.

image

brucenguyen1 commented 1 month ago

(2) Can you reproduce this if you put the nodes in a NxN-pixel grid layout? It only happens with the long sequence of nodes as shown, and only happens when the number of nodes is about 350 or more. We've never had this issue with very large networks with Sugiyama hierarchical layout.

maxkfranz commented 1 month ago

Do you know the dimensions of the layers that the cache creates (or tries to create, in the case of some edge cases perhaps)?

maxkfranz commented 1 month ago

There's already some limit to the layer caches so that they don't get too big:

https://github.com/cytoscape/cytoscape.js/blob/b2e3f65b3b13b2af11eb3d01407fdb3ec69e6817/src/extensions/renderer/canvas/layered-texture-cache.js#L20

It looks like it only limits the area currently.

Would you try amending the checks where maxLayerArea is used to also do a sanity check on the length and width -- perhaps with some new constant like maxLayerLength?

Some experimentation may be needed to find an appropriate value.

I suspect you're running into some initialisation limitation in the browser on canvases with large lengths.