Skip to content

Commit 4343e56

Browse files
author
Iain Collins
committed
Initial commit
1 parent 98056e7 commit 4343e56

File tree

5 files changed

+201
-1
lines changed

5 files changed

+201
-1
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
# d3-tree
1+
# d3-tree
2+
3+
Based on https://bl.ocks.org/d3noob/8375092

data.json

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "Top Level",
3+
"parent": "null",
4+
"children": [
5+
{
6+
"name": "Level 2: A",
7+
"parent": "Top Level",
8+
"children": [
9+
{
10+
"name": "Son of A",
11+
"parent": "Level 2: A"
12+
},
13+
{
14+
"name": "Daughter of A",
15+
"parent": "Level 2: A"
16+
}
17+
]
18+
},
19+
{
20+
"name": "Level 2: B",
21+
"parent": "Top Level"
22+
}
23+
]
24+
}

index.html

+171
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Tree Example</title>
6+
<style>
7+
.node {
8+
cursor: pointer;
9+
}
10+
11+
.node circle {
12+
fill: #fff;
13+
stroke: steelblue;
14+
stroke-width: 3px;
15+
}
16+
17+
.node text {
18+
font: 12px sans-serif;
19+
}
20+
21+
.link {
22+
fill: none;
23+
stroke: #ccc;
24+
stroke-width: 2px;
25+
}
26+
</style>
27+
</head>
28+
<body>
29+
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
30+
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
31+
<script>
32+
// Adapted from https://bl.ocks.org/d3noob/8375092
33+
var margin = {top: 20, right: 120, bottom: 20, left: 120},
34+
width = 960 - margin.right - margin.left,
35+
height = 500 - margin.top - margin.bottom;
36+
37+
var i = 0,
38+
duration = 750,
39+
root,
40+
tree,
41+
svg,
42+
diagonal,
43+
treeData;
44+
45+
fetch(window.location.protocol + '/data.json')
46+
.then(response => response.json())
47+
.then(json => draw(json) );
48+
49+
function draw(json) {
50+
treeData = [json]; // Needs to be in an array
51+
52+
tree = d3.layout.tree().size([height, width]);
53+
54+
diagonal = d3.svg.diagonal().projection(function(d) { return [d.y, d.x]; });
55+
56+
svg = d3.select("body").append("svg")
57+
.attr("width", width + margin.right + margin.left)
58+
.attr("height", height + margin.top + margin.bottom)
59+
.append("g")
60+
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
61+
62+
root = treeData[0];
63+
root.x0 = height / 2;
64+
root.y0 = 0;
65+
66+
update(root);
67+
68+
d3.select(self.frameElement).style("height", "500px");
69+
}
70+
71+
function update(source) {
72+
73+
// Compute the new tree layout.
74+
var nodes = tree.nodes(root).reverse(),
75+
links = tree.links(nodes);
76+
77+
// Normalize for fixed-depth.
78+
nodes.forEach(function(d) { d.y = d.depth * 180; });
79+
80+
// Update the nodes…
81+
var node = svg.selectAll("g.node")
82+
.data(nodes, function(d) { return d.id || (d.id = ++i); });
83+
84+
// Enter any new nodes at the parent's previous position.
85+
var nodeEnter = node.enter().append("g")
86+
.attr("class", "node")
87+
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
88+
.on("click", click);
89+
90+
nodeEnter.append("circle")
91+
.attr("r", 1e-6)
92+
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
93+
94+
nodeEnter.append("text")
95+
.attr("x", function(d) { return d.children || d._children ? -13 : 13; })
96+
.attr("dy", ".35em")
97+
.attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
98+
.text(function(d) { return d.name; })
99+
.style("fill-opacity", 1e-6);
100+
101+
// Transition nodes to their new position.
102+
var nodeUpdate = node.transition()
103+
.duration(duration)
104+
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
105+
106+
nodeUpdate.select("circle")
107+
.attr("r", 10)
108+
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
109+
110+
nodeUpdate.select("text")
111+
.style("fill-opacity", 1);
112+
113+
// Transition exiting nodes to the parent's new position.
114+
var nodeExit = node.exit().transition()
115+
.duration(duration)
116+
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
117+
.remove();
118+
119+
nodeExit.select("circle")
120+
.attr("r", 1e-6);
121+
122+
nodeExit.select("text")
123+
.style("fill-opacity", 1e-6);
124+
125+
// Update the links…
126+
var link = svg.selectAll("path.link")
127+
.data(links, function(d) { return d.target.id; });
128+
129+
// Enter any new links at the parent's previous position.
130+
link.enter().insert("path", "g")
131+
.attr("class", "link")
132+
.attr("d", function(d) {
133+
var o = {x: source.x0, y: source.y0};
134+
return diagonal({source: o, target: o});
135+
});
136+
137+
// Transition links to their new position.
138+
link.transition()
139+
.duration(duration)
140+
.attr("d", diagonal);
141+
142+
// Transition exiting nodes to the parent's new position.
143+
link.exit().transition()
144+
.duration(duration)
145+
.attr("d", function(d) {
146+
var o = {x: source.x, y: source.y};
147+
return diagonal({source: o, target: o});
148+
})
149+
.remove();
150+
151+
// Stash the old positions for transition.
152+
nodes.forEach(function(d) {
153+
d.x0 = d.x;
154+
d.y0 = d.y;
155+
});
156+
}
157+
158+
// Toggle children on click.
159+
function click(d) {
160+
if (d.children) {
161+
d._children = d.children;
162+
d.children = null;
163+
} else {
164+
d.children = d._children;
165+
d._children = null;
166+
}
167+
update(d);
168+
}
169+
</script>
170+
</body>
171+
</html>

now.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "d3-tree"
3+
}

stylesheet.css

Whitespace-only changes.

0 commit comments

Comments
 (0)