在 Cytoscape.js 中动态添加数据
Adding data dynamically in Cytoscape.js
我的设置是先有一个在线图表,然后获取一个新图表(通过 Ajax 调用服务器)并使用它来更新在线图表。例如,我可能只想包含两个图中都存在的节点。
我想使用内置的集合函数(此处:http://js.cytoscape.org/#collection/building--filtering)来处理旧图和新图,但我需要两个集合才能完成。如果我将新图形添加到 cy
对象集合,则节点会立即绘制,我无法将它们作为新集合引用。
我的解决方案是有一个单独的 cy
对象,然后在这两个集合之间使用集合操作。但正如我的示例所示,它没有按预期工作。这不仅仅是动画,这只是一个玩具用例。我可能想删除这些节点,或将它们移动到特定位置。
出于某种原因,这不起作用。也就是说,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,
});
这里可能发生了两件事,但你的问题不够清楚,无法知道你实际想要完成的是什么。您只是想创建 一个 图表并向其添加 nodes/edges 吗?
要解决您所说的不适用于 just2.animate 的问题,您使用了错误的功能。 Animate 不适用于动画样式转换。对于 use-case 您只需使用此处找到的过渡动画属性添加到您的样式表:http://js.cytoscape.org/#style/transition-animation.
对于更大的问题...您是否有意创建两个单独的图表,然后将两者结合使用?或者您打算创建一个图形并向其中添加元素,第二批元素的颜色与第一批不同?
如果是后者,那么您只需将 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);
我的设置是先有一个在线图表,然后获取一个新图表(通过 Ajax 调用服务器)并使用它来更新在线图表。例如,我可能只想包含两个图中都存在的节点。
我想使用内置的集合函数(此处:http://js.cytoscape.org/#collection/building--filtering)来处理旧图和新图,但我需要两个集合才能完成。如果我将新图形添加到 cy
对象集合,则节点会立即绘制,我无法将它们作为新集合引用。
我的解决方案是有一个单独的 cy
对象,然后在这两个集合之间使用集合操作。但正如我的示例所示,它没有按预期工作。这不仅仅是动画,这只是一个玩具用例。我可能想删除这些节点,或将它们移动到特定位置。
出于某种原因,这不起作用。也就是说,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,
});
这里可能发生了两件事,但你的问题不够清楚,无法知道你实际想要完成的是什么。您只是想创建 一个 图表并向其添加 nodes/edges 吗?
要解决您所说的不适用于 just2.animate 的问题,您使用了错误的功能。 Animate 不适用于动画样式转换。对于 use-case 您只需使用此处找到的过渡动画属性添加到您的样式表:http://js.cytoscape.org/#style/transition-animation.
对于更大的问题...您是否有意创建两个单独的图表,然后将两者结合使用?或者您打算创建一个图形并向其中添加元素,第二批元素的颜色与第一批不同?
如果是后者,那么您只需将 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);