npm安装antv/g6
npm install @antv/g6 --save
上代码
<template><div id="tpt1" ref="container" style="width: 100%;height: 100%;"></div>
</template><script setup>import { Renderer as SVGRenderer } from '@antv/g-svg';//通过svg方式呈现import { Graph,iconfont } from '@antv/g6';import { onMounted, onUnmounted, ref,nextTick,computed } from 'vue';const container = ref();const nodes = ref([{ id: '1', style: { x: 550, y: 100 },data:{id:'1',name:"wifi路由器",type:"路由器"} }//数据格式])const edges = ref([{ id:'1-3-g1',source: '1', target: '3',data:{id:1,name:"线路1",status:0,outRate:"80MB/s",inRate:"50MB/s",scoureName:"url",scoureType:"",scoureUrl:"",targetName:"http",targetType:"",targetUrl:"",watchDevice:"",watchUrl:""} }//数据格式])let graph:any = nullonMounted(() => {updateChart();})onUnmounted(() => {graph && graph.clear();});//获取所有节点const getNodeData = () => {return graph.getNodeData()}//获取所有边const getEdgeData = () => {return graph.getEdgeData()}//获取缩放比例const getZoom = () => {return graph.getZoom();}const updateChart = () => {const style = document.createElement('style');style.innerHTML = `@import url(${iconfont.css});`;document.head.appendChild(style);graph = new Graph({container: container.value,data: {nodes: nodes.value,edges: edges.value,},edge: {// type:"extra-label-edge",style: {//线条的样式cursor: 'pointer',lineWidth: 1,labelText: (d:any) => {// 改变边上的第一行第二行颜色nextTick(()=>{let parentElement = document.getElementById(d.id)let tspanList = parentElement.getElementsByTagName("tspan")setTimeout(()=>{if(tspanList.length>=2){tspanList[0].setAttribute("fill","#81f4f9")tspanList[1].setAttribute("fill","#eca13c")}})})return props.isEdit||(d.data.outRate==''&&d.data.inRate=='')?'':`⬆${d.data.outRate}\n⬇${d.data.inRate}`;},data:(d)=>{return d.data},endArrow: props.isEdit?true:false,endArrowType: (d) => d.id.split('-')[0],increasedLineWidthForHitTesting:10,stroke: '#83d6dc',labelAutoRotate:true,//是否旋转与边一致labelFill: '#fff',labelFontSize: 11,labelPadding:[3,7],zIndex:2},},transforms: [{type:"process-parallel-edges",mode:"bundle",distance: 50}],node: {type: 'image',style:{padding:[10,10],size: [60,60],labelText: (d:any) => {return d.data.name;},src: (d)=>{//通过类型自定义节点图片let imgArr:any = {"交换机":"tpt_jhj.png","路由器":"tpt_lyq.png","安全设备":"tpt_fhq.png","其他设备":"tpt_qt.png",}return (d.data.type?getImageUrl(imgArr[d.data.type]):getImageUrl('tpt_qt.png')) || getImageUrl('tpt_qt.png')},data:(d)=>{return d.data},labelPosition: 'bottom',labelFill: '#fff',labelFontSize: 13,labelBackground: false,//背景颜色labelBackgroundFill: 'linear-gradient(#e66465, #9198e5)',labelBackgroundStroke: '#9ec9ff',labelBackgroundRadius: 2,labelFontWeight: 600,labelPadding:[3,10],zIndex:3,labelOffsetY:8,badge: false, // 是否显示徽标badges: [{ text: 'x', placement: 'right-top',padding:[2,5] },],badgePalette: ['red'], // 徽标的背景色板badgeFontSize: 10, // 徽标字体大小}},behaviors: [{type:'zoom-canvas'//缩放},{type: 'drag-canvas',key: 'drag-canvas-1',},{type:"drag-element",key: 'drag-element-1',enableAnimation:false,shadow:false//拖动样式},{type: 'create-edge',key:"create-edge-1",trigger: 'click',//dragonCreate: (edge) => {//创建线的样式const { style, ...rest } = edge;return {...rest,data:{name:"",status:0,scoureName:"",scoureType:"",scoureUrl:"",targetName:"",targetType:"",targetUrl:"",watchDevice:"",watchUrl:"",inRate:"",outRate:"",},style: {...style,stroke: 'red',lineWidth: 2,endArrow: true,},};},},],renderer: () => new SVGRenderer(),});graph.render();//鼠标右键点击节点编辑graph.on('node:contextmenu', (e) => {//添加编辑设备不为0是修改form.value = e.target.config.style.datasubmitNode();});}//添加设备按钮const addNode = () => {form.value.id = 0submitNode();}//添加修改节点const submitNode = () => {if(form.value.id == 0){//添加nodes.value = graph.getNodeData();graph.addData({nodes:[{id: nodes.value.length>0?`${graph.getNodeData().length+1}`:"1",style:{ x: container.value.clientWidth/2, y: 30 },data:{id:nodes.value.length>0?`${graph.getNodeData().length+1}`:"1",name:form.value.name,type:form.value.type}}]})}else{graph.updateNodeData([{id:form.value.id,data:form.value}])}graph.render();}
</script>
运行结果
不断更新