如何使用cytoscape.js保存和还原复合节点的布局 [英] How to save and restore layout of compound nodes using cytoscape.js

查看:113
本文介绍了如何使用cytoscape.js保存和还原复合节点的布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JavaScript库 cytoscape.js 绘制一些拓扑图.

我可以使用以下代码段保存和恢复非复合节点的布局.

 < button id =保存" class ="button">保存</button>< button id ="reload" class ="button"> reload</button>document.getElementById("save").addEventListener("click",function(){window.localStorage.setItem('savedlayout',JSON.stringify(cy.json()));});document.getElementById("reload").addEventListener("click",function(){cy.json(JSON.parse(window.localStorage.getItem('savedlayout'))));}); 

此解决方案似乎不适用于复合节点的情况.我已经下载了一些复合节点演示,并尝试添加上面的代码片段,无法正确还原布局.

请参阅我的演示.您可以拖动任何节点,然后单击 save 按钮,然后拖动某些节点并单击 restore .

  document.addEventListener('DOMContentLoaded',function(){var cy = window.cy = cytoscape({容器:document.getElementById('cy'),准备就绪:function(){this.nodes().forEach(function(node){设宽度= [30,70,110];let size = width [Math.floor(Math.random()* 3)];node.css("width",size);node.css("height",size);});this.layout({name:'cose-bilkent',animationDuration:1000}).run();},风格: [{选择器:节点",风格: {'背景颜色':'#ad1a66'}},{选择器:':parent',风格: {背景不透明度":0.333}},{选择器:"edge",风格: {'宽度':3,'line-color':'#ad1a66'}}],元素:[{组:'节点',数据:{id:'n0'}},{组:节点",数据:{id:"n1"}},{组:节点",数据:{id:"n2"}},{组:节点",数据:{id:"n3"}},{组:节点",数据:{id:"n4",父级:"n37"}},{组:节点",数据:{id:"n5"}},{组:节点",数据:{id:"n6"}},{组:节点",数据:{id:"n7",父级:"n37"}},{组:节点",数据:{id:"n8",父级:"n37"}},{组:节点",数据:{id:"n9",父级:"n37"}},{组:节点",数据:{id:"n10",父级:"n38"}},{组:节点",数据:{id:"n12"}},{组:节点",数据:{id:"n13"}},{组:节点",数据:{id:"n14"}},{组:节点",数据:{id:"n15"}},{组:节点",数据:{id:"n16"}},{组:节点",数据:{id:"n17"}},{组:节点",数据:{id:"n18"}},{group:'nodes',数据:{id:'n19'}},{组:节点",数据:{id:"n20"}},{group:'nodes',数据:{id:'n21'}},{组:节点",数据:{id:"n22"}},{group:'nodes',数据:{id:'n23'}},{组:节点",数据:{id:"n24",父级:"n39"}},{组:节点",数据:{id:"n25",父级:"n39"}},{组:节点",数据:{id:"n26",父级:"n42"}},{组:节点",数据:{id:"n27",父级:"n42"}},{组:节点",数据:{id:"n28",父级:"n42"}},{组:节点",数据:{id:"n29",父级:"n40"}},{组:节点",数据:{id:"n31",父级:"n41"}},{组:节点",数据:{id:"n32",父级:"n41"}},{组:节点",数据:{id:"n33",父级:"n41"}},{组:节点",数据:{id:"n34",父级:"n41"}},{组:节点",数据:{id:"n35",父级:"n41"}},{组:节点",数据:{id:"n36",父级:"n41"}},{组:节点",数据:{id:"n37"}},{组:节点",数据:{id:"n38"}},{组:节点",数据:{id:"n39",父级:"n43"}},{组:节点",数据:{id:"n40",父级:"n42"}},{组:节点",数据:{id:"n41",父级:"n42"}},{组:节点",数据:{id:"n42",父级:"n43"}},{组:节点",数据:{id:"n43"}},{group:'edges',数据:{id:'e0',来源:'n0',目标:'n1'}},{group:'edges',数据:{id:'e1',来源:'n1',目标:'n2'}},{group:'edges',数据:{id:'e2',来源:'n2',目标:'n3'}},{group:'edges',数据:{id:'e3',来源:'n0',目标:'n3'}},{group:'edges',数据:{id:'e4',来源:'n1',目标:'n4'}},{group:'edges',数据:{id:'e5',来源:'n2',目标:'n4'}},{group:'edges',数据:{id:'e6',来源:'n4',目标:'n5'}},{group:'edges',数据:{id:'e7',来源:'n5',目标:'n6'}},{group:'edges',数据:{id:'e8',来源:'n4',目标:'n6'}},{group:'edges',数据:{id:'e9',来源:'n4',目标:'n7'}},{group:'edges',数据:{id:'e10',来源:'n7',目标:'n8'}},{group:'edges',数据:{id:'e11',来源:'n8',目标:'n9'}},{group:'edges',数据:{id:'e12',来源:'n7',目标:'n9'}},{group:'edges',数据:{id:'e13',来源:'n13',目标:'n14'}},{group:'edges',数据:{id:'e14',来源:'n12',目标:'n14'}},{group:'edges',数据:{id:'e15',来源:'n14',目标:'n15'}},{group:'edges',数据:{id:'e16',来源:'n14',目标:'n16'}},{group:'edges',数据:{id:'e17',来源:'n15',目标:'n17'}},{group:'edges',数据:{id:'e18',来源:'n17',目标:'n18'}},{group:'edges',数据:{id:'e19',来源:'n18',目标:'n19'}},{group:'edges',数据:{id:'e20',来源:'n17',目标:'n20'}},{group:'edges',数据:{id:'e21',来源:'n19',目标:'n20'}},{group:'edges',数据:{id:'e22',来源:'n16',目标:'n20'}},{group:'edges',数据:{id:'e23',来源:'n20',目标:'n21'}},{group:'edges',数据:{id:'e25',来源:'n23',目标:'n24'}},{group:'edges',数据:{id:'e26',来源:'n24',目标:'n25'}},{group:'edges',数据:{id:'e27',来源:'n26',目标:'n38'}},{group:'edges',数据:{id:'e29',来源:'n26',目标:'n39'}},{group:'edges',数据:{id:'e30',来源:'n26',目标:'n27'}},{group:'edges',数据:{id:'e31',来源:'n26',目标:'n28'}},{group:'edges',数据:{id:'e33',来源:'n21',目标:'n31'}},{group:'edges',数据:{id:'e35',来源:'n31',目标:'n33'}},{group:'edges',数据:{id:'e36',来源:'n31',目标:'n34'}},{group:'edges',数据:{id:'e37',来源:'n33',目标:'n34'}},{group:'edges',数据:{id:'e38',来源:'n32',目标:'n35'}},{group:'edges',数据:{id:'e39',来源:'n32',目标:'n36'}},{group:'edges',数据:{id:'e40',来源:'n16',目标:'n40'}}],elements1:[{组:'节点',数据:{id:'n0'}},{组:节点",数据:{id:"n1"}},{组:节点",数据:{id:"n2"}},{组:节点",数据:{id:"n3"}},{组:节点",数据:{id:"n4",parent1:"n37"}},{组:节点",数据:{id:"n5"}},{组:节点",数据:{id:"n6"}},{组:节点",数据:{id:"n7",parent1:"n37"}},{组:节点",数据:{id:"n8",parent1:"n37"}},{组:节点",数据:{id:"n9",parent1:"n37"}},{组:节点",数据:{id:"n10",parent1:"n38"}},{组:节点",数据:{id:"n12"}},{组:节点",数据:{id:"n13"}},{组:节点",数据:{id:"n14"}},{组:节点",数据:{id:"n15"}},{组:节点",数据:{id:"n16"}},{组:节点",数据:{id:"n17"}},{组:节点",数据:{id:"n18"}},{group:'nodes',数据:{id:'n19'}},{组:节点",数据:{id:"n20"}},{group:'nodes',数据:{id:'n21'}},{组:节点",数据:{id:"n22"}},{group:'nodes',数据:{id:'n23'}},{组:节点",数据:{id:"n24",parent1:"n39"}},{组:节点",数据:{id:"n25",parent1:"n39"}},{组:节点",数据:{id:"n26",parent1:"n42"}},{组:节点",数据:{id:"n27",parent1:"n42"}},{组:节点",数据:{id:"n28",parent1:"n42"}},{组:节点",数据:{id:"n29",parent1:"n40"}},{组:节点",数据:{id:"n31",parent1:"n41"}},{组:节点",数据:{id:"n32",parent1:"n41"}},{组:节点",数据:{id:"n33",parent1:"n41"}},{组:节点",数据:{id:"n34",parent1:"n41"}},{组:节点",数据:{id:"n35",parent1:"n41"}},{组:节点",数据:{id:"n36",parent1:"n41"}},{group:'edges',数据:{id:'e0',来源:'n0',目标:'n1'}},{group:'edges',数据:{id:'e1',来源:'n1',目标:'n2'}},{group:'edges',数据:{id:'e2',来源:'n2',目标:'n3'}},{group:'edges',数据:{id:'e3',来源:'n0',目标:'n3'}},{group:'edges',数据:{id:'e4',来源:'n1',目标:'n4'}},{group:'edges',数据:{id:'e5',来源:'n2',目标:'n4'}},{group:'edges',数据:{id:'e6',来源:'n4',目标:'n5'}},{group:'edges',数据:{id:'e7',来源:'n5',目标:'n6'}},{group:'edges',数据:{id:'e8',来源:'n4',目标:'n6'}},{group:'edges',数据:{id:'e9',来源:'n4',目标:'n7'}},{group:'edges',数据:{id:'e10',来源:'n7',目标:'n8'}},{group:'edges',数据:{id:'e11',来源:'n8',目标:'n9'}},{group:'edges',数据:{id:'e12',来源:'n7',目标:'n9'}},{group:'edges',数据:{id:'e13',来源:'n13',目标:'n14'}},{group:'edges',数据:{id:'e14',来源:'n12',目标:'n14'}},{group:'edges',数据:{id:'e15',来源:'n14',目标:'n15'}},{group:'edges',数据:{id:'e16',来源:'n14',目标:'n16'}},{group:'edges',数据:{id:'e17',来源:'n15',目标:'n17'}},{group:'edges',数据:{id:'e18',来源:'n17',目标:'n18'}},{group:'edges',数据:{id:'e19',来源:'n18',目标:'n19'}},{group:'edges',数据:{id:'e20',来源:'n17',目标:'n20'}},{group:'edges',数据:{id:'e21',来源:'n19',目标:'n20'}},{group:'edges',数据:{id:'e22',来源:'n16',目标:'n20'}},{group:'edges',数据:{id:'e23',来源:'n20',目标:'n21'}},{group:'edges',数据:{id:'e25',来源:'n23',目标:'n24'}},{group:'edges',数据:{id:'e26',来源:'n24',目标:'n25'}},{group:'edges',数据:{id:'e30',来源:'n26',目标:'n27'}},{group:'edges',数据:{id:'e31',来源:'n26',目标:'n28'}},{group:'edges',数据:{id:'e33',来源:'n21',目标:'n31'}},{group:'edges',数据:{id:'e35',来源:'n31',目标:'n33'}},{group:'edges',数据:{id:'e36',来源:'n31',目标:'n34'}},{group:'edges',数据:{id:'e37',来源:'n33',目标:'n34'}},{group:'edges',数据:{id:'e38',来源:'n32',目标:'n35'}},{group:'edges',数据:{id:'e39',来源:'n32',目标:'n36'}},]});document.getElementById("layoutButton").addEventListener("click",function(){var layout = cy.layout({名称:风俗",动画:结束",animationEasing:缓出",animationDuration:1000,随机化:真});layout.run();});document.getElementById("randomize").addEventListener("click",function(){var layout = cy.layout({名称:"random",动画:是的,animationDuration:1000,animationEasing:缓出"});layout.run();});document.getElementById("save").addEventListener("click",function(){window.localStorage.setItem('savedlayout',JSON.stringify(cy.json()));});document.getElementById("reload").addEventListener("click",function(){cy.json(JSON.parse(window.localStorage.getItem('savedlayout'))));});});  

  body {字体家族:helvetica;font-size:14px;}#cy {宽度:100%;高度:90%;z索引:999;}h1 {不透明度:0.5;字号:1em;}按钮 {右边距:10px;}  

 <脚本src ="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></脚本><!-对于IE之类的旧浏览器,此扩展程序需要使用polyfills->< script src ="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.5.7/shim.min.js"></script>< script src ="https://unpkg.com/layout-base/layout-base.js"></script>< script src ="https://unpkg.com/cose-base/cose-base.js"></script>< script src ="https://unpkg.com/cytoscape-cose-bilkent/cytoscape-cose-bilkent.js"</script>< button id ="randomize" type ="button"> Randomize</button>< button id ="layoutButton" type ="button"> CoSE-Bilkent</button>< button id ="save" class ="button"> save</button>< button id ="reload" class ="button"> reload</button>< div id ="cy"></div>  

解决方案

在@Ravenous指出cy.json()的好处之后,我再次尝试了此方法:

如果在添加旧元素之前先删除其他元素,则在本示例中使用 cy.json()效果很好.

只要您运行预设布局,代码也将如下所示:

  document.getElementById("save").addEventListener("click",函数(){window.localStorage.setItem("elements",JSON.stringify(cy.json()));});document.getElementById("reload").addEventListener("click",function(){cy.elements().remove();cy.json({元素:JSON.parse(window.localStorage.getItem("elements")).elements}).layout({{name:'preset'}).run();}); 

  document.getElementById("save").addEventListener("click",function(){window.localStorage.setItem("elements",JSON.stringify({节点:cy.nodes.jsons(),边缘:cy.edges.jsons()}));});document.getElementById("reload").addEventListener("click",function(){cy.elements().remove();cy.add(JSON.parse(window.localStorage.getItem("elements"))).layout({name:'preset'}).run();}); 



旧答案:

此问题已经得到解决

  var elements1 = [{组:节点",数据: {id:"n0"}},{组:节点",数据: {id:"n1"}},{组:节点",数据: {id:"n2"}},{组:节点",数据: {id:"n3"}},{组:节点",数据: {id:"n4",parent1:"n37"}},{组:节点",数据: {id:"n5"}},{组:节点",数据: {id:"n6"}},{组:节点",数据: {id:"n7",parent1:"n37"}},{组:节点",数据: {id:"n8",parent1:"n37"}},{组:节点",数据: {id:"n9",parent1:"n37"}},{组:节点",数据: {id:"n10",parent1:"n38"}},{组:节点",数据: {id:"n12"}},{组:节点",数据: {id:"n13"}},{组:节点",数据: {id:"n14"}},{组:节点",数据: {id:"n15"}},{组:节点",数据: {id:"n16"}},{组:节点",数据: {id:"n17"}},{组:节点",数据: {id:"n18"}},{组:节点",数据: {id:"n19"}},{组:节点",数据: {id:"n20"}},{组:节点",数据: {id:"n21"}},{组:节点",数据: {id:"n22"}},{组:节点",数据: {id:"n23"}},{组:节点",数据: {id:"n24",parent1:"n39"}},{组:节点",数据: {id:"n25",parent1:"n39"}},{组:节点",数据: {id:"n26",parent1:"n42"}},{组:节点",数据: {id:"n27",parent1:"n42"}},{组:节点",数据: {id:"n28",parent1:"n42"}},{组:节点",数据: {id:"n29",parent1:"n40"}},{组:节点",数据: {id:"n31",parent1:"n41"}},{组:节点",数据: {id:"n32",parent1:"n41"}},{组:节点",数据: {id:"n33",parent1:"n41"}},{组:节点",数据: {id:"n34",parent1:"n41"}},{组:节点",数据: {id:"n35",parent1:"n41"}},{组:节点",数据: {id:"n36",parent1:"n41"}},{组:边缘",数据: {id:"e0",来源:"n0",目标:"n1"}},{组:边缘",数据: {id:"e1",来源:"n1",目标:"n2"}},{组:边缘",数据: {id:"e2",来源:"n2",目标:"n3"}},{组:边缘",数据: {id:"e3",来源:"n0",目标:"n3"}},{组:边缘",数据: {id:"e4",来源:"n1",目标:"n4"}},{组:边缘",数据: {id:"e5",来源:"n2",目标:"n4"}},{组:边缘",数据: {id:"e6",来源:"n4",目标:"n5"}},{组:边缘",数据: {id:"e7",来源:"n5",目标:"n6"}},{组:边缘",数据: {id:"e8",来源:"n4",目标:"n6"}},{组:边缘",数据: {id:"e9",来源:"n4",目标:"n7"}},{组:边缘",数据: {id:"e10",来源:"n7",目标:"n8"}},{组:边缘",数据: {id:"e11",来源:"n8",目标:"n9"}},{组:边缘",数据: {id:"e12",来源:"n7",目标:"n9"}},{组:边缘",数据: {id:"e13",来源:"n13",目标:"n14"}},{组:边缘",数据: {id:"e14",来源:"n12",目标:"n14"}},{组:边缘",数据: {id:"e15",来源:"n14",目标:"n15"}},{组:边缘",数据: {id:"e16",来源:"n14",目标:"n16"}},{组:边缘",数据: {id:"e17",来源:"n15",目标:"n17"}},{组:边缘",数据: {id:"e18",来源:"n17",目标:"n18"}},{组:边缘",数据: {id:"e19",来源:"n18",目标:"n19"}},{组:边缘",数据: {id:"e20",来源:"n17",目标:"n20"}},{组:边缘",数据: {id:"e21",来源:"n19",目标:"n20"}},{组:边缘",数据: {id:"e22",来源:"n16",目标:"n20"}},{组:边缘",数据: {id:"e23",来源:"n20",目标:"n21"}},{组:边缘",数据: {id:"e25",来源:"n23",目标:"n24"}},{组:边缘",数据: {id:"e26",来源:"n24",目标:"n25"}},{组:边缘",数据: {id:"e30",来源:"n26",目标:"n27"}},{组:边缘",数据: {id:"e31",来源:"n26",目标:"n28"}},{组:边缘",数据: {id:"e33",来源:"n21",目标:"n31"}},{组:边缘",数据: {id:"e35",来源:"n31",目标:"n33"}},{组:边缘",数据: {id:"e36",来源:"n31",目标:"n34"}},{组:边缘",数据: {id:"e37",来源:"n33",目标:"n34"}},{组:边缘",数据: {id:"e38",来源:"n32",目标:"n35"}},{组:边缘",数据: {id:"e39",来源:"n32",目标:"n36"}}];document.addEventListener("DOMContentLoaded",function(){var cy =(window.cy = cytoscape({容器:document.getElementById("cy"),准备好了:function(){this.nodes().forEach(function(node){设宽度= [30,70,110];let size = width [Math.floor(Math.random()* 3)];node.css("width",size);node.css("height",size);});this.layout({名称:高价位的钞票",animationDuration:1000}).跑步();},风格: [{选择器:节点",风格: {'content':'data(id)','text-valign':'居中','text-halign':'center','背景颜色':'#ad1a66'}},{选择器::parent",风格: {背景不透明度":0.333}},{选择器:边缘",风格: {宽度:3,"line-color":#ad1a66"}}],元素:[{组:节点",数据: {id:"n0"}},{组:节点",数据: {id:"n1"}},{组:节点",数据: {id:"n2"}},{组:节点",数据: {id:"n3"}},{组:节点",数据: {id:"n4",父母:"n37"}},{组:节点",数据: {id:"n5"}},{组:节点",数据: {id:"n6"}},{组:节点",数据: {id:"n7",父母:"n37"}},{组:节点",数据: {id:"n8",父母:"n37"}},{组:节点",数据: {id:"n9",父母:"n37"}},{组:节点",数据: {id:"n10",父母:"n38"}},{组:节点",数据: {id:"n12"}},{组:节点",数据: {id:"n13"}},{组:节点",数据: {id:"n14"}},{组:节点",数据: {id:"n15"}},{组:节点",数据: {id:"n16"}},{组:节点",数据: {id:"n17"}},{组:节点",数据: {id:"n18"}},{组:节点",数据: {id:"n19"}},{组:节点",数据: {id:"n20"}},{组:节点",数据: {id:"n21"}},{组:节点",数据: {id:"n22"}},{组:节点",数据: {id:"n23"}},{组:节点",数据: {id:"n24",父母:"n39"}},{组:节点",数据: {id:"n25",父母:"n39"}},{组:节点",数据: {id:"n26",父母:"n42"}},{组:节点",数据: {id:"n27",父母:"n42"}},{组:节点",数据: {id:"n28",父母:"n42"}},{组:节点",数据: {id:"n29",父母:"n40"}},{组:节点",数据: {id:"n31",父母:"n41"}},{组:节点",数据: {id:"n32",父母:"n41"}},{组:节点",数据: {id:"n33",父母:"n41"}},{组:节点",数据: {id:"n34",父母:"n41"}},{组:节点",数据: {id:"n35",父母:"n41"}},{组:节点",数据: {id:"n36",父母:"n41"}},{组:节点",数据: {id:"n37"}},{组:节点",数据: {id:"n38"}},{组:节点",数据: {id:"n39",父母:"n43"}},{组:节点",数据: {id:"n40",父母:"n42"}},{组:节点",数据: {id:"n41",父母:"n42"}},{组:节点",数据: {id:"n42",父母:"n43"}},{组:节点",数据: {id:"n43"}},{组:边缘",数据: {id:"e0",来源:"n0",目标:"n1"}},{组:边缘",数据: {id:"e1",来源:"n1",目标:"n2"}},{组:边缘",数据: {id:"e2",来源:"n2",目标:"n3"}},{组:边缘",数据: {id:"e3",来源:"n0",目标:"n3"}},{组:边缘",数据: {id:"e4",来源:"n1",目标:"n4"}},{组:边缘",数据: {id:"e5",来源:"n2",目标:"n4"}},{组:边缘",数据: {id:"e6",来源:"n4",目标:"n5"}},{组:边缘",数据: {id:"e7",来源:"n5",目标:"n6"}},{组:边缘",数据: {id:"e8",来源:"n4",目标:"n6"}},{组:边缘",数据: {id:"e9",来源:"n4",目标:"n7"}},{组:边缘",数据: {id:"e10",来源:"n7",目标:"n8"}},{组:边缘",数据: {id:"e11",来源:"n8",目标:"n9"}},{组:边缘",数据: {id:"e12",来源:"n7",目标:"n9"}},{组:边缘",数据: {id:"e13",来源:"n13",目标:"n14"}},{组:边缘",数据: {id:"e14",来源:"n12",目标:"n14"}},{组:边缘",数据: {id:"e15",来源:"n14",目标:"n15"}},{组:边缘",数据: {id:"e16",来源:"n14",目标:"n16"}},{组:边缘",数据: {id:"e17",来源:"n15",目标:"n17"}},{组:边缘",数据: {id:"e18",来源:"n17",目标:"n18"}},{组:边缘",数据: {id:"e19",来源:"n18",目标:"n19"}},{组:边缘",数据: {id:"e20",来源:"n17",目标:"n20"}},{组:边缘",数据: {id:"e21",来源:"n19",目标:"n20"}},{组:边缘",数据: {id:"e22",来源:"n16",目标:"n20"}},{组:边缘",数据: {id:"e23",来源:"n20",目标:"n21"}},{组:边缘",数据: {id:"e25",来源:"n23",目标:"n24"}},{组:边缘",数据: {id:"e26",来源:"n24",目标:"n25"}},{组:边缘",数据: {id:"e27",来源:"n26",目标:"n38"}},{组:边缘",数据: {id:"e29",来源:"n26",目标:"n39"}},{组:边缘",数据: {id:"e30",来源:"n26",目标:"n27"}},{组:边缘",数据: {id:"e31",来源:"n26",目标:"n28"}},{组:边缘",数据: {id:"e33",来源:"n21",目标:"n31"}},{组:边缘",数据: {id:"e35",来源:"n31",目标:"n33"}},{组:边缘",数据: {id:"e36",来源:"n31",目标:"n34"}},{组:边缘",数据: {id:"e37",来源:"n33",目标:"n34"}},{组:边缘",数据: {id:"e38",来源:"n32",目标:"n35"}},{组:边缘",数据: {id:"e39",来源:"n32",目标:"n36"}},{组:边缘",数据: {id:"e40",来源:"n16",目标:"n40"}}],}));document.getElementById("layoutButton").addEventListener("click",function(){var layout = cy.layout({名称:高价位的钞票",动画:结束",animationEasing:缓出",animationDuration:1000,随机化:真});layout.run();});document.getElementById("randomize").addEventListener("click",function(){var layout = cy.layout({名称:随机",动画:是的,animationDuration:1000,animationEasing:缓出"});layout.run();});document.getElementById("save").addEventListener("click",function(){window.localStorage.setItem("elements",JSON.stringify(cy.json()));});document.getElementById("reload").addEventListener("click",function(){cy.elements().remove();cy.json({元素:JSON.parse(window.localStorage.getItem("elements")).elements}).布局({名称:预设"}).跑步();cy.fit();cy.center();});});  

  body {字体家族:helvetica;font-size:14px;}#cy {高度:100%;宽度:90%;位置:绝对;}h1 {不透明度:0.5;字号:1em;}按钮 {右边距:10px;}  

 <脚本src ="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></脚本><!-对于IE之类的旧浏览器,此扩展程序需要使用polyfills->< script src ="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.5.7/shim.min.js"></script>< script src ="https://unpkg.com/layout-base/layout-base.js"></script>< script src ="https://unpkg.com/cose-base/cose-base.js"></script>< script src ="https://cdn.jsdelivr.net/npm/cytoscape-cose-bilkent@4.1.0/cytoscape-cose-bilkent.min.js"</script>< body>< button id ="randomize" type ="button"> Randomize</button>< button id ="layoutButton" type ="button"> CoSE-Bilkent</button>< button id ="save" class ="button"> save</button>< button id ="reload" class ="button"> reload</button>< div id ="cy"></div></body>  

I'm using the JavaScript library cytoscape.js to draw some topology graph.

I could use the following snippet to save and restore layout for non-compound nodes case.

<button id="save" class="button">save</button>
<button id="reload" class="button">reload</button>

document.getElementById("save").addEventListener("click", function(){
    window.localStorage.setItem('savedlayout', JSON.stringify(cy.json()));
});

document.getElementById("reload").addEventListener("click", function(){
    cy.json(JSON.parse(window.localStorage.getItem('savedlayout')));
});

This solution seems not working for compound nodes case. I have downloaded some compound nodes demos and tried to add my above snippet, the layout can't be restored correctly.

Please see my demo. You could drag any nodes and click save button, then drag some nodes and click restore.

document.addEventListener('DOMContentLoaded', function(){

        var cy = window.cy = cytoscape({
          container: document.getElementById('cy'),

          ready: function(){
            this.nodes().forEach(function(node){
              let width = [30, 70, 110];
              let size = width[Math.floor(Math.random()*3)];
              node.css("width", size);
              node.css("height", size);
            });
            this.layout({name: 'cose-bilkent', animationDuration: 1000}).run();
          },
            
          style: [
            {
              selector: 'node',
              style: {
                'background-color': '#ad1a66'
              }
            },

            {
              selector: ':parent',
              style: {
                'background-opacity': 0.333
              }
            },

            {
              selector: 'edge',
              style: {
                'width': 3,
                'line-color': '#ad1a66'
              }
            }
          ],

            elements: [{ group:'nodes', data:{ id: 'n0'}},
                    { group:'nodes', data:{ id: 'n1'}},
                    { group:'nodes', data:{ id: 'n2'}},
                    { group:'nodes', data:{ id: 'n3'}},
                    { group:'nodes', data:{ id: 'n4', parent: 'n37'}},
                    { group:'nodes', data:{ id: 'n5'}},
                    { group:'nodes', data:{ id: 'n6'}},
                    { group:'nodes', data:{ id: 'n7', parent: 'n37'}},
                    { group:'nodes', data:{ id: 'n8', parent: 'n37'}},
                    { group:'nodes', data:{ id: 'n9', parent: 'n37'}},
                    { group:'nodes', data:{ id: 'n10', parent: 'n38'}},
                    { group:'nodes', data:{ id: 'n12'}},
                    { group:'nodes', data:{ id: 'n13'}},
                    { group:'nodes', data:{ id: 'n14'}},
                    { group:'nodes', data:{ id: 'n15'}},
                    { group:'nodes', data:{ id: 'n16'}},
                    { group:'nodes', data:{ id: 'n17'}},
                    { group:'nodes', data:{ id: 'n18'}},
                    { group:'nodes', data:{ id: 'n19'}},
                    { group:'nodes', data:{ id: 'n20'}},
                    { group:'nodes', data:{ id: 'n21'}},
                    { group:'nodes', data:{ id: 'n22'}},
                    { group:'nodes', data:{ id: 'n23'}},
                    { group:'nodes', data:{ id: 'n24', parent: 'n39'}},
                    { group:'nodes', data:{ id: 'n25', parent: 'n39'}},
                    { group:'nodes', data:{ id: 'n26', parent: 'n42'}},
                    { group:'nodes', data:{ id: 'n27', parent: 'n42'}},
                    { group:'nodes', data:{ id: 'n28', parent: 'n42'}},
                    { group:'nodes', data:{ id: 'n29', parent: 'n40'}},
                    { group:'nodes', data:{ id: 'n31', parent: 'n41'}},
                    { group:'nodes', data:{ id: 'n32', parent: 'n41'}},
                    { group:'nodes', data:{ id: 'n33', parent: 'n41'}},
                    { group:'nodes', data:{ id: 'n34', parent: 'n41'}},
                    { group:'nodes', data:{ id: 'n35', parent: 'n41'}},
                    { group:'nodes', data:{ id: 'n36', parent: 'n41'}},
                    { group:'nodes', data:{ id: 'n37'}},
                    { group:'nodes', data:{ id: 'n38'}},
                    { group:'nodes', data:{ id: 'n39', parent: 'n43'}},
                    { group:'nodes', data:{ id: 'n40', parent: 'n42'}},
                    { group:'nodes', data:{ id: 'n41', parent: 'n42'}},
                    { group:'nodes', data:{ id: 'n42', parent: 'n43'}},
                    { group:'nodes', data:{ id: 'n43'}},
                    { group:'edges', data:{ id: 'e0', source: 'n0', target: 'n1'} },
                    { group:'edges', data:{ id: 'e1', source: 'n1', target: 'n2'} },
                    { group:'edges', data:{ id: 'e2', source: 'n2', target: 'n3'} },
                    { group:'edges', data:{ id: 'e3', source: 'n0', target: 'n3'} },
                    { group:'edges', data:{ id: 'e4', source: 'n1', target: 'n4'} },
                    { group:'edges', data:{ id: 'e5', source: 'n2', target: 'n4'} },
                    { group:'edges', data:{ id: 'e6', source: 'n4', target: 'n5'} },
                    { group:'edges', data:{ id: 'e7', source: 'n5', target: 'n6'} },
                    { group:'edges', data:{ id: 'e8', source: 'n4', target: 'n6'} },
                    { group:'edges', data:{ id: 'e9', source: 'n4', target: 'n7'} },
                    { group:'edges', data:{ id: 'e10', source: 'n7', target: 'n8'} },
                    { group:'edges', data:{ id: 'e11', source: 'n8', target: 'n9'} },
                    { group:'edges', data:{ id: 'e12', source: 'n7', target: 'n9'} },
                    { group:'edges', data:{ id: 'e13', source: 'n13', target: 'n14'} },
                    { group:'edges', data:{ id: 'e14', source: 'n12', target: 'n14'} },
                    { group:'edges', data:{ id: 'e15', source: 'n14', target: 'n15'} },
                    { group:'edges', data:{ id: 'e16', source: 'n14', target: 'n16'} },
                    { group:'edges', data:{ id: 'e17', source: 'n15', target: 'n17'} },
                    { group:'edges', data:{ id: 'e18', source: 'n17', target: 'n18'} },
                    { group:'edges', data:{ id: 'e19', source: 'n18', target: 'n19'} },
                    { group:'edges', data:{ id: 'e20', source: 'n17', target: 'n20'} },
                    { group:'edges', data:{ id: 'e21', source: 'n19', target: 'n20'} },
                    { group:'edges', data:{ id: 'e22', source: 'n16', target: 'n20'} },
                    { group:'edges', data:{ id: 'e23', source: 'n20', target: 'n21'} },
                    { group:'edges', data:{ id: 'e25', source: 'n23', target: 'n24'} },
                    { group:'edges', data:{ id: 'e26', source: 'n24', target: 'n25'} },
                    { group:'edges', data:{ id: 'e27', source: 'n26', target: 'n38'} },
                    { group:'edges', data:{ id: 'e29', source: 'n26', target: 'n39'} },
                    { group:'edges', data:{ id: 'e30', source: 'n26', target: 'n27'} },
                    { group:'edges', data:{ id: 'e31', source: 'n26', target: 'n28'} },
                    { group:'edges', data:{ id: 'e33', source: 'n21', target: 'n31'} },
                    { group:'edges', data:{ id: 'e35', source: 'n31', target: 'n33'} },
                    { group:'edges', data:{ id: 'e36', source: 'n31', target: 'n34'} },
                    { group:'edges', data:{ id: 'e37', source: 'n33', target: 'n34'} },
                    { group:'edges', data:{ id: 'e38', source: 'n32', target: 'n35'} },
                    { group:'edges', data:{ id: 'e39', source: 'n32', target: 'n36'} },
                    { group:'edges', data:{ id: 'e40', source: 'n16', target: 'n40'} }
                   ],
                   elements1: [{ group:'nodes', data:{ id: 'n0'}},
                       { group:'nodes', data:{ id: 'n1'}},
                       { group:'nodes', data:{ id: 'n2'}},
                       { group:'nodes', data:{ id: 'n3'}},
                       { group:'nodes', data:{ id: 'n4', parent1: 'n37'}},
                       { group:'nodes', data:{ id: 'n5'}},
                       { group:'nodes', data:{ id: 'n6'}},
                       { group:'nodes', data:{ id: 'n7', parent1: 'n37'}},
                       { group:'nodes', data:{ id: 'n8', parent1: 'n37'}},
                       { group:'nodes', data:{ id: 'n9', parent1: 'n37'}},
                       { group:'nodes', data:{ id: 'n10', parent1: 'n38'}},
                       { group:'nodes', data:{ id: 'n12'}},
                       { group:'nodes', data:{ id: 'n13'}},
                       { group:'nodes', data:{ id: 'n14'}},
                       { group:'nodes', data:{ id: 'n15'}},
                       { group:'nodes', data:{ id: 'n16'}},
                       { group:'nodes', data:{ id: 'n17'}},
                       { group:'nodes', data:{ id: 'n18'}},
                       { group:'nodes', data:{ id: 'n19'}},
                       { group:'nodes', data:{ id: 'n20'}},
                       { group:'nodes', data:{ id: 'n21'}},
                       { group:'nodes', data:{ id: 'n22'}},
                       { group:'nodes', data:{ id: 'n23'}},
                       { group:'nodes', data:{ id: 'n24', parent1: 'n39'}},
                       { group:'nodes', data:{ id: 'n25', parent1: 'n39'}},
                       { group:'nodes', data:{ id: 'n26', parent1: 'n42'}},
                       { group:'nodes', data:{ id: 'n27', parent1: 'n42'}},
                       { group:'nodes', data:{ id: 'n28', parent1: 'n42'}},
                       { group:'nodes', data:{ id: 'n29', parent1: 'n40'}},
                       { group:'nodes', data:{ id: 'n31', parent1: 'n41'}},
                       { group:'nodes', data:{ id: 'n32', parent1: 'n41'}},
                       { group:'nodes', data:{ id: 'n33', parent1: 'n41'}},
                       { group:'nodes', data:{ id: 'n34', parent1: 'n41'}},
                       { group:'nodes', data:{ id: 'n35', parent1: 'n41'}},
                       { group:'nodes', data:{ id: 'n36', parent1: 'n41'}},
                       { group:'edges', data:{ id: 'e0', source: 'n0', target: 'n1'} },
                       { group:'edges', data:{ id: 'e1', source: 'n1', target: 'n2'} },
                       { group:'edges', data:{ id: 'e2', source: 'n2', target: 'n3'} },
                       { group:'edges', data:{ id: 'e3', source: 'n0', target: 'n3'} },
                       { group:'edges', data:{ id: 'e4', source: 'n1', target: 'n4'} },
                       { group:'edges', data:{ id: 'e5', source: 'n2', target: 'n4'} },
                       { group:'edges', data:{ id: 'e6', source: 'n4', target: 'n5'} },
                       { group:'edges', data:{ id: 'e7', source: 'n5', target: 'n6'} },
                       { group:'edges', data:{ id: 'e8', source: 'n4', target: 'n6'} },
                       { group:'edges', data:{ id: 'e9', source: 'n4', target: 'n7'} },
                       { group:'edges', data:{ id: 'e10', source: 'n7', target: 'n8'} },
                       { group:'edges', data:{ id: 'e11', source: 'n8', target: 'n9'} },
                       { group:'edges', data:{ id: 'e12', source: 'n7', target: 'n9'} },
                       { group:'edges', data:{ id: 'e13', source: 'n13', target: 'n14'} },
                       { group:'edges', data:{ id: 'e14', source: 'n12', target: 'n14'} },
                       { group:'edges', data:{ id: 'e15', source: 'n14', target: 'n15'} },
                       { group:'edges', data:{ id: 'e16', source: 'n14', target: 'n16'} },
                       { group:'edges', data:{ id: 'e17', source: 'n15', target: 'n17'} },
                       { group:'edges', data:{ id: 'e18', source: 'n17', target: 'n18'} },
                       { group:'edges', data:{ id: 'e19', source: 'n18', target: 'n19'} },
                       { group:'edges', data:{ id: 'e20', source: 'n17', target: 'n20'} },
                       { group:'edges', data:{ id: 'e21', source: 'n19', target: 'n20'} },
                       { group:'edges', data:{ id: 'e22', source: 'n16', target: 'n20'} },
                       { group:'edges', data:{ id: 'e23', source: 'n20', target: 'n21'} },
                       { group:'edges', data:{ id: 'e25', source: 'n23', target: 'n24'} },
                       { group:'edges', data:{ id: 'e26', source: 'n24', target: 'n25'} },
                       { group:'edges', data:{ id: 'e30', source: 'n26', target: 'n27'} },
                       { group:'edges', data:{ id: 'e31', source: 'n26', target: 'n28'} },
                       { group:'edges', data:{ id: 'e33', source: 'n21', target: 'n31'} },
                       { group:'edges', data:{ id: 'e35', source: 'n31', target: 'n33'} },
                       { group:'edges', data:{ id: 'e36', source: 'n31', target: 'n34'} },
                       { group:'edges', data:{ id: 'e37', source: 'n33', target: 'n34'} },
                       { group:'edges', data:{ id: 'e38', source: 'n32', target: 'n35'} },
                       { group:'edges', data:{ id: 'e39', source: 'n32', target: 'n36'} },
                      ]
        });
        document.getElementById("layoutButton").addEventListener("click", function(){
          var layout = cy.layout({
            name: 'cose-bilkent',
            animate: 'end',
            animationEasing: 'ease-out',
            animationDuration: 1000,
            randomize: true
          });

          layout.run();
        });
        document.getElementById("randomize").addEventListener("click", function(){
          var layout = cy.layout({
            name: 'random',
            animate: true,
            animationDuration: 1000,
            animationEasing: 'ease-out'
          });

          layout.run();
        });
        
        document.getElementById("save").addEventListener("click", function(){
	    	  window.localStorage.setItem('savedlayout', JSON.stringify(cy.json()));
	      });
	      
	      document.getElementById("reload").addEventListener("click", function(){
	    	  cy.json(JSON.parse(window.localStorage.getItem('savedlayout')));
	      });
      });

body {
  font-family: helvetica;
  font-size: 14px;
}

#cy {
  width: 100%;
  height: 90%;
  z-index: 999;
}

h1 {
  opacity: 0.5;
  font-size: 1em;
}

button {
  margin-right: 10px;
}

<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<!--polyfills are needed for this extension for old browsers like IE -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.5.7/shim.min.js"></script>
<script src="https://unpkg.com/layout-base/layout-base.js"></script>
<script src="https://unpkg.com/cose-base/cose-base.js"></script>
<script src="https://unpkg.com/cytoscape-cose-bilkent/cytoscape-cose-bilkent.js"></script>
    
<button id="randomize" type="button">Randomize</button>
<button id="layoutButton" type="button">CoSE-Bilkent</button>
<button id="save" class="button">save</button>
<button id="reload" class="button">reload</button>
<div id="cy"></div>

解决方案

EDIT: I tried this again, after @Ravenous pointed out the benefits of cy.json():

Using cy.json() in this example works just fine, if you delete the other elements before adding the old ones.

As long as you run the preset layout, the code can also look like this:

document.getElementById("save").addEventListener("click", function () {
    window.localStorage.setItem("elements", JSON.stringify( cy.json() ));
});

document.getElementById("reload").addEventListener("click", function () {
    cy.elements().remove();
    cy.json({ elements: JSON.parse( window.localStorage.getItem("elements") ).elements }).layout({ name: 'preset' }).run();
});

or

document.getElementById("save").addEventListener("click", function() {
    window.localStorage.setItem("elements", JSON.stringify({
      nodes: cy.nodes.jsons(),
      edges: cy.edges.jsons() 
    }));
});

document.getElementById("reload").addEventListener("click", function() {
    cy.elements().remove();
    cy.add( JSON.parse(window.localStorage.getItem("elements")) ).layout({ name: 'preset' }).run();  
});



Old answer:

This problem has already been adressed here, but it took me some time to find it. Basically, you'll want to use cy.nodes().jsons() insted of just cy.json():

var elements = {
    nodes: cy.nodes().jsons(),
    edges: cy.edges().jsons(),
};

This way you get the collection with every attribute in a JSON format. After that, you can save the elements.json to your local storage and get them back into the graph via cy.add(). I added a preset layout for the graph, that way the positions are not mixxed up after being reloaded:

var elements1 = [{
    group: "nodes",
    data: {
      id: "n0"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n1"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n2"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n3"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n4",
      parent1: "n37"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n5"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n6"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n7",
      parent1: "n37"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n8",
      parent1: "n37"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n9",
      parent1: "n37"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n10",
      parent1: "n38"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n12"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n13"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n14"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n15"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n16"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n17"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n18"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n19"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n20"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n21"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n22"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n23"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n24",
      parent1: "n39"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n25",
      parent1: "n39"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n26",
      parent1: "n42"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n27",
      parent1: "n42"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n28",
      parent1: "n42"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n29",
      parent1: "n40"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n31",
      parent1: "n41"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n32",
      parent1: "n41"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n33",
      parent1: "n41"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n34",
      parent1: "n41"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n35",
      parent1: "n41"
    }
  },
  {
    group: "nodes",
    data: {
      id: "n36",
      parent1: "n41"
    }
  },
  {
    group: "edges",
    data: {
      id: "e0",
      source: "n0",
      target: "n1"
    }
  },
  {
    group: "edges",
    data: {
      id: "e1",
      source: "n1",
      target: "n2"
    }
  },
  {
    group: "edges",
    data: {
      id: "e2",
      source: "n2",
      target: "n3"
    }
  },
  {
    group: "edges",
    data: {
      id: "e3",
      source: "n0",
      target: "n3"
    }
  },
  {
    group: "edges",
    data: {
      id: "e4",
      source: "n1",
      target: "n4"
    }
  },
  {
    group: "edges",
    data: {
      id: "e5",
      source: "n2",
      target: "n4"
    }
  },
  {
    group: "edges",
    data: {
      id: "e6",
      source: "n4",
      target: "n5"
    }
  },
  {
    group: "edges",
    data: {
      id: "e7",
      source: "n5",
      target: "n6"
    }
  },
  {
    group: "edges",
    data: {
      id: "e8",
      source: "n4",
      target: "n6"
    }
  },
  {
    group: "edges",
    data: {
      id: "e9",
      source: "n4",
      target: "n7"
    }
  },
  {
    group: "edges",
    data: {
      id: "e10",
      source: "n7",
      target: "n8"
    }
  },
  {
    group: "edges",
    data: {
      id: "e11",
      source: "n8",
      target: "n9"
    }
  },
  {
    group: "edges",
    data: {
      id: "e12",
      source: "n7",
      target: "n9"
    }
  },
  {
    group: "edges",
    data: {
      id: "e13",
      source: "n13",
      target: "n14"
    }
  },
  {
    group: "edges",
    data: {
      id: "e14",
      source: "n12",
      target: "n14"
    }
  },
  {
    group: "edges",
    data: {
      id: "e15",
      source: "n14",
      target: "n15"
    }
  },
  {
    group: "edges",
    data: {
      id: "e16",
      source: "n14",
      target: "n16"
    }
  },
  {
    group: "edges",
    data: {
      id: "e17",
      source: "n15",
      target: "n17"
    }
  },
  {
    group: "edges",
    data: {
      id: "e18",
      source: "n17",
      target: "n18"
    }
  },
  {
    group: "edges",
    data: {
      id: "e19",
      source: "n18",
      target: "n19"
    }
  },
  {
    group: "edges",
    data: {
      id: "e20",
      source: "n17",
      target: "n20"
    }
  },
  {
    group: "edges",
    data: {
      id: "e21",
      source: "n19",
      target: "n20"
    }
  },
  {
    group: "edges",
    data: {
      id: "e22",
      source: "n16",
      target: "n20"
    }
  },
  {
    group: "edges",
    data: {
      id: "e23",
      source: "n20",
      target: "n21"
    }
  },
  {
    group: "edges",
    data: {
      id: "e25",
      source: "n23",
      target: "n24"
    }
  },
  {
    group: "edges",
    data: {
      id: "e26",
      source: "n24",
      target: "n25"
    }
  },
  {
    group: "edges",
    data: {
      id: "e30",
      source: "n26",
      target: "n27"
    }
  },
  {
    group: "edges",
    data: {
      id: "e31",
      source: "n26",
      target: "n28"
    }
  },
  {
    group: "edges",
    data: {
      id: "e33",
      source: "n21",
      target: "n31"
    }
  },
  {
    group: "edges",
    data: {
      id: "e35",
      source: "n31",
      target: "n33"
    }
  },
  {
    group: "edges",
    data: {
      id: "e36",
      source: "n31",
      target: "n34"
    }
  },
  {
    group: "edges",
    data: {
      id: "e37",
      source: "n33",
      target: "n34"
    }
  },
  {
    group: "edges",
    data: {
      id: "e38",
      source: "n32",
      target: "n35"
    }
  },
  {
    group: "edges",
    data: {
      id: "e39",
      source: "n32",
      target: "n36"
    }
  }
];

document.addEventListener("DOMContentLoaded", function() {
  var cy = (window.cy = cytoscape({
    container: document.getElementById("cy"),

    ready: function() {
      this.nodes().forEach(function(node) {
        let width = [30, 70, 110];
        let size = width[Math.floor(Math.random() * 3)];
        node.css("width", size);
        node.css("height", size);
      });
      this.layout({
        name: "cose-bilkent",
        animationDuration: 1000
      }).run();
    },

    style: [{
        selector: "node",
        style: {
          'content': 'data(id)',
          'text-valign': 'center',
          'text-halign': 'center',
          'background-color': '#ad1a66'
        }
      },

      {
        selector: ":parent",
        style: {
          "background-opacity": 0.333
        }
      },

      {
        selector: "edge",
        style: {
          width: 3,
          "line-color": "#ad1a66"
        }
      }
    ],

    elements: [{
        group: "nodes",
        data: {
          id: "n0"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n1"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n2"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n3"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n4",
          parent: "n37"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n5"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n6"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n7",
          parent: "n37"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n8",
          parent: "n37"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n9",
          parent: "n37"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n10",
          parent: "n38"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n12"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n13"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n14"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n15"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n16"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n17"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n18"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n19"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n20"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n21"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n22"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n23"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n24",
          parent: "n39"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n25",
          parent: "n39"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n26",
          parent: "n42"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n27",
          parent: "n42"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n28",
          parent: "n42"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n29",
          parent: "n40"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n31",
          parent: "n41"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n32",
          parent: "n41"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n33",
          parent: "n41"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n34",
          parent: "n41"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n35",
          parent: "n41"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n36",
          parent: "n41"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n37"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n38"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n39",
          parent: "n43"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n40",
          parent: "n42"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n41",
          parent: "n42"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n42",
          parent: "n43"
        }
      },
      {
        group: "nodes",
        data: {
          id: "n43"
        }
      },
      {
        group: "edges",
        data: {
          id: "e0",
          source: "n0",
          target: "n1"
        }
      },
      {
        group: "edges",
        data: {
          id: "e1",
          source: "n1",
          target: "n2"
        }
      },
      {
        group: "edges",
        data: {
          id: "e2",
          source: "n2",
          target: "n3"
        }
      },
      {
        group: "edges",
        data: {
          id: "e3",
          source: "n0",
          target: "n3"
        }
      },
      {
        group: "edges",
        data: {
          id: "e4",
          source: "n1",
          target: "n4"
        }
      },
      {
        group: "edges",
        data: {
          id: "e5",
          source: "n2",
          target: "n4"
        }
      },
      {
        group: "edges",
        data: {
          id: "e6",
          source: "n4",
          target: "n5"
        }
      },
      {
        group: "edges",
        data: {
          id: "e7",
          source: "n5",
          target: "n6"
        }
      },
      {
        group: "edges",
        data: {
          id: "e8",
          source: "n4",
          target: "n6"
        }
      },
      {
        group: "edges",
        data: {
          id: "e9",
          source: "n4",
          target: "n7"
        }
      },
      {
        group: "edges",
        data: {
          id: "e10",
          source: "n7",
          target: "n8"
        }
      },
      {
        group: "edges",
        data: {
          id: "e11",
          source: "n8",
          target: "n9"
        }
      },
      {
        group: "edges",
        data: {
          id: "e12",
          source: "n7",
          target: "n9"
        }
      },
      {
        group: "edges",
        data: {
          id: "e13",
          source: "n13",
          target: "n14"
        }
      },
      {
        group: "edges",
        data: {
          id: "e14",
          source: "n12",
          target: "n14"
        }
      },
      {
        group: "edges",
        data: {
          id: "e15",
          source: "n14",
          target: "n15"
        }
      },
      {
        group: "edges",
        data: {
          id: "e16",
          source: "n14",
          target: "n16"
        }
      },
      {
        group: "edges",
        data: {
          id: "e17",
          source: "n15",
          target: "n17"
        }
      },
      {
        group: "edges",
        data: {
          id: "e18",
          source: "n17",
          target: "n18"
        }
      },
      {
        group: "edges",
        data: {
          id: "e19",
          source: "n18",
          target: "n19"
        }
      },
      {
        group: "edges",
        data: {
          id: "e20",
          source: "n17",
          target: "n20"
        }
      },
      {
        group: "edges",
        data: {
          id: "e21",
          source: "n19",
          target: "n20"
        }
      },
      {
        group: "edges",
        data: {
          id: "e22",
          source: "n16",
          target: "n20"
        }
      },
      {
        group: "edges",
        data: {
          id: "e23",
          source: "n20",
          target: "n21"
        }
      },
      {
        group: "edges",
        data: {
          id: "e25",
          source: "n23",
          target: "n24"
        }
      },
      {
        group: "edges",
        data: {
          id: "e26",
          source: "n24",
          target: "n25"
        }
      },
      {
        group: "edges",
        data: {
          id: "e27",
          source: "n26",
          target: "n38"
        }
      },
      {
        group: "edges",
        data: {
          id: "e29",
          source: "n26",
          target: "n39"
        }
      },
      {
        group: "edges",
        data: {
          id: "e30",
          source: "n26",
          target: "n27"
        }
      },
      {
        group: "edges",
        data: {
          id: "e31",
          source: "n26",
          target: "n28"
        }
      },
      {
        group: "edges",
        data: {
          id: "e33",
          source: "n21",
          target: "n31"
        }
      },
      {
        group: "edges",
        data: {
          id: "e35",
          source: "n31",
          target: "n33"
        }
      },
      {
        group: "edges",
        data: {
          id: "e36",
          source: "n31",
          target: "n34"
        }
      },
      {
        group: "edges",
        data: {
          id: "e37",
          source: "n33",
          target: "n34"
        }
      },
      {
        group: "edges",
        data: {
          id: "e38",
          source: "n32",
          target: "n35"
        }
      },
      {
        group: "edges",
        data: {
          id: "e39",
          source: "n32",
          target: "n36"
        }
      },
      {
        group: "edges",
        data: {
          id: "e40",
          source: "n16",
          target: "n40"
        }
      }
    ],
  }));

  document.getElementById("layoutButton").addEventListener("click", function() {
    var layout = cy.layout({
      name: "cose-bilkent",
      animate: "end",
      animationEasing: "ease-out",
      animationDuration: 1000,
      randomize: true
    });

    layout.run();
  });
  document.getElementById("randomize").addEventListener("click", function() {
    var layout = cy.layout({
      name: "random",
      animate: true,
      animationDuration: 1000,
      animationEasing: "ease-out"
    });

    layout.run();
  });

  document.getElementById("save").addEventListener("click", function() {
    window.localStorage.setItem("elements", JSON.stringify(cy.json()));
  });

  document.getElementById("reload").addEventListener("click", function() {
    cy.elements().remove();
    cy.json({
      elements: JSON.parse(window.localStorage.getItem("elements")).elements
    }).layout({
      name: 'preset'
    }).run();
    cy.fit();
    cy.center();
  });
});

body {
  font-family: helvetica;
  font-size: 14px;
}

#cy {
  height: 100%;
  width: 90%;
  position: absolute;
}

h1 {
  opacity: 0.5;
  font-size: 1em;
}

button {
  margin-right: 10px;
}

<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>

<!--polyfills are needed for this extension for old browsers like IE -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.5.7/shim.min.js"></script>
<script src="https://unpkg.com/layout-base/layout-base.js"></script>
<script src="https://unpkg.com/cose-base/cose-base.js"></script>

<script src="https://cdn.jsdelivr.net/npm/cytoscape-cose-bilkent@4.1.0/cytoscape-cose-bilkent.min.js"></script>

<body>
  <button id="randomize" type="button">Randomize</button>
  <button id="layoutButton" type="button">CoSE-Bilkent</button>
  <button id="save" class="button">save</button>
  <button id="reload" class="button">reload</button>
  <div id="cy"></div>

</body>

这篇关于如何使用cytoscape.js保存和还原复合节点的布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