vue用vis插件如何實(shí)現(xiàn)網(wǎng)絡(luò)拓?fù)鋱D
更新時(shí)間:2022年10月09日 15:38:22 作者:十二點(diǎn)的洛杉磯
這篇文章主要介紹了vue用vis插件如何實(shí)現(xiàn)網(wǎng)絡(luò)拓?fù)鋱D,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
vis插件實(shí)現(xiàn)網(wǎng)絡(luò)拓?fù)鋱D
安裝引入vis
1.npm安裝vis
npm install vis
2.引入vis
import { DataSet, Network } from 'vis';vis使用示例
methods:{
globalTrace () {
// create an array with nodes
var nodes = new DataSet([
{id: 1, label: 'Node 1'},
{id: 2, label: 'Node 2'},
{id: 3, label: 'Node 3'},
{id: 4, label: 'Node 4'},
{id: 5, label: 'Node 5'}
]);
// create an array with edges
var edges = new DataSet([
{from: 1, to: 3},
{from: 1, to: 2},
{from: 2, to: 4},
{from: 2, to: 5}
]);
// create a network
var container = document.querySelector('#global_trace_content');
// provide the data in the vis format
var data = {
nodes: nodes,
edges: edges
};
var options = {
//節(jié)點(diǎn)樣式
nodes: {
shape: "box",//設(shè)置節(jié)點(diǎn)node樣式為矩形
fixed:true,//節(jié)點(diǎn)node固定不可移動(dòng)
font: {
color: "white", //字體的顏色
size: 30 //顯示字體大小
},
scaling: {
min: 16,
max: 32 //縮放效果比例
},
},
//連接線的樣式
edges: {
color: {
color: "rgb(97, 168, 224)",
highlight: "rgb(97, 168, 224)",
hover: "green",
inherit: "from",
opacity: 1.0
},
font: {
align: "top",//連接線文字位置
},
smooth: true, //是否顯示方向箭頭
arrows: {to : true },//箭頭指向from節(jié)點(diǎn)
},
layout: {
//以分層方式定位節(jié)點(diǎn)
hierarchical: {
direction: "LR",//分層排序方向
sortMethod: "directed",//分層排序方法
levelSeparation:400//不同級(jí)別之間的距離
},
},
interaction: {
navigationButtons: true,
// hover: true, //鼠標(biāo)移過后加粗該節(jié)點(diǎn)和連接線
selectConnectedEdges: false, //選擇節(jié)點(diǎn)后是否顯示連接線
},
};
// initialize your network!
this.network = new Network(container, data, options);
this.network.on("click",e=> this.showDetail(e));//單擊事件
this.network.on("doubleClick",e=> this.enterService(e))//雙擊事件
},
},
mounted(){
this.globalTrace()
}
vis官方文檔
vis.js網(wǎng)絡(luò)拓?fù)鋱D點(diǎn)擊折疊節(jié)點(diǎn)和展開節(jié)點(diǎn)
首先看一下效果圖

1.數(shù)據(jù)中要添加的屬性如下圖所示:

