cytoscape / cytoscape.js

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

background image sometimes doesn't render until node is clicked #1511

Closed JGMarshall closed 8 years ago

JGMarshall commented 8 years ago

Hi,

I'm using:

... And I'm encountering what I believe may be a bug regarding the 'background-image' node style. Specifically, sometimes when rendering a graph only some of the nodes properly display the background image. Clicking on the node in question always fixes this (for that individual node).

I'm receiving no errors or warnings on the debug console of either Chrome or Edge.

JSBin reproduction link here: https://jsbin.com/zolic/edit?js,console,output

I suspect that this may be related to the way image caching is handled. Chrome never exhibits this when I pre-load the images before creating the cytoscape object and set the max-age in the caching header to a large value. Edge, on the other hand, seems to always have this issue regardless of pre-load or cache behavior and always issues an http request for each image to see if it might have changed.

the rendered window (in Edge) ends up looking like this (note that all nodes in "Network Devices" and "USB Controllers" have the same background-image ctyoscape style property set, but only one of each is rendering their background image).

missing-background-images

maxkfranz commented 8 years ago

Thanks for the demo. It made it much faster to debug the issue.

Try the snapshot : http://js.cytoscape.org/download/cytoscape.js-snapshot-b33f4cb69e-1472752151955.zip

Let me know if it works for you or if you have any issues with it.

Thanks

JGMarshall commented 8 years ago

A quick test confirms that your snapshot fixed the issue for me on Chrome, Edge, and FireFox.

Thanks for your help!

maxkfranz commented 8 years ago

Great; thanks

omeriko commented 7 years ago

I'm facing the same issue with Cytoscape.js 2.7.7, is there a regular version that includes the fix, since we want to work with bower?

JGMarshall commented 7 years ago

The version you are using is older than the one I made the original report on, and Max has tagged it in a milestone released in September of last year. I don't see the point you're trying to make?

omeriko commented 7 years ago

When you say man has "tagged it in a milestone released in September" im not sure i understand what u mean? Does "tag" meas "version" that is some version number of the library that includes that fix?

leots commented 7 years ago

Hello all, I am using version 3.1.1 of Cytoscape, and this issue still appears for me sometimes under the following circumstances: using latest version of Firefox, the Cola.js layout, and it happens most often when having the development tools open. I have a demo here: https://jsbin.com/hinuhowoji/edit?js,console,output It appears to not happen in Chrome at all, or when using Cytoscape 2.7.X versions after 2.7.9. Is this a misconfiguration on my end, or is there some other cause?

Thanks a lot!

Edit: it seems to be reproduced more often when you have the "disable HTTP cache when toolbox is open" in the Firefox console's settings

maxkfranz commented 7 years ago

The Firefox console says you didn't register Cola:

"Can not apply layout: No such layout `cola` found; did you include its JS file?"
leots commented 7 years ago

Hmm, can you try again? I didn't change anything but the lines that include Cola.js and Cytoscape cola from rawgit are in the HTML... On the 2 computers that I tried the demo link, the nodes are using Cola and the problem is shown, without any error in the console.

maxkfranz commented 7 years ago

@leots Your SVG is incorrect for Firefox. Firefox doesn't properly handle SVGs with a viewbox.

dbrodie commented 7 years ago

This is happening to me intermittently with cytoscape 3.1.1 on Chrome and with the dagre layout. I will sit on the page and do a Hard Reload and once every ~5 times it will happen. Clicking the node or restyling the graph will fix it. My nodes are a bit complicated with a pie, image and background/border.

Currently, to fix it, I am reapplying the styling to the graph in dagre's stop function.

maxkfranz commented 7 years ago

@dbrodie Do you have a demo?

dbrodie commented 7 years ago

Sorry I was busy getting the code working, I'll sit on it next week to try and create a reproducible demo.

buffpojken commented 7 years ago

I'm having repro of this reliably as well on 3.1.4, see linked movie (please mute the sound - I'm travelling so recorded on a train) - https://www.youtube.com/watch?v=4ej2o6n8be0&feature=youtu.be

When the user enters "123" and hits the green button, I perform a Bellman-Ford traversing the graph from current node, calculating some weights based on items in data() and then revisits all nodes and add/remove a class setting the background-image to a lock based on calculated weight. Any kind of styling change - such as having a style-change on hover (as shown by the smaller, yellow node) refreshes the image correctly, as does clicking.

What I believe to be the relevant styles:

          {
            selector: 'node',
            style: {
                'width': '120', 
                'height': '120',
                'background-color':'#5a5a5a', 
                'border-opacity':0,
                'background-image': function(el){
                    if(el.data('image')){
                        return el.data('image');
                    }else{
                        return "none";
                    }
                }, 
                'z-index': 2,
                'background-width': 'auto', 
                'background-height':'auto',
                'background-fit': 'cover'       
            }
          },
          {
            selector: '[metaLockedBy="locked"], [lock_state="locked"]', 
            style: {
                'background-image': function(el){
                    if(el.data('image')){
                        return el.data('image') +  ' /assets/images/theme-2/icons/graph/node-locked.png';
                    }else{
                        return ['/assets/images/theme-2/icons/graph/node-locked.png'];
                    }
                }
            }
          }, 

