我有一个图表( source credit ),我可以在其中选择一个(或多个)节点及其连接的边(当我选择节点时,边会变成蓝色)。现在,如果我想在右键单击已选择的节点之一时显示由所选节点和边组成的新图形,我该怎么办?
这是我到目前为止所做的事情:
cytoscape.js
来自here
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('cxtap','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>
现在的问题是,对于同时选择的节点及其边缘,这是否按预期工作。但是,如果我例如首先选择节点 c
和 d
,然后在下一步中,单击节点 a
时选择节点 a
> 新图cy2
将仅包含此单个节点,而不包含其他先前选择的节点。现在我想我可以例如选择所有边缘背景颜色为黄色的节点(原则上,这应该返回所有曾经选择的节点)。但问题是我不知道该怎么做。类似的东西
cy.$('背景颜色:黄色')
不起作用。
再次强调,如果您能提供任何帮助,我们将不胜感激。
最佳答案
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
When passing objects to Cytoscape.js for creating elements, animations, layouts, etc., the objects are considered owned by Cytoscape. Objects like elements have several levels to them, and doing deep copies of those objects every time they are passed to Cytoscape creates additional expense. When desired, the dev can copy objects manually before passing them to Cytoscape. However, copying is not necessary for most developers most of the time.
一个对象不能有两个所有者。
关于javascript - cytoscape.js 右键单击新图中显示选定的节点和边,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46333439/