我有一个图形(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帖子,其中说必须使用类似:
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')
不起作用。
再次,非常感谢任何帮助。
答案 0 :(得分:1)
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之前手动复制对象。但是,大多数时候大多数开发人员都不需要复制。
一个对象不能拥有两个所有者。