cytoscape / cytoscape.js

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

cytoscapeJS- visually highlight hidden nodes in neighborhood #969

Closed AjitPS closed 9 years ago

AjitPS commented 9 years ago

Can I display a shadow/ overlay effect of a specific shape on a node ?

I am using cytoscapeJS to generate small network graphs (of 50-100 nodes, majority of which are hidden when the graph is 1st generated). In the graph, nodes which have hidden nodes in their neighborhood are highlighted visually. I am using the neighborhood() to get all the nodes connected to each node and if hidden nodes exist, I am using addClass() to add a basic shadow effect, for now (was earlier using overlay), on the node.

I noticed an example of the Cola layout (http://marvl.infotech.monash.edu/webcola/examples/browsemovies.html) that uses D3.js to show small, spikes over the nodes, on a mouseover event, and the number of spikes correspond to the number of nodes connected to the selected node. Can something like this be done with cytoscapeJS ?

If not, is there a way to display the number of hidden nodes (numerical value as a label) alongide the shadow/ overlay effect ? Thanks.

maxkfranz commented 9 years ago

Spike state:

(1) Use a circle layout for the neighbourhood, with a small radius and centred on the node of interest.

(2) Make the neighbourhood nodes opacity: 0.

(3) Make the neighbourhood edges opacity: 0.5 or similar low value.

Closing for now, as this should recreate that effect.

AjitPS commented 9 years ago

Hi @maxkfranz , can the layout for my entire graph be different (cose or cola) when I do this, i.e., can I still set a circle layout on a specific neighborhood ?

AjitPS commented 9 years ago

Hi @maxkfranz , I tried what you said. My graph uses the cola layout but for a node with hidden, connected nodes, I set a circle layout with small radius on the neighborhood with the node as the root. However, it still isn't like the example in the url above where the small spikes show up when hovering over a node with hidden connected nodes.

Here is what my implemented solution looks like: neighborhood_spike_attempt

AjitPS commented 9 years ago

@maxkfranz : I posted this in the WebCola Git repo as well and was told that the spikes were made using D3.js and are basically "rotated rectangles with a small gradient".

maxkfranz commented 9 years ago

Try a smaller radius like 10, hide the edge arrows by default, and show the neighbourhood only on mouseover.

AjitPS commented 9 years ago

I used the following code to set the circle layout for the selected element's (ele) neighborhood:

var neighborhood_Layout= { name: 'circle', roots: ele, radius: '0.1', rStepSize: '0.1' }; ele.neighborhood().layout(neighborhood_circleLayout);

maxkfranz commented 9 years ago

(1) You've specified numeric values as strings

(2) Circle doesn't take roots. Use a boundingBox centred on your node of interest

AjitPS commented 9 years ago

Hi @maxkfranz , I've made the 2 changes you suggested above. I have managed to implement showing the hidden, connected edges (with opacity 0.5) on a tapdragover event with the opacity of hidden, connected nodes set to 0.1. However, I have a few questions:

(1) Can I set the layout on just the connected Edges (using ele.connectedEdges()) and Nodes and not the entire neighborhood ? Because setting the circle layout on the node's neighborhood causes the node to also be moved from its original position which results in the tapdragout event handler getting invoked. (2) Setting the circle layout (with a very small radius) on the selected element's neighborhood still shows very long edges. Is there a way to reduce edge length except setting it in the layout (like in the cola layout which my graph uses) ?

(3) I wrote the following code to try and set the circle layout on just the hidden, connected edges for the tapdragover/ mouseover event but it does not work:

var eleID= ele.id();
var ele_bbox= ele.boundingBox(); // the bounding box of this element (node)

// Circle layout for connected neighbors.
var neighborhood_Layout= { name: 'circle', radius: 0.5, boundingBox: ele_bbox, fit: true, 
animate: false, avoidOverlap: true, padding: 10 }; 

var connected_edges= ele.connectedEdges(); // connected edges for this node

// Set the circle layout only for the hidden nodes in this this element's (node) neighborhood.
ele.neighborhood().filter('node[nodeDisplay = "none"]').layout(neighborhood_Layout);

(4) Also, the event handler also affects my radial context menu (using cxtmenu) as using that triggers the tapdragover event first which now causes all the hidden, connected nodes to become invisible (opacity: 0.1). Is there a way to separate the 2 events or do I need to write the code to re-set the style for all the connected nodes and edges for all my radial context menu items/ events ?

Thanks.

maxkfranz commented 9 years ago

(1) Use whatever elements you like and eles.layout().

(2) Use the boundingBox to limit the layout size

(3) & (4) Hover effects are not effective on touch. Even if you could get it working, it's probably not worth it. Affordances should work well on touch and desktop -- meaning that hover effects are not enough. Similarly, this won't work well if you're using the context menu, because you've overloaded the gesture.

AjitPS commented 9 years ago

Thanks