前言
該組件基于 Vue.js 和 AntV G6 構建
項目特色功能
1. 豐富的節點圖標支持
本拓撲圖系統的最大特色是支持使用自定義圖片作為節點圖標
2. 智能的力導向布局
系統采用力導向布局算法,能夠自動優化節點位置,避免重疊,形成美觀的網絡拓撲結構。用戶無需手動調整節點位置,系統會自動計算出最佳的顯示效果。
3. 豐富的交互功能
- 拖拽操作:支持節點拖拽,用戶可以手動調整布局
- 縮放平移:支持畫布縮放和平移,方便查看大型網絡
- 懸停效果:鼠標懸停顯示詳細信息
- 點擊復制:點擊節點可將信息復制到剪貼板
4. 漏洞信息展示
邊緣連接不僅表示網絡連接關系,還能顯示具體的漏洞信息,如:
- SQL注入漏洞
- XSS跨站腳本攻擊
- 網絡協議漏洞
- 配置錯誤等
第一步:安裝依賴
首先確保項目中已安裝必要的依賴包:
npm install @antv/g6 vue axios
第二步:準備圖標資源
在項目的 `public/目錄下放置設備圖標文件:
public/defalut.png # 默認設備圖標kylin_high.png # 麒麟系統高危linux_mid.png # Linux中危win_high.png # Windows高危win_low.png # Windows低危win_safety.png # Windows安全linux_high.png # Linux高危linux_low.png # Linux低危
第三步:創建拓撲圖組件
創建主要的拓撲圖組件文件:
<template><div class="topology-container"><div id="container" class="topology-canvas"></div><screen-component :objF="objF":currentEve="currentEve":questionList="questionList":list="list"@realType="handleRealType"/></div>
</template><script>
import { Graph, NodeEvent } from '@antv/g6'
import axios from 'axios'
import ScreenComponent from './screen.vue'export default {name: 'TopologyViewer',components: {ScreenComponent},data() {return {graphHH: null,objF: {},currentEve: [],questionList: [],list: []}}
}
</script>
第四步:實現數據獲取邏輯
methods: {async fetchTopologyData(type) {try {const urlParams = new URLSearchParams(window.location.search);const taskId = urlParams.get('taskId');const response = await axios.get(`/api/topology?taskId=${taskId}&type=${type}`,{headers: {'platform-token': 'your-token-here'}});if (response.data.code === 200) {const topologyData = response.data.data;this.processTopologyData(topologyData);}} catch (error) {console.error('獲取拓撲數據失敗:', error);this.useDefaultData();}}
}
第五步:初始化拓撲圖
initTopology(allData) {// 銷毀現有實例if (this.graphHH) {this.graphHH.destroy();this.graphHH = null;}const graph = new Graph({container: document.getElementById("container"),width: 1520,height: 900,data: {nodes: allData.nodes.map((node) => ({id: node.id,type: node.type || "circle",style: {size: node.size || 60,labelText: `${node.name}\n${node.title}`,labelFill: '#fff',src: node.style?.src,fill: "rgba(255,255,255,.9)"}})),edges: allData.edges.map((edge) => ({id: edge.id,source: edge.source,target: edge.target,style: {labelText: edge.vulName,stroke: "#aaa",lineWidth: 1,labelFill: "rgba(255,255,255,.8)"}}))},layout: {type: "force"},behaviors: ['hover-activate','drag-canvas','zoom-canvas', 'drag-node','drag-element']});// 綁定事件this.bindEvents(graph);this.graphHH = graph;graph.render();
}
數據結構說明
節點數據結構
{id: 'firewall-001', // 唯一標識name: '外網防火墻', // 顯示名稱type: 'image', // 節點類型size: 80, // 節點大小title: '192.168.1.1', // 副標題(如IP地址)style: {src: '/img2/firewall.png' // 圖標路徑}
}
邊緣數據結構
{id: 'edge-001', // 唯一標識source: 'firewall-001', // 源節點IDtarget: 'router-001', // 目標節點IDvulName: '防火墻策略配置漏洞' // 漏洞描述
}
高級功能實現
1. 節點狀態管理
實現不同狀態下節點的視覺效果:
// 設置節點狀態
setNodeState(nodeId, state) {const graph = this.graphHH;switch(state) {case 'active':graph.updateNodeData([{id: nodeId,style: {stroke: '#ff4d4f',shadowBlur: 10,shadowColor: 'rgba(255, 77, 79, 0.5)'}}]);break;case 'normal':graph.updateNodeData([{id: nodeId,style: {stroke: '#d9d9d9',shadowBlur: 0}}]);break;}graph.draw();
}
2. 動態數據更新
支持實時更新拓撲數據:
updateTopologyData(newData) {const graph = this.graphHH;// 更新節點if (newData.nodes) {graph.updateData({nodes: newData.nodes.map(node => ({id: node.id,style: node.style}))});}// 更新邊緣if (newData.edges) {graph.updateData({edges: newData.edges.map(edge => ({id: edge.id,style: edge.style}))});}
}
3. 搜索和篩選功能
實現節點搜索和類型篩選:
searchNodes(keyword) {const graph = this.graphHH;const allNodes = graph.getNodes();allNodes.forEach(node => {const nodeData = graph.getNodeData(node.id);const isMatch = nodeData.name.includes(keyword) || nodeData.title.includes(keyword);graph.updateNodeData([{id: node.id,style: {opacity: isMatch ? 1 : 0.3}}]);});graph.draw();
}filterByType(deviceType) {const graph = this.graphHH;const allNodes = graph.getNodes();allNodes.forEach(node => {const nodeData = graph.getNodeData(node.id);const isVisible = deviceType === 'all' || nodeData.deviceType === deviceType;graph.updateNodeData([{id: node.id,style: {display: isVisible ? 'block' : 'none'}}]);});graph.draw();
}
性能優化建議
1. 大數據量處理
當節點數量超過1000個時,建議采用以下優化策略:
// 啟用性能模式
const graph = new Graph({// ... 其他配置modes: {default: ['drag-canvas', 'zoom-canvas']},// 禁用一些耗性能的功能animate: false,groupByTypes: false
});
2. 內存管理
正確的實例銷毀:
beforeDestroy() {if (this.graphHH) {this.graphHH.destroy();this.graphHH = null;}// 清理定時器if (this.intervalId) {clearInterval(this.intervalId);}
}
3. 事件優化
避免頻繁的事件觸發:
// 使用防抖處理鼠標事件
const debouncedHover = debounce((e) => {// 懸停處理邏輯
}, 100);graph.on(NodeEvent.POINTER_ENTER, debouncedHover);
樣式定制
CSS樣式配置
.topology-container {width: 100%;height: 100vh;background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);position: relative;
}.topology-canvas {width: 100%;height: 100%;border-radius: 10px;box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}/* 節點標簽樣式 */
.g6-tooltip {background: rgba(0, 0, 0, 0.8);color: white;border-radius: 4px;padding: 8px 12px;font-size: 12px;
}
常見問題及解決方案
- 圖標不顯示:檢查圖片路徑是否正確,確保圖片文件存在
- 節點重疊:調整力導向布局參數或增加畫布大小
- 性能問題:減少節點數量或禁用動畫效果
- 事件不響應:檢查事件綁定是否正確,確保DOM元素已渲染