
const treeThrough = (data, loadAPiData, setMsg) => {
	var tree = document.getElementById('treeThroughBox');
	var zoom, rootData, rootName, lines, treeG;
	var width = tree.clientWidth;
	var height = (document.documentElement.clientHeight || document.body.clientHeight) - 44;

	var scale = 1;
	var directions = ['upward', 'downward'];
	var treeData = {};
	
	let drawing = function(data) {
		var rootRectWidth = 0; //根节点rect的宽度
		var rootRectHeight = 0; //根节点rect的高度
		var downwardLength = 0, upwardLength = 0;
		var forUpward;
		function zoomed() {
			treeG.attr('transform', 'translate(' + d3V3.event.translate + ')' + ' scale(' + d3V3.event.scale + ')');
		}
		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;
			}
		}
		var treeChart = function() {};
		treeChart.prototype.drawChart = function() {
			var self = this;
			directions.forEach(function(direction) {
				treeData[direction] = rootData[direction];
			});

			rootRectWidth = 284;
			lines = Math.ceil(rootName.length / 20);
			rootRectHeight = lines * 15 + 20;
			//获得upward第一级节点的个数
			upwardLength = rootData.upward.children.length;
			//获得downward第一级节点的个数
			downwardLength = rootData.downward.children.length;
			self.graphTree(self.getTreeConfig());
		};

		treeChart.prototype.getTreeConfig = function() {
			var treeConfig = {
				'margin': {
					'top': 0,
					'right': 0,
					'bottom': 0,
					'left': 0
				}
			}
			treeConfig.chartWidth = width;
			treeConfig.chartHeight = height;
			treeConfig.centralHeight = treeConfig.chartHeight / 2;
			treeConfig.centralWidth = treeConfig.chartWidth / 2;
			treeConfig.linkLength = 140;
			treeConfig.duration = 500; //动画时间
			return treeConfig;
		};

		treeChart.prototype.graphTree = function(config) {
			var self = this;
			var linkLength = config.linkLength;
			var duration = config.duration;
			var id = 0;
			var diagonal = d3V3.svg.diagonal()
				.source(function(d) {
					return {
						"x": d.source.x,
						"y": d.source.name == 'origin' ? (forUpward ? d.source.y - 20 : d.source.y + 20) : (forUpward ? d.source.y -
							60 : d.source.y + 60)
					};
				})
				.target(function(d) {
					return {
						"x": d.target.x,
						"y": d.target.y
					};
				})
				.projection(function(d) {
					return [d.x, d.y];
				});
			zoom = d3V3.behavior.zoom()
				.scaleExtent([0.5, 2])
				.on('zoom', zoomed);
			var svg = d3V3.select('#treeThroughBox')
				.append('svg')
				.attr('width', config.chartWidth)
				.attr('height', config.chartHeight)
				.attr('xmlns', 'http://www.w3.org/2000/svg')
				.call(zoom);
			treeG = svg.append('g')
				.attr('class', 'gbox')
				.attr('transform', 'translate(' + (0) + ',' + (0) + ')');

			//箭头(下半部分)
			var markerDown = svg.append("marker")
				.attr("id", "resolvedDown")
				.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', '#333'); //箭头颜色  
			//箭头(上半部分)
			var markerUp = svg.append("marker")
				.attr("id", "resolvedUp")
				.attr("markerUnits", "strokeWidth") //设置为strokeWidth箭头会随着线的粗细发生变化
				.attr("markerUnits", "userSpaceOnUse")
				.attr("viewBox", "0 -5 10 10") //坐标系的区域
				.attr("refX", 10) //箭头坐标
				.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', '#333'); //箭头颜色  

			// Initialize the tree nodes and update chart.
			function update(source, originalData, g) {
				var direction = originalData['direction'];
				forUpward = direction == 'upward';
				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 = 150;
				var tree = d3V3.layout.tree().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' : '';
					});

				nodeEnter.append("svg:rect")
					.attr("x", function(d) {
						return (d.name == 'origin') ? -(rootRectWidth / 2) : -70;
					})
					.attr("y", function(d) {
						return (d.name == 'origin') ? -(rootRectHeight / 2) : forUpward ? -52 : 12;
					})
					.attr("width", function(d) { // 绘制边框高度
						return (d.name == 'origin') ? rootRectWidth : 140;
					})
					.attr("height", function(d) { // 绘制边框高度
						if (d.name == 'origin') {
							return rootRectHeight;
						} else {
							return 40;
						}
					})
					.attr("rx", 1)  // 绘制边框圆角
					.style("stroke", function(d) { // 绘制边框颜色
						if (d.name == 'origin') {
							return "#80c6f6"
						} else {
							return (d.type == 2) ? "#008ded" : "#ccc";
						}
					})
					.attr("stroke-width", function(d) { // 绘制边框线宽度
						if (d.name == 'origin') {
							return 1
						} else {
							return 0.5
						}
					})
					.style("fill", function(d) {
						return d.type == 2 ? "#f1f9fe" : '#fff'; // 绘制边框内背景色
					});

				nodeEnter.append('circle').attr('r', 1e-6); // 绘制点击的圆圈
				nodeEnter.append("text") // 绘制节点文字
					.attr("class", "linkname")
					.attr("x", function(d) {
						return 0;
					})
					.attr('dy', function(d) {
						if (d.name == 'origin') {
							if (lines == 1) {
								return '.35em'
							} else {
								return (rootRectHeight / 2) - 30;
							}
						} else {
							return forUpward ? '-40' : '24';
						}
					})
					.attr("text-anchor", function(d) {
						return 'middle';
					})
					.attr('fill', '#000')
					.text(function(d) {
						if (d.name == 'origin') {
							return rootName.length > 20 ? rootName.substr(0, 20) : rootName;
						}
						return (d.name.length > 10) ? d.name.substr(0, 10) : d.name;
					})
					.style({
						'fill-opacity': 1e-6,
						'fill': function(d) {
							if (d.name == 'origin') {
								return '#333';
							}
						},
						'font-size': function(d) {
							return (d.name == 'origin') ? 14 : 11;
						},
						'cursor': "pointer"
					});
				nodeEnter.append("text")
					.attr("class", "linkname")
					.attr("x", 0)
					.attr("dy", function(d) {
						if (d.name == 'origin') {
							if (lines == 1) {
								return '.35rem'
							} else {
								return (rootRectHeight / 2) - 12;
							}
						} else {
							return forUpward ? '-29' : '35';
						}
					})
					.attr("text-anchor", function() {
						return 'middle';
					})
					.text(function(d) {
						if (d.name == 'origin') {
							return rootName.substr(20, rootName.length);
						}
						return d.name.substr(10, d.name.length);
					})
					.style({
						'fill': "#00",
						'font-size': function(d) {
							return (d.name == 'origin') ? 14 : 11;
						},
						'cursor': "pointer"
					});
				nodeEnter.append("text")
					.attr("x", 0)
					.attr("dy", function(d) {
						return (d.name == 'origin') ? '.35em' : forUpward ? '-16' : '48';
					})
					.attr("text-anchor", "middle")
					.attr("class", "linkname")
					.style("fill", "#999")
					.style('font-size', 10)
					.text(function(d) {
						var str = (d.name == 'origin') ? '' : d.desc;
						return str;
					});
				nodeEnter.append("text")
					.attr("x", "10")
					.attr("dy", function(d) {
						return (d.name == 'origin') ? '.35em' : forUpward ? '0' : '10';
					})
					.attr("text-anchor", "start")
					.attr("class", "linkname")
					.style("fill", "#1c90ee")
					.style('font-size', 10)
					.text(function(d) {
						return (d.name == 'origin') ? "" : d.sign;
					});

				// Transition nodes to their new position.原有节点更新到新位置
				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.name == 'origin') ? 0 : (d.isSearch == 'N') ? 0 : 6;
					})
					.attr('cy', function(d) {
						return (d.name == 'origin') ? -20 : (forUpward) ? -59 : 59;
					})
					.style('fill', function(d) {
						return d.isSearch == 'Y' ? "#fff" : "";
					})
					.style('stroke', function(d) {
						return d.isSearch == 'Y' ? "#1c90ee" : "";
					})
					.style('fill-opacity', function(d) {
						if (d.children) {
							return 0.35;
						}
					});
				//代表是否展开的+-号
				nodeEnter.append("svg:text")
					.attr("class", "isExpand")
					.attr("x", "0")
					.attr("dy", function(d) {
						return forUpward ? -56 : 62;
					})
					.attr("text-anchor", "middle")
					.style("fill", "#1c90ee")
					.text(function(d) {
						if (d.name == 'origin') {
							return '';
						}
						return d.isSearch == 'Y' ? "+" : "";
					})
					.style("font-size", function(d) {
						return '12px'
					})
					.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 '#333'
					})
					.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) {
						return forUpward ? "url(#resolvedUp)" : "url(#resolvedDown)";
					}) //根据箭头标记的id号标记箭头;
					.attr("id", function(d, i) {
						return "mypath" + i;
					})
				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 click(d) {
					var direction = originalData['direction'];
					forUpward = direction == 'upward';
					isExpand = !isExpand;
					if (d.name == 'origin') {
						return;
					}
					if (d.children) {
						d._children = d.children;
						d.children = null;
						d3V3.select(this).text('+').style({
							'font-size': '12px'
						})
						update(d, originalData, g);
					} else {
						d.children = d._children;
						d._children = null;
						let param = {
							key: d.name,
							formatFlag: 2
						}
						loadAPiData(param.key, ({code, data}) => {
							if (code == 200) {
								if (forUpward == true) {
									d.children = data.upward.children || [];
								} else if (forUpward == false) {
									d.children = data.downward.children || [];
								}
								if (d.name == 'origin') {
									d.children.forEach(expand);
								}
								d3V3.select(this).text('-').style({
									'font-size': '12px'
								})
								update(d, originalData, g);
							} else {
								setMsg('无可穿透数据');
							}
						})
					}
				}
			}
            
			function initChart() {
				for (var d in directions) {
					var direction = directions[d];
					var data = treeData[direction];
					data.x0 = config.centralWidth;
					data.y0 = config.centralHeight;
					data.children.forEach(collapse);
					update(data, data, treeG);
				}
			}
			initChart();

			//放大
			d3V3.select("#big").on('click', () => {
				if (scale < 4) {
					scale += 0.2;
				}
				zoom.scale(scale);
				treeG.transition()
					.duration(500)
					.attr("transform", "translate(" + zoom.translate() + ")scale(" + scale + ")");
			})
			// 缩小
			d3V3.select("#small").on('click', () => {
				if (scale > 0.2) {
					scale -= 0.2;
				}
				zoom.scale(scale);
				treeG.transition()
					.duration(500)
					.attr("transform", "translate(" + zoom.translate() + ")scale(" + scale + ")");
			})
		};
		var d3GenerationChart = new treeChart(d3V3);
		d3GenerationChart.drawChart();
	};
	let getData = function(data) {
		data.downward.direction = 'downward';
		data.downward.name = 'origin';
		data.upward.direction = 'upward';
		data.upward.name = 'origin';
		rootData = data;
		rootName = rootData.rootName;
		drawing();
	};
	jQuery(document).ready(function() {
		var child = document.getElementById("treeThroughBox");
		child.innerHTML = '';
		getData(data);
	});
}