股权结构图 (vue2.0 + d3)

在pubic下的html文件中引入d3.js

<script src="https://cdn.bootcss.com/d3/3.2.7/d3.min.js"/>

准备好容器

<template><div id="borrow"><div id="mountNode"></div></div>
</template>

初始化数据

data() {return {companyName: '123',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: '98682337095519887'}},

获取节点

  mounted() {this.getInitData()// this.drawing()window.addEventListener('resize', function() {const svg = document.getElementById('svg')svg.setAttribute('height', window.innerHeight)})},

方法

methods: {getInitData() {this.rootName = '123'this.drawing()console.log(this.rootData)},drawing() {const width = document.getElementById('mountNode').scrollWidthconst height = document.getElementById('mountNode').scrollHeight || 600const 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 = 0var forUpward = truevar treeChart = function(d3Object) {this.d3 = d3Objectthis.directions = ['upward', 'downward']}treeChart.prototype.drawChart = function() {// First get tree data for both directions.this.treeData = {}var self = thisself.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.lengthself.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.lefttreeConfig.chartHeight = height - treeConfig.margin.top - treeConfig.margin.bottomtreeConfig.centralHeight = treeConfig.chartHeight / 2treeConfig.centralWidth = treeConfig.chartWidth / 2treeConfig.linkLength = 160treeConfig.duration = 500 //动画时间return treeConfig}treeChart.prototype.graphTree = function(config) {var self = thisvar d3 = this.d3var linkLength = config.linkLengthvar duration = config.durationvar hasChildNodeArr = []var id = 0var diagonal = function(obj) {//折线var s = obj.sourcevar t = obj.targetlet multiplier = s.x > t.x ? -1 : s.x < t.x ? 1 : 0let path = s.y > t.y ? s.y / 3 + (t.y * 2) / 3 : s.y / 3 + (t.y * 2) / 3 + 15return ('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 = thisreturn 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 : -1target_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_zooml = [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.centralWidthdata.y0 = config.centralHeightdata.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 : 1var nodeColor = forUpward ? '#37592b' : '#8b4513'var isExpand = falsevar statusUp = truevar statusDown = truevar nodeSpace = 210var tree = d3.layout.tree().sort(sortByDate).nodeSize([nodeSpace, 0])var nodes = tree.nodes(originalData)var links = tree.links(nodes)var offsetX = -config.centralWidthnodes.forEach(function(d) {d.y = downwardSign * (d.depth * linkLength) + config.centralHeightd.x = d.x - offsetXif (d.name == 'origin') {d.x = config.centralWidthd.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.defaultlet lColor = lineColor.defaultif (d.isActualController) {sColor = strokeColor.isActualControllerlColor = lineColor.isActualController} else if (d.isFHolder) {sColor = strokeColor.isFHolderlColor = lineColor.isFHolder} else {sColor = strokeColor.personlColor = lineColor.person}getRelationLink(d.id, lColor)d3.selectAll('marker#resolved' + d.id).selectAll('path').attr('fill', lColor)let linkif (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.idreturn 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.xd.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 = !isExpandif (d.name == 'origin') {return}if (d.children) {d._children = d.childrend.children = nulld3.select(this).text('+')update(d, originalData, g)} else {if (d._children && d._children.length > 0) {d.children = d._childrend._children = nullif (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.investorListd.children.map(item => {item.amount = Number(item.subConAm).toFixed(2)item.isFHolder = trueitem.ratio = item.subComBl.length > 6 ? calculation.accMul(item.subComBl, 100).toFixed(2) + '%' : calculation.accMul(item.subComBl, 100) + '%'item.name = item.entNameitem.type = item.bz === '企业' ? 2 : 1item.isHoldingCompany = item.isHolding == 1 ? true : falseitem.isFHolder = item.subComBl >= 0.25 && item.type == 1item.direction = directionitem.holderPercent = item.ratio})} else {d.children = res.result.holderListd.children.map(item => {item.amount = Number(item.subConAm).toFixed(2)item.isFHolder = trueitem.ratio = item.subComBl.length > 6 ? calculation.accMul(item.subComBl, 100).toFixed(2) + '%' : calculation.accMul(item.subComBl, 100) + '%'item.name = item.pentNameitem.type = item.bz === '企业' ? 2 : 1item.isHoldingCompany = item.isHolding == 1 ? true : falseitem.isFHolder = item.subComBl >= 0.25 && item.type == 1item.direction = directionitem.holderPercent = item.ratio})}d._children = nullif (d.name == 'origin') {d.children.forEach(expand)}d3.select(this).text('-')update(d, originalData, g)}})}}}}function expand(d) {if (d._children) {d.children = d._childrend.children.forEach(expand)d._children = null}}function collapse(d) {if (d.children && d.children.length != 0) {d._children = d.childrend._children.forEach(collapse)d.children = nullhasChildNodeArr.push(d)}}function redraw() {treeG.attr('transform', 'translate(' + zoom.translate() + ')' + ' scale(' + zoom.scale() + ')')}function disableRightClick() {// stop zoomif (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(...)},downloadImpByChart(chartName) {var _this = thisvar html = document.getElementsByTagName('html')[0] //获取可视区域宽var Bwidth = html.clientWidth + 20 //转换屏幕宽高var Bheight = html.clientHeight + 150var Bmax = Bwidth > Bheight ? Bwidth : Bheightvar Bmin = Bwidth > Bheight ? Bheight : Bwidthvar 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 = 0g.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').innerHTMLvar 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.widthimg.onload = function() {//将canvas的宽高设置为图像的宽高canvas.width = cwidth + 20canvas.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.msFullscreenEnabledif (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 = trueel.msRequestFullscreen()}}},toggleFullScreen(e) {this.isFullscreen = !this.isFullscreenthis.FullScreen(document.getElementById('borrow'))}}
<style>
.borrow {height: 1000px;position: relative;top: -66px;
}
</style>

效果图:

仿天眼查-股权结构图相关推荐

  1. D3 天眼查 股权结构图

    效果大致就是上图 tianyancha上面 该效果叫股权结构  图上信息属于公示信息 不存在泄密 暂时不考虑兼容性和下载  旋转等问题.如有这些问题 可以查看我上一篇股权穿透图 有对应解决方案. 本文 ...

  2. D3 天眼查 股权穿透 股权结构

    效果图如上 大致效果就是仿照天眼查股权穿透图 曲线会出现节点位置不对(曲线的算法是在不会 技术菜解决不了)   最后刀放到产品脖子他同意用折线代替 在下面已经补充 JSON数据  把请求换成请求本地j ...

  3. D3 天眼查 股权穿透 股权结构,默认第一行,异步添加,加减号居中,拖拽,缩放, hover。

    因为公司项目需求,在以下相关博客的的基础上,进行了修改. ​​​​​​D3 天眼查 股权穿透 股权结构 1.鼠标经过路径高亮. 2. 加减号优化,很多文章都是直接text标签渲染 "+&qu ...

  4. 仿企查查、天眼查股权穿透d3

    企业图谱做出来了,接下来仿企查查写个股权穿透的图谱 企查查股权穿透 自己的 首先使用的方法以及生成图的方法 跟企业图谱类似 也是用的d3官方demo给出的生成双向树的方法,不过版本是d3.v3 相比企 ...

  5. d3 企业图谱 仿天眼查 企查查

    最近接到一个需求,终端要加入企业图谱的功能.能无线穿透下去,之前写过一个类似树形图但是节点长度没有自适应(如下图),样式也不够好看,产品提出做一个类似企查查那种的企业图谱,能更直观的展示企业信息,无奈 ...

  6. 前端vue uni-app仿企查查、天眼查关联投资机构 股权结构 树形结构 控股结构

    快速实现vue uni-app前端仿企查查.天眼查关联投资机构 股权结构 树形结构 控股结构, 下载请访问uni-app插件市场:https://ext.dcloud.net.cn/plugin?id ...

  7. 仿企查查、天眼查关系图以及架构图(双向树,集团图谱,组织架构图谱,企业图谱,网络拓扑,人物关系网络)

    前言: 最近公司有一些新需求,要求仿照企查查,爱企查,天眼查等软件的关系图.股权结构图.公司架构图等作出相似的功能一开始考虑使用echarts来实现但是最后做出的效果与他们的效果太不一样也不太理想,偶 ...

  8. “二查”再开打:企查查控诉天眼查窃取数据

    数据智能产业创新服务媒体 --聚焦数智 · 改变商业 近日,企查查官方微博发布<关于天眼查窃取数据的控诉>声明,并表示:"我们谢绝一切偷盗行为!目前我们已将相关数据信息取证,并同 ...

  9. 专业版云南_云南核桃集中上市市民“囤货”忙,天眼查:我国8万余家核桃相关企业,云南省数量最多...

    [猎云网(微信:ilieyun)北京]11月18日报道 据央视财经报道,现在正是云南的鲜核桃上市的季节. 在昆明一农贸市场,记者看到新鲜核桃标价是二十到二十五元钱一公斤.商户们说,今年新鲜核桃刚上市价 ...

最新文章

  1. 智能产品AI服务智商的权重研究|未来研究
  2. PAT 1052. Linked List Sorting
  3. 从前序与中序遍历序列构造二叉树Python解法
  4. ecshop goods.php,重命名ecshop的商品页goods.php为shangpin.php
  5. Web前端—— JQuery迷你版实现以及使用
  6. python如何将数据保存到本地json文件
  7. 修理计算机英语,英语口语对话:修理电脑
  8. Spring Cloud Hystrix——熔断器
  9. 第一台电子计算机于1846年诞生,全国2010年1月高等教育自学考试计算机与网络技术基础试题.doc...
  10. java开发转测试开发经历
  11. Java的发展 Java在不同系统下的开发环境 Java语言特性 Java实现跨平台
  12. cad文字递增快捷键_史上最全CAD快捷键命令大全(图文版、文字版、键盘版)
  13. 塑料壳上下扣合的卡扣设计_卡扣结构设计常识,结构设计中扣合量如何留
  14. 从零开始部署深信服EDR
  15. 直播平台源码搭建教程之Android音视频开发
  16. JAVA编写元音字母(Switch语句)
  17. 地理信息系统-什么是GIS
  18. Python多线程、多进程最全整理
  19. MySQL数据库:SQL语句优化
  20. node.js命令行程序在Windows系统和Linux系统下的部署

热门文章

  1. 【shell脚本】沐风晓月跟你聊聊shell脚本中的while循环
  2. Docker: 企业级镜像仓库Harbor的使用
  3. 据说年薪30万的Android程序员必须知道的帖子
  4. 【前端学习笔记day35】4.5. Photoshop制作雪碧图技巧
  5. 面朝大海,春暖花开--曼陀山庄之段誉[zz]
  6. r语言导出文件为xlxs_R语言学习——R读取txt、csv、xls和xlsx格式文件
  7. 北大青鸟职业技能等级认定第三方评价机构迎来首考
  8. 使用计算机开机按啥建,电脑开机按TAB键有什么作用?
  9. BurpSuite安装(附安装包)
  10. 2021HW | 04/12 第四天总结