<template>
<div id="borrow">
<div id="Main">
<div class="tupu" id="tupu">
<div class="tupu-toolbar">
<ul>
<li id="zoomOut">
<span class="big"></span>放大
</li>
<li id="zoomIn">
<span class="small"></span>缩小
</li>
<li id="reset">
<span class="refresh"></span>重置
</li>
<li @click="toggleFullScreen($event)">
<span class="screen"></span>
{{isFullscreen?"全屏":"退出"}}
</li>
<li id="TrSave" @click="downloadImpByChart(\'股权穿透图\')">
<span class="save"></span>保存
</li>
</ul>
</div>
<div id="mountNode"></div>
</div>
</div>
<div class="back" @click="onJumpReport">
<!-- <img src="~@/assets/relation/back.svg" alt /> -->
{{companyName}}
</div>
<div class="back2 back" @click="onJumpReport">
<img src="~@/assets/relation/back.svg" alt />返回
</div>
</div>
</template>
export default { components: {}, mixins: [D3Mixin], name: \'relation2\', data() { return { companyName: this.$route.query.companyName, isFullscreen: true, rootData: { "downward": { "direction": "down", "name": "origin", "children": [ { "name": "...有限公司", "amount": "100", "ratio": "55%", "hasHumanholding":true, "hasChildren":true, "isExpand": false, "type": 2, "hasNode": 1, "children": [ { "name": "公司名字", "hasHumanholding":false, "hasChildren":true, "amount": "100", "isHoldingCompany": true, "ratio": "55%", "type": 2, "children": [] }, { "name": "公司名字", "hasHumanholding":false, "hasChildren":true, "amount": "100", "isHoldingCompany": true, "ratio": "55%", "type": 2, "children": [] } ] }, { "name": "...有限公司11", "amount": "100", "isHoldingCompany": true, "ratio": "55%", "hasHumanholding":true, "hasChildren":true, "isExpand": false, "type": 2, "hasNode": 1, "children": [ { "name": "公司名字", "hasHumanholding":false, "hasChildren":true, "amount": "100", "isHoldingCompany": true, "ratio": "55%", "type": 2, "children": [] }, { "name": "公司名字", "hasHumanholding":false, "hasChildren":true, "amount": "100", "isHoldingCompany": true, "ratio": "55%", "type": 2, "children": [] } ] }, { "name": "...有限公司", "amount": "100", "isHoldingCompany": true, "ratio": "55%", "hasHumanholding":true, "hasChildren":true, "isExpand": false, "type": 2, "hasNode": 1, "children": [ { "name": "公司名字", "hasHumanholding":false, "hasChildren":true, "amount": "100", "isHoldingCompany": true, "ratio": "55%", "type": 2, "children": [] }, { "name": "公司名字", "hasHumanholding":false, "hasChildren":true, "amount": "100", "ratio": "55%", "type": 2, "children": [] } ] }, { "name": "...有限公司", "hasHumanholding":false, "hasChildren":true, "amount": "100", "ratio": "55%", "type": 2, "children": [] }, { "name": "...有限公司", "hasHumanholding":false, "hasChildren":true, "isExpand": false, "amount": "100", "ratio": "55%", "type": 2, "hasNode": 1, "children": [ { "name": "公司或股东名字", "hasHumanholding":false, "amount": "100", "ratio": "55%", "type": 2, "children": [] }, { "name": "公司或股东名字", "hasHumanholding":false, "amount": "100", "ratio": "55%", "type": 2, "children": [] }, { "name": "公司或股东名字", "hasHumanholding":false, "amount": "100", "ratio": "55%", "type": 2, "children": [] }, { "name": "公司或股东名字", "hasHumanholding":false, "amount": "100", "ratio": "55%", "type": 2, "children": [] } ] } ] }, "upward": { "direction": "up", "name": "origin", "children": [ { "name": "...(有限合伙)", "hasHumanholding":false, "amount": "100", "isHoldingCompany": true, "ratio": "55%", "type": 2, }, { "name": "...(有限合伙)", "hasHumanholding":false, "amount": "100", "isHoldingCompany": true, "ratio": "55%", "type": 2, "hasNode": 1, "children": [ { "name": "公司或股东名字", "hasHumanholding":false, "amount": "100", "isHoldingCompany": true, "ratio": "55%", "type": 1, "children": [], "isFHolder": true, "holderPercent": \'5%\', }, { "name": "公司或股东名字", "hasHumanholding":false, "isExpand": false, "amount": "100", "isHoldingCompany": true, "ratio": "55%", "type": 2, "hasNode": 1, "children": [ { "name": "公司或股东名字", "hasHumanholding":false, "amount": "100", "isHoldingCompany": true, "ratio": "55%", "type": 1, "isFHolder": true, "isActualController": true, "holderPercent": \'95%\', "children": [] }, { "name": "公司或股东名字", "hasHumanholding":false, "amount": "100", "ratio": "55%", "type": 2, "children": [] } ] }, { "name": "公司或股东名字", "hasHumanholding":false, "amount": "100", "ratio": "55%", "type": 1, "children": [] } ] } ] } }, rootName: \'...有限公司\', // beijingCrid: \'98682337095518809\' beijingCrid: this.$route.query.companyId ? decodeURIComponent(this.$route.query.companyId) : \'98682337095519887\' } }, created () { }, mounted () { this.getInitData() // this.drawing() window.addEventListener(\'resize\',function(){ const svg = document.getElementById(\'svg\') svg.setAttribute(\'height\',window.innerHeight) }) }, methods: { getInitData () { gqctt({ beijingCrid: this.beijingCrid, direction: \'\' }).then(res => { if (res.code === 0) { this.rootData.upward.children = res.result.investorList this.rootData.downward.children = res.result.holderList this.rootData.upward.children.map(item => { item.amount = Number(item.subConAm).toFixed(2) item.ratio = item.subComBl.length > 6 ? calculation.accMul(item.subComBl,100).toFixed(2) + \'%\' : calculation.accMul(item.subComBl,100) + \'%\' item.name = item.entName item.type = item.bz === \'企业\' ? 2 : 1 item.isHoldingCompany = item.isHolding == 1 ? true : false item.isFHolder = item.subComBl >= 0.25 && item.type == 1 item.holderPercent = item.ratio item.direction = \'up\' }) this.rootData.downward.children.map(item => { item.amount = Number(item.subConAm).toFixed(2) item.ratio = item.subComBl.length > 6 ? calculation.accMul(item.subComBl,100).toFixed(2) + \'%\' : calculation.accMul(item.subComBl,100) + \'%\' item.name = item.pentName item.type = item.bz === \'企业\' ? 2 : 1 item.direction = \'down\' }) this.rootName = res.result.name this.drawing() console.log(this.rootData) } }) }, addChildren (obj,beijingCrid,direction,cb) { gqctt({ beijingCrid: beijingCrid, direction: direction }).then(res => { if (res.code === 0) { if (direction == \'up\') { obj.children = res.result.investorList obj.children.map(item => { item.amount = Number(item.subConAm).toFixed(2) item.isFHolder = true item.ratio = item.subComBl.length > 6 ? calculation.accMul(item.subComBl,100).toFixed(2) + \'%\' : calculation.accMul(item.subComBl,100) + \'%\' item.name = item.entName item.type = item.bz === \'企业\' ? 2 : 1 item.isHoldingCompany = item.isHolding == 1 ? true : false item.isFHolder = item.subComBl >= 0.25 && item.type == 1 item.direction = direction item.holderPercent = item.ratio }) } else { obj.children = res.result.holderList obj.children.map(item => { item.amount = Number(item.subConAm).toFixed(2) item.isFHolder = true item.ratio = item.subComBl.length > 6 ? calculation.accMul(item.subComBl,100).toFixed(2) + \'%\' : calculation.accMul(item.subComBl,100) + \'%\' item.name = item.pentName item.type = item.bz === \'企业\' ? 2 : 1 item.isHoldingCompany = item.isHolding == 1 ? true : false item.isFHolder = item.subComBl >= 0.25 && item.type == 1 item.direction = direction item.holderPercent = item.ratio }) } cb() } }) }, drawing () { const width = document.getElementById(\'mountNode\').scrollWidth const height = document.getElementById(\'mountNode\').scrollHeight || 600 const strokeColor = { isActualController: \'#FBC6C3\', isFHolder: \'#F3DDB6\', person: \'#0084FF\', default: \'#CCC\' } const lineColor = { isActualController: \'#FA6B64\', isFHolder: \'#F1B03A\', person: \'#0084FF\', default: \'#919191\' } const fillColor = { isActualController: "#FFFBFB", isFHolder: \'#FEFBF3\', person: \'#F5FAFF\', default: \'#FFF\' } var _this = this; // var rootName = \'\'; //根节点的名字 var rootRectWidth = 0; //根节点rect的宽度 var downwardLength = 0, upwardLength = 0; var forUpward = true var treeChart = function(d3Object) { this.d3 = d3Object; this.directions = [\'upward\', \'downward\']; }; treeChart.prototype.drawChart = function() { // First get tree data for both directions. this.treeData = {}; var self = this; self.directions.forEach(function(direction) { self.treeData[direction] = _this.rootData[direction]; }); // rootName = \'上海冰鉴信息科技有限公司\'; rootRectWidth = _this.rootName.length * 15 + 60; //获得upward第一级节点的个数 upwardLength = _this.rootData.upward.children.length; //获得downward第一级节点的个数 downwardLength = _this.rootData.downward.children.length; self.graphTree(self.getTreeConfig()); }; treeChart.prototype.getTreeConfig = function() { var treeConfig = { \'margin\': { \'top\': 10, \'right\': 5, \'bottom\': 0, \'left\': 30 } } treeConfig.chartWidth = (width - treeConfig.margin.right - treeConfig.margin.left); treeConfig.chartHeight = (height - treeConfig.margin.top - treeConfig.margin.bottom); treeConfig.centralHeight = treeConfig.chartHeight / 2; treeConfig.centralWidth = treeConfig.chartWidth / 2; treeConfig.linkLength = 160; treeConfig.duration = 500; //动画时间 return treeConfig; }; treeChart.prototype.graphTree = function(config) { var self = this; var d3 = this.d3; var linkLength = config.linkLength; var duration = config.duration; var hasChildNodeArr = []; var id = 0; var diagonal = function(obj) { //折线 var s = obj.source; var t = obj.target; let multiplier = s.x > t.x ? -1 : s.x < t.x ? 1 : 0 let path = s.y > t.y ? (s.y / 3 + t.y * 2 / 3) : (s.y / 3 + t.y * 2 / 3 + 15) return ( "M" + s.x + "," + (s.y + 12) + "L" + s.x + "," + path + "L" + t.x + "," + path + // pathA+ "L" + t.x + "," + t.y ); }; var zoom = d3.behavior.zoom() .scaleExtent([0.5, 2]) .on(\'zoom\', redraw); var svg = d3.select(\'#mountNode\') .append(\'svg\') .attr(\'id\',\'svg\') .attr(\'width\', config.chartWidth + config.margin.right + config.margin.left) .attr(\'height\', config.chartHeight + config.margin.top + config.margin.bottom) .attr(\'xmlns\',\'http://www.w3.org/2000/svg\') .on(\'mousedown\', disableRightClick) .call(zoom) .on(\'dblclick.zoom\', null); var treeG = svg.append(\'g\') .attr(\'class\', \'gbox\') .attr(\'transform\', \'translate(\' + config.margin.left + \',\' + config.margin.top + \')\'); d3.select("#reset").on("click", function(d){ interpolateZoom([0, 0], 1); }); function interpolateZoom(translate, scale) { var self = this; return d3 .transition() .duration(350) .tween("zoom", function() { var iTranslate = d3.interpolate(zoom.translate(), translate), iScale = d3.interpolate(zoom.scale(), scale); return function(t) { zoom.scale(iScale(t)).translate(iTranslate(t)); redraw(); }; }); } function zoomClick() { var clicked = d3.event.target, direction = 1, factor = 0.2, target_zoom = 1, center = [width / 2, height / 2], extent = zoom.scaleExtent(), translate = zoom.translate(), translate0 = [], l = [], view = { x: translate[0], y: translate[1], k: zoom.scale() }; d3.event.preventDefault(); direction = this.id === "zoomOut" ? 1 : -1; target_zoom = Number(zoom.scale() + factor * direction).toFixed(1) if (target_zoom === extent[0] || target_zoom === extent[1]) { return false } if (target_zoom < extent[0]) { target_zoom = extent[0] } if (target_zoom > extent[1]) { target_zoom = extent[1] } translate0 = [(center[0] - view.x) / view.k, (center[1] - view.y) / view.k]; view.k = target_zoom; l = [translate0[0] * view.k + view.x, translate0[1] * view.k + view.y]; view.x += center[0] - l[0]; view.y += center[1] - l[1]; interpolateZoom([view.x, view.y], view.k); } d3.select("#zoomIn").on("click", zoomClick); d3.select("#zoomOut").on("click", zoomClick); for(var d in this.directions) { var direction = this.directions[d]; var data = self.treeData[direction]; data.x0 = config.centralWidth; data.y0 = config.centralHeight; data.children.forEach(collapse); update(data, data, treeG); } function update(source, originalData, g) { var direction = originalData[\'direction\']; forUpward = direction == \'up\'; var node_class = direction + \'Node\'; var link_class = direction + \'Link\'; var downwardSign = (forUpward) ? -1 : 1; var nodeColor = (forUpward) ? \'#37592b\' : \'#8b4513\'; var isExpand = false; var statusUp = true; var statusDown = true; var nodeSpace = 210; var tree = d3.layout.tree().sort(sortByDate).nodeSize([nodeSpace, 0]); var nodes = tree.nodes(originalData); var links = tree.links(nodes); var offsetX = -config.centralWidth; nodes.forEach(function(d) { d.y = downwardSign * (d.depth * linkLength) + config.centralHeight; d.x = d.x - offsetX; if(d.name == \'origin\') { d.x = config.centralWidth; d.y += downwardSign * 0; // 上下两树图根节点之间的距离 } }); var node = g.selectAll(\'g.\' + node_class) .data(nodes, function(d) { return d.id || (d.id = ++id); }) var nodeEnter = node.enter().append(\'g\') .attr(\'class\', node_class) .attr(\'transform\', function(d) { return \'translate(\' + source.x0 + \',\' + source.y0 + \')\'; }) .style(\'cursor\', function(d) { return(d.name == \'origin\') ? \'\' : (d.children || d._children) ? \'pointer\' : \'\'; }) .on(\'click\',d => { if (d.type == 2) { if ((d.direction == \'up\' && d.beijingCrid) || (d.direction == \'down\' && d.pbeijingCrid)) { _this.$router.push({ path: \'/search/detail\', name: \'search-detail\', query: { companyId: d.direction == \'up\' ? d.beijingCrid : d.pbeijingCrid } }) } } }) .on(\'mouseover\',d => { if (d.name === \'origin\') { return false } let hoverLinkArr = [d.id] let sColor = strokeColor.default let lColor = lineColor.default if (d.isActualController) { sColor = strokeColor.isActualController lColor = lineColor.isActualController } else if (d.isFHolder) { sColor = strokeColor.isFHolder lColor = lineColor.isFHolder } else { sColor = strokeColor.person lColor = lineColor.person } getRelationLink(d.id,lColor) d3.selectAll(\'marker#resolved\'+d.id).selectAll(\'path\').attr(\'fill\',lColor) let link if (d.direction == \'up\') { link = d3.selectAll(\'.upLink\') } else { link = d3.selectAll(\'.downLink\') } link.sort(function(a,b){ if (a.target.id === d.id) { return 1 } else { return -1 } }) rect.style(\'stroke-width\',function(r) { if (r.id === d.id) { return \'2\' } }).style(\'stroke\', function(r) { if (r.id === d.id) { if (r.type == 2) { return \'#0084FF\' } else { if (r.type == 1) { if (r.isActualController) { return "#FA6B64" } else if (r.isFHolder) { return \'#F1B03A\' } else { return \'#0084FF\' } } else{ return "#CCC" } } } else { if (r.type == 1) { if (r.isActualController) { return "#FBC6C3" } else if (r.isFHolder) { return \'#F3DDB6\' } else { return \'#83C6FF\' } } else if (r.name === \'origin\') { return \'#0E78DB\' } else{ return "#CCC" } } }) }) .on(\'mouseout\',d => { if (d.name === \'origin\') { return false } d3.selectAll(\'marker#resolved\'+d.id).selectAll(\'path\').attr(\'fill\',lineColor.default) link.style(\'stroke\',function(l){ return \'#919191\' }).style(\'stroke-width\',function(l){ return 1 }) rect.style(\'stroke-width\',function(r) { if (r.id === d.id) { return \'1\' } }).style(\'stroke\', function(r) { if (r.type == 1) { if (r.isActualController) { return "#FBC6C3" } else if (r.isFHolder) { return \'#F3DDB6\' } else { return \'#83C6FF\' } } else if (r.name === \'origin\') { return \'#0E78DB\' } else { return "#CCC" } }) }) function getRelationLink (id,color) { if (id == 1) { return false } let sourceId = \'\' link.style(\'stroke\',function(l){ if (id === l.target.id) { sourceId = l.source.id return color } }).style(\'stroke-width\',function(l){ if (id === l.target.id) { return 2 } }) } const rect = nodeEnter.append("svg:rect") .attr("x", function(d) { return(d.name == \'origin\') ? -(rootRectWidth / 2) : -100; }) .attr("y", function(d) { return(d.name == \'origin\') ? -20 : forUpward ? -52 : 12; }) .attr("width", function(d) { return(d.name == \'origin\') ? rootRectWidth : 200; }) .attr("height", function(d) { return(d.name == \'origin\') ? 40 : 80; }) .attr("rx", 0) .style(\'cursor\', "pointer") .style("stroke", function(d) { if (d.name == \'origin\') { return "#0E78DB" } else if (d.type == 1) { if (d.isActualController) { return "#FBC6C3" } else if (d.isFHolder) { return \'#F3DDB6\' } else { return \'#83C6FF\' } } else{ return "#CCC" } }) .style("fill", function(d) { if (d.name == \'origin\') { return "#0084FF" } else if (d.type == 1) { if (d.isActualController) { return "#FFFBFB" } else if (d.isFHolder) { return \'#FEFBF3\' } else { return \'#F5FAFF\' } } else{ return "#fff" } }) const personTopRect = nodeEnter.append("svg:rect") .attr("x", function(d) { return -100; }) .attr("y", function(d) { return !d.isFHolder ? 0 : d.isActualController ? -102 : -82; }) .attr("width", function(d) { return d.isFHolder ? 200 : 0; }) .attr("height", function(d) { return !d.isFHolder ? 0 : d.isActualController ? 50 : 30; }) .attr("rx", 2) .style("stroke", function(d) { return d.isActualController ? "#FA6B64" : "#F1B03A"; }) .style("fill", function(d) { return d.isActualController ? "#FA6B64" : "#F1B03A"; //节点背景色 }) nodeEnter .append("svg:path") .attr("fill", d => { return d.isActualController ? "#FA6B64" : "#F1B03A" }) .attr("d", function(d) { if (d.isFHolder) { return "M0 -44 L-10 -54 L10 -54 Z" } else { return ""; } }) const holdingCompanyRect = nodeEnter.append(\'svg:rect\') .attr("x", "-40") .attr("y", function(d) { return(d.name == \'origin\') ? \'.35em\' : forUpward ? \'31\' : \'-9\'; }) .attr("rx",2) .attr("width", function(d) { return d.isHoldingCompany ? 30 : 0; }) .attr("height", function(d) { return d.isHoldingCompany ? 20 : 0; }) .style("fill", "#EBF5FF") nodeEnter.append("text") .attr("x", "-35") .attr("dy", function(d) { return(d.name == \'origin\') ? \'.35em\' : forUpward ? \'45\' : \'5\'; }) .attr("text-anchor", "start") .style("fill", "#0084FF") .style(\'font-size\', 10) .text(function(d) { return d.isHoldingCompany ? "控股" : ""; }); nodeEnter.append(\'circle\') .attr(\'r\', 1e-6); nodeEnter.append("text") .attr("x", function(d) { return \'0\' }) .attr(\'dy\', function(d) { return(d.name == \'origin\') ? \'.35em\' : forUpward ? \'-24\' : \'40\'; }) .attr("text-anchor", function(d) { return \'middle\' }) .text(function(d) { if(d.name == \'origin\') { return _this.rootName; } if(d.repeated) { return \'[Recurring] \' + d.name; } return(d.name.length > 12) ? d.name.substr(0, 12) : d.name; }) .style({ \'fill\': function(d) { if(d.name == \'origin\') { return \'#fff\'; } else { return \'#333\' } }, \'font-size\': function(d) { return(d.name == \'origin\') ? 16 : 14; }, \'cursor\': "pointer" }) .on(\'click\', Change_modal) .append(\'svg:title\').text(d=>d.name) nodeEnter.append("text") .attr("x", "0") .attr("dy", function(d) { return(d.name == \'origin\') ? \'.35em\' : forUpward ? \'-5\' : \'59\'; }) .attr("text-anchor", function() { return \'middle\' }) .attr(\'fill\', \'#333\') .text(function(d) { return d.name.length > 24 ? d.name.substr(12, 12) + \'...\' : d.name.substr(12, d.name.length); }) .style({ \'font-size\': function(d) { return(d.name == \'origin\') ? 16 : 14; }, \'cursor\': "pointer" }) .append(\'svg:title\').text(d=>d.name) nodeEnter.append("text") .attr("x", "0") .attr("dy", function(d) { if (d.name === \'origin\') { return \'.35em\' } else { if (forUpward) { if (d.name.length > 12) { return \'16\' } else { return \'6\' } } else { if (d.name.length > 12) { return \'80\' } else { return \'70\' } } } }) .attr("text-anchor", "middle") .attr("class", "linkname") .style("fill", "#666") .style(\'cursor\', "pointer") .style(\'font-size\', 12) .text(function(d) { var str = (d.name == \'origin\') ? \'\' : "认缴金额:"+ d.amount +"万人民币"; return(str.length > 18) ? str.substr(0, 18) + ".." : str; }); nodeEnter.append("text") .attr("x", "10") .attr("dy", function(d) { return(d.name == \'origin\') ? \'.35em\' : forUpward ? \'45\' : \'5\'; }) .attr("text-anchor", "start") .attr("class", "linkname") .style("fill", "#0084FF") .style(\'font-size\', 10) .text(function(d) { return(d.name == \'origin\') ? "" : d.ratio; }); nodeEnter.append("text") .attr("x", "0") .attr("dy", function(d) { return d.isActualController ? -87 : -72; }) .attr("text-anchor", "middle") .style("fill", "#fff") .style(\'font-size\', 12) .text(function(d) { return d.isActualController ? \'疑似实际控制人\' : \'\'; }); nodeEnter.append("text") .attr("x", "0") .attr("dy", function(d) { return d.isActualController ? -65 : -63; }) .attr("text-anchor", "middle") .style("fill", "#fff") .style(\'font-size\', 12) .text(function(d) { return d.isFHolder ? "最终受益人:" + d.holderPercent : \'\'; }); var nodeUpdate = node.transition() .duration(duration) .attr(\'transform\', function(d) { return \'translate(\' + d.x + \',\' + d.y + \')\'; }); nodeUpdate.select(\'circle\') .attr(\'r\', function(d) { return d.hasNode == 1 ? 10 : 0 }) .attr(\'cy\', function(d) { return(d.name == \'origin\') ? -20 : (forUpward) ? -63 : 103; }) .style(\'fill\', function(d) { return d.hasNode == 1 ? "#9CD0FF" : "" }) .style(\'stroke\', function(d) { return d.hasNode == 1 ? "#9CD0FF" : "" }) .style(\'stroke-width\', function(d) { if(d.repeated) { return 5; } }); //代表是否展开的+-号 nodeEnter.append("svg:text") .attr("class", "isExpand") .attr("x", "0") .attr("dy", function(d) { return forUpward ? -57 : 109; }) .attr("text-anchor", "middle") .style("fill", "#fff") .style(\'font-size\',\'20px\') .style(\'cursor\',\'pointer\') .text(function(d) { if(d.name == \'origin\') { return \'\'; } return d.hasNode == 1 ? "+" : \'\' }) .on(\'click\',click) nodeUpdate.select(\'text\').style(\'fill-opacity\', 1) var nodeExit = node.exit().transition() .duration(duration) .attr(\'transform\', function(d) { return \'translate(\' + source.x + \',\' + source.y + \')\'; }) .remove(); nodeExit.select(\'circle\') .attr(\'r\', 1e-6) nodeExit.select(\'text\') .style(\'fill-opacity\', 1e-6); var link = g.selectAll(\'path.\' + link_class) .data(links, function(d) { return d.target.id; }); link.enter().insert(\'path\', \'g\') .attr(\'class\', link_class) .attr(\'stroke\',function(d){ // return \'#8b4513\' return \'#919191\' }) .attr(\'fill\',"none") .attr(\'stroke-width\',\'1px\') // .attr(\'opacity\', 0.5) .attr(\'d\', function(d) { var o = { x: source.x0, y: source.y0 }; return diagonal({ source: o, target: o }); }) .attr("marker-end",function (d, i) { return forUpward ? getMarkerUpArrow(d,i) : getMarkerDownArrow(d,i) }) .attr("id", function(d, i) { return "mypath" + "-" + d.source.id + "-" + d.target.id; }) link.transition() .duration(duration) .attr(\'d\', diagonal); link.exit().transition() .duration(duration) .attr(\'d\', function(d) { var o = { x: source.x, y: source.y }; return diagonal({ source: o, target: o }); }) .remove(); nodes.forEach(function(d) { d.x0 = d.x; d.y0 = d.y; }); function getMarkerUpArrow(d,i) { svg.append("defs").append("marker") //箭头 .attr("id", "resolved"+d.target.id) .attr("markerUnits", "strokeWidth") //设置为strokeWidth箭头会随着线的粗细发生变化 .attr("markerUnits", "userSpaceOnUse") .attr("viewBox", "0 -5 10 10") //坐标系的区域 .attr("refX", -28) //箭头坐标 .attr("refY", 0) .attr("markerWidth", 12) //标识的大小 .attr("markerHeight", 12) .attr("orient", "90") //绘制方向,可设定为:auto(自动确认方向)和 角度值 .attr("stroke-width", 2) //箭头宽度 .append("path") .attr("d", "M0,-5L10,0L0,5") //箭头的路径 .attr(\'fill\', \'#919191\'); //箭头颜色 return "url(#resolved" + d.target.id + ")"; } function getMarkerDownArrow(d,i) { svg.append("defs").append("marker") //箭头 .attr("id", "resolved"+d.target.id) .attr("markerUnits", "strokeWidth") //设置为strokeWidth箭头会随着线的粗细发生变化 .attr("markerUnits", "userSpaceOnUse") .attr("viewBox", "0 -5 10 10") //坐标系的区域 .attr("refX", 0) //箭头坐标 .attr("refY", 0) .attr("markerWidth", 12) //标识的大小 .attr("markerHeight", 12) .attr("orient", "90") //绘制方向,可设定为:auto(自动确认方向)和 角度值 .attr("stroke-width", 2) //箭头宽度 .append("path") .attr("d", "M0,-5L10,0L0,5") //箭头的路径 .attr(\'fill\',\'#919191\'); return "url(#resolved" + d.target.id + ")"; } function Change_modal () { _this.Modal = true } function click(d) { event.stopPropagation() if(forUpward) { } else { if(d._children) { console.log(\'对外投资--ok\') } else { console.log(\'对外投资--no\') } } isExpand = !isExpand; if(d.name == \'origin\') { return; } if(d.children) { d._children = d.children; d.children = null; d3.select(this).text(\'+\') update(d, originalData, g); } else { if (d._children && d._children.length > 0) { d.children = d._children; d._children = null; if(d.name == \'origin\') { d.children.forEach(expand); } d3.select(this).text(\'-\') update(d, originalData, g); } else { gqctt({ beijingCrid: d.direction == \'up\' ? d.beijingCrid : d.pbeijingCrid, direction: d.direction }).then(res => { if (res.code === 0) { if (d.direction == \'up\') { d.children = res.result.investorList d.children.map(item => { item.amount = Number(item.subConAm).toFixed(2) item.isFHolder = true item.ratio = item.subComBl.length > 6 ? calculation.accMul(item.subComBl,100).toFixed(2) + \'%\' : calculation.accMul(item.subComBl,100) + \'%\' item.name = item.entName item.type = item.bz === \'企业\' ? 2 : 1 item.isHoldingCompany = item.isHolding == 1 ? true : false item.isFHolder = item.subComBl >= 0.25 && item.type == 1 item.direction = direction item.holderPercent = item.ratio }) } else { d.children = res.result.holderList d.children.map(item => { item.amount = Number(item.subConAm).toFixed(2) item.isFHolder = true item.ratio = item.subComBl.length > 6 ? calculation.accMul(item.subComBl,100).toFixed(2) + \'%\' : calculation.accMul(item.subComBl,100) + \'%\' item.name = item.pentName item.type = item.bz === \'企业\' ? 2 : 1 item.isHoldingCompany = item.isHolding == 1 ? true : false item.isFHolder = item.subComBl >= 0.25 && item.type == 1 item.direction = direction item.holderPercent = item.ratio }) } d._children = null; if(d.name == \'origin\') { d.children.forEach(expand); } d3.select(this).text(\'-\') update(d, originalData, g) } }) } } } } function expand(d) { if(d._children) { d.children = d._children; d.children.forEach(expand); d._children = null; } } function collapse(d) { if(d.children && d.children.length != 0) { d._children = d.children; d._children.forEach(collapse); d.children = null; hasChildNodeArr.push(d); } } function redraw() { treeG.attr(\'transform\', \'translate(\' + zoom.translate() + \')\' + \' scale(\' + zoom.scale() + \')\'); } function disableRightClick() { // stop zoom if(d3.event.button == 2) { console.log(\'No right click allowed\'); d3.event.stopImmediatePropagation(); } } function sortByDate(a, b) { var aNum = a.name.substr(a.name.lastIndexOf(\'(\') + 1, 4); var bNum = b.name.substr(b.name.lastIndexOf(\'(\') + 1, 4); return d3.ascending(aNum, bNum) || d3.ascending(a.name, b.name) || d3.ascending(a.id, b.id); } }; var d3GenerationChart = new treeChart(d3); d3GenerationChart.drawChart(); }, onJumpReport() { this.$router.push(...) } } }
.g6-tooltip { border: 1px solid #e2e2e2; border-radius: 4px; font-size: 12px; color: #545454; background-color: rgba(255, 255, 255, 0.9); padding: 10px 8px; box-shadow: rgb(174, 174, 174) 0px 0px 10px; } .borrow{ height: 1000px; position: relative; top: -66px; }
D3Mixin.js
/** * 全屏 toggleFullScreen * 保存 downloadImpByChart */ export const D3Mixin = { data() { return { isFullscreen: true, } }, methods: { downloadImpByChart(chartName) { var _this = this; var html = document.getElementsByTagName("html")[0]; //获取可视区域宽 var Bwidth = html.clientWidth + 20; //转换屏幕宽高 var Bheight = html.clientHeight + 150; var Bmax = Bwidth > Bheight ? Bwidth : Bheight; var Bmin = Bwidth > Bheight ? Bheight : Bwidth; var canvas = document.createElement("canvas"); var g = document.getElementsByTagName("g")[0].getBBox(); var svgbox = d3.select(\'#mountNode svg\'); var gbox = document.getElementsByClassName("gbox")[0] || document.getElementsByClassName("container")[0]; var x = g.width / 2 - html.clientWidth / 2 + 20; //计算偏移位置 var y = 0; g.y < 0 ? (y = Math.abs(g.y)) : (y = 0); // gbox.style.transform = "translate(" + x + \'px\' + "," + (y-60) + "px" + ") scale(1)"; //偏移位置 gbox.style.transform = "translate(" + x + "px" + "," + y + "px" + ") scale(1)"; //偏移位置 svgbox.attr("width", g.width + 20); svgbox.attr("height", g.height + 150); var svg = document.getElementById("mountNode").innerHTML; var c = canvas.getContext("2d"); //新建Image对象 var img = new Image(); //svg内容 img.src = "data:image/svg+xml," + encodeURIComponent(svg); //svg内容中可以有中文字符 // img.src = "data:image/svg+xml," + svg; //svg内容中不能有中文字符 //图片初始化完成后调用 var cwidth = g.width; img.onload = function () { //将canvas的宽高设置为图像的宽高 canvas.width = cwidth + 20; canvas.height = g.height + 150; //canvcas画图片 c.fillStyle = "#fff"; c.fillRect(0, 0, canvas.width, canvas.height); c.drawImage(img, 0, 30); var a = document.createElement("a"); a.download = `${chartName}-${_this.companyName}.png`; a.href = canvas.toDataURL("image/png"); a.click(); }; //图片转换为base64后 传给后端 发邮件 gbox.style.transform = ""; svgbox.attr("width", Bmax); svgbox.attr("height", Bmin); }, checkFull() { var isFull = document.fullscreenEnabled || window.fullScreen || document.webkitIsFullScreen || document.msFullscreenEnabled if (isFull === undefined) { isFull = false } return isFull }, FullScreen(el) { if (this.isFullscreen) { //退出全屏 if (document.exitFullscreen) { document.exitFullscreen() } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen() } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen() } else if (!document.msRequestFullscreen) { document.msExitFullscreen() } } else { //进入全屏 if (el.requestFullscreen) { el.requestFullscreen() } else if (el.mozRequestFullScreen) { el.mozRequestFullScreen() } else if (el.webkitRequestFullscreen) { //改变平面图在google浏览器上面的样式问题 el.webkitRequestFullscreen() } else if (el.msRequestFullscreen) { this.isFullscreen = true el.msRequestFullscreen() } } }, toggleFullScreen(e) { this.isFullscreen = !this.isFullscreen this.FullScreen(document.getElementById(\'borrow\')) } }, mounted() { window.addEventListener(\'resize\', () => { let that = this if (!that.checkFull()) { //要执行的动作 that.isFullscreen = true } }) } }