ivis-at-bilkent / cytoscape.js-expand-collapse Goto Github PK
View Code? Open in Web Editor NEWA Cytoscape.js extension to expand/collapse nodes for better management of complexity of compound graphs
License: MIT License
A Cytoscape.js extension to expand/collapse nodes for better management of complexity of compound graphs
License: MIT License
I'm using cytoscape.js with expand collapse. When using Google Chrome I see an error after clicking on a button that runs api.expandAll()
. I see no error when using Firefox or GNOME Web. The error does not seem to be a problem, but I wanted to report it anyway. This is the error message:
cytoscape.min.js:8 Uncaught TypeError: Cannot read property 'x' of undefined
at v (cytoscape.min.js:8)
at m (cytoscape.min.js:8)
at u.l.boundingBox (cytoscape.min.js:8)
at u.l.boundingBoxAt (cytoscape.min.js:8)
at u.layoutPositions (cytoscape.min.js:8)
at o._CoSELayout.run (cytoscape-cose-bilkent.js:4250)
at Object.rearrange (elementUtilities.js:45)
at expandCollapseUtilities.js:96
v @ cytoscape.min.js:8
m @ cytoscape.min.js:8
l.boundingBox @ cytoscape.min.js:8
l.boundingBoxAt @ cytoscape.min.js:8
layoutPositions @ cytoscape.min.js:8
_CoSELayout.run @ cytoscape-cose-bilkent.js:4250
rearrange @ elementUtilities.js:45
(anonymous) @ expandCollapseUtilities.js:96
setTimeout (async)
(anonymous) @ expandCollapseUtilities.js:95
(anonymous) @ cytoscape.min.js:1
(anonymous) @ cytoscape.min.js:1
h @ cytoscape.min.js:1
u.emit.u.trigger @ cytoscape.min.js:1
ready @ cytoscape.min.js:1
endOperation @ expandCollapseUtilities.js:94
expandAllNodes @ expandCollapseUtilities.js:107
api.expandRecursively @ index.js:89
api.expandAll @ index.js:110
(anonymous) @ main.js:470
Line 470 in main.js
is
api.expandAll();
where api
is defined as
var api = cy.expandCollapse("get");
It seem that we do not have this integration yet. In demo expand/collapse operations can be undone/redone. However, nearly everthing about this functionality is handled in 'demo.html'. However, 'demo.html' is just a kind of sample application. This should be handled in extension itself in a way that if 'undoable' option is not truthy then we should simply do the operation as we do now. However, if it is truthy, then we should call it through the cytoscape.js-undo-redo extension as it is done in 'demo.html' now.
JS Fiddle: https://jsfiddle.net/bababalcksheep/njp2jk2j/33/
G Path => F,C,B,A
G Path => Group-CDF,B,A
What I need :
Even when collapsed , how can I get complete path ? which is G Path => F,C,B,A
Problem is before Group-CDF collapse, everything works fine.
After collapse, I am expecting same result as nodes are actually not removed , they are just collapsed
cy.on('tap', function(event) {
var evtTarget = event.target;
var node = evtTarget;
if (evtTarget.isNode()) {
var predecessors = node.predecessors('node').map(function(_node) {
return _node.data('name');
});
console.log(node.data('name'), ' Path => ', predecessors.join(','));
}
});
When calling getCollapsedChildrenRecursively on an empty collection, i'm getting an
Uncaught TypeError: Cannot read property 'length' of undefined
Exception in the console.
I managed to recreate the issue in jsFiddle.
I looked at the call stack and it seems that node.data('collapsedChildren');
returns undefined and when length
is called on the returned value an exception is thrown.
I actually ran into this problem before when the collection was not empty and node.data('collapsedChildren');
returned null.
As a workaround I iterated over the collection and checked the return value of node.data('collapsedChildren');
for each node.
Wherever I got null I replaced it with an empty array and it solved the issue.
I am about to click the blue node to expand it using the extension api:
Here is where it ends up after I click to expand it:
For example it would be nice to specify position for the child nodes like this, so when it expands, I can pass in it's parents position so it doesn't move to unexpected positions:
api.expand(node, { childPos: {x: 100, y: 100}});
I currently bind an event to track the parent's position, and set the children's position after the expand, but it still looks bad @gbader @ugurdogrusoz
I know this is a pretty dumb question, but I found so far the easiest way to get started with something is by having an example to read, e.g. for instance how to easily make something press able so I can use your extension and so on.
Again, this is probably very straightforward, but I haven't really programmed too much with js as I'm a researcher, but want to use your extension for some hierarchical visualization. So far cytoscape worked really great for this, but we need a way of managing the complexity.
Hi, I’ trying to build a Petri Net with Cytoscape.js, using Dagre.js layout and compound nodes for representing places witch in turns are subnets.
I foud very useful using Expand-Collapse extension, starting with an overall collapsed network. As the net evolve, I’d need to update some data on every node, including children of collapsed nodes witch users may decide to expand or not.
Here is the issue: I’ not able using Cytoscape selectors, say cy.nodes() for example, to select nodes inside collapsed ones. They seem not exist until node is expanded. I’ m new to the world of Cytoscape and probably this is the correct way to manage collapsed nodes but I can’t find a better solution to my problem. Any suggestion ?
Thanks
It seems that an issue similar (not the same) to this one ( iVis-at-Bilkent/cytoscape.js-context-menus#5 ) exists in this repository as well.
Please try the following link: https://tonicdev.com/56dd390fafca530d006e8a75/57b6b9d9138af81400a6481b
We should draw distribution guidelines consistently when the dragged node is in between two nodes (same as equally distanced outside of two nodes)
I notice there is a src/index.js
file that can expose the project as a module. Why isn't this used as main
in the package.json
?
My dataset has a large number of nodes which takes a long time to load. I was thinking it would load faster if I started with some of the compound nodes collapsed. How can I go about doing this? Does this need to happen when cytoscape is initialized or does it happen in this extension?
We need to change the name of the state value as described in the title and make it taking boolean value. In this way we get rid of seting its value as 'expanded' on load. It seems that this is a better and safer approach. Please see ( iVis-at-Bilkent/sbgnviz.js#166 ).
Also we need to keep this value in 'scratch' instead of 'data' (As it is expected from a Cy.js extension).
I've been working with the Cose-Bilkent layout lately and I've just added this plug-in to be able to collapse and expand compound nodes. It seems that everything works fine but I think there is some issue with some padding for the cues. It seems to get placed outside of the compound node so the action doesn't get trigger. It seems to get better when I zoom in to certain level so the cue finally gets placed inside the compound node. Please, find attached below some screenshots of this issue. The first one is an example of the original placement of the cue on a compound node when the graph gets displayed. The second one is the result of zooming in. Any clue of why is this happening? I'm using the following parameters for the layout:
layout_params = {
name: 'cose-bilkent',
animate: false,
randomize: true,
tilingPaddingVertical: 20,
tilingPaddingHorizontal: 20,
}
Many thanks!
Namespacing:
Same of the problem here 'iVis-at-Bilkent/cytoscape.js-view-utilities#5'
Triggered event names:
Should include the extension name as prefix
The example uses a variable named expand-collapse
which is not valid JS.
It seems that the readability of the code decreased signaficantly when we try to syncronize animated operations. The problem especially exists in expand-collapse-utilities.js file. We need to revise it and try to improve the readability as much as possible. In worst case we can improve the comments.
In an app using remove() and restore(), meta edges can be saved and restored (along with their connectedNodes) The user needs to be able to call repairEdges to fix meta edges after they are restored.
I'd like to save the node status whether the node is collapsed or not in json data, and then restore it to the visualized graph with keeping the collapsed status. When using some libraries "collapsed" member in json data indicates the collapsed status of each nodes.
For example, the collapsed status can be stored as other json data, then after loading the elements json, according to the collapsed status json, the collapsed function can be applied to the graph.
What method is supposed as the regular method in this library?
I got a error "$container.cytoscape is not a function"
Here is my code:
var jquery = require('jquery')
var expandCollapse = require('cytoscape-expand-collapse');
expandCollapse(cytoscape, jquery)
var cy = window.cy = cytoscape({
container: document.getElementById('topo'),
boxSelectionEnabled: false,
autounselectify: true,
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(id)',
'width': 15,
'height': 15,
'background-color': '#ad1a66',
})
.selector('edge')
.css({
'target-arrow-shape': 'triangle',
'width': 2,
'line-color': '#ddd',
'target-arrow-color': '#ddd',
'curve-style': 'bezier'
})
.selector(':parent')
.css({
'background-opacity': 0.333
})
.selector("node.cy-expand-collapse-collapsed-node")
.css({
"background-color": "darkblue",
"shape": "rectangle"
}),
elements: {
nodes: [
{ data: { id: 'qt0'}, position: {x: 120,y: 0} },
{ data: { id: 'qt1'}, position: {x: 180,y: 0} },
{ data: { id: 'qt2'}, position: {x: 240,y: 0} },
{ data: { id: 'qt3'}, position: {x: 300,y: 0} },
],
edges: [
]
},
layout: {
name: 'preset',
roots: '#a',
padding: 0
}
})
var api = cy.expandCollapse({
layoutBy: {
name: "preset",
// animate: true,
// randomize: false,
// fit: true
},
fisheye: true,
animate: true,
undoable: false
});
I think that this extension considers whether undoRedo extension is registered when undoable option is true at some code segments (https://github.com/iVis-at-Bilkent/cytoscape.js-expand-collapse/blob/unstable/src/undoRedoUtilities.js#L2). But it does not consider it consistently, so the extension crashes when you initilize it in undoable mode (it is undoable by default) where the undoRedo extension is not registered and then try to expand/collapse nodes.
cy = cytoscape({
container: document.getElementById('cy'),
elements:[
{'data': {'id': '1'}, 'group': 'nodes'},
{'data': {'id': '2', 'parent': '1'}, 'group': 'nodes'},
{'data': {'id': '3', 'parent': '2'}, 'group': 'nodes'},
]
});
Uncaught TypeError: Cannot read property 'x' of undefined. expandCollapseUtilities.js:13
Is it possible to keep the cues visibile? I'm trying to make the expand/collapse accessible to those with touch only interface (ie tablets).
Firstly, thanks for the library. It has been very helpful till now for our use case.
I wanted to know if there is a way to use the library for touch screens. For now, it seems that you only see the expand-collapse cue on mouse hover. Is there any other way that could also be used for touch screens using this library? If not, is there any chance that it will be added soon?
References can get stale if move() is used. The ID should be preserved, so you can use cy.getElementById() to get the reference when you need it (in findNewEnds()).
Hi,
Seems very useful plugin. However I wish there was a function in which one could specify which parent nodes can have expand collapse functionality and which can not (kind of filter).
For example I want to add cytoscape.js-expand-collapse control to specific parents not all.
cytoscape.js-edgehandles
provides such functionality with a beautiful function handleNodes
which can be used as a function like this
// from https://github.com/cytoscape/cytoscape.js-edgehandles
// as string selector
handleNodes: 'node',
// as filter function
handleNodes: function () {
if (this.data().isExpandable) {
// proceed with control
return true;
} else {
// no controls
return false
}
}
hey,
Please let me know of a way, by which I can show a label for the collapse/ expanded nodes.
I tried doing the following in compound nodes
selector: 'node',
style: {
'content': 'data(label)',
},
2 problems,
It would be great if the README could link to the demo to make it easier to preview what this looks like. This link works for me: http://cdn.rawgit.com/iVis-at-Bilkent/cytoscape.js-expand-collapse/master/demo.html
when using AMD, functions are under scope not under global window.
This should work but does not , ReferenceError: cy is not defined
require(['jquery', 'cytoscape', 'cytoscape-expand-collapse'], function ($, cytoscape, expandCollapse) {
expandCollapse(cytoscape, $); // register extension
$('#cy').cytoscape({
ready: function () {
var cy = this; // scoped cy
cy.expandCollapse();
}
});
});
This one works because of window.cy = this;
require(['jquery', 'cytoscape', 'cytoscape-expand-collapse'], function ($, cytoscape, expandCollapse) {
expandCollapse(cytoscape, $); // register extension
$('#cy').cytoscape({
ready: function () {
window.cy = this; // expandCollpase only works if this line is defined
var cy = this;
cy.expandCollapse();
}
});
});
This is confusing because there could be multiple instances of cy running in tabs for example.
expandCollpase should accept the cy it is being provided with, instead of looking for window.cy
When the graph gets rendered in expanded form it appears like this i.e. with Topological Ordering -
But when I collapse/expand node, initially the same ordering is maintained but after a couple seconds maybe even minutes depending on the size of the graph elements.
Just a few pictures to showcase the same -
I was unable to pin point the function call causing this. Would like to preserve the ordering of my graph even after collapse/expand of nodes. Kindly let me how can I do this.
I observed that these lines get printed in console.log whenever the rearrangement happens -
The expandcollapse.afterexpand event is fired before the node positions are corrected. Is it possible to fire this after the node positions are corrected?
i.e switch the order of line 31 and line 34?
I just download the master.zip. But the demo page does not work. I got the below error:
Uncaught TypeError: $container.cytoscape is not a function
at init (cueUtilities.js:195)
at module.exports (cueUtilities.js:292)
at u.expandCollapse (index.js:187)
at HTMLDocument. (demo-undoable.html:96)
As I understand when node is collapsed, technically it is still a compound node and not just a simple node, right?
If so, is it necessary to keep it as compound node when it is collapsed?
The issue with compound nodes is that one can't really edit their dimensions, it is understandable when node actually has some children but it is very limiting when node is collapsed.
E.g for collapsed nodes I'm trying to put label inside the node and have node width and height aligned with label size + some padding, but currently it is doesn't work.
Would it be possible to add the ability to hide all edges for collapsed nodes? Would you like to have this functionality as part of this plugin?
If so I can provide a PR, if you could point me to the proper places. From a quick look it seems that I just need to hook into simpleCollapseNode and simpleExpandNode and hide/show all incoming/outgoing edges.
Or maybe in case of this option we can just make nodes invisible, and edges will not be displayed by default. Any ideas, suggestions are welcome.
I am using layouts and inside layouts are tabs , each tab has cytoscape js with expand collapse.
From what I have fiigured, I need to manually call internal sizeCanvas()
of expand-collapse afetr tab shown or layout resized sicne my buttons hide after window resize or layout resize.
I tried calling cy.expandCollapse( ); // without options
on tab shown or layout resized hoping it will fix that. expand cues do appear but they make an extra canvas.
It will be very helpful if to call resize();
on expandCollapse like cy.expandCollapseResize( );
Problem is canvas resizing is bound with window and it resizes it before layouts are resized.so once layouts are resized, expandCollapse canvas is already resized and defaults to 100,100 width height.
I'm trying to use api.expand(nodes, options)
but I think I must be doing something wrong.
I'm using this method without options so I have something like this api.expand(target)
where target
is an Element
. What would be the correct syntax?
Let's please add a demo for this as well to the README
I've noticed that calling cy.collapseAll
on a graph (250 nodes, 70 edges) takes almost twice as long as computing the layout/rendering. I don't quite understand the machinery behind expand-collapse
, but I wonder if there's been any benchmarks to evaluate its performance?
Update: I did some profiling and it seems the longest operation is eles.move
, which accounts for ~40% of total time.
Please see 'iVis-at-Bilkent/chise.js#84'
Fixing iVis-at-Bilkent/chise.js#96 triggered this.
Using the View->Collapse/expand menu works fine. Only the top left icon clicking is glitching.
To allow to enable / disable menu item based on node state (for example - disable 'expand' menu item if node is expanded) - add 'onDisplay' event
When you zoom out, the cues get too small, and become difficult to see let alone hit. Maybe they should be drawn at a minimal size (similar to grapples in resize extension?)
cy.on("afterExpand", function(node) { })
should be cy.on("afterExpand", function(event) { var node = this; ... })
cy.nodes().on("expandcollapse.afterexpand", function(event) { var node = this; ... })
won't worked while
cy.nodes().on("afterExpand", function(event) { var node = this; ... })
worked fine.
in your code you are triggering node.trigger("afterExpand");
Please update your documentation :)
Thanks !
I have been trying to get all compound nodes in collapsed form by default.
For achieving this I changed the cy.expandCollapse() function, by changing the following on line 1333 in cytoscape-expand-collapse.js -
cy.nodes(':parent').data('expanded-collapsed', 'collapsed');
When I did the above I got an error in cueUtilities.js line 72 [Uncaught TypeError: Cannot read property 'options' of undefined] -
The strange part whoever is that when I tried to debug this using console.log, the changes were not being reflected, maybe because all the files are imported using dereq rather than normal require(). I still couldn't this part out. PS - Yes, I have cleared my cache, cookies and history. Also tried the same in Incognito mode as well, still the changes done weren't reflected.
Kindly let me know how can I achieve collapsed nodes by default on initialization itself.
My agenda behind this is to observe whether this improves my performance with large number of nodes(>3000) and edges(>15000). If you already done any similar experiment, kindly share your observations here.
Passing cueEnabled: false
to cy.expandCollapse()
breaks Cytoscape.
I suspect this is due to calling cy.off()
with undefined event handlers causing all handlers (including the core's) to be unbound.
To reproduce add the following style:
{
selector: "[expanded-collapsed='collapsed']",
style: {
"background-color": "darkblue",
"shape": "ellipse",
"width": 100,
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.