Skip to content

Instantly share code, notes, and snippets.

@d3noob
Last active February 6, 2022 18:16
Show Gist options
  • Save d3noob/8329404 to your computer and use it in GitHub Desktop.
Save d3noob/8329404 to your computer and use it in GitHub Desktop.
D3.js tree diagram generated from 'flat' data
license: mit

This is a simple d3.js tree diagram that is generated from 'flat' data as used as an example in the book D3 Tips and Tricks.

It is derived from the Mike Bostock Collapsible tree example but it is a VERY cut down version without the ability to update (collapse).

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Collapsible Tree Example</title>
<style>
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 3px;
}
.node text { font: 12px sans-serif; }
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}
</style>
</head>
<body>
<!-- load the d3.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script>
var data = [
{ "name" : "Level 2: A", "parent":"Top Level" },
{ "name" : "Top Level", "parent":"null" },
{ "name" : "Son of A", "parent":"Level 2: A" },
{ "name" : "Daughter of A", "parent":"Level 2: A" },
{ "name" : "Level 2: B", "parent":"Top Level" }
];
// *********** Convert flat data into a nice tree ***************
// create a name: node map
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);
}
});
// ************** Generate the tree diagram *****************
var margin = {top: 20, right: 120, bottom: 20, left: 120},
width = 960 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var i = 0;
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
root = treeData[0];
update(root);
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180; });
// Declare the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
// Enter the nodes.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.y + "," + d.x + ")"; });
nodeEnter.append("circle")
.attr("r", 10)
.style("fill", "#fff");
nodeEnter.append("text")
.attr("x", function(d) {
return d.children || d._children ? -13 : 13; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
return d.children || d._children ? "end" : "start"; })
.text(function(d) { return d.name; })
.style("fill-opacity", 1);
// Declare the links…
var link = svg.selectAll("path.link")
.data(links, function(d) { return d.target.id; });
// Enter the links.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", diagonal);
}
</script>
</body>
</html>
@dominiquenauroy
Copy link

Great script, thanks for sharing.
Do you know if it could be possible that one child may be sharing two parents ?
For instance, in your example, could "Daughter of A" be linked to "Level 2: A" AND to "Level 2: B" ?

Cheers,
Dominique

@vicharerohan07
Copy link

if i have 1 parent in that parent ,2 child is there and in that 2 child's also, i have 3 child's ...how this program will help me and how to do it?

@d3noob
Copy link
Author

d3noob commented Jul 1, 2020

if i have 1 parent in that parent ,2 child is there and in that 2 child's also, i have 3 child's ...how this program will help me and how to do it?

This will definitly help you do that. I reccomend that you use an example from version 5 rather than this version (3). This example (and others) are all part of several free books that you can download which have full insturctions on how the code works.

@vicharerohan07
Copy link

if i have 1 parent in that parent ,2 child is there and in that 2 child's also, i have 3 child's ...how this program will help me and how to do it?

This will definitly help you do that. I reccomend that you use an example from version 5 rather than this version (3). This example (and others) are all part of several free books that you can download which have full insturctions on how the code works.

actually i have a dictionary in that,
var dict = {
"161100": [
"161101",
"161102"
],
"161101": [
"111",
"222",
"333"
],
"161102": [
"444",
"555",
"666"
]

        }

in this dictionary first key is superior parent and it has 2 child's and that 2 child's also have some child's in 2nd and 3rd key value pair so how can i apply for loop so that i can put it in the flat data and use for diagram

@d3noob
Copy link
Author

d3noob commented Jul 2, 2020

actually i have a dictionary in that,
var dict = {
"161100": [
"161101",
"161102"
],
"161101": [
"111",
"222",
"333"
],
"161102": [
"444",
"555",
"666"
]

        }

in this dictionary first key is superior parent and it has 2 child's and that 2 child's also have some child's in 2nd and 3rd key value pair so how can i apply for loop so that i can put it in the flat data and use for diagram

Please read the ebook (its free). There is a chapter on generating a tree diagram from flat data. That will explain the format transition and it will also explain the requirements that you will need for the data. One important part that you might be missing could be the naming convention for the nodes (name and parent). You may need to work that part out yourself. Have a read of the book.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment