D3 天眼查 股权结构图

效果大致就是上图 tianyancha上面 该效果叫股权结构  图上信息属于公示信息 不存在泄密

暂时不考虑兼容性和下载  旋转等问题。如有这些问题 可以查看我上一篇股权穿透图 有对应解决方案。

本文直接贴简版代码 不做注释 有问题再加我qq2557551314

d3 用的是v4版本

css

body{ 
	font-family:sans-serif;
	width: 100%;
	height: 100%;
	overflow: hidden;
	margin:0;
	padding: 0;
}

.link {
  fill: none;
  stroke: #666;
  stroke-width: 0.5px;
}

js

<script>
	var i = 0,
	duration = 400,
	root;
	var margin = {top: 30, right: 20, bottom: 30, left: 20},
	    width = document.body.clientWidth,
        height = document.body.clientHeight;
		barHeight = 50,
		barSpace = 10,
		barWidth = (width - margin.left - margin.right);

	var diagonal = d3.linkHorizontal()
		.x(function(d) { return d.y; })
		.y(function(d) { return d.x; });
		var scale=0.6;
	var svg = d3.select("body").append("svg")
		//.attr("width", width) // + margin.left + margin.right)
		.attr("class", 'svg')
		.attr('width', width)
		.attr('height', height)
		.on("dblclick.zoom", null)

	var container = svg.append('g')
		.attr("transform", "translate(" + margin.left + "," + margin.top + ")scale(0.8)")
		.attr('class', 'container');

	function zoomFn() {
		const transform = d3.event.transform
		container.attr('transform', "translate(" + (transform.x + margin.left) + "," + (transform.y + margin.top) + ")scale(" + (transform.k) * 0.8 + ")");
	}
	svg.call(d3.zoom()
		.scaleExtent([1 / 2, 4])
		.on("zoom", zoomFn))


	d3.json("flare.json", function(error, flare) {
	  if (error) throw error;
	  root = d3.hierarchy(flare);
	  root.x0 = 0;
	  root.y0 = 0;
	  update(root);
	});

	function update(source) {
		//Compute the flattened node list.
		var nodes = root.descendants();
		var height = Math.max(1000, nodes.length * barHeight + margin.top + margin.bottom);

		d3.select("svg").transition()
			.duration(duration)
			.attr("height", height);

		d3.select(self.frameElement).transition()
			.duration(duration)
			.style("height", height + "px");

		//Compute the "layout". TODO https://github.com/d3/d3-hierarchy/issues/67
		var index = -1,
			count = 0;
		root.eachBefore(function(n) {
			count+=barSpace;
			n.style = "node_" + n.depth;
			n.x = ++index * barHeight + count;
			n.y = n.depth * 20;
		});

		// Update the nodes…
		var node = container.selectAll(".node")
			.data(nodes, function(d) { return d.id || (d.id = ++i); });

		var nodeEnter = node.enter().append("g")
			.attr("class", function(d){ return "node node_" + d.depth +" "+  getClass(d); })
			.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
			.style("opacity", 0);

		//Enter any new nodes at the parent's previous position.
		nodeEnter.append("rect")
			.attr("y", -barHeight / 2)
			.attr("height", barHeight)
			.attr("width", barWidth)
			.style('stroke',"#333")
			.style('fill', "#fff")
			.style('stroke-width',"0.5px")
			

		nodeEnter.append("rect")
			.attr("y", -barHeight / 2)
			.attr("height", barHeight)
			.attr("width", 3)
			.style('fill', "red")

		nodeEnter.append("text")
			.attr("dy", -3.5)
			.attr("dx", 40)
			.style("font-size", "14px")
			.text(function(d) {
				if(d.data.name.length>9){
					return	d.data.name.substring(0, 10) + '...'; 
				} 
				return d.data.name; 
			});

		nodeEnter.append("text")
			.attr("dy", 15.5)
			.attr("dx", 40)
			.style("font-size", "14px")
			.text(function(d) {
				if(!d.data.tap){
					return ('持股' + '(' + d.data.shareNumProportion + ')')
				} 
			});
		nodeEnter.append("text")
			.attr("dy", 5.5)
			.attr("dx",220 )
			.style("font-size", "14px")
			.style('fill', "#359FFB")
			.text(function(d) {
				if(!d.data.tap){
					return "企业信息"
				}
				
			});
		var circle = nodeEnter.append("g")
            .attr("class", "circle")
			.on("click", click);
			
		circle.append("circle")
            .style('fill', "#fff")
            .style("stroke","#D9D8D8")
            .style('stroke-width', 1)
            .attr("r", function (d) {
				if (d.children) {
					return 8.5;
				} else if (d._children) {
					return 8.5;
				} else {
					return;
				}
                
            })

            // .style('stroke-opacity', 1)
            .attr("transform", function (d) {
                return "translate(20,0)"; 
			})
		
        // circle.append("text")
        //     .attr("class", "sign")
        //     .attr("cx", "20px")
        //     .attr("cy", ".1.8em")
        //     .style('font-size', 18)
        //     .style('fill', function (d) {
        //         return "#D9D8D8 ";
        //     })

        //     .attr('text-anchor', 'middle')
        //     .attr('dy', '.28em')
        //     .text(function (d) {
		// 		if (d.children) {
		// 			return '-';
		// 		} else if (d._children) {
		// 			return '+';
		// 		} else {
		// 			return '';
		// 		}
        //     })
        //     .attr("transform", function (d) {
        //         return "translate(20,0)"; 
        //     })
		circle.append("text")
		    .attr("dy", 4.5)
			.attr("cx", "20px")
			.attr("cy", "30px")
			.attr("font-family","FontAwesome")
			.attr('text-anchor', 'middle')
			.attr("class", "fa")
			.style('fill', function (d) {
                return "#D9D8D8 ";
            })
			.attr("transform", function (d) {
				return "translate(20,0)"; 
            })
			.text(function(d) {
				if (d.children) {
					return '-';
				} else if (d._children) {
					return '+';
				} else {
					return '';
				}
			})
		node.select('.fa')
		.text(function (d) {
			if (d.children) {
				return '-';
			} else if (d._children) {
				return '+';
			} else {
				return '';
			}
		})

		

		//Transition nodes to their new position.
		nodeEnter.transition()
			.duration(duration)
			.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
			.style("opacity", 1);

		node.transition()
			.duration(duration)
			.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
			.style("opacity", 1)
			.select("rect")
			.style("stroke","#666")
			.style("fill", color);

		// Transition exiting nodes to the parent's new position.
		node.exit().transition()
			.duration(duration)
			.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
			.style("opacity", 0)
			.remove();

		//Update the links…
		var link = container.selectAll(".link")
			.data(root.links(), function(d) { return d.target.id; });

		//Enter any new links at the parent's previous position.
		link.enter().insert("path", "g")
			.attr("class", function(d){ 
				return "link link_" + d.target.depth +" "+ getClass(d.target); 
			})
			.attr("d", function(d) {
				var o = {x: source.x0, y: source.y0};
				return elbow({source: o, target: o});
			})
			.transition()
			.duration(duration)
			.attr("d", elbow);

		//Transition links to their new position.
		link.transition()
		.duration(duration)
		.attr("d", elbow);

		//Transition exiting nodes to the parent's new position.
		link.exit().transition()
			.duration(duration)
			.attr("d", function(d) {
				var o = {x: source.x, y: source.y};
				return elbow({source: o, target: o});
			})
			.remove();

		//Stash the old positions for transition.
		root.each(function(d) {
			d.x0 = d.x;
			d.y0 = d.y;
		});

	}

	/*Toggle children on click.
	function click(d) {
		if (d.children) {
			d._children = d.children;
			d.children = null;
		} else {
			d.children = d._children;
			d._children = null;
		}
		update(d);
	}*/

	// Toggle children on click.
	var lastClickD = null;
	function click(d) {
	  if (d.children) {
		d._children = d.children;
		d.children = null;
	  } else {
		d.children = d._children;
		d._children = null;
	  }
	  if (lastClickD){
		lastClickD._isSelected = false;
	  }
	  d._isSelected = true;
	  lastClickD = d;
	  update(d);
	}
	
	function getClass(d){
		if(d.data.class)
		{
			return d.data.class
		}else{
			return "";
		}
	}
	function elbow(d) {
		return "M" + d.source.y + "," + d.source.x
		+ "H" + (d.source.y + (d.target.y-d.source.y)/2)
		+ "V" + d.target.x 
		+ "H" + d.target.y;
	}
	function color(d) {
		if (d._isSelected) return '#fff';
		return d._children ? "#fff" : d.children ? "#fff" : "#fff";
	}


</script>

json

{
  "name": "马云",
  "tap":"节点",
  "children": [
    {
      "name": "中国平安人寿保险股份有限公司-自有资金",
      "shareNumProportion": "2.27%",
      "children": [
        {
          "name": "中国证券金融股份有限公司",
          "shareNumProportion": "2.27%",
          "children": [
            {
              "name": "中国证券金融股份有限公司",
              "shareNumProportion": "2.27%"
            }
          ]
        },
        {
          "name": "中央汇金资产管理有限责任公司",
          "shareNumProportion": "2.27%"
        }
      ]
    }
  ]
}

有些的不好的地方 或者有大神做过相应优化的 欢迎指点。

转载的话请附带链接

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值