import { DataSet, Network } from "vis/index-network"; import vpnService from '../../services/vpn.service' let vpnTopuHttps = new vpnService() let ori_data = null, cur_data = {}, network = null, container = null, nodeBorderWidth = 5, vm = null, options = { physics: { enabled: false }, interaction: { hover: true }, nodes: { shape: "dot", size: 10, font: { size: 13 }, borderWidth: nodeBorderWidth }, edges: { width: 1, smooth: false, font: { size: 10 } } }; let bExcIds = { "0": [], "1": [], "2": [] }; let int = 0; let nodecontext = null; let edgecontext = null; let colors = { n: "#dddddd", // 闪烁背景色 y: "#ffff00", // 黄色 (闪烁背景色) d: "#cf2b0b", // 深红 (闪烁背景色) l: "#59db49", // 线默认色 r: "#ff3d32", // 红色 (节点出问题) // q:'#72D572', // 淡绿色 (未纳管) q:'#b9bbb9', // 淡绿色 (未纳管) g: "#0A8F08", // 绿色 (已纳管) b: '#2CABE3', // 蓝色 (已部署) }; // 0 异常,1 正常,2 黄色报警,3 橙色报警,4 红色报警,5 紫色报警 let levels = ["a", "l", "y", "o", "d", "v"]; let MapNodeIdIndex = {}; let MapEdgeIdIndex = {}; let registerNetworkEvent = () => { network.on("zoom", params => { let scale = network.getScale(); if (scale < 0.3) { scale = 0.3; } network.moveTo({ scale: scale }); }); network.on("oncontext", params => { let __nodeId = network.getNodeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y }); if (__nodeId) { // 获取点击节点id let isType = 3; let innerStr = ""; let innerClass = ""; cur_data.nodes.forEach((v,i)=>{ if(v.id == __nodeId){ if(v.vpnStatus == '1'){ //vpnStatus 0 未纳管 1 已纳管 2 已部署 isType = 1; innerStr = '添加vpn'; innerClass = 'icon-vpn-add' }else if(v.vpnStatus == '2'){ isType = 2 innerStr = '删除vpn'; innerClass = 'icon-vpn-minus' }else { isType = 3 } } }) if (!nodecontext&&isType!=3) { let div = document.createElement("div"); div.className = `${innerClass} node-oncontext`; div.innerHTML = innerStr; nodecontext = container.appendChild(div); nodecontext.addEventListener( "mouseout", function(e) { document.querySelector('.node-oncontext').remove() nodecontext = null }, false ); } if(document.querySelector(".node-oncontext")){ document.querySelector(".node-oncontext").dataset.v = __nodeId; nodecontext.style.left = params.event.layerX + "px"; nodecontext.style.top = params.event.layerY + "px"; nodecontext.style.display = "block"; document.querySelector(".node-oncontext").onclick = function(e) { let checkData = _store.getters.getCheckId // //改变 选中的id let checkIp = e.currentTarget.dataset.v if(checkData.indexOf(checkIp) == -1){ checkData.push(checkIp) _store.commit('updateCheckId',checkData) }else { _toast('不能重复操作') } }; } } else { hidecontext(); } }); network.on("doubleClick", params => { saveviewpos(); hidecontext(); let id = params.nodes[0]; if (id == undefined) { return; } localStorage.setItem("cfg", ""); let bexc = 0; let bend = 0; let v = ori_data.nodes[MapNodeIdIndex[id]]; bexc = v.bexc; //是否有异常子节点 0 没有光圈 1 正常光圈 2 有异常光圈 bend = v.bend; if(bend == '1'){ //叶子节点 return } if (bexc != "0") { id && redraw(id, 1); } else { id && redraw(id, 2); } }); //更新闪烁状态 int = setInterval(() => { update_nodes_status(); }, 500); //屏蔽右键菜单 document.getElementsByTagName("canvas")[0].oncontextmenu = function(ev) { ev.preventDefault(); }; }; let redraw = (id, qryType,that) => { vm = that?that:vm let cfg = { qryType // 1,展开 2,收缩 3,刷新 0,按点查询 }; cfg.vpnName = sessionStorage.getItem('topuVpnName'); if (qryType === 3 || qryType == 0) { cfg.nodeId = id; } let list = []; if(qryType === 3){ ori_data = JSON.parse(sessionStorage.getItem('graph')) container = document.querySelector(`#topuDiv`) } ori_data && ori_data.nodes.forEach(v => { if (qryType == 1 || qryType == 2) { if (v.ip == id) { cfg.nodeId = v.ip; } } list.push({nodeid:v.ip}) }); if (!list) { return; } cfg.nodeList = list; localStorage.setItem("cfg", JSON.stringify(cfg)); vpnTopuHttps.getTopoList(cfg).then((res)=>{ if(res.code===0){ let data = res.data; update(data) }else { _toast(res.msg) } }).catch((err=>{ console.log(err) })) }; let update= (d) => { // if (!network) { // return; // } d = handleData(d) sessionStorage.setItem("graph", JSON.stringify(d)); int = clearInterval(int); nodecontext = null; edgecontext = null; bExcIds = { "0": [], "1": [], "2": [] }; MapNodeIdIndex = {}; MapEdgeIdIndex = {}; ori_data = d; cur_data = JSON.parse(JSON.stringify(ori_data)); cur_data.nodes.forEach((v, i) => { MapNodeIdIndex[v.id] = i v.color = {} if(v["bexc"] == "1"){ v.color = { border:colors.y} }else if(v["bexc"] == "2"){ v.color = { border:colors.d} }else { v.borderWidth = 0 //无光圈 } if(v.status == '0'){ v.color.background = colors.r }else { if(v.vpnStatus == '0'){ v.color.background = colors.q }else if(v.vpnStatus == '1'){ v.color.background = colors.g }else if(v.vpnStatus == '2'){ v.color.background = colors.b } } bExcIds[v["bexc"]] && bExcIds[v["bexc"]].push(v); }); cur_data.edges.forEach((v, i) => { MapEdgeIdIndex[v.lkId] = i; v.color = { color: colors.l }; v.width = 1; }); cur_data["edges"] = new DataSet(cur_data["edges"]); cur_data["nodes"] = new DataSet(cur_data["nodes"]); network = new Network(container, cur_data, options); registerNetworkEvent(); moveTo(); // 计算 let initpos = JSON.parse(sessionStorage.getItem("initpos")); let initid = sessionStorage.getItem("initid"); if (!initpos) { return; } let initX = initpos.x; let initY = initpos.y; let newpos = network.getPositions([initid]); if (!newpos[initid]) { return; } let newX = newpos[initid].x; let newY = newpos[initid].y; sessionStorage.setItem("initpos", JSON.stringify(newpos[initid])); let offsetX = initX - newX; let offsetY = initY - newY; if (offsetX != 0 || offsetY != 0) { let T = JSON.parse(localStorage.getItem("viewposition")); network.moveTo({ position: { x: T.x - offsetX, y: T.y - offsetY } }); localStorage.setItem( "viewposition", JSON.stringify({ x: T.x - offsetX, y: T.y - offsetY }) ); } }; let moveTo = () => { let scale = JSON.parse(localStorage.getItem("scale")); let viewposition = JSON.parse(localStorage.getItem("viewposition")); if (scale && viewposition) { network.moveTo({ position: viewposition, scale: scale }); } }; let saveviewpos = () => { localStorage.setItem("scale", JSON.stringify(network.getScale())); localStorage.setItem( "viewposition", JSON.stringify(network.getViewPosition()) ); }; let hidecontext = () => { if (nodecontext) { nodecontext.style.display = "none"; } if (edgecontext) { edgecontext.style.display = "none"; } }; let update_nodes_status = () => { if (cur_data["nodes"]) { //正常光环的 if (bExcIds["1"].length > 0) { bExcIds["1"].forEach(v => { if (v.color.border == colors.n) { v.color.border = colors.y; } else if (v.color.border == colors.y) { v.color.border = colors.n; } }) } cur_data["nodes"].update(bExcIds["1"]); } if (bExcIds["2"].length > 0) { bExcIds["2"].forEach(v => { if (v.color.border == colors.n) { v.color.border = colors.d; } else if (v.color.border == colors.d) { v.color.border = colors.n; } }); cur_data["nodes"].update(bExcIds["2"]); } }; let handleData = (data) =>{ let newData = {nodes:[],edges:[]} if(data.retnode.length !=0){ _store.commit('updateRetNode', data.retnode) data.retnode.forEach((v,i)=>{ v.id = v.ip v.x = v.axisX v.y = v.axisY v.label = v.nodeName newData.nodes.push(v) }) } if(data.retlink.length !=0){ data.retlink.forEach((v,i)=>{ v.id = v.lkId v.from = v.snode v.to = v.dnode newData.edges.push(v) }) } return newData } export default { init: (ccClassName, data,that) => { data = handleData(data) vm = that sessionStorage.setItem("graph", JSON.stringify(data)); container = document.querySelector(`#${ccClassName}`); //topu 容器 ori_data = data; //原始数据 cur_data = JSON.parse(JSON.stringify(ori_data)); //拷贝数据(使用) //bexc 是否有异常子节点 0 没有光圈 1 正常光圈 2 有异常光圈 (光圈代表有子节点) //status 节点状态 0 异常 1 正常 2 初始状态 //vpnStatus vpn部署状态 0 未纳管 1已纳管 2 已部署 cur_data.nodes.forEach((v, i) => { MapNodeIdIndex[v.id] = i v.color = {} if(v["bexc"] == "1"){ v.color = { border:colors.y} }else if(v["bexc"] == "2"){ v.color = { border:colors.d} }else { v.borderWidth = 0 //无光圈 } if(v.status == '0'){ v.color.background = colors.r }else { if(v.vpnStatus == '0'){ v.color.background = colors.q }else if(v.vpnStatus == '1'){ v.color.background = colors.g }else if(v.vpnStatus == '2'){ v.color.background = colors.b } } bExcIds[v["bexc"]] && bExcIds[v["bexc"]].push(v); }); //遍历 线 //state 0 正常 1异常 cur_data.edges.forEach((v, i) => { MapEdgeIdIndex[v.lkId] = i; v.color = { color: colors.l }; v.width = 1; }); }, getnetwork: () => { return network; }, destroy: () => { network && (network.destroy(), (network = null)); container && (container.innerHTML = ""); int = clearInterval(int); ori_data = null; cur_data = {}; bExcIds = { "0": [], "1": [], "2": [] }; int = 0; nodecontext = null; edgecontext = null; MapNodeIdIndex = {}; MapEdgeIdIndex = {}; localStorage.removeItem("cfg"); localStorage.removeItem('scale'); localStorage.removeItem('viewposition'); }, cgraph: (fn, S, __fn) => { //改变数据类型 cur_data["edges"] = new DataSet(cur_data["edges"]); cur_data["nodes"] = new DataSet(cur_data["nodes"]); //初始绘制图表 if (!container) return; network = new Network(container, cur_data, options); registerNetworkEvent(); if (!S) { //计算位置 let initpos = network.getPositions(); let initid = Object.keys(initpos)[0]; sessionStorage.setItem("initpos", JSON.stringify(initpos[initid])); sessionStorage.setItem("initid", initid); } }, redraw:redraw };