function Relation(legcerNo,regNo,data){ this.legcerNo = legcerNo; this.regNo = regNo; this.data = data; this.zoomlevel = 1; this.w = 0; this.h = 0; this.index = -1; this.redrawflag = false; this.infovisdiv = null; this.svg = null; this.force = null; this.lines = null; this.nodes = null; this.mouseoverstatus = false; this.chargeVal = -1600; } Relation.prototype.init = function(){ var thisClass = this; thisClass.w = $("#entrelation").width(); thisClass.h = $("#entrelation").height(); $("#entrelation-infovis").width(thisClass.w).append( '' ); $("#entrelation-fullscreen").click(function(){ thisClass.initFullScreen(); }); if($(".entrelation-controlls").length>0){ $(".entrelation-controlls").css({left:$("#entrelation").width()-$(".entrelation-controlls").width()}); } //处理全屏 $(document).on('webkitfullscreenchange mozfullscreenchange msfullscreenchange fullscreenchange', function(){ if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement){ //退出 thisClass.cancelFullScreen(); } }); this.infovisdiv = document.getElementById("entrelation-infovis"); document.onkeydown=function(event){ var e = event || window.event || arguments.callee.caller.arguments[0]; if(e && e.keyCode==122){ event.preventDefault?event.preventDefault():window.event.returnValue = false; if(!!window.ActiveXObject || "ActiveXObject" in window){//ie下F11不能用,屏蔽掉 if($(".exit").length == 0){ return; } } thisClass.initFullScreen(); }else if(e && e.keyCode==27){ event.preventDefault?event.preventDefault():window.event.returnValue = false; thisClass.cancelFullScreen(); } }; $(window).resize(function(){ if(!thisClass.redrawflag){ //1秒后重绘 thisClass.redrawflag=true; setTimeout(thisClass.redraw,1000); } firstresize=false; }); if(document.getElementById("entrelation-infovis")){ document.getElementById("entrelation-infovis").oncontextmenu=function(){return false;}; } $("#entrelation-fullscreen").attr("title","进入全屏视图"+((!!window.ActiveXObject || "ActiveXObject" in window)?"":" (F11)")); ///////////////////////关系网实例//////////////////////////// var htmls="
"; htmls= htmls+ "
本企业
"; htmls= htmls+ "
其他企业
"; htmls= htmls+ "
个人
"; htmls= htmls+ "
注吊销企业
"; htmls= htmls+ "
投资关系(股东→企业)
"; htmls= htmls+ "
法定代表人
"; htmls= htmls+ ""; htmls= htmls+"
" $("#entrelation").append(htmls); try{ this.dataProcess(); this.makeRelation(); }catch(e){} } Relation.prototype.dataProcess = function(){ var reg = new RegExp(/(有限公司|有限责任公司|股份有限公司|总公司|分公司|公司|事务所|合伙企业)$|\(.*\)|\(.*\)/g); /*var provinces = []; $.ajax({ url: "/js/provinceData.min.json", dataType: "json", cache: true, async: false, success: function(json){ provinces = json; } });*/ for(var i=0;i 2){//先替换结尾 text = text.replace(reg,""); } if(text.length > 2){//再替换开头 //text = this.filterEntName(text); } if(text.length > 2){//小于两个字符不生效 nodeObj.shortText = text; } if(nodeObj.name == this.regNo){//先找本企业位置 this.index = i; nodeObj["regcap"] = (typeof(d1) == "undefined")?0:d1; nodeObj["legcerno"] = this.legcerNo; } } } /*********************************连线处理***********************************/ var minLink=-1,maxLink=-1; for(var i=0;i maxLink){ maxLink = invacconam; }else if(invacconam < minLink){ minLink = invacconam; } } ///////////// var linkSectionArray = this.getLineSectionArray(minLink,maxLink); for(var i=0;i= sectionObj.minVal && invacconam < sectionObj.maxVal){ linksObj["linkVal"] = sectionObj.linkVal; continue; } } } /*********************************节点处理***********************************/ var minNode=-1,maxNode=-1; for(var i=0;i maxNode){ maxNode = regcap; }else if(regcap < minNode){ minNode = regcap; } } } var nodeSectionArray = this.getNodeSectionArray(minNode,maxNode); for(var i=0;i= sectionObj.minVal && regcap < sectionObj.maxVal){ nodeObj["nodeVal"] = sectionObj.nodeVal; continue; } } } } //计算点之间的距离 var chargeArray = [[0,10],[10,20],[20,30],[30,40],[40,50],[50,60],[60,70],[70,80],[80,90],[90,100],[100,110]]; var nodeCount = this.data.nodes.length; for(var i in chargeArray){ if(nodeCount >= chargeArray[i][0] && nodeCount < chargeArray[i][1]){ this.chargeVal += i*100; break; }else if(i == chargeArray.length){ this.chargeVal += i*100; } } } Relation.prototype.filterEntName = function(text){ this.allProvinces = "河南省、青海省、山西省、黑龙江省、安徽省、广西壮族自治区、西藏自治区"; this.commonReplace = function(t){ if(t.length > 1 && text.startWith(t)){ var textCopy = text.replace(new RegExp("^"+t),""); if(textCopy.length > 2){ text = textCopy; } return true; } return false; }; this.replaceStart = function(t,f){ var flag = false; var minus = null; if(this.commonReplace(t)){//替换省、市、县、区 return true; } if(f){//不替换 flag = false; }else if(t.endWith("维吾尔自治区")){ flag = true; minus = 6; }else if(t.endWith("回族自治区") || t.endWith("壮族自治区") || t.endWith("特别行政区")){ flag = true; minus = 5; }else if(t.endWith("自治州") || t.endWith("自治县") || t.endWith("自治区")){ flag = true; minus = 3; }else if(t.endWith("地区")){ flag = true; minus = 2; }else if(t.endWith("省") || t.endWith("市") || t.endWith("区")){ flag = true; minus = 1; } if(flag){ return this.commonReplace(t.substring(0,t.length-minus)); } return false; }; this.replaceCity = function(citys){ if(citys){ for(var c in citys){//市 var c_name = citys[c].n; if(this.replaceStart(c_name)){ this.replaceAreas(citys[c].s); return true; }else if(this.replaceAreas(citys[c].s)){ return true; } } } }; this.replaceAreas = function(areas){ if(areas){ for(var a in areas){//县、区 var a_name = areas[a].n; if(this.replaceStart(a_name,true)){ return true; } } } }; for(var p in provinces){//省 var p_name = provinces[p].n; if(this.allProvinces.indexOf(p_name) == -1){ continue; } if(this.replaceStart(p_name)){ this.replaceCity(provinces[p].s); break; }else if(this.replaceCity(provinces[p].s)){ break; } } return text; } Relation.prototype.getLineSectionArray = function(minLink,maxLink){ var countSection = 6; var section = (maxLink - minLink) / countSection; var sectionArr = []; for(var i=2;i<=countSection;i++){ var minVal = minLink; if(sectionArr.length > 0){ minVal = sectionArr[sectionArr.length - 1].maxVal; } var maxVal = minLink+section*i; if(i == countSection){ maxVal += section; } var sectionObj = {linkVal:i,minVal:minVal,maxVal:maxVal}; sectionArr.push(sectionObj); } return sectionArr; } Relation.prototype.getNodeSectionArray = function(minNode,maxNode){ var countSection = 7; var section = (maxNode - minNode) / countSection; var sectionArr = []; for(var i=1;i<=countSection;i++){ var minVal = minNode; if(sectionArr.length > 0){ minVal = sectionArr[sectionArr.length - 1].maxVal; } var maxVal = minNode+section*i; if(i == countSection){ maxVal += section; } var sectionObj = {nodeVal:6+i,minVal:minVal,maxVal:maxVal}; sectionArr.push(sectionObj); } return sectionArr; } Relation.prototype.launchFullScreen = function(element) { if(element){ if (element.requestFullscreen) { element.requestFullscreen(); } else if (element.msRequestFullscreen) { element.msRequestFullscreen(); } else if (element.mozRequestFullScreen) { element.mozRequestFullScreen(); } else if (element.webkitRequestFullscreen) { // 对 Chrome 特殊处理, // 参数 Element.ALLOW_KEYBOARD_INPUT 使全屏状态中可以键盘输入。 if ( window.navigator.userAgent.toUpperCase().indexOf( 'CHROME' ) >= 0 ) { element.webkitRequestFullScreen( Element.ALLOW_KEYBOARD_INPUT ); }else { // Safari 浏览器中,如果方法内有参数,则 Fullscreen 功能不可用。 element.webkitRequestFullScreen(); } } } } Relation.prototype.cancelFullScreen = function(){ this.h = $("#entrelation-infovis").height(); $("#entrelation-fullscreen").attr("title","进入全屏视图"+((!!window.ActiveXObject || "ActiveXObject" in window)?"":" (F11)")); //force.linkDistance(120).charge(-200).size([w,h]).resume(); $("#entrelation-infovis").css({width:this.w,height:this.h}); //设置svg标签的宽度与高度 d3.select("svg").attr("width", this.w).attr("height", this.h); $(".entrelation-controlls").css({left:$("#entrelation").width()-$(".entrelation-controlls").width()-30}); if(document.exitFullscreen) { document.exitFullscreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } } Relation.prototype.initFullScreen = function(){ var thisClass = this; var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; $(".entrelation-fullscreen").toggleClass("exit"); if(!fullscreenElement || fullscreenElement==null){ this.redrawflag = true; $("#entrelation-fullscreen").attr("title","退出全屏视图 (F11)"); this.launchFullScreen(this.infovisdiv); var timeout = 100; if(!!window.ActiveXObject || "ActiveXObject" in window){ timeout = 200; } setTimeout(function(){ if(thisClass.force != null){ //重绘 var w=document.body.clientWidth; var h=document.body.clientHeight; //if(w>1200){ //w= 1200 //} $("#entrelation-infovis").css({width:w,height:h}); d3.select("svg").attr("width", w).attr("height", h); $(".entrelation-controlls").css({left:w-$(".entrelation-controlls").width() - 70}); thisClass.force.linkDistance(h).charge(-700).size([w,h]).resume(); } },timeout); }else{ this.cancelFullScreen(); } } //重绘 Relation.prototype.redraw = function(){ if(this.force != undefined){ d3.select("svg").attr("width",this.w).attr("height", this.h); this.force.size([this.w,this.h]).resume(); $("#entrelation-infovis").css({width:this.w,height:this.h}); // this.redrawflag = false; } } Relation.prototype.removeNode = function(obj){ if(d3.event.which != 3){ return; } this.highlightObject(obj,false); d3.select(obj).remove(); var name = obj.__data__.name; var removeAloneNode = function(removeNodeName){ var isRemoveAloneNode = true; d3.selectAll("path").each(function (i){ if(removeNodeName == this.__data__.source.name || removeNodeName == this.__data__.target.name){ isRemoveAloneNode = false; return true; } }); if(isRemoveAloneNode){ d3.selectAll("rect").each(function (){ if(this.__data__.name == removeNodeName){ d3.select(this).remove(); return true; } }); d3.selectAll("text").each(function (){ if(this.__data__.name == removeNodeName){ d3.select(this).remove(); return true; } }); } } d3.selectAll("path").each(function (){ if(name == this.__data__.target.name){ var fromNodeName = this.__data__.source.name; d3.select(this).remove(); removeAloneNode(fromNodeName); }else if(name == this.__data__.source.name){ var toNodeName = this.__data__.target.name; d3.select(this).remove(); removeAloneNode(toNodeName); } }); d3.selectAll("rect").each(function (){ if(name == this.__data__.name){ d3.select(this).remove(); } }); d3.selectAll("text").each(function (){ if(name == this.__data__.name){ d3.select(this).remove(); } }); } Relation.prototype.tick = function(e){ var thisClass = this; this.lines.attr("d", function(d){ var sy = d.source.y, x = d.target.x, y = d.target.y; if(sy > y){ sy -= 12; }else{ sy += 5; } var line = new geo.LineSegment(d.source.x, sy, x, y); for (var e in d.target.edge) { var ix = line.intersect(d.target.edge[e].offset(x, y)); if (ix.in1 && ix.in2) { x = ix.x; y = ix.y; break; } } var dx = x - d.source.x, dy = y - sy, dr = Math.sqrt(dx * dx + dy * dy), theta = Math.atan2(dy, dx) + Math.PI / 7.85, d90 = Math.PI / 2, dtxs = x - Math.cos(theta), dtys = y - Math.sin(theta); return "M" + d.source.x + "," + sy + "A" + dr + "," + dr + " 0 0 1," + x + "," + y + "A" + dr + "," + dr + " 0 0 0," + d.source.x + "," + sy + "M" + dtxs + "," + dtys + "l" + (3.5 * Math.cos(d90 - theta) - 10 * Math.cos(theta)) + "," + (-3.5 * Math.sin(d90 - theta) - 10 * Math.sin(theta)) + "L" + (dtxs - 3.5 * Math.cos(d90 - theta) - 10 * Math.cos(theta)) + "," + (dtys + 3.5 * Math.sin(d90 - theta) - 10 * Math.sin(theta)) + "z"; }); this.nodes.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")scale(" + thisClass.zoomlevel+ ")"; }); } Relation.prototype.zoomed = function() { this.svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); } Relation.prototype.highlightObject = function(obj,flag){ if(this.mouseoverstatus){ return; } if(!flag){ d3.selectAll(".node").each(function (){ d3.select(this).style("opacity","1"); }); d3.selectAll("path").each(function (){ d3.select(this).style("opacity","1"); }); return; } var name = obj.__data__.name; d3.selectAll(".node").each(function (){ if(name != this.__data__.name){ d3.select(this).style("opacity","0.2"); } }); d3.selectAll("path").each(function (){ var targetName = this.__data__.target.name; var sourceName = this.__data__.source.name; if(name != targetName && name != sourceName){ d3.select(this).style("opacity","0.2"); }else{ d3.selectAll(".node").each(function (){ if(targetName == this.__data__.name || sourceName == this.__data__.name){ d3.select(this).style("opacity","1"); } }); } }); } Relation.prototype.makeRelation = function(){ var thisClass = this; this.force = d3.layout.force() .nodes(this.data.nodes) .links(this.data.links) .size([this.w, this.h]) .linkDistance(function(p){ return Math.floor(Math.random()*60)+90; }) .chargeDistance(600) .charge(this.chargeVal) .linkStrength(1) .on('tick',function(){ thisClass.tick(); }); var dragstatus = false; var drag = this.force.drag() .on("dragstart",function(d,i){ d.fixed = true; //拖拽开始后设定被拖拽对象为固定 d3.event.sourceEvent.stopPropagation(); // Prevent panning }) .on("drag",function(d,i){ dragstatus = true; thisClass.mouseoverstatus = true; }) .on("dragend",function(d,i){ thisClass.mouseoverstatus = false; setTimeout(function(){ dragstatus = false; },500) }); //处理缩放 var zoom = d3.behavior.zoom().scaleExtent([0.4, 10]).on("zoom", function(){ thisClass.zoomed(); }); this.svg = d3.select("#entrelation-infovis").append("svg:svg") .attr("width", this.w) .attr("height", this.h) .call(zoom) .append("g"); this.lines = this.svg.append("svg:g") .selectAll("path") .data(this.force.links()) .enter().append("path") .style("fill", function(p){ return (p.type=="cp" || p.isLegal)?"#cd93d7":"#cecece"; }) .style("stroke", function(p){ return (p.type=="cp" || p.isLegal)?"#cd93d7":"#cecece"; }) .attr("stroke-width",function (e,i){ return e.linkVal; }); this.lines.each(function (d,i){ var invacconam = new Number(d.invacconam); if(invacconam > 0){ var lenInvacconam = (invacconam + "").length; if(lenInvacconam > 4 && (invacconam + "").indexOf(".") > -1 && (lenInvacconam - (invacconam + "").indexOf(".")) > 4){ invacconam = (new Number(invacconam)).toFixed(4); } d3.select(this).append("title").text("投资金额:"+invacconam+"万元"); } }); this.nodes = this.svg.append("svg:g") .selectAll(".node") .data(this.force.nodes()) .enter() .append("g") .call(this.force.drag) .attr('class', 'node') .on('mouseover', function(d) { thisClass.highlightObject(this,true); }) .on('mouseout', function(d) { thisClass.highlightObject(this,false); }) .on("mousedown",function (e,i){ d3.event.preventDefault(); thisClass.removeNode(this); }); this.nodes.append("rect") .attr("rx", 5) .attr("ry", 5) .attr('height', 20) .attr("fill", function(p){ if(p.type == "e" && (p.opstate == "11" || p.opstate == "07")){ return "#cecece"; } return p.type=="p"?"#2196f3":p.type=="ce"?"#ff9800":"#cddc39"; }) .attr("stroke", function(p){ if(p.type == "e" && (p.opstate == "11" || p.opstate == "07")){ return "#cecece"; } return p.type=="p"?"#2196f3":p.type=="ce"?"#ff9800":"#cddc39"; }).style("opacity",function(p){ if(p.type=="e" && (p.opstate != "11" || p.opstate != "07")){ return "0.5"; } return "1"; }); this.nodes.each(function (d,i){ if(d.type == "ce" || d.type == "e"){ var title = ""; if(d.text != d.shortText){ title = d.text; } var regcap = d.regcap; if(regcap > 0){ var lenRegcap = (regcap + "").length; if(lenRegcap > 4 && (regcap + "").indexOf(".") > -1 && (lenRegcap - (regcap + "").indexOf(".")) > 4){ regcap = (new Number(regcap)).toFixed(4); } if(title != ""){ title += "\n"; } title += "注册资本:"+regcap+"万元"; } if(title != ""){ d3.select(this).append("title").text(title); } } }); this.nodes.append('text') .text(function(d){ return d.shortText; }) .style("cursor",function (d,i){ if(d.type == "e"){ return "pointer"; }else{ return "auto"; } }) .on("click",function (d,i){ if(!dragstatus && d.type == "e"){ window.open("/enterpriseInfoByRegNO/"+d.name+".html"); } }); setTimeout(function() { thisClass.nodes.each(function(d) { var node = d3.select(this), text = node.selectAll('text'), bounds = {}, first = true; text.each(function() { var box = this.getBBox(); if (first || box.x < bounds.x1) { bounds.x1 = box.x; } if (first || box.y < bounds.y1) { bounds.y1 = box.y; } if (first || box.x + box.width > bounds.x2) { bounds.x2 = box.x + box.width; } if (first || box.y + box.height > bounds.y2) { bounds.y2 = box.y + box.height; } first = false; }).attr('text-anchor', 'middle'); var padding = {"left":3,"right":3,"top":2,"bottom":2}, margin = {"left":3,"right":3,"top":2,"bottom":2}, oldWidth = bounds.x2 - bounds.x1; bounds.x1 -= oldWidth / 2; bounds.x2 -= oldWidth / 2; bounds.x1 -= padding.left; bounds.y1 -= padding.top; bounds.x2 += padding.left + padding.right; bounds.y2 += padding.top + padding.bottom; var width = bounds.x2 - bounds.x1; var height = bounds.y2 - bounds.y1; node.select('rect') .attr('x', bounds.x1) .attr('y', bounds.y1) //.attr('height', height) .attr('width', width); d.edge = { left : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x1, bounds.y2), right : new geo.LineSegment(bounds.x2, bounds.y1, bounds.x2, bounds.y2), top : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x2, bounds.y1), bottom : new geo.LineSegment(bounds.x1, bounds.y2, bounds.x2, bounds.y2) }; }); thisClass.force.start(); },10); //var diagonal = d3.svg.diagonal().projection(function(d) { return [d.y, d.x]; }); }