【问题标题】:Cytoscape.js can't get initial positions with cy.nodes().forEachCytoscape.js 无法使用 cy.nodes().forEach 获得初始位置
【发布时间】:2018-05-30 21:09:27
【问题描述】:

我是 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}?

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

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);
  });
}

【问题讨论】:

    标签: javascript cytoscape.js


    【解决方案1】:

    我测试了你的函数,它似乎对我很好,循环返回每个节点的模型位置(绝对位置)。我想到的唯一一件事是您在节点实际加载之前调用该函数:

    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) 开始,然后更改(异步函数)。所以这可能就是你的功能这样做的原因......

    【讨论】:

    • 感谢您的回答,这没有用。但是,考虑到这个想法,我设置了一个超时,它解决了我的问题。难道没有更好的方法吗?
    • setTimeout( function() { cy.nodes().forEach(function(ele){ console.log("loop", ele.id(), ele.position()); }) ; }, 2000);
    • 但它应该是这样工作的,你的超时功能在这里并不是真正的解决方案,你能显示你当前的代码吗?
    • 就像我说的,唯一造成麻烦的是,你的 position() 在你的图表准备好之前被调用了。
    • 您可以检查 cy.ready() 是否正常工作,方法是转到开发工具并在 cy.ready() 上设置断点,如果该函数在 cy.layout 之前调用().run() 完成,则错误来自于此,否则它应该可以工作。编辑:wiered,这从未发生在我身上,但我很高兴它现在有效
    猜你喜欢
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 2013-03-07
    • 2016-03-25
    相关资源
    最近更新 更多