cytoscape / cytoscape.js-cose-bilkent Goto Github PK
View Code? Open in Web Editor NEWThe CoSE layout for Cytoscape.js by Bilkent with enhanced compound node placement.
License: MIT License
The CoSE layout for Cytoscape.js by Bilkent with enhanced compound node placement.
License: MIT License
A layout option to specify the maximum width/height of the parent nodes
Please see 'iVis-at-Bilkent/chise.js#106'
Have you run this algorithm with very large networks (30K Nodes, 25K edges). If so what is the expected performance?
@metincansiper @ugurdogrusoz Since the layout does not use workers/threads anymore, you could enable babel and use es2015 classes etc. That would make your code more like the java impl
See https://github.com/cytoscape/cytoscape.js-cose-bilkent/blob/master/gulpfile.js#L54
Layouts usually have a boundingBox
option so that the area in which the layout is run can be specified/constrained. This is useful when running layouts on subsets of the graph, e.g. eles.layout()
.
It would be nice to have this feature in CoSE Bilkent.
Avoiding overlap with nodes can contradict the bounding box (i.e. the bounding box may not have enough room to prevent node overlap). In that case, it's OK to overflow the bounding box. However, there is usually an option so the dev can decide (i.e. avoidOverlap
: on true
avoids node overlap and might overflow the bounding box, on false
respects the bounding box but nodes might overlap).
Refer to cytoscape/cytoscape.js#1372
As discussed earlier, we should take compound weights (# of children) into account when cumulative forces are applied. In other words, we should divide the total force to compound weights to figure out movement amount. Recent repulsion force calculation was in a sense achieving this but not as clean as what's suggested here.
I have the following fragment of code where I try to stop a running layout:
var options = {
name: 'cose-bilkent',
// Called on `layoutready`
ready: function () {
console.log("LAYOUT READY");
},
// Called on `layoutstop`
stop: function () {
console.log("LAYOUT STOP");
},
fit:true,padding:20,randomize:false,nodeRepulsion:40500,idealEdgeLength:70,edgeElasticity:0.45,nestingFactor:0.9,gravity:0.9,numIter:1000,tile:true,us eMultitasking:true,animate:false
}
var layout = cy.makeLayout(options);
layout.run();
console.log("DONE");
setTimeout(function() {
console.log("LAYOUT_FORCED_STOP");
layout.stop();
}, 5000);
However it seems the layout doesn't stop after 5 seconds:
DONE
Thread log: start thread
LAYOUT_FORCED_STOP
Classic CoSE layout finished after 1000 iterations
Total execution time: 10597 miliseconds.
LAYOUT READY
LAYOUT STOP
My project uses require.js
but registering the extension did not work since regCose
remains undefined. Without registering the extension cytoscape was unable to find the layout cose-bilkent
.
require(['cytoscape', 'cytoscape-cose-bilkent'], function( cytoscape, regCose ){
regCose( cytoscape ); // register extension
});
Any ideas why this would happen? How I can test that I'm doing things correctly?
edgeElasticity and idealEdgeLength parameters are redundant since they both control the same formula for calculating spring forces. lets remove idealEdgeLength from the list of parameters exposed to the user.
https://github.com/cytoscape/cytoscape.js-cose-bilkent/blob/master/cytoscape-cose-bilkent.js#L5121
I think it should be "this.cy" instead of "cy".
var cyNode = this.cy.getElementById(lNode.id).parent()[0];
It was throwing an error, which I corrected in the source file and now all's ok for me.
Hello,
would you be so kind, and publish it to atmosphere/meteor, please ? cose-bilkent, which is already published to atmosphere, is
maxkfranz:cytoscape-cose-bilkent
, but it depend on maxkfranz:cytoscape, which is older version
it would be perfect, if cose-bilken is avaiable for already published https://atmospherejs.com/cytoscape/cytoscape
thank you alot.
During development (not minified), everything works fine. But after using grunt to uglify all resources, this component breaks.
I tried to exclude the mangling of variables on which it broke (like _dereq_
, and anything downstream, like CoSELayout
) but new unresolved references continue to pop up. Any other suggestions on a workaround or fix?
(This happens on versions 1.0.4 and 1.0.5)
I'm using cytoscape.js-cose-bilkent project transitively. In the library I'm using, it has a dependency on version "^1.3.6", which is currently resolving to 1.5.2. Unfortuntely, this version has a depedency on cytoscape.js with version specification "^2.4.0 | ^3.0.0", which is not resolving for me (bower version 1.3.12 is giving me: bower ENORESTARGET Tag/branch ^2.4.0 | ^3.0.0 does not exist). Is this a version specification error, or maybe my bower version is just too old, or maybe there's something else going on?
This would allow us to determine what kind of tiling padding we want on a per-node basis :)
Hi,
I get the following error when applying the layout.
Cytoscape version: 2.7.2
cose-bilkent version: 1.3.6
index.js:622 Uncaught TypeError: Cannot read property 'data' of undefined
The node
object in the following line is undefined:
cytoscape.js-cose-bilkent/src/Layout/index.js
Line 621 in 19747ec
The following graph was used:
{
"nodes": [
{
"data": {
"id": "test-system123-nodeGroup-1",
"name": "CoCoMe",
"systemId": "system123",
"type": "nodeGroup",
"label": "CoCoMe"
}
},
{
"data": {
"id": "test-system123-node-2",
"name": "Logicnode",
"ip": "10.0.0.2",
"hostname": "host2",
"nodeGroupId": "test-system123-nodeGroup-1",
"systemId": "system123",
"type": "node",
"label": "Logicnode",
"parent": "test-system123-nodeGroup-1"
}
},
{
"data": {
"id": "test-system123-node-3",
"name": "Adapter",
"ip": "10.0.0.2",
"hostname": "host3",
"nodeGroupId": "test-system123-nodeGroup-1",
"systemId": "system123",
"type": "node",
"label": "Adapter",
"parent": "test-system123-nodeGroup-1"
}
},
{
"data": {
"id": "test-system123-node-4",
"name": "Database",
"ip": "10.0.0.2",
"hostname": "host4",
"nodeGroupId": "test-system123-nodeGroup-1",
"systemId": "system123",
"type": "node",
"label": "Database",
"parent": "test-system123-nodeGroup-1"
}
},
{
"data": {
"id": "test-system123-node-1",
"name": "WebNode",
"ip": "10.0.0.1",
"hostname": "test hostname",
"nodeGroupId": "test-system123-nodeGroup-1",
"systemId": "system123",
"type": "node",
"label": "WebNode",
"parent": "test-system123-nodeGroup-1"
}
},
{
"data": {
"id": "test-system123-serviceInstance-4",
"name": "Inventory",
"nodeId": "test-system123-node-2",
"serviceId": "test-system123-service-4",
"systemId": "system123",
"type": "serviceInstance",
"label": "Inventory",
"parent": "test-system123-node-2"
}
},
{
"data": {
"id": "test-system123-serviceInstance-5",
"name": "Data",
"nodeId": "test-system123-node-3",
"serviceId": "test-system123-service-5",
"systemId": "system123",
"type": "serviceInstance",
"label": "Data",
"parent": "test-system123-node-3"
}
},
{
"data": {
"id": "test-system123-serviceInstance-6",
"name": "PostgreSQL",
"nodeId": "test-system123-node-4",
"serviceId": "test-system123-service-6",
"systemId": "system123",
"type": "serviceInstance",
"label": "PostgreSQL",
"parent": "test-system123-node-4"
}
},
{
"data": {
"id": "test-system123-serviceInstance-1",
"name": "FrontEnd",
"nodeId": "test-system123-node-1",
"serviceId": "test-system123-service-1",
"systemId": "system123",
"type": "serviceInstance",
"label": "FrontEnd",
"parent": "test-system123-node-1"
}
},
{
"data": {
"id": "test-system123-serviceInstance-2",
"name": "WebService",
"nodeId": "test-system123-node-2",
"serviceId": "test-system123-service-2",
"systemId": "system123",
"type": "serviceInstance",
"label": "WebService",
"parent": "test-system123-node-2"
}
},
{
"data": {
"id": "test-system123-serviceInstance-3",
"name": "CashDesk",
"nodeId": "test-system123-node-2",
"serviceId": "test-system123-service-3",
"systemId": "system123",
"type": "serviceInstance",
"label": "CashDesk",
"parent": "test-system123-node-2"
}
}
],
"edges": [
{
"data": {
"id": "test-system123-communicationInstance-1",
"sourceId": "test-system123-serviceInstance-1",
"targetId": "test-system123-serviceInstance-2",
"communicationId": null,
"systemId": "system123",
"type": "communicationInstance",
"source": "test-system123-serviceInstance-1",
"target": "test-system123-serviceInstance-2"
}
},
{
"data": {
"id": "test-system123-communicationInstance-2",
"sourceId": "test-system123-serviceInstance-2",
"targetId": "test-system123-serviceInstance-3",
"communicationId": null,
"systemId": "system123",
"type": "communicationInstance",
"source": "test-system123-serviceInstance-2",
"target": "test-system123-serviceInstance-3"
}
},
{
"data": {
"id": "test-system123-communicationInstance-3",
"sourceId": "test-system123-serviceInstance-3",
"targetId": "test-system123-serviceInstance-4",
"communicationId": null,
"systemId": "system123",
"type": "communicationInstance",
"source": "test-system123-serviceInstance-3",
"target": "test-system123-serviceInstance-4"
}
},
{
"data": {
"id": "test-system123-communicationInstance-4",
"sourceId": "test-system123-serviceInstance-3",
"targetId": "test-system123-serviceInstance-5",
"communicationId": null,
"systemId": "system123",
"type": "communicationInstance",
"source": "test-system123-serviceInstance-3",
"target": "test-system123-serviceInstance-5"
}
},
{
"data": {
"id": "test-system123-communicationInstance-5",
"sourceId": "test-system123-serviceInstance-4",
"targetId": "test-system123-serviceInstance-5",
"communicationId": null,
"systemId": "system123",
"type": "communicationInstance",
"source": "test-system123-serviceInstance-4",
"target": "test-system123-serviceInstance-5"
}
},
{
"data": {
"id": "test-system123-communicationInstance-6",
"sourceId": "test-system123-serviceInstance-5",
"targetId": "test-system123-serviceInstance-6",
"communicationId": null,
"systemId": "system123",
"type": "communicationInstance",
"source": "test-system123-serviceInstance-5",
"target": "test-system123-serviceInstance-6"
}
}
]
}
I would appreciate help.
Thanks
I have nested compound nodes but it seems that cose-bilkent failed to layout them properly. Basically in the end all nodes end-up on the same position.
We need to investigate whether incompatibility between paddings in client and in l-level play a role in bad layouts. Also proper reflection of geometry from l-level to v-level might be the cause of such bad layouts. Notice also that vertical padding is more than horizontal one due to labels for compounds!
This is in reference to an issue @ugurdogrusoz had about the "pathways-search" app.
If I understand his concerns correctly, the "bad results" are related to node overlap.
Here is the original issue that Ugur posted on the pathway-commons dev group:
- why does cose-bilkent layout yield such bad layouts
(trust me I know the weaknesses of our algorithms but it doesn’t produce such layouts).
please point us to the related repository if you’d like us to take a look.
maybe something incorrect is getting done during collapse of complexes prior to display.
- consider using cytoscape.js-expand-collapse extension for expand-collapse of complexes (and compartments in my opinion)
Here is an example of a "bad layout" that I think Ugur is talking about, the cut-corner rectangle nodes are the ones that I frequently see overlapping, and those are the collapsed nodes:
I want to reiterate:
I am using the cytoscape-expand-collapse
extension.
I am using the following that I think are contributing factors to the problem:
I use these settings:
cy.layout({
name: 'cose-bilkent',
paddingCompound: 50,
fit: true,
nodeRepulsion: 4500,
idealEdgeLength: 50,
edgeElasticity: 0.45,
nestingFactor: 0.1,
gravity: 0.25,
numIter: 2500,
tile: false,
animationEasing: 'cubic-bezier(0.19, 1, 0.22, 1)',
animate: 'end',
animationDuration: 1000,
randomize: true,
tilingPaddingVertical: 20,
tilingPaddingHorizontal: 20,
gravityRangeCompound: 1.5,
gravityCompound: 1.0,
gravityRange: 3.8,
}).run();
Which are mostly the same settings that you use for Newt, with the exception of tiling
set to false
. Either way, with tiling set to true/false it still produces the same result.
Here is an example with paddingCompound set to different values:
As you can see, compoundPadding is not applying to the collapsed complex nodes, only the actual compartment compounds
I'm trying to start and stop the layout programmatically.
While this works:
var layout = cy.layout({ name: 'cose-bilkent' });
layout.run();
When after some time I try this:
layout.stop();
nothing happens and the animation still runs.
The only difference I can see is that the layout object gets a new property stopped: true
.
Hi, I don't know exactly is it an issue, or just a normal behavior. But cose-bilkent always makes my nodes fit the canvas bounds. So if i have the square one, nodes that place closer to the canvas bounds will always go one after another like if I use boundingBox param of original CoSe mode.
How can I fix that issue?
Version 1.0.2 works great for my project, but does not work in IE. Version 1.0.4 works in IE, but lays out the nodes in a way that can't be right (tight diagonal line across the canvas). This happens in both IE and Chrome. I've created a JSFiddle here using CDN code: https://jsfiddle.net/pr8f5dLk/. Swap version numbers in the script tag to see the difference.
It points to the source code. If you do this, you can't use Babel.
It should point to the built file.
If a node has no edges, a dummy node seems to be created, I then get:
Do not assign mappings to elements without corresponding data (e.g. ele DummyCompound_undefined
for property background-color
with data field faveColor
); try a [faveColor]
selector to limit scope to elements with faveColor
defined
where my css selector for node is defined like:
.css({
'width': 'label',
'content': 'data(name)',
'text-valign': 'center',
'text-outline-width': 2,
'text-outline-color': '#fff',
'background-color': 'data(faveColor)',
'color': '#000',
'visiblity': 'visible'
})
We should get rid of multi-edges (parallel edges) since they bring additional cost for no reason.
As mentioned in #15 as well, the peformance of the algorithm could be improved (mostly to speed it up) by a number of things:
If you use this layout as the one specified at init, the animation doesn't work. It just flashes quickly
This should automatically build in the background and automatically reload the debug page
This should make development easier
See https://github.com/jvwong/GOList as a reference with the code in the gulpfile and the livereload include in the html https://github.com/jvwong/GOList/blob/master/index.html#L11
Here is example without paddings - http://jsbin.com/qodotekale/1/edit?html,output , it works as expected.
And here is example with node paddings - http://jsbin.com/qowekuvofa/1/edit?html,output , as you can see nodes are overlaping.
Also for the reference, with simple cose layout nodes are not overlapping, see http://jsbin.com/tejufolire/1/edit?output
Can we please expose the following parameters as options:
I am using Cytoscape on Angular 2 project and wanted to use Cose-bilkent layout. Hence I added the dependency to my project using npm. Since I am using Angular 2 with Typescript I have added the js module first to the angular-cli.json file then to the index.html file. After that in my NetworkComponent , which is the angular component I am using to display the graph, I am importing the library as follows:
declare var CoSELayout:any;
Then I am trying to use the layout as follows:
this.cyto = cytoscape({
container: document.getElementById("graph"),
elements: this.graph.elements,
style: res.json()
});
this.cyto.layout({name: "cose-bilkent"});
The graph displays but the layout is not set to cose-bilkent
and I get the following error in the console:
Can not apply layout: No such layout
cose-bilkent found; did you include its JS file?
How can I import cose-bilkent library and use it as my graph layout? What might be wrong here?
Thanks.
I was wondering if I could use arbitrary function as layout option nodeRepulsion
argument?
Cose layout in the core allows that but I am getting an error if when using the same function for cose-bilkent.
Thanks,
Mikhail
The function can be called on the element to provide per-element values.
Let's discuss and re-evaluate inter-graph ideal edge calculation
the code snippet from README can not work with browserify:
var cytoscape = require('cytoscape');
var regCose = require('cytoscape-cose-bilkent');
regCose( cytoscape ); //register extension
Instead, code snippet blow works:
var cytoscape = window.cytoscape = require('cytoscape');
require('cytoscape-cose-bilkent');
This was discovered by @hasanbalci:
Open up daily Newt, set animation true (perform animation during layout), set incremental off (randomize: true) and perform layout on default graph. You'll see that at the very end of layout things get messed up (compounds placed in weird locations):
This doesn't happen when animation if off (animation is set to 'end'). I don't know if this is somehow related to #45.
We suspect this was introduced after tiling was moved in l-level.
We need a new layout option named initialEnergyOnIncremental. This will directly be used as the initial cooling factor. When user is asking for an incremental layout (randomize=false), how stable do they think the current layout is. A number in range (0.0, 1.0], default is whatever cooling factor we currently use by default on incremental layout (0.8?)
Minimal test case, just run yarn
and gulp
to build https://github.com/cmdcolin/cytoscape-error-demo
I haven't looked into the cause yet but thought I'd follow up on #4
I am using Cytoscape.js within React.js. I can use the bundled CoSE with no issues, and also I can use the Cola layout without issues, but when dropping CoSE-Bilkent in, I get the error that is shown in the screen cap.
If you have any ideas what this might be or how to work around it, I would be quite grateful.
I use several layout algorithms in a project, where the user can choose out of a list of layouts. For the case-bilkent layout I recognized an added property in the data section of nodes called dummy_parent_id
and sometimes tempchildren
.
This messes up the data-editor as my app assumes that only clean data is stored there. Cytoscape.JS has a scratch
-store for such things, that to my opinion is much more suitable in this particular case.
I made some small modifications in order to store the data in scratch
instead of data
.
see PR #24
An exception is raised when trying to run cose-bilkent layout with headless option.
It is working fine until specifying 'headless: false' in options (the same with 'container: undefined' option).
Is cose-bilkent designed to support headless layout ?
e.g.
elements: {
nodes: [{"data":{"id":"0"}},{"data":{"id":"1"}},{"data":{"id":"2"}},{"data":{"id":"3"}},{"data":{"id":"4"}},{"data":{"id":"5"}},{"data":{"id":"6"}},{"data":{"id":"7"}},{"data":{"id":"8"}},{"data":{"id":"9"}},{"data":{"id":"10"}},{"data":{"id":"11"}},{"data":{"id":"12"}},{"data":{"id":"13"}},{"data":{"id":"14"}},{"data":{"id":"15"}},{"data":{"id":"16"}},{"data":{"id":"17"}},{"data":{"id":"18"}},{"data":{"id":"19"}},{"data":{"id":"20"}},{"data":{"id":"21"}},{"data":{"id":"22"}},{"data":{"id":"23"}},{"data":{"id":"24"}},{"data":{"id":"25"}},{"data":{"id":"26"}},{"data":{"id":"27"}},{"data":{"id":"28"}},{"data":{"id":"29"}},{"data":{"id":"30"}},{"data":{"id":"31"}},{"data":{"id":"32"}},{"data":{"id":"33"}},{"data":{"id":"34"}},{"data":{"id":"35"}},{"data":{"id":"36"}},{"data":{"id":"37"}},{"data":{"id":"38"}},{"data":{"id":"39"}},{"data":{"id":"40"}},{"data":{"id":"41"}},{"data":{"id":"42"}},{"data":{"id":"43"}},{"data":{"id":"44"}},{"data":{"id":"45"}},{"data":{"id":"46"}},{"data":{"id":"47"}},{"data":{"id":"48"}},{"data":{"id":"49"}},{"data":{"id":"50"}},{"data":{"id":"51"}},{"data":{"id":"52"}},{"data":{"id":"53"}},{"data":{"id":"54"}},{"data":{"id":"55"}},{"data":{"id":"56"}},{"data":{"id":"57"}},{"data":{"id":"58"}},{"data":{"id":"59"}},{"data":{"id":"60"}},{"data":{"id":"61"}},{"data":{"id":"62"}},{"data":{"id":"63"}},{"data":{"id":"64"}},{"data":{"id":"65"}},{"data":{"id":"66"}},{"data":{"id":"67"}},{"data":{"id":"68"}},{"data":{"id":"69"}},{"data":{"id":"70"}},{"data":{"id":"71"}},{"data":{"id":"72"}},{"data":{"id":"73"}},{"data":{"id":"74"}},{"data":{"id":"75"}},{"data":{"id":"76"}},{"data":{"id":"77"}},{"data":{"id":"78"}},{"data":{"id":"79"}},{"data":{"id":"80"}},{"data":{"id":"81"}},{"data":{"id":"82"}},{"data":{"id":"83"}},{"data":{"id":"84"}},{"data":{"id":"85"}},{"data":{"id":"86"}},{"data":{"id":"87"}},{"data":{"id":"88"}},{"data":{"id":"89"}},{"data":{"id":"90"}},{"data":{"id":"91"}},{"data":{"id":"92"}},{"data":{"id":"93"}},{"data":{"id":"94"}},{"data":{"id":"95"}},{"data":{"id":"96"}},{"data":{"id":"97"}},{"data":{"id":"98"}},{"data":{"id":"99"}}],
edges: [{"data":{"source":"10","target":"0"}},{"data":{"source":"20","target":"10"}},{"data":{"source":"30","target":"20"}},{"data":{"source":"40","target":"30"}},{"data":{"source":"50","target":"40"}},{"data":{"source":"60","target":"50"}},{"data":{"source":"70","target":"60"}},{"data":{"source":"80","target":"70"}},{"data":{"source":"90","target":"80"}},{"data":{"source":"1","target":"0"}},{"data":{"source":"11","target":"10"}},{"data":{"source":"11","target":"1"}},{"data":{"source":"21","target":"20"}},{"data":{"source":"21","target":"11"}},{"data":{"source":"31","target":"30"}},{"data":{"source":"31","target":"21"}},{"data":{"source":"41","target":"40"}},{"data":{"source":"41","target":"31"}},{"data":{"source":"51","target":"50"}},{"data":{"source":"51","target":"41"}},{"data":{"source":"61","target":"60"}},{"data":{"source":"61","target":"51"}},{"data":{"source":"71","target":"70"}},{"data":{"source":"71","target":"61"}},{"data":{"source":"81","target":"80"}},{"data":{"source":"81","target":"71"}},{"data":{"source":"91","target":"90"}},{"data":{"source":"91","target":"81"}},{"data":{"source":"2","target":"1"}},{"data":{"source":"12","target":"11"}},{"data":{"source":"12","target":"2"}},{"data":{"source":"22","target":"21"}},{"data":{"source":"22","target":"12"}},{"data":{"source":"32","target":"31"}},{"data":{"source":"32","target":"22"}},{"data":{"source":"42","target":"41"}},{"data":{"source":"42","target":"32"}},{"data":{"source":"52","target":"51"}},{"data":{"source":"52","target":"42"}},{"data":{"source":"62","target":"61"}},{"data":{"source":"62","target":"52"}},{"data":{"source":"72","target":"71"}},{"data":{"source":"72","target":"62"}},{"data":{"source":"82","target":"81"}},{"data":{"source":"82","target":"72"}},{"data":{"source":"92","target":"91"}},{"data":{"source":"92","target":"82"}},{"data":{"source":"3","target":"2"}},{"data":{"source":"13","target":"12"}},{"data":{"source":"13","target":"3"}},{"data":{"source":"23","target":"22"}},{"data":{"source":"23","target":"13"}},{"data":{"source":"33","target":"32"}},{"data":{"source":"33","target":"23"}},{"data":{"source":"43","target":"42"}},{"data":{"source":"43","target":"33"}},{"data":{"source":"53","target":"52"}},{"data":{"source":"53","target":"43"}},{"data":{"source":"63","target":"62"}},{"data":{"source":"63","target":"53"}},{"data":{"source":"73","target":"72"}},{"data":{"source":"73","target":"63"}},{"data":{"source":"83","target":"82"}},{"data":{"source":"83","target":"73"}},{"data":{"source":"93","target":"92"}},{"data":{"source":"93","target":"83"}},{"data":{"source":"4","target":"3"}},{"data":{"source":"14","target":"13"}},{"data":{"source":"14","target":"4"}},{"data":{"source":"24","target":"23"}},{"data":{"source":"24","target":"14"}},{"data":{"source":"34","target":"33"}},{"data":{"source":"34","target":"24"}},{"data":{"source":"44","target":"43"}},{"data":{"source":"44","target":"34"}},{"data":{"source":"54","target":"53"}},{"data":{"source":"54","target":"44"}},{"data":{"source":"64","target":"63"}},{"data":{"source":"64","target":"54"}},{"data":{"source":"74","target":"73"}},{"data":{"source":"74","target":"64"}},{"data":{"source":"84","target":"83"}},{"data":{"source":"84","target":"74"}},{"data":{"source":"94","target":"93"}},{"data":{"source":"94","target":"84"}},{"data":{"source":"5","target":"4"}},{"data":{"source":"15","target":"14"}},{"data":{"source":"15","target":"5"}},{"data":{"source":"25","target":"24"}},{"data":{"source":"25","target":"15"}},{"data":{"source":"35","target":"34"}},{"data":{"source":"35","target":"25"}},{"data":{"source":"45","target":"44"}},{"data":{"source":"45","target":"35"}},{"data":{"source":"55","target":"54"}},{"data":{"source":"55","target":"45"}},{"data":{"source":"65","target":"64"}},{"data":{"source":"65","target":"55"}},{"data":{"source":"75","target":"74"}},{"data":{"source":"75","target":"65"}},{"data":{"source":"85","target":"84"}},{"data":{"source":"85","target":"75"}},{"data":{"source":"95","target":"94"}},{"data":{"source":"95","target":"85"}},{"data":{"source":"6","target":"5"}},{"data":{"source":"16","target":"15"}},{"data":{"source":"16","target":"6"}},{"data":{"source":"26","target":"25"}},{"data":{"source":"26","target":"16"}},{"data":{"source":"36","target":"35"}},{"data":{"source":"36","target":"26"}},{"data":{"source":"46","target":"45"}},{"data":{"source":"46","target":"36"}},{"data":{"source":"56","target":"55"}},{"data":{"source":"56","target":"46"}},{"data":{"source":"66","target":"65"}},{"data":{"source":"66","target":"56"}},{"data":{"source":"76","target":"75"}},{"data":{"source":"76","target":"66"}},{"data":{"source":"86","target":"85"}},{"data":{"source":"86","target":"76"}},{"data":{"source":"96","target":"95"}},{"data":{"source":"96","target":"86"}},{"data":{"source":"7","target":"6"}},{"data":{"source":"17","target":"16"}},{"data":{"source":"17","target":"7"}},{"data":{"source":"27","target":"26"}},{"data":{"source":"27","target":"17"}},{"data":{"source":"37","target":"36"}},{"data":{"source":"37","target":"27"}},{"data":{"source":"47","target":"46"}},{"data":{"source":"47","target":"37"}},{"data":{"source":"57","target":"56"}},{"data":{"source":"57","target":"47"}},{"data":{"source":"67","target":"66"}},{"data":{"source":"67","target":"57"}},{"data":{"source":"77","target":"76"}},{"data":{"source":"77","target":"67"}},{"data":{"source":"87","target":"86"}},{"data":{"source":"87","target":"77"}},{"data":{"source":"97","target":"96"}},{"data":{"source":"97","target":"87"}},{"data":{"source":"8","target":"7"}},{"data":{"source":"18","target":"17"}},{"data":{"source":"18","target":"8"}},{"data":{"source":"28","target":"27"}},{"data":{"source":"28","target":"18"}},{"data":{"source":"38","target":"37"}},{"data":{"source":"38","target":"28"}},{"data":{"source":"48","target":"47"}},{"data":{"source":"48","target":"38"}},{"data":{"source":"58","target":"57"}},{"data":{"source":"58","target":"48"}},{"data":{"source":"68","target":"67"}},{"data":{"source":"68","target":"58"}},{"data":{"source":"78","target":"77"}},{"data":{"source":"78","target":"68"}},{"data":{"source":"88","target":"87"}},{"data":{"source":"88","target":"78"}},{"data":{"source":"98","target":"97"}},{"data":{"source":"98","target":"88"}},{"data":{"source":"9","target":"8"}},{"data":{"source":"19","target":"18"}},{"data":{"source":"19","target":"9"}},{"data":{"source":"29","target":"28"}},{"data":{"source":"29","target":"19"}},{"data":{"source":"39","target":"38"}},{"data":{"source":"39","target":"29"}},{"data":{"source":"49","target":"48"}},{"data":{"source":"49","target":"39"}},{"data":{"source":"59","target":"58"}},{"data":{"source":"59","target":"49"}},{"data":{"source":"69","target":"68"}},{"data":{"source":"69","target":"59"}},{"data":{"source":"79","target":"78"}},{"data":{"source":"79","target":"69"}},{"data":{"source":"89","target":"88"}},{"data":{"source":"89","target":"79"}},{"data":{"source":"99","target":"98"}},{"data":{"source":"99","target":"89"}}]
}
See https://github.com/cytoscape/cytoscape.js-cose-bilkent/blob/1.6.12/src/Layout/index.js#L261
There really shouldn't be a setTimeout()
here. It might seem to work ok for the animate: 'end'
case, but it wouldn't work as expected for the animate: false
case.
For animate: false
, the layout is expected to run synchronously.
That is, bar()
runs after the layout is done.
cy.layout({ name: 'cose-bilkent', animate: false }).run();
bar();
This will always work:
cy.one('layoutstop', bar);
cy.layout({ name: 'cose-bilkent', animate: false }).run();
However, there is an expectation --- and it's so stated in the docs --- that a discrete layout run should be synchronous.
Correct me if I am wrong, but I search locked
in the codebase and find nothing.
In cose
layout, the gravitational/repulsion force takes locked
into consideration, see https://github.com/cytoscape/cytoscape.js/blob/master/src/extensions/layout/cose.js#L357 and https://github.com/cytoscape/cytoscape.js/blob/master/src/extensions/layout/cose.js#L529.
However, I did not see any locked
in https://github.com/cytoscape/cytoscape.js-cose-bilkent/blob/master/src/Layout/FDLayout.js#L208 and https://github.com/cytoscape/cytoscape.js-cose-bilkent/blob/master/src/Layout/FDLayout.js#L281.
I can work on a PR to respect locked nodes. Is there any algorithmic difficult on locked nodes? Thank you.
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.