2.數(shù)據(jù)中添加入上圖屬性后,添加點(diǎn)擊事件即可,代碼如下:
//todo 雙擊時(shí)折疊和展開
network.on("doubleClick", function(params) {//雙擊事件
if (params.nodes.length != 0) {//確定為節(jié)點(diǎn)雙擊事件
var click_node_id = params.nodes[0];
remove_all_sub_nodes(click_node_id);
}
});
//todo 刪除下級(jí)所有節(jié)點(diǎn)
function remove_all_sub_nodes(node_id) {
var sub_nodes = get_directly_sub_nodes(node_id);
// console.log('sub_nodes',sub_nodes)
if (sub_nodes.length == 0) {//當(dāng)前點(diǎn)擊的為葉子節(jié)點(diǎn)
//判斷是否有下級(jí)節(jié)點(diǎn)
// console.log('sub',allNodes[node_id - 1]['subids']);
if (typeof (allNodes[node_id - 1]['subids']) != 'undefined') {
$.each(allNodes[node_id - 1]['subids'], function(index, item) {
// console.log('allNodes[item - 1]',allNodes[item - 1])
nodes.add(allNodes[item - 1]);
edges.add({id: node_id + '_' + item, from: node_id, to: item});
});
} else {
alert('當(dāng)前為葉子節(jié)點(diǎn)');
}
} else {
$.each(sub_nodes, function(index, item) {
var sub_sub_nodes = get_directly_sub_nodes(item);
if (sub_sub_nodes.length == 0) {
nodes.remove({id: item});
edges.remove({id: node_id + '_' + item});
} else {
remove_all_sub_nodes(item);
}
nodes.remove({id: item});
edges.remove({id: node_id + '_' + item});
});
}
}
//todo 獲取某節(jié)點(diǎn)直屬下級(jí)節(jié)點(diǎn)
function get_directly_sub_nodes(node_id) {
var return_nodes = [];
var connectedNodes = network.getConnectedNodes(node_id);//獲取所有連接節(jié)點(diǎn)
$.each(connectedNodes, function(index, item) {
// console.log('allNodes',allNodes)
if (item != allNodes[node_id - 1]['pid']) {//當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn) ,不操作
return_nodes.push(item);
}
});
return return_nodes;
}3.完整代碼如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vis.js</title>
<link rel="stylesheet" rel="external nofollow" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
<!--<script type="text/javascript" src="js/vis-network.min.js"></script>-->
<style type="text/css">
#mynetwork {
width: 600px;
height: 600px;
border: 1px solid lightgray;
}
*{padding: 0;margin: 0;}
.menu{
/*這個(gè)樣式不寫,右鍵彈框會(huì)一直顯示在畫布的左下角*/
position: absolute;
background: rgba(3,3,3,0.6);
border-radius: 5px;
left: -99999px;
top: -999999px;
}
.menu ul{list-style: none}
.menu ul li{
padding: 5px 10px;
color: #ffff;
border-bottom: 1px solid #ffffff;
font-size: 14px;
cursor: pointer;
list-style: none;
}
.menu ul li:hover{
color: #659bc5;
}
.menu ul li:last-child{
border-bottom: none;
padding: 5px 10px 0 10px;
}
</style>
</head>
<body>
<div id="mynetwork"></div>
<!--菜單操作-->
<div id="menuOperation" class="menu" style="display: none;">
<ul>
<li><span class="glyphicon glyphicon-off" aria-hidden="true"></span> 下線</li>
<li><span class="glyphicon glyphicon-road" aria-hidden="true"></span> 通行</li>
</ul>
</div>
<!--節(jié)點(diǎn)懸停-->
<div class="menu" id="divHoverNode" style="display: none;">
<!--<ul></ul>-->
</div>
<script type="text/javascript">
// 創(chuàng)建節(jié)點(diǎn)數(shù)據(jù)數(shù)組
var allNodes = [
{id: 1,name: "外部網(wǎng)絡(luò)",type: "Internet",ip:"1.1.1.1",port:"未知",pid:0,subids: [2]},
{id: 2,name: "交換機(jī)",type: "switch",ip:"192.168.30.125",mac:"48:de:3d:e2:49:a8",model:"H3C",uptime:"2020-09-03 10:50:50",port:"22",pid:1, subids: [3, 4, 5, 6]},
{id: 3,name: "交換機(jī)",type: "switch",ip:"192.168.1.8",mac:"cd:bd:3d:e2:55:55",model:"pf",uptime:"2020-09-03 10:50:50",port:"33",pid: 2,subids: [7, 8]},
{id:4,name: "計(jì)算機(jī)",type: "computer",ip:"192.168.1.8",mac:"dv:bd:fd:e2:df:fd",model:"pf",uptime:"2020-09-03 10:50:50",account:"xiaox",location:"xianm",port:"44",pid: 2},
{id:5,name: "路由器",type: "rooter",ip:"192.168.1.8",mac:"ds:bd:3d:e2:ds:55",model:"pf",uptime:"2020-09-03 10:50:50",account:"xiaox",location:"xianm",port:"55",pid: 2},
{id:6,name: "服務(wù)器",type: "service",ip:"192.168.1.8",mac:"vf:eq:dd:e2:55:55",model:"pf",uptime:"2020-09-03 10:50:50",account:"xiaox",location:"xianm",port:"66",pid:2},
{id:7,name: "打印機(jī)",type: "print",ip:"192.168.1.8",mac:"ss:bd:3d:ju:55:55",model:"pf",uptime:"2020-09-03 10:50:50",account:"xiaox",location:"xianm",port:"77",pid: 3},
{id:8,name: "手機(jī)",type: "phone",ip:"192.168.1.8",mac:"ju:ju:3d:e2:55:uy",model:"pf",uptime:"2020-09-03 10:50:50",account:"xiaox",location:"xianm",port:"88",pid:3}
];
// 創(chuàng)建邊數(shù)據(jù)數(shù)組
var allEdges = [
{ id:"1_2",from: 1, to: 2 },
{ id:"2_3",from: 2, to: 3 },
{ id:"2_4",from: 2, to: 4 },
{ id:"2_5",from: 2, to: 5 },
{ id:"2_6",from: 2, to: 6 },
{ id:"3_7",from: 3, to: 7 },
{ id:"3_8",from: 3, to: 8 }
];
/**
* 自定義圖片
*/
for (var i = 0;i < allNodes.length;i++){
if (allNodes[i].type == 'Internet'){
allNodes[i].image = 'image/internet.png';
}
if (allNodes[i].type == 'switch'){
allNodes[i].image = 'image/switch.png';
}
if (allNodes[i].type == 'hub'){
allNodes[i].image = 'image/hub.png';
}
if (allNodes[i].type == 'computer'){
allNodes[i].image = 'image/computer.png';
}
if (allNodes[i].type == 'rooter'){
allNodes[i].image = 'image/rooter.png';
}
if (allNodes[i].type == 'service'){
allNodes[i].image = 'image/service.png';
}
if (allNodes[i].type == 'print'){
allNodes[i].image = 'image/print.png';
}
if (allNodes[i].type == 'phone'){
allNodes[i].image = 'image/phone.png';
}
}
// 獲取容器
var container = document.getElementById('mynetwork');
// 創(chuàng)建節(jié)點(diǎn)對(duì)象
var nodes = new vis.DataSet(allNodes);
// 創(chuàng)建連線對(duì)象
var edges = new vis.DataSet(allEdges);
// 將數(shù)據(jù)賦值給vis 數(shù)據(jù)格式化器
var data = {
nodes: nodes,
edges: edges
};
console.log('nodes',data.nodes);
var options = {
nodes:{
shape: 'image'//設(shè)置圖片
// image:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1599645215703&di=0cb23e74736a6a1222f35b822f5bf833&imgtype=0&src=http%3A%2F%2Fa1.att.hudong.com%2F05%2F00%2F01300000194285122188000535877.jpg"
},
interaction:{
hover:true,
hoverConnectedEdges: true
},
layout: {
//樹形
// hierarchical: {direction: 'UD', sortMethod: 'hubsize'}
},
};
// 初始化關(guān)系圖
var network = new vis.Network(container, data, options);
/**
* 節(jié)點(diǎn)鼠標(biāo)懸停(點(diǎn)擊)獲取到的信息
* 因?yàn)閔overNode事件官方文檔中給的信息懸停時(shí)只傳了id值,想在鼠標(biāo)懸停的時(shí)候顯示該節(jié)點(diǎn)的信息拿不到值,所以遍歷節(jié)點(diǎn),相等的時(shí)候return改節(jié)點(diǎn)的信息
* @param option-----鼠標(biāo)懸停時(shí)取得的id
* @returns {{flag, port, ip, name, ignore, id, type}|{flag, port, ip, name, ignore, model, id, type, mac, uptime}|{flag, port, ip, name, ignore, model, location, id, type, mac, account, uptime}|*}
*/
function getNode(option) {
for (var i = 0;i < allNodes.length;i++){
if (option == allNodes[i].id){
// console.log('i',allNodes[i]);
return allNodes[i];
}
}
}
/**
* 線懸停(點(diǎn)擊)時(shí)兩端節(jié)點(diǎn)的信息(與節(jié)點(diǎn)類似)
* edges中加了id屬性,代表線條指向,懸停時(shí)通過edges--id與nodes--id對(duì)比,將兩端節(jié)點(diǎn)信息拼湊出來
* @param option----鼠標(biāo)懸停在線上時(shí)取得的id
* @returns {Array}
*/
function getEdge(option){
var linkId = option;
var linkIdFirst = linkId.substring(0,1);//截取第一位
var linkIdLast = linkId.substring(linkId.length-1,linkId.length);//截取最后一位
var dataList = [];//存放線條兩邊的節(jié)點(diǎn)nodes數(shù)據(jù)
for (var j =0;j<allNodes.length;j++){
if (linkIdFirst == allNodes[j].id || linkIdLast == allNodes[j].id){
dataList.push(allNodes[j]);
}
}
return dataList;
}
//todo 懸停在節(jié)點(diǎn)上--顯示彈框
network.on('hoverNode',function(properties){
// console.log('懸停節(jié)點(diǎn)',properties);
var hoveNodeList = getNode(properties.node);
// console.log('hoveNodeList',hoveNodeList);
var deviceType = hoveNodeList.type;
var imgPathSrc = hoveNodeList.image;
if (deviceType == "Internet" || deviceType == "hub"){
var $ul = "<ul>"
+"<li><img src=' "+imgPathSrc+" ' width='30px' height='25px'><span> "+hoveNodeList.name+" </span> </li>"
+"</ul>";
$("#divHoverNode").append($ul);
}
else if (deviceType == "switch"){
var $ul = "<ul>"
+"<li><img src=' "+imgPathSrc+" ' width='30px' height='25px'><span> 設(shè)備類型: "+hoveNodeList.name+" </span> </li>"
+"<li>IP:"+ hoveNodeList.ip+"</li>"
+"<li>MAC:"+ hoveNodeList.mac+"</li>"
+"<li>設(shè)備型號(hào):"+ hoveNodeList.model+"</li>"
+"</ul>";
$("#divHoverNode").append($ul);
}else{
var $ul = "<ul>"
+"<li><img src=' "+imgPathSrc+" ' width='30px' height='25px'><span> 設(shè)備類型:"+hoveNodeList.name+" </span> </li>"
+"<li>IP:"+ hoveNodeList.ip+"</li>"
+"<li>MAC:"+ hoveNodeList.mac+"</li>"
+"<li>賬號(hào):"+ hoveNodeList.account+"</li>"
+"<li>所在位置:"+ hoveNodeList.location+"</li>"
+"<li>最后登錄時(shí)間:"+ hoveNodeList.uptime+"</li>"
+"</ul>";
$("#divHoverNode").append($ul);
}
$('#divHoverNode').css({
'display': 'block',
'left': properties.event.offsetX + 15,
'top' : properties.event.offsetY + 15
});
$('#menuOperation').hide();
});
//todo 從節(jié)點(diǎn)移開---隱藏彈框
network.on('blurNode',function(){
$("#divHoverNode").hide();
$("#divHoverNode").empty();//移除之后清空div
});
//todo 懸停在邊上--顯示彈框
network.on('hoverEdge',function(properties){
// console.log('懸停邊',properties);
var hoveEdgeList = getEdge(properties.edge);
// console.log('hoveEdgeList',hoveEdgeList);
var $ul = "<ul>"
+"<li>名稱:"+ hoveEdgeList[0].name+"->"+hoveEdgeList[1].name+"</li>"
+"<li>端口號(hào):"+ hoveEdgeList[0].ip+"->"+hoveEdgeList[1].ip+"</li>"
+"</ul>";
$("#divHoverNode").append($ul);
$('#divHoverNode').css({
'display': 'block',
'left': properties.event.offsetX + 15,
'top' : properties.event.offsetY + 15
});
$('#menuOperation').hide();
});
//todo 從邊上移開---隱藏彈框
network.on('blurEdge',function(properties){
$("#divHoverNode").hide();
$("#divHoverNode").empty();//移除之后清空div
});
//todo 點(diǎn)擊的判斷是否選中節(jié)點(diǎn)時(shí)候顯示隱藏
network.on('click',function(properties){
var clickNodeList = getNode(properties.nodes[0]);
// console.log('clickNodeList',clickNodeList);
if (typeof(clickNodeList) == "undefined") {
$('#menuOperation').hide();
}else{
$('#menuOperation').css({
'display': 'block',
'left': properties.event.center.x + 15,
'top' : properties.event.center.y + 15
});
$("#divHoverNode").hide();
}
});
//todo 雙擊時(shí)折疊和展開
network.on("doubleClick", function(params) {//雙擊事件
if (params.nodes.length != 0) {//確定為節(jié)點(diǎn)雙擊事件
var click_node_id = params.nodes[0];
remove_all_sub_nodes(click_node_id);
}
});
//todo 刪除下級(jí)所有節(jié)點(diǎn)
function remove_all_sub_nodes(node_id) {
var sub_nodes = get_directly_sub_nodes(node_id);
// console.log('sub_nodes',sub_nodes)
if (sub_nodes.length == 0) {//當(dāng)前點(diǎn)擊的為葉子節(jié)點(diǎn)
//判斷是否有下級(jí)節(jié)點(diǎn)
// console.log('sub',allNodes[node_id - 1]['subids']);
if (typeof (allNodes[node_id - 1]['subids']) != 'undefined') {
$.each(allNodes[node_id - 1]['subids'], function(index, item) {
// console.log('allNodes[item - 1]',allNodes[item - 1])
nodes.add(allNodes[item - 1]);
edges.add({id: node_id + '_' + item, from: node_id, to: item});
});
} else {
alert('當(dāng)前為葉子節(jié)點(diǎn)');
}
} else {
$.each(sub_nodes, function(index, item) {
var sub_sub_nodes = get_directly_sub_nodes(item);
if (sub_sub_nodes.length == 0) {
nodes.remove({id: item});
edges.remove({id: node_id + '_' + item});
} else {
remove_all_sub_nodes(item);
}
nodes.remove({id: item});
edges.remove({id: node_id + '_' + item});
});
}
}
//todo 獲取某節(jié)點(diǎn)直屬下級(jí)節(jié)點(diǎn)
function get_directly_sub_nodes(node_id) {
var return_nodes = [];
var connectedNodes = network.getConnectedNodes(node_id);//獲取所有連接節(jié)點(diǎn)
$.each(connectedNodes, function(index, item) {
// console.log('allNodes',allNodes)
if (item != allNodes[node_id - 1]['pid']) {//當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn) ,不操作
return_nodes.push(item);
}
});
return return_nodes;
}
</script>
</body>以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
淺談mvvm-simple雙向綁定簡(jiǎn)單實(shí)現(xiàn)
本篇文章主要介紹了淺談mvvm-simple雙向綁定簡(jiǎn)單實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04
詳解axios 全攻略之基本介紹與使用(GET 與 POST)
本篇文章主要介紹了axios 全攻略之基本介紹與使用(GET 與 POST),詳細(xì)的介紹了axios的安裝和使用,還有 GET 與 POST方法,有興趣的可以了解一下2017-09-09
Vue或者React項(xiàng)目配置@路徑別名及智能提示方案
這篇文章主要介紹了Vue或者React項(xiàng)目配置@路徑別名及智能提示方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10

