On a Cytoscape network that all the nodes are draggable, I want to click an edge connecting 2 particular nodes and access the (x,y) coordinates of the source and target nodes for some computation.
Here is the working code:
<script>src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.29.2/cytoscape.min.js"</script>
<div id="cy"></div>
var cy = cytoscape({
container: document.getElementById("cy"),
var cy = cytoscape({
container: document.getElementById("cy"),
elements: {
nodes: [
{
data: { id: "UK", name: "UK" },
position: { x: 100, y: 100 },
classes: "text_UK"
},
{
data: { id: "germany", name: "Germany" },
position: { x: 270, y: 340 },
classes: "germany"
}
],
edges: [
{
data: {
id: "UK2DE",
source: "UK",
target: "germany",
label: "UK_DE"
}
}
]
},
style: [
{
selector: "node.text_UK",
style: {
//shape: "rectangle",
"background-color": "#bbbbbb",
"background-image": svgtext_mkr("UK", "red"),
label: "data(name)",
width: 60,
height: 60,
opacity: 1.0
}
},
{
selector: "node.germany",
style: {
shape: "rectangle",
"background-color": "#ffffff",
"background-image": svg3colorIcon(
"black",
"red",
"rgb(256,200,0)",
"90"
),
//label: "data(name)",
label: function(ele){return ele.data("name")+"; x:"+ele.position("x").toFixed(1) + "; y:"+ele.position("y").toFixed(1)},
width: 90,
height: 60,
opacity: 0.9,
"text-halign": "right",
"text-valign": "top"
}
},
{
selector: "edge",
style: {
label: "data(label)",
width: 3,
"line-color": "#c0c",
"target-arrow-color": "#00c",
"curve-style": "bezier",
"target-arrow-shape": "triangle",
"target-arrow-fill": "#c00",
"arrow-scale": 2
}
},
//
{
selector: "edge#UK2DE",
style: {
label: "data(label)",
"source-label": "data(source)",
"target-label": "data(target)",
"source-text-offset": 20,
"target-text-offset": 25,
"text-rotation": "autorotate",
width: 3,
"line-color": "#c0c",
"target-arrow-color": "#00c",
"curve-style": "bezier",
"target-arrow-shape": "triangle",
"target-arrow-fill": "#c00",
"arrow-scale": 2
}
},
{
selector: ".highlight",
css: {
"background-color": "yellow"
}
}
],
layout: {
name: "preset"
}
})
cy.on('click','edge', function(e){
//console.log(this.source().id(), this.target().id());
const src = this.source().id();
const tgt = this.target().id();
console.log(`Src: ${src}, Target: ${tgt}`);
//console.log("Src(x,y):" + JSON.stringify( cy.$("#"+src).position() ));
//"Src(x,y):[object Object]" without stringify
//"Src(x,y):{'x':100,'y':100}"
//Use JSON.parse() to create object again
const srcxy = JSON.parse(JSON.stringify( cy.$("#"+src).position() ));
const tgtxy = JSON.parse(JSON.stringify( cy.$("#"+tgt).position() ));
console.log("Src(x,y): " + srcxy.x + ", " + srcxy.y);
console.log("Tgt(x,y): " + tgtxy.x + ", " + tgtxy.y);
});
My question is: how to avoid using JSON.parse(JSON.stringify(..))
to get access to the position of the node.