Example of using custom binary tree layout.
Last active
August 17, 2018 10:12
-
-
Save higuoxing/65368acc4fb9750710c2497269503fff to your computer and use it in GitHub Desktop.
Expanding Binary Tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: gpl-3.0 | |
height: 500 | |
scrolling: no | |
border: yes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
/* set the CSS */ | |
.link { | |
fill: none; | |
stroke: #330; | |
stroke-width: 2px; | |
} | |
</style> | |
<body> | |
<!-- load the d3.js library --> | |
<script src="//d3js.org/d3.v4.min.js"></script> | |
<script> | |
var data = [ | |
{ "parent": "", "name": "-1" }, | |
{ "parent": "-1", "name": "0" }, | |
{ "parent": "0", "name": "1" }, | |
{ "parent": "0", "name": "2" }, | |
{ "parent": "1", "name": "3" }, | |
{ "parent": "1", "name": "4" }, | |
{ "parent": "2", "name": "5" }, | |
{ "parent": "2", "name": "6" }, | |
{ "parent": "3", "name": "7" }, | |
{ "parent": "3", "name": "8" }, | |
{ "parent": "4", "name": "9" }, | |
{ "parent": "4", "name": "10" }, | |
{ "parent": "5", "name": "11" }, | |
{ "parent": "5", "name": "12" }, | |
{ "parent": "6", "name": "13" }, | |
{ "parent": "6", "name": "14" }, | |
{ "parent": "7", "name": "15" }, | |
{ "parent": "7", "name": "16" }, | |
{ "parent": "8", "name": "17" }, | |
{ "parent": "8", "name": "18" }, | |
{ "parent": "9", "name": "19" }, | |
{ "parent": "9", "name": "20" }, | |
{ "parent": "10", "name": "21" }, | |
{ "parent": "10", "name": "22" }, | |
{ "parent": "11", "name": "23" }, | |
{ "parent": "11", "name": "24" }, | |
{ "parent": "12", "name": "25" }, | |
{ "parent": "12", "name": "26" }, | |
{ "parent": "13", "name": "27" }, | |
{ "parent": "13", "name": "28" }, | |
{ "parent": "14", "name": "29" }, | |
{ "parent": "14", "name": "30" }, | |
{ "parent": "15", "name": "31" }, | |
{ "parent": "15", "name": "32" }, | |
{ "parent": "16", "name": "33" }, | |
{ "parent": "16", "name": "34" }, | |
{ "parent": "17", "name": "35" }, | |
{ "parent": "17", "name": "36" }, | |
{ "parent": "18", "name": "37" }, | |
{ "parent": "18", "name": "38" }, | |
{ "parent": "19", "name": "39" }, | |
{ "parent": "19", "name": "40" }, | |
{ "parent": "20", "name": "41" }, | |
{ "parent": "20", "name": "42" }, | |
{ "parent": "21", "name": "43" }, | |
{ "parent": "21", "name": "44" }, | |
{ "parent": "22", "name": "45" }, | |
{ "parent": "22", "name": "46" }, | |
{ "parent": "23", "name": "47" }, | |
{ "parent": "23", "name": "48" }, | |
{ "parent": "24", "name": "49" }, | |
{ "parent": "24", "name": "50" }, | |
{ "parent": "25", "name": "51" }, | |
{ "parent": "25", "name": "52" }, | |
{ "parent": "26", "name": "53" }, | |
{ "parent": "26", "name": "54" }, | |
{ "parent": "27", "name": "55" }, | |
{ "parent": "27", "name": "56" }, | |
{ "parent": "28", "name": "57" }, | |
{ "parent": "28", "name": "58" }, | |
{ "parent": "29", "name": "59" }, | |
{ "parent": "29", "name": "60" }, | |
{ "parent": "30", "name": "61" }, | |
{ "parent": "30", "name": "62" }, | |
{ "parent": "31", "name": "63" }, | |
{ "parent": "31", "name": "64" }, | |
{ "parent": "32", "name": "65" }, | |
{ "parent": "32", "name": "66" }, | |
{ "parent": "33", "name": "67" }, | |
{ "parent": "33", "name": "68" }, | |
{ "parent": "34", "name": "69" }, | |
{ "parent": "34", "name": "70" }, | |
{ "parent": "35", "name": "71" }, | |
{ "parent": "35", "name": "72" }, | |
{ "parent": "36", "name": "73" }, | |
{ "parent": "36", "name": "74" }, | |
{ "parent": "37", "name": "75" }, | |
{ "parent": "37", "name": "76" }, | |
{ "parent": "38", "name": "77" }, | |
{ "parent": "38", "name": "78" }, | |
{ "parent": "39", "name": "79" }, | |
{ "parent": "39", "name": "80" }, | |
{ "parent": "40", "name": "81" }, | |
{ "parent": "40", "name": "82" }, | |
{ "parent": "41", "name": "83" }, | |
{ "parent": "41", "name": "84" }, | |
{ "parent": "42", "name": "85" }, | |
{ "parent": "42", "name": "86" }, | |
{ "parent": "43", "name": "87" }, | |
{ "parent": "43", "name": "88" }, | |
{ "parent": "44", "name": "89" }, | |
{ "parent": "44", "name": "90" }, | |
{ "parent": "45", "name": "91" }, | |
{ "parent": "45", "name": "92" }, | |
{ "parent": "46", "name": "93" }, | |
{ "parent": "46", "name": "94" }, | |
{ "parent": "47", "name": "95" }, | |
{ "parent": "47", "name": "96" }, | |
{ "parent": "48", "name": "97" }, | |
{ "parent": "48", "name": "98" }, | |
{ "parent": "49", "name": "99" }, | |
{ "parent": "49", "name": "100" }, | |
{ "parent": "50", "name": "101" }, | |
{ "parent": "50", "name": "102" }, | |
{ "parent": "51", "name": "103" }, | |
{ "parent": "51", "name": "104" }, | |
{ "parent": "52", "name": "105" }, | |
{ "parent": "52", "name": "106" }, | |
{ "parent": "53", "name": "107" }, | |
{ "parent": "53", "name": "108" }, | |
{ "parent": "54", "name": "109" }, | |
{ "parent": "54", "name": "110" }, | |
{ "parent": "55", "name": "111" }, | |
{ "parent": "55", "name": "112" }, | |
{ "parent": "56", "name": "113" }, | |
{ "parent": "56", "name": "114" }, | |
{ "parent": "57", "name": "115" }, | |
{ "parent": "57", "name": "116" }, | |
{ "parent": "58", "name": "117" }, | |
{ "parent": "58", "name": "118" }, | |
{ "parent": "59", "name": "119" }, | |
{ "parent": "59", "name": "120" }, | |
{ "parent": "60", "name": "121" }, | |
{ "parent": "60", "name": "122" }, | |
{ "parent": "61", "name": "123" }, | |
{ "parent": "61", "name": "124" }, | |
{ "parent": "62", "name": "125" }, | |
{ "parent": "62", "name": "126" }, | |
{ "parent": "63", "name": "127" }, | |
{ "parent": "63", "name": "128" }, | |
{ "parent": "64", "name": "129" }, | |
{ "parent": "64", "name": "130" }, | |
{ "parent": "65", "name": "131" }, | |
{ "parent": "65", "name": "132" }, | |
{ "parent": "66", "name": "133" }, | |
{ "parent": "66", "name": "134" }, | |
{ "parent": "67", "name": "135" }, | |
{ "parent": "67", "name": "136" }, | |
{ "parent": "68", "name": "137" }, | |
{ "parent": "68", "name": "138" }, | |
{ "parent": "69", "name": "139" }, | |
{ "parent": "69", "name": "140" }, | |
{ "parent": "70", "name": "141" }, | |
{ "parent": "70", "name": "142" }, | |
{ "parent": "71", "name": "143" }, | |
{ "parent": "71", "name": "144" }, | |
{ "parent": "72", "name": "145" }, | |
{ "parent": "72", "name": "146" }, | |
{ "parent": "73", "name": "147" }, | |
{ "parent": "73", "name": "148" }, | |
{ "parent": "74", "name": "149" }, | |
{ "parent": "74", "name": "150" }, | |
{ "parent": "75", "name": "151" }, | |
{ "parent": "75", "name": "152" }, | |
{ "parent": "76", "name": "153" }, | |
{ "parent": "76", "name": "154" }, | |
{ "parent": "77", "name": "155" }, | |
{ "parent": "77", "name": "156" }, | |
{ "parent": "78", "name": "157" }, | |
{ "parent": "78", "name": "158" }, | |
{ "parent": "79", "name": "159" }, | |
{ "parent": "79", "name": "160" }, | |
{ "parent": "80", "name": "161" }, | |
{ "parent": "80", "name": "162" }, | |
{ "parent": "81", "name": "163" }, | |
{ "parent": "81", "name": "164" }, | |
{ "parent": "82", "name": "165" }, | |
{ "parent": "82", "name": "166" }, | |
{ "parent": "83", "name": "167" }, | |
{ "parent": "83", "name": "168" }, | |
{ "parent": "84", "name": "169" }, | |
{ "parent": "84", "name": "170" }, | |
{ "parent": "85", "name": "171" }, | |
{ "parent": "85", "name": "172" }, | |
{ "parent": "86", "name": "173" }, | |
{ "parent": "86", "name": "174" }, | |
{ "parent": "87", "name": "175" }, | |
{ "parent": "87", "name": "176" }, | |
{ "parent": "88", "name": "177" }, | |
{ "parent": "88", "name": "178" }, | |
{ "parent": "89", "name": "179" }, | |
{ "parent": "89", "name": "180" }, | |
{ "parent": "90", "name": "181" }, | |
{ "parent": "90", "name": "182" }, | |
{ "parent": "91", "name": "183" }, | |
{ "parent": "91", "name": "184" }, | |
{ "parent": "92", "name": "185" }, | |
{ "parent": "92", "name": "186" }, | |
{ "parent": "93", "name": "187" }, | |
{ "parent": "93", "name": "188" }, | |
{ "parent": "94", "name": "189" }, | |
{ "parent": "94", "name": "190" }, | |
{ "parent": "95", "name": "191" }, | |
{ "parent": "95", "name": "192" }, | |
{ "parent": "96", "name": "193" }, | |
{ "parent": "96", "name": "194" }, | |
{ "parent": "97", "name": "195" }, | |
{ "parent": "97", "name": "196" }, | |
{ "parent": "98", "name": "197" }, | |
{ "parent": "98", "name": "198" }, | |
{ "parent": "99", "name": "199" }, | |
{ "parent": "99", "name": "200" }, | |
{ "parent": "100", "name": "201" }, | |
{ "parent": "100", "name": "202" }, | |
{ "parent": "101", "name": "203" }, | |
{ "parent": "101", "name": "204" }, | |
{ "parent": "102", "name": "205" }, | |
{ "parent": "102", "name": "206" }, | |
{ "parent": "103", "name": "207" }, | |
{ "parent": "103", "name": "208" }, | |
{ "parent": "104", "name": "209" }, | |
{ "parent": "104", "name": "210" }, | |
{ "parent": "105", "name": "211" }, | |
{ "parent": "105", "name": "212" }, | |
{ "parent": "106", "name": "213" }, | |
{ "parent": "106", "name": "214" }, | |
{ "parent": "107", "name": "215" }, | |
{ "parent": "107", "name": "216" }, | |
{ "parent": "108", "name": "217" }, | |
{ "parent": "108", "name": "218" }, | |
{ "parent": "109", "name": "219" }, | |
{ "parent": "109", "name": "220" }, | |
{ "parent": "110", "name": "221" }, | |
{ "parent": "110", "name": "222" }, | |
{ "parent": "111", "name": "223" }, | |
{ "parent": "111", "name": "224" }, | |
{ "parent": "112", "name": "225" }, | |
{ "parent": "112", "name": "226" }, | |
{ "parent": "113", "name": "227" }, | |
{ "parent": "113", "name": "228" }, | |
{ "parent": "114", "name": "229" }, | |
{ "parent": "114", "name": "230" }, | |
{ "parent": "115", "name": "231" }, | |
{ "parent": "115", "name": "232" }, | |
{ "parent": "116", "name": "233" }, | |
{ "parent": "116", "name": "234" }, | |
{ "parent": "117", "name": "235" }, | |
{ "parent": "117", "name": "236" }, | |
{ "parent": "118", "name": "237" }, | |
{ "parent": "118", "name": "238" }, | |
{ "parent": "119", "name": "239" }, | |
{ "parent": "119", "name": "240" }, | |
{ "parent": "120", "name": "241" }, | |
{ "parent": "120", "name": "242" }, | |
{ "parent": "121", "name": "243" }, | |
{ "parent": "121", "name": "244" }, | |
{ "parent": "122", "name": "245" }, | |
{ "parent": "122", "name": "246" }, | |
{ "parent": "123", "name": "247" }, | |
{ "parent": "123", "name": "248" }, | |
{ "parent": "124", "name": "249" }, | |
{ "parent": "124", "name": "250" }, | |
{ "parent": "125", "name": "251" }, | |
{ "parent": "125", "name": "252" }, | |
{ "parent": "126", "name": "253" }, | |
{ "parent": "126", "name": "254" }, | |
] | |
// set the dimensions and margins of the diagram | |
var margin = { top: 40, right: 90, bottom: 50, left: 90 }, | |
width = 500 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
// declares a tree layout and assigns the size | |
var tree = d3.tree() | |
.size([width, height]); | |
// assigns the data to a hierarchy using parent-child relationships | |
var dataMap = data.reduce(function (map, node) { | |
map[node.name] = node; | |
return map; | |
}, { }); | |
// create the tree array | |
var treeData = [ ]; | |
data.forEach(function (node) { | |
// add to parent | |
var parent = dataMap[node.parent]; | |
if (parent) { | |
// create child array if it doesn't exist | |
(parent.children || (parent.children = [ ])) | |
// add node to child array | |
.push(node); | |
} else { | |
// parent is null or missing | |
treeData.push(node); | |
} | |
}); | |
function compute_structure(v) { | |
if (!v.children) return; | |
if (v.children.length == 2) { | |
v.children.forEach(c => { | |
var child_id = parseInt(c.data.name) % 2; | |
c.angle = (child_id) ? v.angle + v.delta_angle: v.angle - v.delta_angle; | |
c.delta_angle = v.delta_angle; | |
c.path_len = v.path_len * 0.65; | |
c.x = v.x + v.path_len * Math.sin(c.angle); | |
c.y = v.y + v.path_len * Math.cos(c.angle); | |
}); | |
} else { | |
v.children[0].angle = 0; | |
v.children[0].delta_angle = v.delta_angle; | |
v.children[0].path_len = v.path_len; | |
v.children[0].x = v.x; | |
v.children[0].y = v.y + v.path_len + 20; | |
} | |
} | |
function expanding_tree_hierarchy(root, position) { | |
root.x = position.x; | |
root.y = position.y; | |
root.delta_angle = position.delta_angle; | |
root.angle = 0.0; | |
root.path_len = position.path_len; | |
root.eachBefore(compute_structure); | |
return root; | |
} | |
var interval = 200; | |
var init_data = d3.hierarchy(treeData[0]); | |
function draw(angle, delta_angle) { | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom), | |
g = svg.append("g") | |
.attr("transform", | |
"translate(" + margin.left + "," + margin.top + ")"); | |
nodes = expanding_tree_hierarchy(init_data, { | |
x: 150.0, | |
y: 50.0, | |
angle: angle, | |
delta_angle: delta_angle, | |
path_len: 75 | |
}); | |
// maps the node data to the tree layout | |
// nodes = tree(nodes); | |
// console.log(nodes); | |
// | |
// append the svg obgect to the body of the page | |
// appends a 'group' element to 'svg' | |
// moves the 'group' element to the top left margin | |
// adds the links between the nodes | |
var link = g.selectAll(".link") | |
.data(nodes.descendants().slice(1)) | |
.enter().append("path") | |
.attr("class", "link") | |
.attr("d", function (d) { | |
return "M" + d.x + "," + (height - d.y) | |
+ "L" + d.parent.x + "," + (height - d.parent.y); | |
}) | |
.attr("stroke-width", 1.5) | |
.attr("stroke", "url(#linear-gradient)") | |
.attr("fill", "#cc"); | |
} | |
var theta = 0.0; | |
setInterval(function () { | |
theta += 0.1; | |
d3.select("svg").remove(); | |
draw(theta, theta); | |
}, 200); | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment