Created
October 1, 2019 01:33
-
-
Save ralexrdz/6020cff9b6ac3a5232d0724216ed3c92 to your computer and use it in GitHub Desktop.
This file contains hidden or 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> | |
<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="http://d3js.org/d3.v4.min.js"></script> | |
<script> | |
var pubs = { | |
name: "Tracker Project", | |
children: [{ | |
name: "Bioregions" | |
}, | |
{ | |
name: "Water", | |
children: [ | |
{ | |
name: "Water in agriculture", | |
children: [{ | |
name: "Systems for Watering", | |
children: [{ | |
name: "Drip systems" | |
}, | |
{ | |
name: "Inundation" | |
}, | |
{ | |
name: "Sprinklers" | |
}, | |
{ | |
name: "Gravity" | |
}, | |
{ | |
name: "Test" | |
} | |
] | |
}, | |
{ | |
name: "Microbes" | |
}, | |
{ | |
name: "Drought remediation", | |
children: [{ | |
name: "Reservoirs" | |
}] | |
}, | |
{ | |
name: "Water tables" | |
}, | |
{ | |
name: "Structured water" | |
}, | |
{ | |
name: "Drought" | |
}, | |
{ | |
name: "Transport" | |
}, | |
{ | |
name: "Water harvesting" | |
}, | |
{ | |
name: "Flood" | |
}, | |
{ | |
name: "Toilets" | |
}, | |
{ | |
name: "Hygiene" | |
}, | |
{ | |
name: "Potable" | |
}, | |
{ | |
name: "Cleaning" | |
}, | |
{ | |
name: "Pollution" | |
} | |
] | |
}, | |
{ | |
name: "Seas", | |
children: [{ | |
name: "Nuclear radiation" | |
}, | |
{ | |
name: "Plastic contamination" | |
}, | |
{ | |
name: "Sea life", | |
children: [{ | |
name: "Fishing" | |
}, | |
{ | |
name: "Species dieoff" | |
}, | |
] | |
}, | |
{ | |
name: "Oil contamination" | |
}, | |
{ | |
name: "Acidification" | |
}, | |
{ | |
name: "Glacier melt", | |
children: [{ | |
name: "Methane release" | |
}, | |
{ | |
name: "Rising sea levels" | |
} | |
] | |
} | |
] | |
}, | |
{ | |
name: "Lakes", | |
children: [{ | |
name: "Pollution" | |
}, | |
{ | |
name: "Water levels" | |
}, | |
{ | |
name: "Underwater life" | |
} | |
] | |
}, | |
{ | |
name: "Rivers", | |
children: [{ | |
name: "Dams", | |
children: [{ | |
name: "Ecosystem destruction" | |
}] | |
}, | |
{ | |
name: "Contamination" | |
}, | |
{ | |
name: "Life in river" | |
}, | |
] | |
}, | |
{ | |
name: "Pollution", | |
children: [ | |
{ | |
name: "Untreated sewage" | |
}, | |
{ | |
name: "Fertilizer" | |
}, | |
{ | |
name: "Pesticides" | |
}, | |
{ | |
name: "Animal waste" | |
}, | |
{ | |
name: "Salts from evaporated irrigation water" | |
}, | |
{ | |
name: "Silt from deforestation" | |
}, | |
{ | |
name: "Agricultural runoff" | |
}, | |
{ | |
name: "Industry", | |
children: [{ | |
name: "Toxic chemicals and heavy metals" | |
}, | |
{ | |
name: "Power plant emissions", | |
children: [{ | |
name: "Acid rain" | |
}] | |
} | |
] | |
} | |
] | |
}, | |
{ | |
name: "Water Problems", | |
children: [{ | |
name: "Shortages of water", | |
children: [{ | |
name: "Drought" | |
}] | |
}, | |
{ | |
name: "Shortages of clean water", | |
children: [{ | |
name: "Growing populations " | |
}, | |
{ | |
name: "Expanding agriculture " | |
}, | |
{ | |
name: "Industrialization " | |
}, | |
{ | |
name: "High living standards " | |
} | |
] | |
} | |
] | |
}, | |
{ | |
name: "Wetlands" | |
}, | |
{ | |
name: "Groundwater", | |
children: [{ | |
name: "Megacities" | |
}, | |
{ | |
name: "Agriculture" | |
}, | |
{ | |
name: "Fertilizer runoff" | |
}, | |
{ | |
name: "Pollution", | |
children: [{ | |
name: "Water quality" | |
}, | |
{ | |
name: "Health" | |
} | |
] | |
} | |
] | |
}, | |
{ | |
name: "Water Disputes" | |
}, | |
{ | |
name: "Water Wastes", | |
children: [{ | |
name: "Bad drainage" | |
}, | |
{ | |
name: "Leaking pipes" | |
}, | |
{ | |
name: "Evaporation from reservoirs and canals" | |
}, | |
{ | |
name: "Poor irrigation" | |
}, | |
{ | |
name: "Industrial practices" | |
}, | |
{ | |
name: "Drinking water treatment" | |
} | |
] | |
}, | |
{ | |
name: "Plastic bottles and Distribution" | |
}, | |
{ | |
name: "Water Shortages", | |
children: [ | |
{ | |
name: "Water tables declining" | |
}, | |
{ | |
name: "Drilling" | |
}, | |
{ | |
name: "Well building" | |
}, | |
{ | |
name: "Rich countries", | |
children: [{ | |
name: "Building dams" | |
}, | |
{ | |
name: "Importing food" | |
}, | |
{ | |
name: "Tapping deep water aquifers" | |
}, | |
{ | |
name: "Recycling wastewater" | |
}, | |
{ | |
name: "Desalinated seawater" | |
}, | |
{ | |
name: "Overpopulation" | |
} | |
] | |
} | |
] | |
}, | |
{ | |
name: "Solutions", | |
children: [{ | |
name: "Ultraviolet radiation" | |
}, | |
{ | |
name: "Filtering through cloth" | |
}, | |
{ | |
name: "Reusing and recycling water" | |
} | |
] | |
}, | |
{ | |
name: "Water Conservation", | |
children: [{ | |
name: "Transporting and storing rain water" | |
}, | |
{ | |
name: "Catchments" | |
}, | |
{ | |
name: "Gutters and other channels" | |
}, | |
{ | |
name: "Storage tanks" | |
}, | |
{ | |
name: "Gravity or pump driven delivery system" | |
} | |
] | |
}, | |
{ | |
name: "Water Extracting Methods" | |
} | |
] | |
}, | |
{ | |
name: "Air" | |
}, | |
{ | |
name: "Earth (soil)" | |
}, | |
{ | |
name: "Government Projects" | |
}, | |
{ | |
name: "City Projects" | |
}, | |
{ | |
name: "Food" | |
}, | |
{ | |
name: "Agriculture" | |
}, | |
{ | |
name: "Environmental Technologies" | |
}, | |
{ | |
name: "Construction" | |
}, | |
{ | |
name: "Sustainability Communities" | |
}, | |
{ | |
name: "Transportation" | |
}, | |
{ | |
name: "Energy" | |
}, | |
{ | |
name: "Problem & Solutions" | |
}, | |
{ | |
name: "Indigenous" | |
}, | |
{ | |
name: "Legal" | |
}, | |
{ | |
name: "Waste" | |
}, | |
{ | |
name: "Economy" | |
}, | |
{ | |
name: "Land Use" | |
}, | |
{ | |
name: "Species Dieoff" | |
} | |
] | |
} | |
// Set the dimensions and margins of the diagram | |
var margin = {top: 20, right: 90, bottom: 30, left: 90}, | |
width = 960 - margin.left - margin.right, | |
height = 800 - margin.top - margin.bottom; | |
// append the svg object to the body of the page | |
// appends a 'group' element to 'svg' | |
// moves the 'group' element to the top left margin | |
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 + ")"); | |
var i = 0, | |
duration = 750, | |
root; | |
// declares a tree layout and assigns the size | |
var treemap = d3.tree().size([height, width]); | |
// Assigns parent, children, height, depth | |
root = d3.hierarchy(pubs, function(d) { return d.children; }); | |
root.x0 = height / 2; | |
root.y0 = 0; | |
// Collapse after the second level | |
root.children.forEach(collapse); | |
update(root); | |
// Collapse the node and all it's children | |
function collapse(d) { | |
if(d.children) { | |
d._children = d.children | |
d._children.forEach(collapse) | |
d.children = null | |
} | |
} | |
function update(source) { | |
// Assigns the x and y position for the nodes | |
var treeData = treemap(root); | |
// Compute the new tree layout. | |
var nodes = treeData.descendants(), | |
links = treeData.descendants().slice(1); | |
// Normalize for fixed-depth. | |
nodes.forEach(function(d){ d.y = d.depth * 180}); | |
// ****************** Nodes section *************************** | |
// Update the nodes... | |
var node = svg.selectAll('g.node') | |
.data(nodes, function(d) {return d.id || (d.id = ++i); }); | |
// Enter any new modes at the parent's previous position. | |
var nodeEnter = node.enter().append('g') | |
.attr('class', 'node') | |
.attr("transform", function(d) { | |
return "translate(" + source.y0 + "," + source.x0 + ")"; | |
}) | |
.on('click', click); | |
// Add Circle for the nodes | |
nodeEnter.append('circle') | |
.attr('class', 'node') | |
.attr('r', 1e-6) | |
.style("fill", function(d) { | |
return d._children ? "lightsteelblue" : "#fff"; | |
}); | |
// Add labels for the nodes | |
nodeEnter.append('text') | |
.attr("dy", ".35em") | |
.attr("x", function(d) { | |
return d.children || d._children ? -13 : 13; | |
}) | |
.attr("text-anchor", function(d) { | |
return d.children || d._children ? "end" : "start"; | |
}) | |
.text(function(d) { return d.data.name; }); | |
// UPDATE | |
var nodeUpdate = nodeEnter.merge(node); | |
// Transition to the proper position for the node | |
nodeUpdate.transition() | |
.duration(duration) | |
.attr("transform", function(d) { | |
return "translate(" + d.y + "," + d.x + ")"; | |
}); | |
// Update the node attributes and style | |
nodeUpdate.select('circle.node') | |
.attr('r', 10) | |
.style("fill", function(d) { | |
return d._children ? "lightsteelblue" : "#fff"; | |
}) | |
.attr('cursor', 'pointer'); | |
// Remove any exiting nodes | |
var nodeExit = node.exit().transition() | |
.duration(duration) | |
.attr("transform", function(d) { | |
return "translate(" + source.y + "," + source.x + ")"; | |
}) | |
.remove(); | |
// On exit reduce the node circles size to 0 | |
nodeExit.select('circle') | |
.attr('r', 1e-6); | |
// On exit reduce the opacity of text labels | |
nodeExit.select('text') | |
.style('fill-opacity', 1e-6); | |
// ****************** links section *************************** | |
// Update the links... | |
var link = svg.selectAll('path.link') | |
.data(links, function(d) { return d.id; }); | |
// Enter any new links at the parent's previous position. | |
var linkEnter = link.enter().insert('path', "g") | |
.attr("class", "link") | |
.attr('d', function(d){ | |
var o = {x: source.x0, y: source.y0} | |
return diagonal(o, o) | |
}); | |
// UPDATE | |
var linkUpdate = linkEnter.merge(link); | |
// Transition back to the parent element position | |
linkUpdate.transition() | |
.duration(duration) | |
.attr('d', function(d){ return diagonal(d, d.parent) }); | |
// Remove any exiting links | |
var linkExit = link.exit().transition() | |
.duration(duration) | |
.attr('d', function(d) { | |
var o = {x: source.x, y: source.y} | |
return diagonal(o, o) | |
}) | |
.remove(); | |
// Store the old positions for transition. | |
nodes.forEach(function(d){ | |
d.x0 = d.x; | |
d.y0 = d.y; | |
}); | |
// Creates a curved (diagonal) path from parent to the child nodes | |
function diagonal(s, d) { | |
path = `M ${s.y} ${s.x} | |
C ${(s.y + d.y) / 2} ${s.x}, | |
${(s.y + d.y) / 2} ${d.x}, | |
${d.y} ${d.x}` | |
return path | |
} | |
// 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); | |
} | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment