我有一个图(source credit),可以在其中选择一个(或多个)节点及其连接的边(选择一个节点时,边变为蓝色)。现在,如果我想在右键单击已经选择的节点之一时显示一个由所选节点和边组成的新图,该怎么办?
到目前为止,这是我所做的:
来自here的cytoscape.js
index.html
:
<!doctype html>
<!-- source: http://blog.js.cytoscape.org/public/demos/getting-started/index-layout.html -->
<html>
<head>
<meta charset="utf-8"></meta>
<title>Tutorial 1: Getting Started</title>
<script src="cytoscape.js"></script>
</head>
<style>
#cy {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
</style>
<body>
<div id="cy"></div>
<script>
var cy = cytoscape({
container: document.getElementById('cy'),
elements: [
// nodes
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{ data: { id: 'c' } },
{ data: { id: 'd' } },
{ data: { id: 'e' } },
{ data: { id: 'f' } },
// edges
{
data: {
id: 'ab',
source: 'a',
target: 'b'
}
},
{
data: {
id: 'cd',
source: 'c',
target: 'd'
}
},
{
data: {
id: 'ef',
source: 'e',
target: 'f'
}
},
{
data: {
id: 'ac',
source: 'a',
target: 'c'
}
},
{
data: {
id: 'be',
source: 'b',
target: 'e'
}
}
],
style: [
{
selector: 'node',
style: {
shape: 'vee',
'background-color': '#A60059',
label: 'data(id)'
}
}],
layout: {
name: 'grid'
}
});
cy.on('select', 'node', function(evt){
evt.cyTarget.connectedEdges().animate({
style: { lineColor: 'blue' }
});
});
/* cy.on('cxttap', 'node', function(evt) {
evt.cyTarget.connectedEdges().animate({
style: {lineColor: 'green'}
});
});*/
</script>
</body>
带注释的
cy.on('cxttap','node', function()...)
显示了在右键单击节点时将边缘变为绿色的事件处理。但是,如何获取(即加载)所有先前选择的节点和边到新图中(并显示它)?我看过this帖子,其中说必须使用sth:cy.$(':selected').jsons()
但老实说,我对如何做到这一点有些迷茫。任何帮助将不胜感激。
编辑:
好的,因此在maxkfranz的提示下,我能够将所选节点(及其边缘)移至另一个图
cy2
。因此,当我选择多个节点(`ctrl + drag-selector-over-nodes),然后右键单击所选节点之一时,它们会被绘制到另一个div中的新图形。这是我更新的代码(数据现在从外部json文件加载):testdata.json:
{ "nodes" : [
{"data": {"id": "a"}},
{"data": {"id": "b"}},
{"data": {"id": "c"}},
{"data": {"id": "d"}},
{"data": {"id": "e"}},
{"data": {"id": "f"}}
],
"edges" : [
{
"data": {
"id": "ab",
"source": "a",
"target": "b"
}
},
{
"data": {
"id": "cd",
"source": "c",
"target": "d"
}
},
{
"data": {
"id": "ef",
"source": "e",
"target": "f"
}
},
{
"data": {
"id": "ac",
"source": "a",
"target": "c"
}
},
{
"data": {
"id": "be",
"source": "b",
"target": "e"
}
}
]
}
index.html:
<!doctype html>
<!-- source: http://blog.js.cytoscape.org/public/demos/getting-started/index-layout.html -->
<html>
<head>
<meta charset="utf-8"></meta>
<title>Tutorial 1: Getting Started</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="cytoscape.js"></script>
</head>
<style>
#cy {
width: 50%;
height: 50%;
position: absolute;
top: 0px;
left: 0px;
}
#cy2 {
width: 50%;
height: 50%;
position: absolute;
top: 0px;
right: 0px;
}
</style>
<body>
<div id="cy"></div>
<div id="cy2"></div>
<script>
var cy2 = cytoscape({
container: document.getElementById('cy2'),
style: [
{
selector: 'node',
style: {
shape: 'vee',
'background-color': '#A60059',
label: 'data(id)'
}
}],
layout: {
name: 'grid'
}
});
$.getJSON("testdata.json", function (data) {
//console.log(data);
var cy = cytoscape({
container: document.getElementById('cy'),
elements: data,
style: [
{
selector: 'node',
style: {
shape: 'vee',
'background-color': '#A60059',
label: 'data(id)'
}
}],
layout: {
name: 'grid'
}
});
cy.on('select', 'node', function(evt){
evt.cyTarget.connectedEdges().animate({
style: { lineColor: 'blue' }
});
evt.cyTarget.nodes().animate({
style: {'background-color': 'yellow'}
});
});
cy.on('cxttap', 'node', function(evt) {
var newData = cy.$(':selected');
console.log(newData);
cy2.add(newData.jsons());
});
console.log(cy.$('node:selected'));
});
</script>
</body>
现在的问题是,这对于同时选择的节点及其egdes可以按预期工作。但是,如果我首先选择节点
c
和d
,然后在下一步中选择节点a
,当单击节点a
时,新图cy2
将仅包含该单个节点,而没有其他先前选择的节点。现在我想我可以选择所有背景颜色为黄色且带有边缘的节点(然后,原则上应返回所有曾经选择的节点)。但是问题是我不知道该怎么做。就像是cy.$('background-color:yellow')
不起作用。
再次,这里的任何帮助将不胜感激。
最佳答案
cy2.add( copy( elementsOfInterest.jsons() ) );
// where copy deep copies json, e.g. obj => _.cloneDeep(obj) or obj => JSON.parse( JSON.stringify(obj) )
参见文档:http://js.cytoscape.org/#notation/object-ownership
当将对象传递到Cytoscape.js来创建元素,动画,布局等时,这些对象被视为Cytoscape所拥有。像元素这样的对象具有多个层次,每次将它们传递给Cytoscape时都要对这些对象进行深层复制,这会产生额外的费用。如果需要,开发人员可以在将对象传递给Cytoscape之前手动对其进行复制。但是,大多数情况下,大多数开发人员无需复制。
一个对象不能有两个所有者。
关于javascript - 右键单击cytoscape.js在新图中显示选定的节点和边,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46333439/