(function(){
	function NewGraph(settings){
		this.opt = $.extend({
			con:"",     //画布的容器id
			width:"",   //画布的宽度
			height:"",   //画布的高度
			linkDistance:200,
			charge: -800, //正数为引力，负数为斥力
			url:"/EGraphPlaform"
		},settings);
	}
	NewGraph.prototype = {
		para:{
			svg:null,
			graph:null,
			simulation:null, //引力布局
			zoomFactor:{k:1,tx:0,ty:0},
			data:null,
			loop:[],
			isHover:false,
			type:"",
			nowId:"",
			ids:[],
			nodeToNode:null,
			nodeSelect:{
				Zpress:0,
				ids:[]
			},
			rangeSelect:{
				isClick:false,
				isOutRange:false,
				mouseStartCoor:null,
				mouseCurrCoor:null,
				mouseEndCoor:null
			},
			makeMark:{
				isClick:false,
				isSourceChoose:false,
				source:null,
				target:null
			},
			hightlight:{
				isEnable:0,
				con:"",
				autoRun:null,
				nodes:null,
				links:[]
			}
		},
		option:{
			type:{
				peo:"P",
				phone:"T",
				order:"C",
				car:"V",
				org:"org",
				invoice:"invoice",
				account:"A"
			},
			line:{
				straight:{
					solid:{
						dashArray:"1,0"
					},
					dotted:{
						dashArray:"2,2"
					}
				}
			},
			arrow:[
		        {
					type:"C",
					fill:"#bc8c8f"
				},
				{
					type:"P",
					fill:"#00b591"
				},
				{
					type:"CDB",
					fill:"#00BFFF"
				}
			],
			opcaity:{
				nodes:{
					weak:0.3,
					strong:1
				},
				links:{
					weak:0.1,
					strong:1
				}
			}
		},
		constructor:NewGraph,
		/*
		 *  初始化
		 */
		init:function(){
			var self = this;
			//初始化svg画布
			self.para.svg = d3.select("#"+self.opt.con)
			             .append("svg")
			             .attr("viewBox", "0 0 " + self.opt.width + " " + self.opt.height )
			             .attr("width",self.opt.width)
			             .attr("height",self.opt.height);
			//设置node，link，linkText的group
			self.para.graph = self.para.svg.append("g").attr("class","graph");
			self.para.graph.append("g").attr("class","markLinks");
			self.para.graph.append("g").attr("class","links");
			self.para.graph.append("g").attr("class","linkTexts");
			self.para.graph.append("g").attr("class","nodes");
			self.para.graph.append("g").attr("class","nodeLabels");
			//初始化引力布局
			self.para.simulation = d3.forceSimulation()
									 //.alphaDecay([0.01])							     
								     .force("charge", d3.forceManyBody().strength(function(d){
								    	 if(d.type=="case"){
								    		 return 10*self.opt.charge;
								    	 }else{
								    		 return 2*self.opt.charge;
								    	 }
								     }))
								     .force("center", d3.forceCenter(self.opt.width / 2, self.opt.height / 2));
			//定义箭头,分为三种类型，实线、虚线、自连接
			self.para.svg.append("defs").selectAll("marker")
					    .data(self.option.arrow)
					    .enter().append("marker")
					    .attr("id", function(d) { return d.type; })
					    .attr("viewBox", "-1 -6 12 12")
					    .attr("refX", function(d){
					    	if(d.type=="C" || d.type=="CDB"){
					    		return 48;
					    	}else{
					    		return 32;
					    	}
					    })
					    //.attr("refY", -1.5)
					    .attr("markerWidth", 8)
					    .attr("markerHeight", 8)
					    .attr("orient", "auto")
					    .append("path")
					    .attr("d", "M10,0L0,5L0,-5L10,0")
					    .attr("fill", function(d){
					    	return d.fill;
					    })
					    .attr("stroke-width", 1)
					    .attr("stroke",function(d){
					    	return d.fill
					    });
			self.zoom(true);
			self.bind();
		},
		bind:function(){
			var self = this;
			_.MessageManager.on("hoverLoop",function($ev,data){
				self.hoverLoop(data);
			});
			self.para.svg.on("click",function(){
				if(self.para.isHover){
					self.para.graph.selectAll(".node").attr("opacity",1);
					self.para.graph.selectAll(".node").select("circle").attr("fill",function(d){
						/*
						if(d.type==self.option.type.company){
							if(d.isDB==0){
								return "#CCEEFF";
							}else if(d.isDB==1){
								return "#00BFFF";
							}
						}else if(d.type==self.option.type.people){
							return "#CCEEFF";
						}else{ 
							return "#CCEEFF";
						}
						*/
						return self.getNodeColor(d.type);
					});
					self.para.graph.selectAll(".link").attr("opacity",1);
					self.para.isHover = false;
					_.MessageManager.fire("clearSelect");
				}
				//删除功能菜单
				self.para.svg.selectAll(".menu").remove();
				self.para.svg.selectAll(".subMenu").remove();
			});
			self.showMenu();
			//keyDown事件
			self.para.nodeSelect.Zpress = 0;
			d3.select("body").on("keydown", function() {
		    	if(d3.event.keyCode ==18){
		    		self.para.graph.selectAll(".node").attr("opacity",1)
		    		self.para.graph.selectAll(".link").attr("opacity",1)
		    		self.para.graph.selectAll(".linkText").attr("opacity",1)
		    		self.para.nodeSelect.Zpress = 1;
		    		self.zoom(false);
		    		self.selectArea(true);
		    	}
		    }).on("keyup",function(){
		    	if(d3.event.keyCode == 18){
		    		//如果提前送掉shift按钮，手动执行mounseup
		    		if(self.para.rangeSelect.isClick==true){
		    			self.para.rangeSelect.isClick = false;
						self.para.svg.selectAll(".selectArea").remove();
						self.selectNodes(self.para.rangeSelect.mouseStartCoor,self.para.rangeSelect.mouseCurrCoor,true);
		    		}
		    		self.para.nodeSelect.Zpress = 0;
		    		self.zoom(true);
		    		self.selectArea(false);
		    	}
		    });
		},
		/*
		 *  显示环形菜单
		 */
		showMenu:function(){
			var self = this;
			self.para.svg.on("dblclick",function(){
				if (d3.event.defaultPrevented) return;
				self.createMenu(d3.mouse(this));
				//self.replace();
			});
		},
		/*
		 *  画饼图
		 *  @param item 饼图父元素
		 *  @param innerR 内半径
		 *  @param outerR 外半径
		 *  @param transitionTime 动画时间
		 *  @param data 数据    例如： [{dataValue:1,name:"编辑",id:"edit"},{dataValue:1,name:"添加",id:"add"},{dataValue:1,name:"删除",id:"delete"}]
		 *  @param coor 圆心坐标
		 *  @param startAngle 开始角度
		 *  @param endAngle 结束角度
		 *  @param className 饼图对应类名
		 *  @return arcs 饼图元素
		 */
		createPie:function(item,innerR,outerR,transitionTime,data,coor,startAngle,endAngle,className){
			var self = this;
			var pieData = d3.pie()
							.value(function(d) { return d.dataValue; })
							.startAngle(startAngle)
							.endAngle(endAngle)(data);
			var arc = d3.arc().innerRadius(innerR).outerRadius(outerR);
			var arcs = item.selectAll("."+className).data(pieData).enter().append("g").attr("class",className).attr("transform","translate("+ coor[0] +","+ coor[1] +")");
			arcs.append("path")
				.attr("fill","#8B8B7A")
				.attr("opacity",0.8)
				.attr("d",function(d){return arc(d);});
				/*
				.transition()
				.duration(transitionTime)
				
				
				.attrTween("d",function(finish){
					var start = {
							startAngle: 0,
							endAngle: 0
						};
					var i = d3.interpolate(start, finish);
					return function(d) { return arc(i(d)); };
				});		
				*/
			//等图形变化完成之后才显示数值	
			arcs.append("text")
				.attr("transform",function(d){
					return "translate(" + arc.centroid(d) + ")";
				})
				.attr("text-anchor","middle")
				.attr("fill","#FFFFFF")
				.style("cursor","pointer")
				.text(function(d){
					return d.data.name;
				})
				.attr("opacity",1)
				/*
				.transition()
				.delay(transitionTime/2)
				.duration(transitionTime)
				.attrTween("opacity",function(d){
					return d3.interpolateNumber(0,1);
				})
				*/;
			return arcs;
		},
		/*
		 *  创建环形菜单
		 *  @param coor 菜单显示的坐标
		 */
		createMenu:function(coor){
			var self = this;
			var data = [{dataValue:1,name:"功能",id:"func"},{dataValue:1,name:"布局",id:"layout"},{dataValue:1,name:"编辑",id:"edit"}];
			var subData = {
				"func":[{dataValue:1,name:"标注",id:"mark"},{dataValue:1,name:"展开",id:"extend"},{dataValue:1,name:"高亮",id:"find"},{dataValue:1,name:"删除线",id:"delLine"}],
				"layout":[{dataValue:1,name:"方阵",id:"matrix"},{dataValue:1,name:"力导向",id:"force"}],
				"edit":[{dataValue:1,name:"删除",id:"delete"}]
			};
			//,{dataValue:1,name:"添加",id:"add"}
			//,{dataValue:1,name:"圆形",id:"circle"}
			
			//删除画布中已有的一级菜单和二级菜单元素
			self.para.svg.selectAll(".menu").remove();
			self.para.svg.selectAll(".subMenu").remove();
			var menu = self.createPie(self.para.svg,40,80,1000,data,coor,0,Math.PI*2,"menu");
			
			var subMenuAngle = Math.PI/6; //一个二级菜单所占的角度
			//点击一级菜单出现相应的二级菜单
			menu.selectAll("*").on("click",function(d){
				d3.event.stopPropagation();
				var subMenuNum = subData[d.data.id].length;   //二级菜单个数
				var midAngle = (d.startAngle+d.endAngle)/2;   //二级菜单中间的角度值
				var angleRange = subMenuAngle*subMenuNum;     //二级菜单的角度范围
				self.para.svg.selectAll(".subMenu").remove(); //删除已有的二级菜单
				var subMenu = self.createPie(self.para.svg,83,123,1000,subData[d.data.id],coor,midAngle-angleRange/2,midAngle+angleRange/2,"subMenu");
				
				subMenu.selectAll("*").on("click",function(d){
					if(d.data.id=="delete"){
						self.deleteNodes();
					}else if(d.data.id=="matrix"){
						self.matrixLayout();
					}else if(d.data.id=="force"){
						self.draw(self.para.data);
						self.para.graph.selectAll(".node").selectAll("circle").each(function(innerD){
							if(self.para.nodeSelect.ids.indexOf(innerD.id)>=0){
								d3.select(this).attr("fill","#0080ff");
							}
						});
					}else if(d.data.id=="mark"){
						//停止force布局
						self.para.simulation.stop();
						self.para.makeMark.isClick=true;
					}else if(d.data.id=="extend"){
						console.log(self.para.nodeSelect.ids);
						self.extendNodes();
						
						/*
						self.para.graph.select(".link").each(function(d){
							var path = d3.select(this).attr("d");
							console.log(path);
							var l = d3.select(this).node().getTotalLength();
							var p = d3.select(this).node().getPointAtLength(0.5 * l);
							var p2 = d3.select(this).node().getPointAtLength(0.55 * l);

							var x = p2.x - p.x;
							var y = p2.y - p.y;
							
							console.log([l,p]);
						});
						*/
					}else if(d.data.id=="add"){
						var coor = d3.mouse(this);
						self.para.simulation.stop();
						console.log(self.para.data.nodes);
						
						var newNode = {
								enable:0,
								id:"new",
								name:"null",
								type:"null",
								vx:0,
								vy:0,
								x:self.getReverseNodeX(coor[0]),
								y:self.getReverseNodeY(coor[1])
						}
						console.log(newNode);
						
						//self.addNode()
					}else if(d.data.id=="delLine"){
						if(self.para.nodeSelect.ids.length<2){
							alert("至少选择两个节点！");
						}else{
							self.deleteLinks();
						}	
					}else if(d.data.id=="find"){
						self.para.hightlight.isEnable;
						self.para.hightlight.nodes = self.getLinkTargetId(self.para.data.links[0]);
						for(var i=0;i<self.para.data.links.length;i++){
							if(self.getLinkSourceId(self.para.data.links[i])==self.para.hightlight.nodes){
								if(self.para.hightlight.links.indexOf(self.para.data.links[i].id)<0){
									self.para.hightlight.links.push(self.para.data.links[i].id);
								}
							}
							if(self.getLinkTargetId(self.para.data.links[i])==self.para.hightlight.nodes){
								if(self.para.hightlight.links.indexOf(self.para.data.links[i].id)<0){
									self.para.hightlight.links.push(self.para.data.links[i].id);
								}
							}
						}
						console.log([self.para.hightlight.nodes,self.para.hightlight.links]);
						
						var lineId = [
				              "58020243740,6338480263181679417",
				              "10768849960,6338480263181679417",
				              "58032319972,6338480263181679417",
				              "58999297804,6338480263181679417",
				              "58018331428,6338480263181679417"];
						console.log(self.para.hightlight.isEable);
						
						self.para.hightlight.nodes = "6338480263181679417";
						self.para.hightlight.links = lineId;
						//如果没有高亮，而且可高亮的links长度大于0
						if(self.para.hightlight.isEnable==0 && self.para.hightlight.links.length>0){
							self.para.hightlight.isEnable = 1; //高亮状态
							self.oneMove(self.para.hightlight.links); //第一次动画
							var outter = null; 
							//添加节点的边框和高亮样式
							self.para.graph.select(".nodes").selectAll(".node").each(function(innerD) { 
								if(innerD.id==self.para.hightlight.nodes){
									var thisNode = d3.select(this);
									thisNode.select("circle").attr("stroke","#FFFFB7")
											.transition().delay(3000).duration(2000).attr("stroke-opacity",1);
									var r = d3.select(this).select("circle").attr("r");
									var outter = thisNode.append("g").attr("class","outter").attr("opacity",0);
									outter.append("circle").attr("fill","#FFFFB7").attr("r",5).attr("cx",function(){
										return r;
									})
									.attr("cy",function(){
										return 0;
									});
									outter.append("circle").attr("fill","#FFFFB7").attr("r",5).attr("cx",function(){
										return -1*r;
									})
									.attr("cy",function(){
										return 0;
									});
								}
							});
							//循环播放动画
							self.para.hightlight.autoRun = setInterval(function(){
								self.oneMove(self.para.hightlight.links);
								self.para.graph.selectAll(".outter").attr("opacity",1).transition()
									.duration(3000)
									.attrTween("transform",function(){
										return d3.interpolateString("rotate(0)", "rotate(360)");
								});
							},3000);
						}else{
							self.para.hightlight.isEnable = 0;
							//清除动画
							clearInterval(self.para.hightlight.autoRun);
							self.para.hightlight.autoRun = null;
							//去掉节点高亮效果
							self.para.graph.select(".nodes").selectAll(".node").each(function(innerD) { 
								if(innerD.id==self.para.hightlight.nodes){
									var thisNode = d3.select(this);
									thisNode.select(".outter").remove();
									thisNode.select("circle").attr("stroke-opacity",0);
								}
							});
						}
					}
					
					self.para.svg.selectAll(".menu").remove();
					self.para.svg.selectAll(".subMenu").remove();
				});
			});
		},
		oneMove:function(lineId){
			var self = this;
			self.para.graph.selectAll(".link").each(function(d){
				if(lineId.indexOf(d.id)<0){
					return;
				}
				var thisLink = d3.select(this),
				thisLinkPath = thisLink.node();
				thisLinkPathLen = thisLinkPath.getTotalLength();
				self.fadeRoute(d,thisLink,thisLinkPath,thisLinkPathLen,3000);
			});
		},
		deleteLinks:function(){
			var self = this;
			//删除相关的线段
			self.para.graph.selectAll(".link").each(function(d){
				var sourceId = self.getLinkSourceId(d);
				var targetId = self.getLinkTargetId(d);
				if(self.para.nodeSelect.ids.indexOf(sourceId)>=0 &&
					self.para.nodeSelect.ids.indexOf(targetId)>=0){
					self.removeLink(d.id);
					d3.select(this).remove();
				}
			});
			//删除相关linktext
			self.para.graph.selectAll(".linkText").each(function(d){
				var sourceId = self.getLinkSourceId(d);
				var targetId = self.getLinkTargetId(d);
				if(self.para.nodeSelect.ids.indexOf(sourceId)>=0 &&
					self.para.nodeSelect.ids.indexOf(targetId)>=0){
					d3.select(this).remove();
				}
			});
			self.clearSelect();
		},
		deleteNodes:function(){
			var self = this;
			for(var i=0;i<self.para.nodeSelect.ids.length;i++){
				//删除相关的节点
				self.removeNode(self.para.nodeSelect.ids[i]);
				self.para.graph.selectAll(".node").each(function(d){
					if(d.id==self.para.nodeSelect.ids[i]){
						d3.select(this).remove();
					}
				});
				//删除相关的线段
				self.para.graph.selectAll(".link").each(function(d){
					if(self.getLinkSourceId(d)==self.para.nodeSelect.ids[i] ||
					   self.getLinkTargetId(d)==self.para.nodeSelect.ids[i]){
						self.removeLink(d.id);
						d3.select(this).remove();
					}
				});
				//删除相关linktext
				self.para.graph.selectAll(".linkText").each(function(d){
					if(self.getLinkSourceId(d)==self.para.nodeSelect.ids[i] ||
							   self.getLinkTargetId(d)==self.para.nodeSelect.ids[i]){
								d3.select(this).remove();
							}
				});
			}
			self.clearSelect();
		},
		extendNodes:function(){
			var self = this;
			if(self.para.nodeSelect.ids.length<=0){
				return;
			}
			var id = self.para.nodeSelect.ids.join(";")
			$.post("/EGraphPlaform/graph/extendData.do",{id:id,level:1},function(result){
				var newGraph = {
						nodes:[
						       	{id:"500",name:"500",type:"people"},
						       	{id:"501",name:"501",type:"car"}
						       ],
						links:[
						       {id:"24500",source:"24",target:"500"},
						       {id:"24501",source:"24",target:"501"}
						       ]
				}
				var mergeData = self.putExtendData(result);
				self.clearFunc();
				self.draw(mergeData);
			},"json");
		},
		fadeRoute:function(d,thisLink,thisLinkPath,thisLinkPathLen,time){
			var self = this;
			var sourceR=0,targetR=0;
			if(d.source.type=="people"){
				sourceR = 50;
			}else{
				sourceR = 50;
			}
	
			var num = {num:sourceR};
			var tween = new TWEEN.Tween(num)
								 .to({num:(thisLinkPathLen-sourceR)},time)
								 .start();
			
			function animate(){
				if(self.para.hightlight.isEnable==0){
					return;
				}
				if(num.num>=(thisLinkPathLen-sourceR)){
					return;
				}
				var tmpPoint = thisLinkPath.getPointAtLength(num.num);
				self.para.graph.append("circle").attr("fill","#FFFFB7").attr("r",5)
					.attr("cx",tmpPoint.x).attr("cy",tmpPoint.y)
					.transition()
					.on("end",function(){
						d3.select(this).remove();
					})
					.duration(700)
					.attrTween("opacity",function(d){
						return d3.interpolateNumber(1,0);
					});
				requestAnimationFrame(animate);
				TWEEN.update();
			}
			animate();
		},
		/*
		 *   加入展开数据
		 * */
		putExtendData:function(data){
			var self = this;
			var mergeData = self.mergeData(self.para.data,data);
			return mergeData;
		},
		/*
		 * 合并数据
		 * */
		mergeData:function(newData,comeData){
			var self = this;
			var nodeIds = self.getAllNodeIds(newData.nodes);
			var linkIds = self.getAllLinkIds(newData.links);
			var tmpData = comeData;
			for(var i=0;i<tmpData.nodes.length;i++){
				var nodeId = tmpData.nodes[i].id;
				var nodeIndex = nodeIds.indexOf(nodeId);
				if(nodeIndex<0){
					newData.nodes.push(tmpData.nodes[i]);
					nodeIds.push(nodeId);
				}else{
					var preCount = newData.nodes[nodeIndex].count;
					var newCount = tmpData.nodes[i].count<0?1:tmpData.nodes[i].count;
					newData.nodes[nodeIndex].count = preCount<newCount?preCount:newCount;
				}
			}
			for(var i=0;i<tmpData.links.length;i++){
				var linkId = tmpData.links[i].id;
				var linkIndex = linkIds.indexOf(linkId);
				if(linkIndex<0){
					newData.links.push(tmpData.links[i]);
					linkIds.push(linkId);
				}else{
					var preCount = newData.links[linkIndex].count;
					var newCount = tmpData.links[i].count<0?1:tmpData.links[i].count;
					newData.links[linkIndex].count = preCount<newCount?preCount:newCount;
				}
			}
			return newData;
		},
		makeMark:function(){
			var self = this;
			//停止force布局
			self.para.simulation.stop();
			
			var linkObj = {
					source:id,
					target:null,
					id:id+""
			};
			self.para.graph.select("links").append("line").datum(linkObj)
							.attr("class","link")
							.attr("stroke-width",2)
							.attr("data-id",function(d){ return d.id;})
							.attr("stroke",function(d){
								return "#red";
							})
							.attr("opacity",function(d){
								return 1;
							})
							.attr("marker-end", function(d) { 
								return "url(#C)"; 
							});
			
			self.para.svg.on("mousedown",function(){
				
			});	
		},
		matrixLayout:function(){
			var self = this;
			var num = self.para.data.nodes.length;
			var coor = new Array();
			var col = Math.ceil(Math.sqrt(num));
			var margin_top = 55,
				margin_left = 10,
				circleR = 100,
				spanCol = circleR+30,
				spanRow = circleR+30;
			var colNum = 0;
			while(coor.length<num){
				for(var i=0;i<col;i++){
					coor.push([margin_left+(i+1)*spanCol,margin_top+(colNum)*spanRow]);
				}
				colNum++;
			}
			self.para.simulation.stop();
			//给每个点固定坐标
			self.para.graph.selectAll(".node").each(function(d,i){
				d.x = coor[i][0];
				d.y = coor[i][1];
			});
			//移动nodes
			self.para.graph.selectAll(".node")
				.transition()
				.duration(750)
				.attr("transform",function(d,i){
					return "translate("+d.x+","+d.y+")";
				});
			//修改link的起始点坐标,线的透明度先设为0，延迟750在出现
			self.para.graph.selectAll(".link").attr("opacity",0)
				.attr("d",function(d){
					return "M"+d.source.x+" "+d.source.y+" L"+d.target.x+" "+d.target.y;
				})
				.transition().delay(750).attr("opacity",1);
			//修改linkText的位置
			self.para.graph.selectAll(".linkText").attr("opacity",0)
				.attr("transform",function(d){
					return "translate("+(d.source.x+d.target.x)/2+","+(d.source.y+d.target.y)/2+")"
				})
				.transition().delay(750).attr("opacity",1);
		},
		removeNode:function(id){
			var self = this;
			var nodes = self.para.data.nodes;
			for(var i=0;i<nodes.length;i++){
				if(nodes[i].id==id){
					nodes.splice(i,1);
					break;
				}
			}
		},
		removeLink:function(id){
			var self = this;
			var links = self.para.data.links;
			for(var i=0;i<links.length;i++){
				if(links[i].id==id){
					links.splice(i,1);
					break;
				}
			}
		},
		hoverLoop:function(data){
			var self = this;
			self.para.isHover = true;
			/*
			var originData = self.clone(self.para.data);
			var loopData = originData[data.name];
			var nodeIds = [], linkIds = [];
			var index = [];
			for(var i=0;i<loopData.length;i++){
				for(var j=0;j<loopData[i].length;j++){
					if(data.id==loopData[i][j].id){
						index.push(i);
						break;
					}
				}
			}
			for(var i=0;i<loopData.length;i++){
				if(index.indexOf(i)>=0){
					for(var j=0;j<loopData[i].length-1;j++){
						if(nodeIds.indexOf(loopData[i][j].id)<0){
							nodeIds.push(loopData[i][j].id);
						}
						var linkId;
						if(j==loopData[i].length-1){
							linkId = loopData[i][j].id+loopData[i][0].id;
						}else{
							linkId = loopData[i][j].id+loopData[i][j+1].id;
						}
						if(linkIds.indexOf(linkId)<0){
							linkIds.push(linkId);
						}
					}
				}
			}
			*/
			var linkIds = ["21","1","88","7","6","2"];
			var nodeIds = ["25","34","15","1","2","6","7","8"];
			self.para.graph.selectAll(".node").attr("opacity",function(d){
				if(nodeIds.indexOf(d.id)>=0){
					return 1;
				}else{
					return 0.2;
				}
			});
			/*
			self.para.graph.selectAll(".node").select("circle").attr("fill",function(d){
				if(d.id==data.id){
					return "#3f51b5";
				}else if(d.type==self.option.type.company){
					if(d.isDB==0){
						return "#00b591";
					}else if(d.isDB==1){
						return "#00BFFF";
					}
				}else if(d.type==self.option.type.people){
					return "#f66800";
				}else{ 
					return "#f66800";
				}
			});
				*/
			self.para.graph.selectAll(".link").attr("opacity",function(d){
				/*
				if(linkIds.indexOf(d.id)>=0){
					return 1;
				}else{
					return 0.05;
				}
				*/
				console.log(d.source);
				if(d.id == "7111"){
					return 0.05;
				}
				if(nodeIds.indexOf(d.source.id)>=0&&nodeIds.indexOf(d.target.id)>=0){
					return 1;
				}else{
					return 0.05;
				}
			});
		},
		/*
		 *  初始化关系图缩放功能
		 *  
		 *  放大原理：<x*k + tx , y*k + ty>
		 *  初始值为： k = 1, tx = ty = 0.
		 *  每次放大通过改变k,tx,ty的数值实现元素的缩放，位置改变
		 *  
		 */
		zoom:function(isZoom){
			var self = this;
			if(isZoom == true){
				self.para.svg.call(d3.zoom().scaleExtent([1/10,8]).on("zoom",function(){
					self.para.graph.attr("transform",d3.event.transform);
					//保存放大参数
					self.para.zoomFactor.k = d3.event.transform.k;
					self.para.zoomFactor.tx = d3.event.transform.x;
					self.para.zoomFactor.ty = d3.event.transform.y;
				}))
				.on("dblclick.zoom", null);
			}else{
				self.para.svg.on(".zoom", null);
			}
		},
		/*
		 *  读取数据
		 *  @param url 后台接口地址
		 */
		loadData:function(url,data){
			var self = this;
			self.para.nowId = data.id+"";   		//记录当前的id
			self.para.ids.push(data.ids+""); 		//记录图中的根节点id
			$.post(url,{id:data.id,level:1,type:data.searchType},function(result){
				/*
				var graph = new Object();
				graph.nodes = [
			               {id:"1",name:"刘员奕",type:"people",enable:0},
			               {id:"2",name:"C013",type:"case",enable:0},
			               {id:"6",name:"C053",type:"case",enable:0},
                           {id:"7",name:"C063",type:"case",enable:0},
                           {id:"8",name:"C092",type:"case",enable:0},
			               {id:"3",name:"car1",type:"car",enable:0},
			               {id:"21",name:"car1",type:"car",enable:0},
			               {id:"22",name:"car2",type:"car",enable:0},
			               {id:"23",name:"car3",type:"car",enable:0},
			               {id:"24",name:"car4",type:"car",enable:0},
			               {id:"25",name:"car5",type:"car",enable:0},
			               {id:"26",name:"car6",type:"car",enable:0},
			               {id:"4",name:"card1",type:"account",enable:0},
			               {id:"18",name:"card2",type:"account",enable:0},
			               {id:"19",name:"card3",type:"account",enable:0},
			               {id:"31",name:"黄建华",type:"people",enable:0},
			               {id:"32",name:"黄会将",type:"people",enable:0},
			               {id:"33",name:"张靠生",type:"people",enable:0},
			               {id:"34",name:"刘楠",type:"people",enable:0},
			               {id:"35",name:"方雷",type:"people",enable:0},
			               {id:"36",name:"王欧普",type:"people",enable:0},
			               {id:"5",name:"13310131101",type:"tel",enable:0},
			               {id:"15",name:"15510231203",type:"tel",enable:1},
			               {id:"16",name:"13990124501",type:"tel",enable:0},
			               {id:"88",name:"XL1",type:"org",enable:0}
			               ];
			
					graph.links = [
			               {id:"12",source:"1",target:"2"},
			               {id:"23",source:"3",target:"2"},
			               {id:"16",source:"1",target:"6"},
			               {id:"42",source:"4",target:"2"},
			               {id:"52",source:"5",target:"2"},
			               {id:"17",source:"1",target:"7"},
			               {id:"156",source:"15",target:"6"},
			               {id:"157",source:"15",target:"7"},
			               {id:"167",source:"16",target:"8"},
			               {id:"186",source:"18",target:"6"},
			               {id:"197",source:"19",target:"7"},
			               {id:"252",source:"25",target:"2"},
			               {id:"216",source:"21",target:"6"},
			               {id:"267",source:"26",target:"7"},
			               {id:"248",source:"24",target:"8"},
			               {id:"258",source:"25",target:"8"},
			               {id:"312",source:"31",target:"2"},
			               {id:"327",source:"32",target:"7"},
			               {id:"358",source:"35",target:"8"},
			               {id:"367",source:"36",target:"7"},
			               {id:"332",source:"33",target:"2"},
			               {id:"882",source:"88",target:"2"},
			               {id:"347",source:"34",target:"7"},
			               {id:"348",source:"34",target:"8"}
			               ];
			               
				var result = new Object();
				result.data = graph;
				*/
				self.clearFunc();
				self.preProcess(result,self.para.nowId);
				self.updateData(self.para.data);
			},"json");
		},
		/*
		 *   预处理新数据，记录每个节点被哪些根节点包含
		 *   @param newData 新数据
		 *   @param newId 新查询的节点
		 * */
		preProcess:function(newData,newId){
			var self =this;			
			if(self.para.data==null){ //如果第一次查询
				self.para.data = newData;//深复制一份新数据保存到本地
				for(var i=0;i<self.para.data.nodes.length;i++){
					if(!self.para.data.nodes[i].hasOwnProperty("belong")){
						self.para.data.nodes[i].belong = new Array();
					}
					self.para.data.nodes[i].belong.push(newId);
				}
				for(var i=0;i<self.para.data.links.length;i++){
					if(!self.para.data.links[i].hasOwnProperty("belong")){
						self.para.data.links[i].belong = new Array();
					}
					self.para.data.links[i].belong.push(newId);
				}
			}else{
				console.log(self.clone(self.para.data));
				var oldData = self.para.data;
				var nodeIds = self.getAllNodeIds(oldData.nodes);
				var linkIds = self.getAllLinkIds(oldData.links);
				for(var i=0;i<newData.nodes.length;i++){
					var index = nodeIds.indexOf(newData.nodes[i].id);
					if(index>=0){
						oldData.nodes[index].belong.push(newId);
					}else{
						newData.nodes[i].belong = new Array();
						newData.nodes[i].belong.push(newId);
						oldData.nodes.push(newData.nodes[i]);
						nodeIds.push(newData.nodes[i]);
					}						
				}
				for(var i=0;i<newData.links.length;i++){
					var index = linkIds.indexOf(newData.links[i].id);
					if(index>=0){
						oldData.links[index].belong.push(newId);
					}else{
						newData.links[i].belong = new Array();
						newData.links[i].belong.push(newId);
						oldData.links.push(newData.links[i]);
						linkIds.push(newData.links[i]);
					}						
				}
			}
			console.log(self.para.data);
		},
		/*
		 * 删除一条查询记录
		 * */
		delOne:function(nodeId){
			var self = this;
			var idsIndex = self.para.ids.indexOf(nodeId);
			self.para.ids.splice(idsIndex,1);
			
			var oldData = self.para.data;
			var delNodeIds = [];
			var delLinkIds = [];
			for(var i=0;i<oldData.nodes.length;i++){
				var tmpBelong = oldData.nodes[i].belong;
				var tmpBelongIndex = tmpBelong.indexOf(nodeId);
				if(tmpBelongIndex>=0){
					tmpBelong.splice(tmpBelongIndex,1);
					if(tmpBelong.length==0){
						delNodeIds.push(oldData.nodes[i].id);
					}
				}
			}
			for(var i=0;i<oldData.links.length;i++){
				var tmpBelong = oldData.links[i].belong;
				var tmpBelongIndex = tmpBelong.indexOf(nodeId);
				if(tmpBelongIndex>=0){
					tmpBelong.splice(tmpBelongIndex,1);
					if(tmpBelong.length==0){
						delLinkIds.push(oldData.links[i].id);
					}
				}
			}
			var newData = {nodes:[],links:[]};
			for(var i=0;i<oldData.nodes.length;i++){
				var index = delNodeIds.indexOf(oldData.nodes[i].id);
				if(index<0){
					newData.nodes.push(oldData.nodes[i]);
				}
			}
			for(var i=0;i<oldData.links.length;i++){
				var index = delLinkIds.indexOf(oldData.links[i].id);
				if(index<0){
					newData.links.push(oldData.links[i]);
				}
			}
			
			self.para.data = null;
			self.para.data = newData;
			
			self.updateData(self.para.data);
		},
		/*
		 *  画布大小调整
		 */
		resize:function(w,h){
			var self = this;
			self.opt.width = w;
			self.opt.height = h;
			self.para.svg.attr("viewBox","0 0 " + w + " " + h)
				.attr("width",w)
				.attr("height",h);;
			self.para.simulation.force("center", d3.forceCenter(self.opt.width / 2, self.opt.height / 2));
		},
		clearSelect:function(){
			var self = this;
			self.para.nodeSelect.ids.splice(0,self.para.nodeSelect.ids.length);
			self.para.graph.select(".nodes").selectAll("circle").attr("fill",function(d){
				return self.getNodeColor(d.type);
			});
		},
		clearFunc:function(){
			var self = this;
			self.para.nodeSelect.ids.splice(0,self.para.nodeSelect.ids.length);
			self.para.graph.select(".nodes").selectAll("circle").attr("fill",function(d){
				return self.getNodeColor(d.type);
			});
			
			self.para.graph.select(".nodes").selectAll(".node").each(function(innerD) { 
				if(innerD.id==self.para.hightlight.nodes){
					var thisNode = d3.select(this);
					thisNode.select(".outter").remove();
					thisNode.select("circle").attr("stroke-opacity",0);
				}
			});
			self.para.hightlight.isEnable=0;
			self.para.hightlight.nodes=null;
			self.para.hightlight.links.splice(0,self.para.hightlight.links.length);
			clearInterval(self.para.hightlight.autoRun);
			self.para.hightlight.autoRun = null;
		},
		clear:function(){
			var self = this;
			self.para.graph.select(".links").selectAll("*").remove();
			self.para.graph.select(".nodes").selectAll("*").remove();
			self.para.graph.select(".linkTexts").selectAll("*").remove();
			self.para.loop.splice(0,self.para.loop.length);
			self.para.isHover = false;
			self.para.data = null;
			self.para.type = "";
			self.para.nodeSelect.ids.splice(0,self.para.nodeSelect.ids.length);
			
			self.clearFunc();
		},
		updateData:function(graph){
			var self = this;
			//self.para.data = graph;
			self.draw(graph);
		},
		getNodeColor:function(type){
			var self = this;
			if(type==self.option.type.order){
				return "#c7fa9e";
			}else if(type==self.option.type.car){
				return "#90fbde";
			}else if(type==self.option.type.phone){
				return "#00fffc";
			}else if(type==self.option.type.account){
				return "#fd199a";
			}else if(type==self.option.type.org){
				return "#0a86fa";
			}else if(type==self.option.type.peo){
				return "#fbf311";
			}else{
				return "#c7fa9e";
			}
		},
		createNode:function(item,nodesData){
			var self = this;
			//item.select(".nodes").selectAll("*").remove();
			var nodes = item.selectAll(".node").data(nodesData,function(d){ return d.id;});
			
			nodes.exit().remove();//删除已有的线段
			var nodesEnter = nodes.enter().append("g").attr("class","node")
						.attr("opacity",1).attr("cursor","pointer")
						.attr("data-id",function(d){return d.id;});
			//鼠标移入节点虚化其他节点
			nodesEnter.on("mouseover",function(d){
				self.mouseoverNode(d);
			}).on("mouseout",function(d){
				self.mouseoutNode(d);
			}).on("dblclick",function(d){
				
			}).on("click",function(d){
				d3.event.stopPropagation();
				self.clickNode(d);
				/*
				var data = {	
						id:d.id,
						name:d.group
				};
				*/
				//self.hoverLoop(data);
				//_.MessageManager.fire("listChange",data);
			});
			
			nodesEnter.append("circle").attr("r",function(d){
				/*
				if(d.type==self.option.type.company){
					return 50;
				}else if(d.type==self.option.type.people){
					return 30; 
				}else{ 
					return 50;
				}*/
				return 50;
			}).attr("fill",function(d){
				/*
				if(d.type==self.option.type.company){
					if(d.isDB==0){
						return "#CCEEFF";
					}else if(d.isDB==1){
						return "#00BFFF";
					}
				}else if(d.type==self.option.type.people){
					return "#CCEEFF";
				}else{ 
					return "#CCEEFF";
				}
				*/
				return self.getNodeColor(d.type);
			});
			
			nodesEnter.selectAll("circle").each(function(d){
				var nodeThis = d3.select(this);
				if(d.enable==1){
					nodeThis.attr("stroke","red").attr("stroke-width",4).attr("stroke-opacity",1);
				}else{
					nodeThis.attr("stroke","red").attr("stroke-width",4).attr("stroke-opacity",0);
				}
			});
			
			nodesEnter.append("image")  
	            .attr("x",-57) //20  
	            .attr("y",-57)  
	            .attr("width",114) //40 
	            .attr("height",114)  
	            /*
	            .attr("xlink:href",function(){
	            	return self.opt.url+"/images/graph/ren.png";
	            })
	            */
	            .attr("xlink:href",function(d){  
	            	if(d.type==self.option.type.peo){
	            		return self.opt.url+"/images/graph/ren.png";  
	            	}else if(d.type==self.option.type.order){
	            		return self.opt.url+"/images/graph/case.png"; 
	            	}else if(d.type==self.option.type.car){
	            		return self.opt.url+"/images/graph/car.png"; 
	            	}else if(d.type==self.option.type.phone){
	            		return self.opt.url+"/images/graph/phone.png"; 
	            	}else if(d.type==self.option.type.account){
	            		return self.opt.url+"/images/graph/account.png"; 
	            	}else if(d.type==self.option.type.org){
	            		return self.opt.url+"/images/graph/4S.png"; 
	            	}else{
	            		// return self.opt.url+"/images/graph/null.png";
	            	}
	            });  
			
			nodesEnter.append("text").text(function(d){
					if(d.type == self.option.type.order){
						return d.name;
					}else{
						return d.name;
					}
				 })
				 .attr("fill","#FFFFFF")
				 .attr("font-size",16)
				 .attr("text-anchor","middle")
				 .attr("x",0).attr("y",70);
			return item;			
		},
		createLink:function(item,linksData){
			var self = this;
			//item.select(".links").selectAll("*").remove();
			var link = item.selectAll(".link").data(linksData,function(d){ return d.id;});
			link.exit().remove();
			link.enter().append("path")
						.attr("class","link")
						.attr("stroke-width",2)
						.attr("data-id",function(d){ return d.id;})
						.attr("id",function(d){ return d.id;})
						.attr("stroke",function(d){
							return "#bc8c8f";
						})
						.attr("opacity",function(d){
							return 1;
						})
						.attr("marker-end", function(d) { 
							return "url(#C)"; 
						});
			return item;
		},
		createLinkText:function(item,linksData){
			var self = this;
			var linkText = item.selectAll(".linkText").data(linksData,function(d){ return d.id;});
			linkText.exit().remove();
			var oneLinkText = linkText.enter().append("g").attr("class","linkText");
			oneLinkText.append("text").attr("fill","#FFFFFF")
									  .style("text-anchor","middle")
									  .style("cursor","default")
									  .text(function(d){ 
										  return d.rel.join(",");
									  });
			/*
			linkText.enter().append("text")
							.append("textPath")
							.attr("class","linkText")
							.attr("xlink:href",function(d){
								return "#"+d.id+"";
							})
							.style("text-anchor","middle")
							.attr("startOffset","50%")
							.attr("fill","#FFFFFF")
							.text(function(d){
								return d.id;
							});
							*/
			return item;
		},
		mouseoverNode:function(d){
			var self = this;
			if(self.para.nodeSelect.Zpress==1 ){
				return;
			}
			//if(self.func.relation.enable==0 && self.func.shortestPath.enable==0){
				self.para.graph.selectAll(".node").attr("opacity",function(inner){
					if(self.para.nodeToNode[inner.id+"-"+d.id]==1){
						return 1;
					}else{
						return 0.3;
					}
				});
				self.para.graph.selectAll(".link").attr("opacity",function(inner){
					if(inner.source.id==d.id || inner.target.id==d.id){
						return 1;
					}else{
						return 0.1;
					}
				});
			//}
			self.para.graph.selectAll(".linkText").attr("opacity",function(inner){
				if(inner.source.id==d.id || inner.target.id==d.id){
					return 1;
				}else{
					return 0;
				}
			});
		},
		mouseoutNode:function(d){
			var self = this;
			if(self.para.nodeSelect.Zpress==1){
				return;
			}
			//if(self.func.relation.enable==0  && self.func.shortestPath.enable==0){
				self.para.graph.selectAll(".node").attr("opacity",function(inner){
					return inner.originOpacity;
				});
				self.para.graph.selectAll(".link").attr("opacity",function(inner){
					return inner.originOpacity;
				});
			//}
			self.para.graph.selectAll(".linkText").attr("opacity",function(inner){
				return 1;
			});
		},
		clickNode:function(d){
			var self = this;
			if(self.para.nodeSelect.Zpress==1){
				var index = self.para.nodeSelect.ids.indexOf(d.id);
				if(index<0){
					self.para.nodeSelect.ids.push(d.id);
					self.nodeColChange(d.id,"#0080ff");
				}else{
					self.para.nodeSelect.ids.splice(index,1);
					self.nodeColChange(d.id,self.getNodeColor(d.type));
				}
			}else if(self.para.makeMark.isClick==true){
				if(self.para.makeMark.isSourceChoose==false){
					self.para.makeMark.source = d;
					self.para.graph.select(".markLinks").append("path")
									.attr("class","markLine")
									.attr("stroke-width",2)
									.attr("stroke","red")
									.attr("opacity",1)
									.attr("marker-end", "url(#C)");
					
					self.para.svg.on("mousemove",function(){
						self.para.graph.select(".markLine")
										.attr("d",function(){
											return "M"+self.para.makeMark.source.x+" "+self.para.makeMark.source.y+
												   " L"+d3.mouse(this)[0]+" "+d3.mouse(this)[1];
										});
					});	
					self.para.makeMark.isSourceChoose=true;
				}else{
					self.para.makeMark.target = d;
					var linkObj = {
							id:self.para.makeMark.source.id+""+self.para.makeMark.target.id,
							source:self.para.makeMark.source,
							target:self.para.makeMark.target,
							type:"mark",
							rel:[]
					}
					console.log(linkObj);
					
					var linkIds = self.getAllLinkIds(self.para.data.links);
					console.log(linkIds);
					if(linkIds.indexOf(linkObj.id)<0){
						console.log("add");
						self.para.data.links.push(linkObj);
						self.para.graph.select(".links").append("path").datum(linkObj)
							.attr("class","link")
							.attr("stroke-width",2)
							.attr("stroke","red")
							.attr("opacity",1)
							.attr("marker-end", "url(#C)")
							.attr("d",function(inner){ 
								return "M"+inner.source.x+" "+inner.source.y+" L"+inner.target.x+" "+inner.target.y;
							});
					}
					self.para.graph.select(".markLinks").selectAll("*").remove();
					self.para.svg.on("mousemove",null);
					self.para.makeMark.isSourceChoose=false;
					self.para.makeMark.isClick=false;
					
					console.log(self.para.data);
					
					self.para.nodeToNode[self.getLinkSourceId(linkObj)+"-"+self.getLinkTargetId(linkObj)] = 1;
					self.para.nodeToNode[self.getLinkTargetId(linkObj)+"-"+self.getLinkSourceId(linkObj)] = 1;
				}
			}else{
				_.MessageManager.fire("infoDetail",d);
			}
		},
		nodeColChange:function(id,col){
			var self = this;
			self.para.graph.selectAll(".node").each(function(d){
				if(d.id == id){
					d3.select(this).select("circle").attr("fill",col);
				}
			});
		},
		/*
		 *  实现矩形区域选择nodes
		 */
		selectArea:function(flag){
			var self = this;
			if(flag){
				self.para.svg.on("mousedown",function(){
					//console.log(1);
					if(self.para.svg.select(".selectArea")._groups[0][0]!=null){
						self.para.rangeSelect.isClick = false;
					}else{
						self.para.rangeSelect.isClick = true;
						self.para.rangeSelect.mouseStartCoor = d3.mouse(this);
						self.para.svg.selectAll(".selectArea").remove();
						return false;
					}				
				})
				.on("mousemove",function(){
					//console.log(2);
					if(self.para.rangeSelect.isOutRange){
						self.para.rangeSelect.isClick = false;
						self.para.svg.selectAll(".selectArea").remove();
						self.selectNodes(self.para.rangeSelect.mouseStartCoor,self.para.rangeSelect.mouseCurrCoor,true);
						self.para.rangeSelect.isOutRange = false;
					}
					if(self.para.rangeSelect.isClick){
						self.para.rangeSelect.mouseCurrCoor = d3.mouse(this);
						var x = self.para.rangeSelect.mouseCurrCoor[0]>self.para.rangeSelect.mouseStartCoor[0]?self.para.rangeSelect.mouseStartCoor[0]:self.para.rangeSelect.mouseCurrCoor[0];
						var y = self.para.rangeSelect.mouseCurrCoor[1]>self.para.rangeSelect.mouseStartCoor[1]?self.para.rangeSelect.mouseStartCoor[1]:self.para.rangeSelect.mouseCurrCoor[1];
						self.para.svg.selectAll(".selectArea").remove();
						self.para.svg.append("rect").attr("class","selectArea")
								  .attr("x",x).attr("y",y)
								  .attr("width",Math.abs(self.para.rangeSelect.mouseCurrCoor[0]-self.para.rangeSelect.mouseStartCoor[0]))
								  .attr("height",Math.abs(self.para.rangeSelect.mouseCurrCoor[1]-self.para.rangeSelect.mouseStartCoor[1]))
								  .attr("opacity",0.8);
						self.selectNodes(self.para.rangeSelect.mouseStartCoor,self.para.rangeSelect.mouseCurrCoor,false);
					}
				})
				.on("mouseup",function(){
					//console.log(3);
					if(self.para.rangeSelect.isClick == false){
						return false;
					}
					self.para.rangeSelect.isClick = false;
					self.para.rangeSelect.mouseEndCoor = d3.mouse(this);
					self.para.svg.selectAll(".selectArea").remove();
					self.selectNodes(self.para.rangeSelect.mouseStartCoor,self.para.rangeSelect.mouseEndCoor,true);
					return false;
				});
				$("body").on("mouseup",function(){
					//console.log(4);
					if(self.para.rangeSelect.isClick==true){
						self.para.rangeSelect.isOutRange = true;
					}
				});
			}else{
				console.log("cancel");
				self.para.svg.on("mousedown",null);
				self.para.svg.on("mousemove",null);
				self.para.svg.on("mouseup",null);
				$("body").on("mouseup",null);
			}
		},
		/*
		 *  筛选坐标范围内的nodes
		 *  @param mouseStartCoor 区域开始坐标
		 *  @param mouseEndCoor   区域结束坐标
		 */
		selectNodes:function(mouseStartCoor,mouseEndCoor,flag){
			var self = this;
			var nodes = self.para.graph.selectAll(".node");
			var tempNode = new Array();
			nodes.select("circle").each(function(d){
				var a = (self.getNodeX(d.x)-mouseStartCoor[0])*(self.getNodeX(d.x)-mouseEndCoor[0]);
				var b = (self.getNodeY(d.y)-mouseStartCoor[1])*(self.getNodeY(d.y)-mouseEndCoor[1]);
				if(a<0&&b<0){
					if(tempNode.indexOf(d.id)<0){
						tempNode.push(d.id);
					}
					d3.select(this).attr("fill","#0080ff");
				}else{
					d3.select(this).attr("fill",function(d){
						return self.getNodeColor(d.type);
					});
				}
			});
			nodes.select("circle").each(function(d){
				if(self.para.nodeSelect.ids.indexOf(d.id)>=0){
					d3.select(this).attr("fill","#0080ff");
				}
			});
			if(flag){
				for(var i=0;i<tempNode.length;i++){
					if(self.para.nodeSelect.ids.indexOf(tempNode[i])<0){
						self.para.nodeSelect.ids.push(tempNode[i]);
					}
				}
			}
			console.log(self.para.nodeSelect);
		},
		getNodeX:function(x){
			var self = this;
			return x*self.para.zoomFactor.k+self.para.zoomFactor.tx;
		},
		getNodeY:function(y){
			var self = this;
			return y*self.para.zoomFactor.k+self.para.zoomFactor.ty;
		},
		getReverseNodeX:function(x){
			var self = this;
			return (x-self.para.zoomFactor.tx)/self.para.zoomFactor.k;
		},
		getReverseNodeY:function(y){
			var self = this;
			return (y-self.para.zoomFactor.ty)/self.para.zoomFactor.k;
		},
		draw:function(graph){
			console.log("---draw---")
			console.log(this.para.nodeSelect.ids);
			console.log(graph);
			var self = this;
			//添加连线
			var links = self.createLink(self.para.graph.select(".links"),graph.links);
			//添加连线label
			var linkTextG = self.createLinkText(self.para.graph.select(".linkTexts"),graph.links);
			//添加节点
			var nodes = self.createNode(self.para.graph.select(".nodes"),graph.nodes);
			nodes.selectAll("circle").attr("fill",function(d){ 
				return self.getNodeColor(d.type);
			})
			//force布局
			self.para.simulation.nodes(graph.nodes).on("tick",ticked);
			self.para.simulation.force("link",d3.forceLink().id(function(d,i) { 
		    	return d.id;
		    }).links(graph.links).distance(self.opt.linkDistance));
			self.para.simulation.force("collide", d3.forceCollide().radius(80).iterations(4));
			self.para.simulation.alpha(1).restart(); 
			//构建相连节点
			self.para.nodeToNode = null;
			self.para.nodeToNode = new Object();
			for(var i=0;i<graph.nodes.length;i++){
				self.para.nodeToNode[graph.nodes[i].id+"-"+graph.nodes[i].id] = 1;
			}
			for(var i=0;i<graph.links.length;i++){//marker
				self.para.nodeToNode[self.getLinkSourceId(graph.links[i])+"-"+self.getLinkTargetId(graph.links[i])] = 1;
				self.para.nodeToNode[self.getLinkTargetId(graph.links[i])+"-"+self.getLinkSourceId(graph.links[i])] = 1;
			}
			
			//node拖拽事件
			self.nodeDrag("node");
			
			function ticked() {
				nodes.selectAll(".node").attr("transform",function(d){
					return "translate("+d.x+","+d.y+")";
				});
				
				//调整link位置
				links.selectAll(".link").attr("d",function(d){
					return "M"+d.source.x+" "+d.source.y+" L"+d.target.x+" "+d.target.y;
				});
				
				
				//调整link标签位置
				linkTextG.selectAll(".linkText").each(function(d){
					/*
					var r = null;
					links.selectAll(".link").each(function(innerD){
						if(innerD.id==d.id){
							var path = d3.select(this).node();
							var len = path.getTotalLength();
							var p = path.getPointAtLength(0.5 * len);
							var p2 = path.getPointAtLength(0.55*len);
							var x = p2.x - p.x;
							var y = p2.y - p.y;
							r = Math.atan2(y, x) * 180 / Math.PI;
						}
					});
					d3.select(this).attr("data-deg",r).attr("transform",function(innerD){ 
						var deg = null;
						if(r<90 && r>=0){
							deg = r;
						}else if(r<=180 && r>=90){
							deg = 180-r;
						}else if(r<0 && r>=-90){
							deg = Math.abs(r);
						}else{
							deg = r+180;
						}
						return "translate("+((innerD.source.x + innerD.target.x)/2)+"," +((innerD.source.y + innerD.target.y)/2)+") rotate("+deg+")";
					});
					*/
					d3.select(this).attr("transform",function(){
						return "translate("+((d.source.x + d.target.x)/2)+"," +((d.source.y + d.target.y)/2)+")";
					})
				});
			}
		},
		/*
		 * 返回node的指定字段
		 * */
		getNodeDetail:function(nodeArr,id,key){
			for(var i=0;i<nodeArr.length;i++){
				if(nodeArr[i].id==id){
					return nodeArr[i][key];
				}
			}
			return null;
		},
		/*
		 *  实现、取消node拖拽
		 */
		nodeDrag:function(className){
			var self = this;
			var isDrag = true;
			var nodes = self.para.graph.select(".nodes").selectAll("."+className);
			if(isDrag==true){
				nodes.call(
					d3.drag().on("start",dragStart)
							 .on("drag",dragged)
							 .on("end",dragEnd)
				);
			}else{
				nodes.on(".start", null);
				nodes.on(".drag", null);
				nodes.on(".end", null);
			}
			function dragStart(d) {		
		
			}
			function dragged(d){
				self.mytick(d,this);
			}
			function dragEnd(d) {

			}
		},
		mytick:function(d,thisNode){
			var self = this;
			d3.select(thisNode).attr("transform",function(nodeD){
				nodeD.x = d3.event.x;
				nodeD.y = d3.event.y;
				return "translate("+d3.event.x+","+d3.event.y+")";
			});
			self.para.graph.selectAll(".link").each(function(linkD){
				if(linkD.source.id == d.id){
					d3.select(this).attr("d", function() { 
						return "M"+d3.event.x+" "+d3.event.y+" L"+linkD.target.x+" "+linkD.target.y;
					})
				}
				if(linkD.target.id == d.id){
					d3.select(this).attr("d", function() { 
						return "M"+linkD.source.x+" "+linkD.source.y+" L"+d3.event.x+" "+d3.event.y;
					})
				}
			});
			//调整link标签位置
			self.para.graph.selectAll(".linkText").each(function(linkD){
				if(linkD.source.id == d.id){
					d3.select(this).attr("transform", function() { 
						return "translate("+((d3.event.x + linkD.target.x)/2)+"," +((d3.event.y + linkD.target.y)/2)+")";
					})
				}
				if(linkD.target.id == d.id){
					d3.select(this).attr("transform", function() { 
						return "translate("+((d3.event.x + linkD.source.x)/2)+"," +((d3.event.y + linkD.source.y)/2)+")";
					})
				}
			});
			
		},
		getLinkSourceId:function(link){
			var source = link.source;
			if(link.source instanceof Object){
				source = link.source.id;
			}
			return source;
		},
		getLinkTargetId:function(link){
			var target = link.target;
			if(link.target instanceof Object){
				target = link.target.id;
			}
			return target;
		},
		/*
		 *  获取说有node的id数组
		 *  @param data
		 *  @return ids
		 */
		getAllNodeIds:function(nodes){
			var ids = [];
			for(var i=0;i<nodes.length;i++){
				if(ids.indexOf(nodes[i].id)<0){
					ids.push(nodes[i].id);
				}
			}
			return ids;
		},
		/*
		 *  获取说有node的id数组
		 *  @param data
		 *  @return ids
		 */
		getAllLinkIds:function(links){
			var ids = [];
			for(var i=0;i<links.length;i++){
				if(ids.indexOf(links[i].id)<0){
					ids.push(links[i].id);
				}
			}
			return ids;
		},
		/*
		 * 复制
		 * */
		clone:function(obj){
			var o,i,j,k;
			if(typeof(obj)!="object" || obj===null)return obj;
			if(obj instanceof(Array))
			{
				o=[];
				i=0;j=obj.length;
				for(;i<j;i++)
				{
					if(typeof(obj[i])=="object" && obj[i]!=null)
					{
						o[i]=arguments.callee(obj[i]);
					}
					else
					{
						o[i]=obj[i];
					}
				}
			}
			else
			{
				o={};
				for(i in obj)
				{
					if(typeof(obj[i])=="object" && obj[i]!=null)
					{
						o[i]=arguments.callee(obj[i]);
					}
					else
					{
						o[i]=obj[i];
					}
				}
			}
			return o;
		}
	};
	window.NewGraph=NewGraph;
})()