Cytoscape.js - 为什么旧的 graphs/instances 在以编程方式添加新实例时消失?
Cytoscape.js - why do old graphs/instances disappear when new instances are added programmatically?
我创建了 "multiple instances" 示例 (https://js.cytoscape.org/demos/310dca83ba6970812dd0/) 的一个变体,其中不是在开头添加所有实例,而是一个新的 DIV 容器和一个 cytoscape 实例每次点击文档添加:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<title>Multiple instances</title>
<script src="https://js.cytoscape.org/js/cytoscape.min.js"></script>
</head>
<body>
<script>
var elesJson = {
nodes: [
{ data: { id: 'a', foo: 3, bar: 5, baz: 7 } },
{ data: { id: 'b', foo: 7, bar: 1, baz: 3 } },
{ data: { id: 'c', foo: 2, bar: 7, baz: 6 } },
{ data: { id: 'd', foo: 9, bar: 5, baz: 2 } },
{ data: { id: 'e', foo: 2, bar: 4, baz: 5 } }
],
edges: [
{ data: { id: 'ae', weight: 1, source: 'a', target: 'e' } },
{ data: { id: 'ab', weight: 3, source: 'a', target: 'b' } },
{ data: { id: 'be', weight: 4, source: 'b', target: 'e' } },
{ data: { id: 'bc', weight: 5, source: 'b', target: 'c' } },
{ data: { id: 'ce', weight: 6, source: 'c', target: 'e' } },
{ data: { id: 'cd', weight: 2, source: 'c', target: 'd' } },
{ data: { id: 'de', weight: 7, source: 'd', target: 'e' } }
]
};
var count = 1;
// add new container and cytoscape instance
document.onclick = function () {
var t = (count - 1) * 20;
// first, add the container
document.body.innerHTML += `<div id="cy${count}" style="position: absolute; left: 0; top: ${t}%; width: 100%; height: 20%; z-index: 999;"></div>`
// then, add the cytoscape instance
cytoscape({
container: document.getElementById(`cy${count}`),
style: cytoscape.stylesheet()
.selector('node')
.css({
'background-color': '#B3767E',
'width': 'mapData(baz, 0, 10, 10, 40)',
'height': 'mapData(baz, 0, 10, 10, 40)',
'content': 'data(id)'
})
.selector('edge')
.css({
'line-color': '#F2B1BA',
'target-arrow-color': '#F2B1BA',
'width': 2,
'target-arrow-shape': 'circle',
'opacity': 0.8
})
.selector(':selected')
.css({
'background-color': 'black',
'line-color': 'black',
'target-arrow-color': 'black',
'source-arrow-color': 'black',
'opacity': 1
})
.selector('.faded')
.css({
'opacity': 0.25,
'text-opacity': 0
}),
elements: elesJson,
layout: {
name: 'circle',
padding: 10
},
ready: function(){
// ready 1
}
});
// increment
count++;
}
</script>
</body>
</html>
我的预期是新实例出现在旧实例下方,但事实并非如此。
相反,新实例出现在预期位置,而旧实例消失了。旧实例的容器保留在 DOM.
我无法完全找到对这种行为的解释,尤其是因为所有其他内容都与原始示例中的一样。我在这里做错了什么?
Cytoscape 实例仍然存在,但是这些实例所附加的 DOM 元素会被新元素替换,因为您更改了整个 body.innerHTML
。
所以,基本上,而不是
document.body.innerHTML += `<div id="cy${count}" style="position: absolute; left: 0; top: ${t}%; width: 100%; height: 20%; z-index: 999;"></div>`
你应该做
let newCytoscapeInstanceContainer = document.createElement('div');
newCytoscapeInstanceContainer.id = `cy${count}`;
newCytoscapeInstanceContainer.style.cssText = `position: absolute; left: 0; top: ${t}%; width: 100%; height: 20%; z-index: 999;`;
document.body.appendChild(newCytoscapeInstanceContainer);
或使用 cy.mount()
将每个以前的 Cytoscape 实例绑定到新的 DOM 元素,但我不推荐。
我创建了 "multiple instances" 示例 (https://js.cytoscape.org/demos/310dca83ba6970812dd0/) 的一个变体,其中不是在开头添加所有实例,而是一个新的 DIV 容器和一个 cytoscape 实例每次点击文档添加:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<title>Multiple instances</title>
<script src="https://js.cytoscape.org/js/cytoscape.min.js"></script>
</head>
<body>
<script>
var elesJson = {
nodes: [
{ data: { id: 'a', foo: 3, bar: 5, baz: 7 } },
{ data: { id: 'b', foo: 7, bar: 1, baz: 3 } },
{ data: { id: 'c', foo: 2, bar: 7, baz: 6 } },
{ data: { id: 'd', foo: 9, bar: 5, baz: 2 } },
{ data: { id: 'e', foo: 2, bar: 4, baz: 5 } }
],
edges: [
{ data: { id: 'ae', weight: 1, source: 'a', target: 'e' } },
{ data: { id: 'ab', weight: 3, source: 'a', target: 'b' } },
{ data: { id: 'be', weight: 4, source: 'b', target: 'e' } },
{ data: { id: 'bc', weight: 5, source: 'b', target: 'c' } },
{ data: { id: 'ce', weight: 6, source: 'c', target: 'e' } },
{ data: { id: 'cd', weight: 2, source: 'c', target: 'd' } },
{ data: { id: 'de', weight: 7, source: 'd', target: 'e' } }
]
};
var count = 1;
// add new container and cytoscape instance
document.onclick = function () {
var t = (count - 1) * 20;
// first, add the container
document.body.innerHTML += `<div id="cy${count}" style="position: absolute; left: 0; top: ${t}%; width: 100%; height: 20%; z-index: 999;"></div>`
// then, add the cytoscape instance
cytoscape({
container: document.getElementById(`cy${count}`),
style: cytoscape.stylesheet()
.selector('node')
.css({
'background-color': '#B3767E',
'width': 'mapData(baz, 0, 10, 10, 40)',
'height': 'mapData(baz, 0, 10, 10, 40)',
'content': 'data(id)'
})
.selector('edge')
.css({
'line-color': '#F2B1BA',
'target-arrow-color': '#F2B1BA',
'width': 2,
'target-arrow-shape': 'circle',
'opacity': 0.8
})
.selector(':selected')
.css({
'background-color': 'black',
'line-color': 'black',
'target-arrow-color': 'black',
'source-arrow-color': 'black',
'opacity': 1
})
.selector('.faded')
.css({
'opacity': 0.25,
'text-opacity': 0
}),
elements: elesJson,
layout: {
name: 'circle',
padding: 10
},
ready: function(){
// ready 1
}
});
// increment
count++;
}
</script>
</body>
</html>
我的预期是新实例出现在旧实例下方,但事实并非如此。
相反,新实例出现在预期位置,而旧实例消失了。旧实例的容器保留在 DOM.
我无法完全找到对这种行为的解释,尤其是因为所有其他内容都与原始示例中的一样。我在这里做错了什么?
Cytoscape 实例仍然存在,但是这些实例所附加的 DOM 元素会被新元素替换,因为您更改了整个 body.innerHTML
。
所以,基本上,而不是
document.body.innerHTML += `<div id="cy${count}" style="position: absolute; left: 0; top: ${t}%; width: 100%; height: 20%; z-index: 999;"></div>`
你应该做
let newCytoscapeInstanceContainer = document.createElement('div');
newCytoscapeInstanceContainer.id = `cy${count}`;
newCytoscapeInstanceContainer.style.cssText = `position: absolute; left: 0; top: ${t}%; width: 100%; height: 20%; z-index: 999;`;
document.body.appendChild(newCytoscapeInstanceContainer);
或使用 cy.mount()
将每个以前的 Cytoscape 实例绑定到新的 DOM 元素,但我不推荐。