Javascript 在Cytoscape.js中动态添加数据

Javascript 在Cytoscape.js中动态添加数据,javascript,cytoscape.js,Javascript,Cytoscape.js,我的设置是让一个图在线,然后获得一个新的图(通过对服务器的Ajax调用),并使用它来更新在线图。例如,我可能只想包括两个图中的节点 我想使用内置的set函数(这里:)来处理新旧图形,但我需要两个集合来完成。如果我将新图形添加到cy对象集合,则会立即绘制节点,并且我无法将它们作为新集合引用 我的解决方案是使用一个单独的cy对象,然后在这两个集合之间使用set操作。但正如我的例子所示,它并没有像预期的那样工作。这不仅仅是动画,这只是一个玩具用例。我可能要删除这些节点,或将它们移动到特定位置 出于某种

我的设置是让一个图在线,然后获得一个新的图(通过对服务器的Ajax调用),并使用它来更新在线图。例如,我可能只想包括两个图中的节点

我想使用内置的set函数(这里:)来处理新旧图形,但我需要两个集合来完成。如果我将新图形添加到
cy
对象集合,则会立即绘制节点,并且我无法将它们作为新集合引用

我的解决方案是使用一个单独的
cy
对象,然后在这两个集合之间使用set操作。但正如我的例子所示,它并没有像预期的那样工作。这不仅仅是动画,这只是一个玩具用例。我可能要删除这些节点,或将它们移动到特定位置

出于某种原因,这不起作用。也就是说,
just2
不是我希望的蓝色。有人能解释为什么不行,以及我需要做什么来修复它吗

var cy = cytoscape({

    container: document.getElementById('cy'), // container to render in

    style: [ // the stylesheet for the graph
        {
            selector: 'node',
            style: {
                'background-color': '#666',
                'label': 'data(id)'
            }
        },
    ],

    elements: {
        nodes: [
            { data: { id: 'n0' } },
            { data: { id: 'n1' } },
            { data: { id: 'n2' } },

        ],
            edges: [
            { data: { source: 'n0', target: 'n1' } },
            { data: { source: 'n1', target: 'n2' } }
        ]
    },
    layout: {
        name: 'grid'
    },

});

// Add new data here -- potentially the result of an Ajax call.
var newarray = [
    { data: { id: 'n0' } },
    { data: { id: 'n8' } },
    { data: { id: 'n9' } },
    { data: { source: 'n8', target: 'n9' } },
];

var cy2 = cytoscape(
    {
        elements: newarray,
        headless: true,
        renderer: { name: null }
    });

var el = cy.elements();
var cy2el = cy2.elements();

var both = el.intersection(cy2el);
var justel = el.difference(cy2el);
var just2 = cy2el.difference(el);

cy.add(cy2el);

// This works.
both.animate({
    style: { "background-color" : "yellow" }
}, {
    duration: 500,
});

// This works. 
justel.animate({
    style: { "background-color" : "red" }
}, {
    duration: 500,
});

// This does not work.
just2.animate({
    style: { "background-color" : "blue" }
}, {
    duration: 500,
});

这里可能会发生两件事,但是你的问题不够清楚,不知道你实际上在努力完成什么。您是否只是尝试创建一个图形并向其中添加节点/边

要解决您所说的just2.animate不起作用的问题,您使用了错误的函数。“动画”不用于设置样式转换的动画。对于该用例,您只需使用以下转换动画属性将其添加到样式表中:

对于更大的问题…您是否有意创建两个单独的图形,然后将两者结合使用?或者您的意图是创建一个单独的图形并向其中添加元素,而第二批元素的颜色与第一批元素的颜色不同

如果是后者,那么您可以简单地将newArray元素添加到第一个cytoscape实例中,并使用另一个样式选择器为它们指定不同的颜色


如果你能更具体地说明你想要完成的任务,那么帮助你会容易得多。

我对回答问题比较陌生……所以我希望我能通过添加另一个答案而不是完全改变第一个答案来正确地做这件事

根据您的说明,似乎最好、最有效、最明智的方法是只使用一个图形,并在运行时向其中添加新数据。如果您添加一个标识批处理或更新的数据元素,这将允许您只需使用新的选择器(您可以根据需要动态添加)即可完成所有您似乎想做的事情,如设置操作。这个例子对你有意义吗

var cy = window.cy = cytoscape({
  container: document.getElementById('cy'),
  elements: {
    nodes: [{
      data: {
        id: 'n0',
        batchID: 'b0'
      },
      classes: '.original_nodes'
    }, {
      data: {
        id: 'n1',
        batchID: 'b0'
      },
      classes: '.original_nodes'
    }, {
      data: {
        id: 'n2',
        batchID: 'b0'
      },
      classes: '.original_nodes'
    }],
    edges: [{
      data: {
        id: 'e0',
        batchID: 'b0',
        source: 'n0',
        target: 'n1'
      },
      classes: '.orginal_edges'
    }, {
      data: {
        id: 'e1',
        batchID: 'b0',
        source: 'n1',
        target: 'n2'
      },
      classes: '.orginal_edges'
    }]
  },
  style: [{
    // This is now essentially your default for the graph
    selector: 'node',
    style: {
      'background-color': '#666',
      'label': 'data(id)
    }
  }, {
    // This is for the original batch
    selector: '.original_nodes',
    style: {
      'background-color': '#666',
      'label': 'data(id)
    }
  }],
  layout: {
    name: 'grid'
  }
);


// Add new data here -- potentially the result of an Ajax call.
// Also, might want to reformat the array to be better ingested and more explicit about which ones are nodes or edges

var newarray = [{
  group: 'nodes',
  classes: '.b1_nodes',
  data: {
    id: 'n0',
    batchID: 'b1'
  }
}, {
  group: 'nodes',
  classes: '.b1_nodes',
  data: {
    id: 'n8',
    batchID: 'b1'
  }
}, {
  group: 'nodes',
  classes: '.b1_nodes',
  data: {
    id: 'n9',
    batchID: 'b1'
  }
}, {
  group: 'edges',
  classes: '.b1_edges',
  data: {
    id: 'e2',
    batchID: 'b1',
    source: 'n8',
    target: 'n9'
  }
}];

// Now, before we add the new data, let's create the new selector
cy.style().selector('.b1_nodes').style({
  'background-color': 'blue'
}).update();

cy.add(newarray);

我担心事情会变成这样。为每个批次包含一个id有点尴尬,但这似乎是最好的解决方案!一旦从Ajax调用返回新的图形元素,添加batchID就相对容易了。只需循环遍历每个元素并添加一个批处理ID…当然比您第一次使用的代码要少…如果您对答案感到满意,那么如果您可以将其标记为已回答就好了。