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]; });
}