vue+D3项目拓扑图缩放,拖拽,保存布局等

注意:vue+D3里面的当数据更新的时候,需要先将之前的数据绘画的点清除 (选择所有的点清除,才可以重新绘画),否则将会重新绘画两次,因为之前的数据渲染的视图并没有清除,这该d3和query功能差不多 ,都是原生js的一些封装,所以不会像那些表格插件一个,选择的时候,初始化一下。故这里需要手动初始化。

 

找了很多资料对vue+D3实现的这些拓扑图的代码比较,

getLinksData:function(nodesData,obj ){   //获取链路的信息数据集合
				this.linksData=[];
				let that=this;
				this.$ajax.get('/topology/links'+'?token='+this.token)
				.then(res => {
					if(res.status==200 && res.data.status==0){
							that.linksData=res.data.data;	
//							that.backupLink=res.data.data;

						this.dealForm(obj,nodesData,that.linksData)
					}
				}).catch(e => {console.log(e)})
			},
			setTopo:function(nodesData,linksData){//设置拓扑图的展示
				d3.select('svg').select('g').remove()
				var width = 890,
				  height = 470;
				var text_dx = -20;
				var text_dy = 20;
				var img_w=16,img_h=16;
				var radius=16;
				linksData.some(function(v, i) {
			        nodesData.some(function(w, j) {
			            if (v.source_node == w.node.id) {
			                v.source_val= w;
			            }
			            if (v.target_node == w.node.id) {
			                v.target_val= w;
			            }
			        });
			        v.index = ++i;
			   });
				
				let that=this
				var linkForce=d3.forceLink(linksData)
				.id(function(d){})
				
				let simulation = d3.forceSimulation()
				.nodes(nodesData)
				
				let centerForce = d3.forceCenter(width / 2, height / 2);
				
				let chargeForce = d3.forceManyBody()
				
				simulation
				.force('chargeForce', chargeForce)
		      	.force('centerForce', centerForce)
		      	.force('links', linkForce)

				simulation.on('tick', tickActions)
				
				var  svg = d3.select('svg')
	            .attr('width',width)
	            .attr('height',height)
//	            
	            var g = svg.append('g');

	            var nodes_text = g.selectAll('.node_text')
	            .data(nodesData)
	            .enter()
	            .append('text')
	            .attr('class','font')
	            .text(function(d){
	            	return d.node.name
	            })
	            var links_text=g.selectAll('.link_text')
	            .data(linksData)
	            .enter()
	            .append('text')
	            .attr('class','links_text')
				.text(function(d){
					return d.bandwidth
	          })
//			    .attr('class', 'link')
				
	        let link = g.append('g') 
	        	.attr('class', 'link')
			    .selectAll('line')
			    .data(linksData)
			    .enter()
			    .append('line')
			    .style('stroke-width', linkWidth)
			    .style('stroke', linkColour)
			    .attr('class',function(d){//对数据进行处理
			    	if(typeof d.speedColor =='undefined'){   //流量的显示不存在的时候   这个时候关闭   返回默认的颜色
			    		return linkColour;
			    	}else {  //当存在  流量的时候    显示流量
			    		return d.speedColor;
			    	}
			    })
			    .on('click',function(d){
			    	var cls=document.getElementsByTagName('line');
			    	for (let index=0;index {   //设置边界
//						d.x= d.x - img_w/2 < 0 ? img_w/2 : d.x;
//						d.y=d.y - img_h/2 < 0? img_h/2 : d.y;
//					});
					link.attr("x1", function(d) {
						if(d.source_val){
							return d.source_val.x;
						}
					})
		                .attr("y1", function(d) {
		                	if(d.source_val){
		                		return d.source_val.y;
		                	}
		                	 })
		                .attr("x2", function(d) {
		                	if(d.target_val){
		                		return d.target_val.x;
		                	}
		                	 })
		                .attr("y2", function(d) {
		                	if(d.target_val){
		                		return d.target_val.y;
		                	}
		                	})
				   nodes_text.attr('x',function(d){d.fx=d.x;return d.x-12})
				            .attr("y", function(d) { d.fy=d.y;return d.y-12 });
		           links_text.attr("x", function(d) { 
		           	if(d.source_val && d.target_val){
		           		return (d.source_val.x+d.target_val.x)/2;
		           	}
		           	 })
		                .attr("y", function(d) {
		                	if(d.source_val && d.target_val){
		                		return (d.source_val.y+d.target_val.y)/2;
		                	}
		                	 })
			   	}
				function nodeTypeImage(nodes){
					if(nodes.type==='node'){
						return require('../../../assets/images/newTopo/node.png')
					}else if(nodes.type==='阿里云'){
						return require('../../../assets/images/newTopo/ali.png')					
					}else if(nodes.type==='腾讯云'){
						return require('../../../assets/images/newTopo/tencent.png')
						
					}else if(nodes.type==='华为云'){
						return require('../../../assets/images/newTopo/huawei.png')
									
					}else if(nodes.type==='UCloud'){
						return require('../../../assets/images/newTopo/ucloud.png')
								
					}else{
						return require('../../../assets/images/newTopo/error.png')
					}
				}
		        function dragStart (d) {
			      if (!d3.event.active) simulation.alphaTarget(0.3).restart()
			      d.fx = d.x
			      d.fy = d.y
			    }
			
			    // make sure you can't drag the circle outside the box
			    function dragDrag (d) {
			      d.fx = d3.event.x
			      d.fy = d3.event.y
			    }
			
			    function dragEnd (d) {
			      if (!d3.event.active) simulation.alphaTarget(0)
			      d.fx = null
			      d.fy = null
			      
			      newObj={
			      	id:d.id,
			      	x:d.x,
			      	y:d.y
			      }
			      that.saveData.push(newObj);
			    }
			},
以上代码就是将数据绘画到组件内渲染的代码

 

 

你可能感兴趣的:(vue,D3,拓扑图)