D3 Network of the Soccer Confederations of the Americas
{ | |
"name": "Soccer Confederations of the Americas", | |
"children": [ | |
{ | |
"name": "CONCACAF", | |
"children": [ | |
{ | |
"name": "North American Zone", | |
"children": [ | |
{"name": "Canada"}, | |
{"name": "USA"}, | |
{"name": "Mexico"} | |
] | |
}, | |
{ | |
"name": "Cental American Zone", | |
"children": [ | |
{"name": "Belize"}, | |
{"name": "Costa Rica"}, | |
{"name": "El Salvador"}, | |
{"name": "Guatemala"}, | |
{"name": "Honduras"}, | |
{"name": "Nicaragua"}, | |
{"name": "Panama"} | |
] | |
}, | |
{ | |
"name": "Carribean Zone", | |
"children": [ | |
{"name": "Anguilla"}, | |
{"name": "Antigua and Barbuda"}, | |
{"name": "Aruba"}, | |
{"name": "Bahamas"}, | |
{"name": "Barbados"}, | |
{"name": "Bermuda"}, | |
{"name": "Bonaire"}, | |
{"name": "British Virgin Islands"}, | |
{"name": "Cayman Islands"}, | |
{"name": "Cuba"}, | |
{"name": "Curacao"}, | |
{"name": "Dominica"}, | |
{"name": "Dominican Republic"}, | |
{"name": "French Guiana"}, | |
{"name": "Grenada"}, | |
{"name": "Guadeloupe"}, | |
{"name": "Guyana"}, | |
{"name": "Haiti"}, | |
{"name": "Jamaica"}, | |
{"name": "Martinique"}, | |
{"name": "Montserrat"}, | |
{"name": "Puerto Rico"}, | |
{"name": "Saint Kitts and Nevis"}, | |
{"name": "Saint Lucia"}, | |
{"name": "Saint Martin"}, | |
{"name": "Saint Vincent and the Grenadines"}, | |
{"name": "Sint Maarten"}, | |
{"name": "Suriname"}, | |
{"name": "Trinidad and Tobago"}, | |
{"name": "Turks and Caicos Islands"}, | |
{"name": "U.S. Virgin Islands"} | |
] | |
} | |
]}, | |
{ | |
"name": "CONMEBOL", | |
"children": [ | |
{"name": "Brazil"}, | |
{"name": "Paraguay"}, | |
{"name": "Bolivia"}, | |
{"name": "Colombia"}, | |
{"name": "Argentina"}, | |
{"name": "Chile"}, | |
{"name": "Peru"}, | |
{"name": "Uruguay"}, | |
{"name": "Venezuela"}, | |
{"name": "Ecuador"} | |
] | |
} | |
] | |
} |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<title>Network of Soccer Confederations of the Americas</title> | |
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> | |
<link href="https://fonts.googleapis.com/css?family=Mako" rel="stylesheet"> | |
<style> | |
body { | |
margin-left: 2%; | |
} | |
line.link { | |
fill: none; | |
stroke: #CCCCCC; | |
stroke-width: 1.5px; | |
} | |
.node circle { | |
fill: #BBDCE8; | |
stroke: #fff; | |
stroke-width: 1.5px; | |
} | |
.node text { | |
fill: #000; | |
pointer-events: none; | |
} | |
</style> | |
</head> | |
<body> | |
<h3>Network of the Soccer Confederations of the Americas</h3> | |
<p>Made with D3.js based on <a href="http://bl.ocks.org/mbostock/1093130">Mike Bostock's Collapsible Force Layout</a>. Used data from the <a href="https://en.wikipedia.org/wiki/CONCACAF">CONCACAF (The Confederation of North, Central America and Caribbean Association Football)</a> and <a href="https://en.wikipedia.org/wiki/CONMEBOL"> CONMNEBOL (The South American Football Confederation)</a> Wikipedia pages. </p> | |
<p>Double-click lighter nodes to collapse. Click and drag nodes to fixed locations. Double click to collapse and release.</p> | |
<script> | |
var width = 1060, | |
height = 1000, | |
root; | |
var force = d3.layout.force() | |
.linkDistance(150) | |
.charge(-1000) | |
.gravity(.2) | |
.size([width, height]) | |
.on("tick", tick); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
var link = svg.selectAll(".link"), | |
node = svg.selectAll(".node"); | |
d3.json("americas.json", function(error, json) { | |
if (error) throw error; | |
root = json; | |
update(); | |
}); | |
function update() { | |
var nodes = flatten(root), | |
links = d3.layout.tree().links(nodes); | |
// Restart the force layout. | |
force | |
.nodes(nodes) | |
.links(links) | |
.start(); | |
// Update links. | |
link = link.data(links, function(d) { return d.target.id; }); | |
link.exit().remove(); | |
link.enter().insert("line", ".node") | |
.attr("class", "link"); | |
// Update nodes. | |
node = node.data(nodes, function(d) { return d.id; }); | |
node.exit().remove(); | |
var nodeEnter = node.enter().append("g") | |
.attr("class", "node") | |
.on("dblclick", dblclick) | |
.on("click", click) | |
.call(force.drag); | |
nodeEnter.append("circle") | |
.attr("r", 12); | |
nodeEnter.append("text") | |
.attr("dx", ".95em") | |
.text(function(d) { return d.name; }) | |
.style("font-family", "Mako"); | |
node.select("circle") | |
.style("fill", color); | |
} | |
var drag = force.drag() | |
.on("dragstart", dragstart); | |
function tick() { | |
link.attr("x1", function(d) { return d.source.x; }) | |
.attr("y1", function(d) { return d.source.y; }) | |
.attr("x2", function(d) { return d.target.x; }) | |
.attr("y2", function(d) { return d.target.y; }); | |
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
} | |
function color(d) { | |
return d._children ? "#BBDCE8" // collapsed package | |
: d.children ? "#BBDCE8" // expanded package | |
: "#8BBCE8"; // leaf node | |
} | |
// Toggle children on click. | |
function dblclick(d) { | |
if (d3.event.defaultPrevented) return; // ignore drag | |
if (d.children) { | |
d._children = d.children; | |
d.children = null; | |
} else { | |
d.children = d._children; | |
d._children = null; | |
} | |
update(); | |
d3.select(this).classed("fixed", d.fixed = false); | |
d3.select(this).select("text").transition() | |
.duration(750) | |
.attr("x", 12) | |
.style("stroke-width", "0px") | |
.style("font", "15px Mako"); | |
} | |
function click(d) { | |
d3.select(this).select("text").transition() | |
.duration(750) | |
.attr("x", 12) | |
.style("font", "20px Mako"); | |
d3.select(this).select("circle").transition() | |
.attr("r", 12) | |
} | |
function dragstart(d) { | |
d3.select(this).classed("fixed", d.fixed = true); | |
d3.select(this).select("text").transition() | |
.duration(750) | |
.attr("x", 10) | |
.style("font", "15px Mako"); | |
d3.select(this).select("circle").transition() | |
.duration(750); | |
} | |
// Returns a list of all nodes under the root. | |
function flatten(root) { | |
var nodes = [], i = 0; | |
function recurse(node) { | |
if (node.children) node.children.forEach(recurse); | |
if (!node.id) node.id = ++i; | |
nodes.push(node); | |
} | |
recurse(root); | |
return nodes; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment