基于vis无向图的动态创建、编辑


<!DOCTYPE html style="width:100%;height:100%;">
<html>
<head>
  <title>动态创建和编辑无向图</title>
  <style>
    #mynetwork {
      width: 600px;
      height: 400px;
      border: 1px solid lightgray;
    }
.btnClass{
margin: 5px;
    padding: 5px;
}
.vr{

display: block;
    height: 20px;
    width: 1px;
    border: 0;
    background-color: black;
}
.label{

line-height: 2.5;
}
  </style>
  <link rel="stylesheet" href="https://unpkg.com/vis-network/standalone/umd/vis-network.min.css" />
  <script src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
</head>
<body>
  <div>
<div style="display: flex;">
    <label for="nodeInput" class="label">节点:</label>
    <input type="text" id="nodeInput" />
    <button onclick="addNode()">添加节点</button>
    <br />
    <label for="fromInput" style="margin-left: 2em;"  class="label">From点:</label>
    <input type="text" id="fromInput" />
    <label for="toInput"  class="label">&nbsp; &nbsp;~&nbsp;&nbsp; To点:</label>
    <input type="text" id="toInput" />
    <button onclick="addEdge()"  class="btnClass" style="margin-left: 2em;">添加边</button>
    <br />
   
    <br />
<!-- 在HTML中添加删除按钮 -->
<button id="deleteButton" class="btnClass" >删除</button>
<button id="searchButton" class="btnClass" >查找</button>
<hr class="vr" />
 <button onclick="generateRoute()" class="btnClass"  style="margin-left: 2em;">生成路由</button>
</div>

<hr/>
<div  style="display: flex;">
<label  for="luyou"  class="label">路由区:</label>
<textarea rows="10" id="route" style="min-heigth:600px;width:80%" ></textarea>
<button id="produceButton">生成无向图</button>
</div>
<hr/>

  </div>
  <div id="mynetwork" style="width:100%;height:90%;"></div>
  <script>
    const nodes = new vis.DataSet();
    const edges = new vis.DataSet();

    const container = document.getElementById('mynetwork');
    const data = {
      nodes: nodes,
      edges: edges
    };
    const options = {};

    var network = new vis.Network(container, data, options);

    function addNode() {
      const nodeValue = document.getElementById('nodeInput').value;

      if (nodeValue) {
        nodes.add({ id: nodeValue, label: nodeValue });
      }
    }

    function addEdge() {
      const fromNode = document.getElementById('fromInput').value;
      const toNode = document.getElementById('toInput').value;

      if (fromNode && toNode) {
        edges.add({ from: fromNode, to: toNode });
      }
    }




function generateSql(data){
var sql="INSERT INTO `temp_point` (`node_name` ,`route`,`displayorder`) VALUES";
var temp="";
i=0;
Object.keys(data).forEach((key) => {
 
temp+="('"+key+"','["+data[key]+"]',"+i+"),";
i++;

})
sql=sql+temp.substring(0,temp.length-1);
console.log('~~~~~~~~~~~~',sql) ;


}






    function generateRoute() {
      const nodesArray = nodes.get();
      const route = {};

      nodesArray.forEach(node => {
        const nodeId = node.id;
        const edgesArray = edges.get({ filter: edge => edge.from === nodeId || edge.to === nodeId });

        route[nodeId] = Array.from({ length: nodesArray.length }, (_, index) => {
          const connectedNode = nodesArray[index].id;
          return edgesArray.some(edge => (edge.from === connectedNode || edge.to === connectedNode) && nodeId !=connectedNode ) ? 1 : 0;
        });
      });

      console.log('before~~~~~',route);

   
   generateSql();


    }






// 获取删除按钮和vis.js的节点和边
const deleteButton = document.getElementById('deleteButton');

// 监听删除按钮的点击事件
deleteButton.addEventListener('click', () => {
  // 获取选中的节点和边
  const selectedNodes = network.getSelectedNodes();
  const selectedEdges = network.getSelectedEdges();

  // 删除选中的节点
  if (selectedNodes.length > 0) {
    data.nodes.remove(selectedNodes);
  }

  // 删除选中的边
  if (selectedEdges.length > 0) {
    data.edges.remove(selectedEdges);
  }

  // 更新图表显示
  network.setData(data);
});






// 监听查找按钮的点击事件
searchButton.addEventListener('click', () => {
 
  var searchNodeInput = document.getElementById('nodeInput');
 var searchValue = searchNodeInput.value;
if(searchValue==''){
    alert('请输入节点关键字!');
return false;
}
  // 在无向图中查找节点
  var foundNode = data.nodes.get().filter(node => node.label.indexOf(searchValue)>-1 );


  if (foundNode) {

 data.nodes.update(data.nodes.get().map(node => ({
      id: node.id,
      color:  '#97c2fc',
    })));

for(var i=0,j=foundNode.length;i<j;i++){
var a= foundNode[i].label;

       // 找到节点,将其标记为绿色
   data.nodes.update(data.nodes.get().map(node => {
if( node.label === a){
   return {   id: node.id,
      color: 'lime' };
}
   
    }));


   

}


  } else {
    // 找不到节点,弹出警告框
    alert('未找到节点!');
  }


});



//根据路由产生无向图
produceButton.addEventListener('click', () => {
var data= document.getElementById('route').value;
var data=eval('('+data+')');

    const tempNodes = Object.keys(data);
  //  const edges = [];
 tempNodes.map((node) =>(  nodes.add( { id: node, label: node }))); 

    tempNodes.forEach((from, i) => {
      for (let j = i + 1; j < nodes.length; j++) {
        const to = tempNodes[j];
        if (data[from][j] === 1) {
          edges.add({ from: from, to: to });
        }
      }
    });

 

if(network==null){
    const graphData = {
      nodes: tempNodes.map((node) => ({ id: node, label: node })),
      edges: edges,
    };

    const options = {
      layout: {
        hierarchical: {
          direction: "UD",
          sortMethod: "directed",
        },
      },
      edges: {
        smooth: {
          type: "cubicBezier",
        },
      },
    };

     network = new vis.Network(container, graphData, options);

}


});




  </script>
</body>
</html>

以上代码是“无向图”的实现,要实现有向图,edges数组中对象元素加上‘arrows: 'to'’即可,

例如:{ from: 1, to: 2, arrows: 'to' }

演示效果:

无向图生成

最终路由格式:var  data={A:[0,1,1,1,0],B:[1,0,1,0,1],C:[1,1,0,0,0],D:[1,0,0,0,0],E:[0,1,0,0,0]}

表示规则 data 对象中每个键值对的键表示一个点,键对应的值是一个一维数组,表示该点是否能分别到达其他点的路由。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值