Might this be related to using a function for setting the value? Or having variously one / two background images?

maxkfranz commented 7 years ago

I tried this

.selector('.foo')
  .css({
    'background-width': 'auto',
    'background-height':'auto',
    'background-fit': 'cover',
    'background-image': function(n){
      if( n.data('weight') > 20 ){
        return 'images/gnu.svg';
      } else {
        return 'images/tux.svg';
      }
    },
  })
.selector('.bar')
  .css({
    'background-fit': ['cover', 'cover'],
    'background-image': function(n){
      return [ 'images/gnu.svg',  'images/tux.svg' ];
    }
  })

No combination of cy.nodes().toggleClass('foo') or cy.nodes().toggleClass('bar') breaks anything. Maybe you have a problem with reliability of image availability? Each fresh element render will try to reload a failed image iirc.

buffpojken commented 7 years ago

Nope, I'm very sure it's not an image-issue because it is only when this specific class-change happens. We have non-function based image changes which are 100% reliable.

I'll see if I can isolate the issue - but I have verified using other images without any change/fix in behavior.

trustao commented 7 years ago

I have the same problem. When I zoom or click on the operation, the image is rendered. How can I solve this problem?@JGMarshall

buffpojken commented 7 years ago

Okey, I have more info. I have 100% repro when the selector used is only data-based, as in:

{
selector: '[metaLockedBy="code"], [lock_state="code"]', 
  style: {
   'text-opacity': 1,
   'background-image': function(el){
      if(el.data('image')){
        return el.data('image') +  ' /assets/images/theme-2/icons/graph/node-passwd-protected.png';
      }else{
        return ['/assets/images/theme-2/icons/graph/node-passwd-protected.png'];
      }
    }
  }
}

but if I switch to using classes instead, it works just fine?

maxkfranz commented 7 years ago

@buffpojken Do you have a standalone demo that reproduces your issue, or is it only in your app?

buffpojken commented 7 years ago

I’ll see if I can extract it!

brassard commented 6 years ago

@dbrodie : did you ever fix your issue with this? I'm seeing identical behavior.

brassard commented 6 years ago

FYI @maxkfranz : the behavior described in the comments from @leots and @dbrodie have surfaced for us in Firefox after upgrading from 2.4.1 to 3.2.2.

The graph uses cola and using spread instead renders correctly.

We've also seen only the end arrows of the edges show up on a rare occasion. 😳

So in summary:

brassard commented 6 years ago

Also, clicking on a node in the graph shows it, but also occasionally shows other nodes in the graph (not always adjacent). In the case where only the edge arrows showed up, clicking on the nodes never showed the svg background images

This seems to indicate that some kind of rendering queue may not be draining properly and selection triggers some number of render events to be emitted.

Sort of shooting in the dark here, but maybe this would ring a bell for somebody.

buffpojken commented 6 years ago

Hmm. Sorry for butting in again - but I just realized we actually found a workaround for our version of this issue by changing the relevant styling changes to use explicit classes instead of data-selectors, and then (due to other, unrelated refactoring) separating the removal of the "outdated" classes and the adding of the new, relevant ones into two separate method calls - just after one another so still within the same context and similar.

brassard commented 6 years ago

Thanks @buffpojken.

Still sounds like a bug in cytoscape or cytoscape-cola.js, since things appear randomly on node click. I don't know enough about how styling events are triggered in the layouts to know why this might happen.

maxkfranz commented 6 years ago

Maybe related to #1998?

Does this resolve it? https://github.com/cytoscape/cytoscape.js/files/1496713/build.zip

maxkfranz commented 6 years ago

@brassard I'd need to see a demo with the exact data, layout options, etc. There are too many variables that can affect rendering behaviour for me to try to reproduce your test case from scratch.

brassard commented 6 years ago

Yea... I know I need to boil it down more to get a resolution. Still plugging away... going to try a few more avenues. Will take a look at these links too. Thanks.

brassard commented 6 years ago

@maxkfranz I updated the original demo in this ticket to use cytoscape-cola layout and grab the versions that we are currently on: http://jsfiddle.net/g83Lpaxh/11/

Interestingly, the behavior shows up for both Chrome and Firefox. There is some caching that fixes it on some subsequent loads, but with the dev tools open and cache disabled, it repeats reliably.

UPDATE: Here is a working (failing) version with the current masters of cytoscape, cytoscape-cola, and webcola: http://jsfiddle.net/g83Lpaxh/13/

You'll see that that the bgimages fail to load sporadically or all the time. They load on click.

maxkfranz commented 6 years ago

@brassard This has a completely separate cause as compared to @JGMarshall's issue. I've created a separate ticket: https://github.com/cytoscape/cytoscape.js/issues/2026

brassard commented 6 years ago

Thanks @maxkfranz !