gpt4 book ai didi

javascript - Cytoscape.js 无法使用 cy.nodes().forEach 获得初始位置

转载 作者:行者123 更新时间:2023-11-30 20:29:04 25 4
gpt4 key购买 nike

我是 Cytoscape.js 的新手,到目前为止我真的很欣赏它的功能。我的问题如下:对于我的项目,我需要创建一个可以由用户修改的图表,并且我需要一个重置按钮来替换用户首先找到的所有元素。

我使用 cose-bilkent 布局,因为我获取没有位置信息的数据。

这是我的js代码。

var cy = cytoscape({
container: document.getElementById('cy'),

style: [{
selector: 'node',
style: {
shape: 'roundrectangle',
'background-color': 'red',
label: 'data(id )'
}
}, ],
});

cy.on('tap', 'node', function(evt) {
var node = evt.target;
console.log("tap", node.id(), node.position());
});

cy.add([{
data: {
id: 'a'
}
},
{
data: {
id: 'b'
}
},
{
data: {
id: 'c'
}
},

{
data: {
id: 'ab',
source: 'a',
target: 'b'
}
},
{
data: {
id: 'ac',
source: 'a',
target: 'c'
}
}
]);

cy.layout({
name: 'cose-bilkent',
avoidOverlap: true,
avoidOverlapPadding: 10,
}).run();

cy.nodes().forEach(function(ele) {
console.log("loop", ele.id(), ele.position());
});

当我点击一个节点后查看控制台时,我看到以下内容:

node c in console

我的问题是:为什么当我点击节点时,对象位置是正确的 ({x: 30, y: 30}),而在循环中对象是 {x:0, y:0}?

编辑:在 Stephan 的回答后,我将代码更改为以下内容:

var cy = cytoscape({
container: document.getElementById('cy'),

style: [
{
selector: 'node',
style: {
shape: 'roundrectangle',
'background-color': 'red',
label: 'data(id )'
}
},
],
});

cy.on('tap', 'node', function(evt) {
var node = evt.target;
console.log("tap", node.id(), node.position());
});

cy.add([
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{ data: { id: 'c' } },

{
data: {
id: 'ab',
source: 'a',
target: 'b'
}
},
{
data: {
id: 'ac',
source: 'a',
target: 'c'
}
}
]);

cy.layout({
name: 'cose-bilkent',
avoidOverlap: true,
avoidOverlapPadding: 10,
}).run();

setTimeout( function() {
cy.nodes().forEach(function(ele){
console.log("loop", ele.id(), ele.position());
});
}, 2000);

// Not Working :
// cy.ready( function() {
// cy.nodes().forEach(function(ele){
// console.log("loop", ele.id(), ele.position());
// });
// });

解决方案:

最后我找到了一个更好的解决方案:我使用事件“layoutstop”以便在正确的时刻开始位置的复制:

cy.on('layoutstop', function() {
cy.nodes().forEach(function(ele){
console.log("loop", ele.id(), ele.position().x, ele.position().y);
});
});

但是,如果您使用此解决方案,您必须知道它不适用于外部函数(出于某些未知原因)。因此以下将不起作用:

cy.on('layoutstop', copyPos());
function copyPos() {
cy.nodes().forEach(function(ele){
console.log("loop", ele.id(), ele.position().x, ele.position().y);
});
}

最佳答案

我测试了你的功能,它似乎对我来说工作正常,循环返回每个节点的模型位置(绝对位置)。我唯一想到的是在实际加载节点之前调用该函数:

var cy = cytoscape({
...
style: [...],
});

cy.on('tap', 'node', function(evt) {
var node = evt.target;
console.log("tap", node.id(), node.position());
});

cy.add([...]);

// Wait for the eles to be added
cy.layout({...}).run(); // Call layout on eles

cy.ready(function () { // Wait for cytoscape to actually load and map eles
cy.nodes().forEach(function(ele) { // Your function call inside
console.log("loop", ele.id(), ele.position());
});
});

在 cytoscape 的布局完全加载之前,所有节点都从位置 (0,0) 开始,然后更改(异步函数)。所以这可能就是为什么你的功能会这样做......

关于javascript - Cytoscape.js 无法使用 cy.nodes().forEach 获得初始位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50562657/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com