<div id="chart">
<h1>National Contiguity - Force Directed Graph</h1>
<div id="notes">
Code by <a href="http://lukewalker.org" target="_blank">Luke Walker</a>, as a solution for <a href="https://www.freecodecamp.com/challenges/show-national-contiguity-with-a-force-directed-graph" target="_blank">this Free Code Camp project</a>. I got a lot of help from <a href="http://jsdatav.is/visuals.html?id=26648f33f3bc9725604a" target="_blank">this</a> series of tutorials.
</div>
</div>
body {
font: 14px sans-serif;
padding: 20px;
background: #333;
}
#notes {
position: absolute;
bottom: 10px;
width: 100%;
text-align: center;
}
#flags-img {
display: block;
position: fixed;
bottom: 0;
left: 0
z-index: 100;
}
#chart {
background: #ccc;
width: 900px;
height: 800px;
box-shadow: 10px 10px 40px -2px rgba(0,0,0,0.62);
padding: 20px 0;
margin: 20px auto;
position: relative;
}
h1 {
position: absolute;
font-size: 30px;
font-family: Courier, monospace;
top: 10px;
left: 10px;
width: 100%;
text-align: center;
}
.countries {
position: absolute;
}
.link {
stroke: #777;
stroke-width: 1px;
}
.tooltip {
position: absolute;
text-align: center;
width: 150px;
height: auto;
padding: 10px 5px;
font: 16px sans-serif;
line-height: 1.4;
font-weight: 100;
background: #000;
border: 0px;
border-radius: 8px;
display: none;
opacity: 0.9;
color: white;
}
/*!
* Generated with CSS Flag Sprite generator (https://www.flag-sprites.com/)
*/
.flag {
position: absolute;
width: 25px;
height: 15px;
background: url('http://lukewalker.org/flags.png') no-repeat;
}
.flag.flag-mh {
background-position: -150px -120px;
}
.flag.flag-th {
background-position: -350px -180px;
}
.flag.flag-ws {
background-position: -200px -210px;
}
.flag.flag-om {
background-position: -75px -150px;
}
.flag.flag-zw {
background-position: -325px -210px;
}
.flag.flag-gt {
background-position: -100px -75px;
}
.flag.flag-jp {
background-position: -250px -90px;
}
.flag.flag-tz {
background-position: -225px -195px;
}
.flag.flag-it {
background-position: -150px -90px;
}
.flag.flag-sa {
background-position: -200px -165px;
}
.flag.flag-vg {
background-position: -75px -210px;
}
.flag.flag-gr {
background-position: -50px -75px;
}
.flag.flag-gw {
background-position: -150px -75px;
}
.flag.flag-au {
background-position: -300px 0;
}
.flag.flag-gq {
background-position: -25px -75px;
}
.flag.flag-bw {
background-position: -350px -15px;
}
.flag.flag-ve {
background-position: -50px -210px;
}
.flag.flag-ie {
background-position: -375px -75px;
}
.flag.flag-lk {
background-position: -250px -105px;
}
.flag.flag-ae {
background-position: -25px 0;
}
.flag.flag-nu {
background-position: -25px -150px;
}
.flag.flag-sb {
background-position: -225px -165px;
}
.flag.flag-sv {
background-position: -175px -180px;
}
.flag.flag-lc {
background-position: -200px -105px;
}
.flag.flag-gs {
background-position: -75px -75px;
}
.flag.flag-kn {
background-position: 0 -105px;
}
.flag.flag-eu {
background-position: -350px -45px;
}
.flag.flag-ug {
background-position: -275px -195px;
}
.flag.flag-by {
background-position: -375px -15px;
}
.flag.flag-ky {
background-position: -100px -105px;
}
.flag.flag-bh {
background-position: -125px -15px;
}
.flag.flag-bs {
background-position: -275px -15px;
}
.flag.flag-lu {
background-position: -350px -105px;
}
.flag.flag-mg {
background-position: -125px -120px;
}
.flag.flag-pr {
background-position: -325px -150px;
}
.flag.flag-et {
background-position: -325px -45px;
}
.flag.flag-ar {
background-position: -225px 0;
}
.flag.flag-li {
background-position: -225px -105px;
}
.flag.flag-ci {
background-position: -150px -30px;
}
.flag.flag-uy {
background-position: -350px -195px;
}
.flag.flag-qa {
background-position: -50px -165px;
}
.flag.flag-fj {
background-position: 0 -60px;
}
.flag.flag-bm {
background-position: -175px -15px;
}
.flag.flag-ge {
background-position: -200px -60px;
}
.flag.flag-pt {
background-position: -375px -150px;
}
.flag.flag-hk {
background-position: -200px -75px;
}
.flag.flag-er {
background-position: -275px -45px;
}
.flag.flag-mc {
background-position: -50px -120px;
}
.flag.flag-jo {
background-position: -225px -90px;
}
.flag.flag-hr {
background-position: -275px -75px;
}
.flag.flag-mx {
background-position: -100px -135px;
}
.flag.flag-no {
background-position: -350px -135px;
}
.flag.flag-eh {
background-position: -250px -45px;
}
.flag.flag-aw {
background-position: -325px 0;
}
.flag.flag-st {
background-position: -150px -180px;
}
.flag.flag-so {
background-position: -100px -180px;
}
.flag.flag-dj {
background-position: -50px -45px;
}
.flag.flag-cf {
background-position: -75px -30px;
}
.flag.flag-eg {
background-position: -225px -45px;
}
.flag.flag-hm {
background-position: -225px -75px;
}
.flag.flag-ly {
background-position: 0 -120px;
}
.flag.flag-tn {
background-position: -75px -195px;
}
.flag.flag-ro {
background-position: -100px -165px;
}
.flag.flag-ph {
background-position: -200px -150px;
}
.flag.flag-jm {
background-position: -200px -90px;
}
.flag.flag-mq {
background-position: -325px -120px;
}
.flag.flag-gi {
background-position: -300px -60px;
}
.flag.flag-pe {
background-position: -125px -150px;
}
.flag.flag-ml {
background-position: -200px -120px;
}
.flag.flag-vc {
background-position: -25px -210px;
}
.flag.flag-fk {
background-position: -25px -60px;
}
.flag.flag-sn {
background-position: -75px -180px;
}
.flag.flag-al {
background-position: -125px 0;
}
.flag.flag-pg {
background-position: -175px -150px;
}
.flag.flag-gp {
background-position: 0 -75px;
}
.flag.flag-uz {
background-position: -375px -195px;
}
.flag.flag-sl {
background-position: -25px -180px;
}
.flag.flag-ck {
background-position: -175px -30px;
}
.flag.flag-sg {
background-position: -325px -165px;
}
.flag.flag-pa {
background-position: -100px -150px;
}
.flag.flag-ht {
background-position: -300px -75px;
}
.flag.flag-re {
background-position: -75px -165px;
}
.flag.flag-gh {
background-position: -275px -60px;
}
.flag.flag-us {
background-position: -325px -195px;
}
.flag.flag-mn {
background-position: -250px -120px;
}
.flag.flag-zm {
background-position: -300px -210px;
}
.flag.flag-nz {
background-position: -50px -150px;
}
.flag.flag-gl {
background-position: -325px -60px;
}
.flag.flag-gu {
background-position: -125px -75px;
}
.flag.flag-fo {
background-position: -75px -60px;
}
.flag.flag-gf {
background-position: -225px -60px;
}
.flag.flag-kh {
background-position: -325px -90px;
}
.flag.flag-pl {
background-position: -250px -150px;
}
.flag.flag-ca {
background-position: -25px -30px;
}
.flag.flag-bb {
background-position: 0 -15px;
}
.flag.flag-la {
background-position: -150px -105px;
}
.flag.flag-at {
background-position: -275px 0;
}
.flag.flag-sh {
background-position: -350px -165px;
}
.flag.flag-af {
background-position: -50px 0;
}
.flag.flag-ni {
background-position: -300px -135px;
}
.flag.flag-za {
background-position: -275px -210px;
}
.flag.flag-mz {
background-position: -150px -135px;
}
.flag.flag-kz {
background-position: -125px -105px;
}
.flag.flag-as {
background-position: -250px 0;
}
.flag.flag-br {
background-position: -250px -15px;
}
.flag.flag-cr {
background-position: -300px -30px;
}
.flag.flag-bz {
background-position: 0 -30px;
}
.flag.flag-es {
background-position: -300px -45px;
}
.flag.flag-ee {
background-position: -200px -45px;
}
.flag.flag-co {
background-position: -275px -30px;
}
.flag.flag-ba {
background-position: -375px 0;
}
.flag.flag-ru {
background-position: -150px -165px;
}
.flag.flag-pk {
background-position: -225px -150px;
}
.flag.flag-kg {
background-position: -300px -90px;
}
.flag.flag-md {
background-position: -75px -120px;
}
.flag.flag-tr {
background-position: -125px -195px;
}
.flag.flag-rw {
background-position: -175px -165px;
}
.flag.flag-mt {
background-position: 0 -135px;
}
.flag.flag-sz {
background-position: -225px -180px;
}
.flag.flag-va {
background-position: 0 -210px;
}
.flag.flag-gd {
background-position: -175px -60px;
}
.flag.flag-dm {
background-position: -100px -45px;
}
.flag.flag-pf {
background-position: -150px -150px;
}
.flag.flag-iq {
background-position: -75px -90px;
}
.flag.flag-yt {
background-position: -250px -210px;
}
.flag.flag-ki {
background-position: -350px -90px;
}
.flag.flag-ne {
background-position: -225px -135px;
}
.flag.flag-je {
background-position: -175px -90px;
}
.flag.flag-ye {
background-position: -225px -210px;
}
.flag.flag-sc {
background-position: -250px -165px;
}
.flag.flag-tg {
background-position: -325px -180px;
}
.flag.flag-am {
background-position: -150px 0;
}
.flag.flag-tj {
background-position: -375px -180px;
}
.flag.flag-an {
background-position: -175px 0;
}
.flag.flag-tt {
background-position: -150px -195px;
}
.flag.flag-bv {
background-position: -325px -15px;
}
.flag.flag-bt {
background-position: -300px -15px;
}
.flag.flag-il {
background-position: 0 -90px;
}
.flag.flag-cm {
background-position: -225px -30px;
}
.flag.flag-tk {
background-position: 0 -195px;
}
.flag.flag-vn {
background-position: -125px -210px;
}
.flag.flag-hn {
background-position: -250px -75px;
}
.flag.flag-cy {
background-position: -375px -30px;
}
.flag.flag-nf {
background-position: -250px -135px;
}
.flag.flag-ec {
background-position: -175px -45px;
}
.flag.flag-bg {
background-position: -100px -15px;
}
.flag.flag-fm {
background-position: -50px -60px;
}
.flag.flag-nl {
background-position: -325px -135px;
}
.flag.flag-lt {
background-position: -325px -105px;
}
.flag.flag-id {
background-position: -350px -75px;
}
.flag.flag-cd {
background-position: -50px -30px;
}
.flag.flag-gm {
background-position: -350px -60px;
}
.flag.flag-sm {
background-position: -50px -180px;
}
.flag.flag-ua {
background-position: -250px -195px;
}
.flag.flag-do {
background-position: -125px -45px;
}
.flag.flag-mk {
background-position: -175px -120px;
}
.flag.flag-tv {
background-position: -175px -195px;
}
.flag.flag-wf {
background-position: -175px -210px;
}
.flag.flag-gg {
background-position: -250px -60px;
}
.flag.flag-cu {
background-position: -325px -30px;
}
.flag.flag-in {
background-position: -25px -90px;
}
.flag.flag-ga {
background-position: -125px -60px;
}
.flag.flag-ma {
background-position: -25px -120px;
}
.flag.flag-tl {
background-position: -25px -195px;
}
.flag.flag-mp {
background-position: -300px -120px;
}
.flag.flag-kr {
background-position: -50px -105px;
}
.flag.flag-ch {
background-position: -125px -30px;
}
.flag.flag-hu {
background-position: -325px -75px;
}
.flag.flag-gy {
background-position: -175px -75px;
}
.flag.flag-cv {
background-position: -350px -30px;
}
.flag.flag-lr {
background-position: -275px -105px;
}
.flag.flag-ke {
background-position: -275px -90px;
}
.flag.flag-gn {
background-position: -375px -60px;
}
.flag.flag-dk {
background-position: -75px -45px;
}
.flag.flag-ad {
background-position: 0 0;
}
.flag.flag-bd {
background-position: -25px -15px;
}
.flag.flag-kw {
background-position: -75px -105px;
}
.flag.flag-sd {
background-position: -275px -165px;
}
.flag.flag-mm {
background-position: -225px -120px;
}
.flag.flag-tm {
background-position: -50px -195px;
}
.flag.flag-bn {
background-position: -200px -15px;
}
.flag.flag-ir {
background-position: -100px -90px;
}
.flag.flag-lv {
background-position: -375px -105px;
}
.flag.flag-mr {
background-position: -350px -120px;
}
.flag.flag-py {
background-position: -25px -165px;
}
.flag.flag-cn {
background-position: -250px -30px;
}
.flag.flag-az {
background-position: -350px 0;
}
.flag.flag-be {
background-position: -50px -15px;
}
.flag.flag-bf {
background-position: -75px -15px;
}
.flag.flag-sy {
background-position: -200px -180px;
}
.flag.flag-fr {
background-position: -100px -60px;
}
.flag.flag-pn {
background-position: -300px -150px;
}
.flag.flag-si {
background-position: -375px -165px;
}
.flag.flag-fi {
background-position: -375px -45px;
}
.flag.flag-rs {
background-position: -125px -165px;
}
.flag.flag-tw {
background-position: -200px -195px;
}
.flag.flag-ps {
background-position: -350px -150px;
}
.flag.flag-de {
background-position: -25px -45px;
}
.flag.flag-cz {
background-position: 0 -45px;
}
.flag.flag-cg {
background-position: -100px -30px;
}
.flag.flag-dz {
background-position: -150px -45px;
}
.flag.flag-ng {
background-position: -275px -135px;
}
.flag.flag-tf {
background-position: -300px -180px;
}
.flag.flag-kp {
background-position: -25px -105px;
}
.flag.flag-is {
background-position: -125px -90px;
}
.flag.flag-io {
background-position: -50px -90px;
}
.flag.flag-nc {
background-position: -200px -135px;
}
.flag.flag-ms {
background-position: -375px -120px;
}
.flag.flag-se {
background-position: -300px -165px;
}
.flag.flag-gb {
background-position: -150px -60px;
}
.flag.flag-sr {
background-position: -125px -180px;
}
.flag.flag-mu {
background-position: -25px -135px;
}
.flag.flag-to {
background-position: -100px -195px;
}
.flag.flag-nr {
background-position: 0 -150px;
}
.flag.flag-np {
background-position: -375px -135px;
}
.flag.flag-ls {
background-position: -300px -105px;
}
.flag.flag-ag {
background-position: -75px 0;
}
.flag.flag-mv {
background-position: -50px -135px;
}
.flag.flag-mo {
background-position: -275px -120px;
}
.flag.flag-pm {
background-position: -275px -150px;
}
.flag.flag-tc {
background-position: -250px -180px;
}
.flag.flag-mw {
background-position: -75px -135px;
}
.flag.flag-bj {
background-position: -150px -15px;
}
.flag.flag-lb {
background-position: -175px -105px;
}
.flag.flag-cl {
background-position: -200px -30px;
}
.flag.flag-bo {
background-position: -225px -15px;
}
.flag.flag-pw {
background-position: 0 -165px;
}
.flag.flag-td {
background-position: -275px -180px;
}
.flag.flag-vu {
background-position: -150px -210px;
}
.flag.flag-me {
background-position: -100px -120px;
}
.flag.flag-my {
background-position: -125px -135px;
}
.flag.flag-um {
background-position: -300px -195px;
}
.flag.flag-km {
background-position: -375px -90px;
}
.flag.flag-na {
background-position: -175px -135px;
}
.flag.flag-ao {
background-position: -200px 0;
}
.flag.flag-sk {
background-position: 0 -180px;
}
.flag.flag-ai {
background-position: -100px 0;
}
.flag.flag-vi {
background-position: -100px -210px;
}
(function() {
var dataUrl = 'https://raw.githubusercontent.com/DealPete/forceDirected/master/countries.json';
var tooltip = d3.select('body').append('div').attr('class', 'tooltip'),
showTooltip = function(d) {
tooltip.html('<div>' + d.country + '</div>')
.style('left', (d3.event.pageX + 10) + 'px')
.style('top', (d3.event.pageY + 10) + 'px')
.style('display', 'block');
},
hideTooltip = function(d) {
tooltip.style('display', 'none');
};
d3.json(dataUrl, function(e, data) {
if (e) throw e;
buildChart(data);
});
function buildChart(graph) {
var margin = {
top: 5,
right: 5,
bottom: 5,
left: 5
};
var width = 900 - margin.right - margin.left,
height = 780 - margin.top - margin.bottom;
var countries = d3.select('#chart')
.append('div')
.attr('class', 'countries');
var svg = d3.select('#chart').append('svg')
.attr('width', width + margin.right + margin.left)
.attr('height', height + margin.top + margin.bottom)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var nodes = graph.nodes,
links = graph.links;
var force = d3.layout.force()
.size([width, height])
.nodes(nodes)
.links(links)
.linkDistance(55)
.charge([-100])
.start();
var borders = svg.selectAll('.link')
.data(links)
.enter().append('line')
.attr('class', 'link')
var node = countries.selectAll('.flag')
.data(nodes)
.enter().append('img')
.attr('class', function(d) {
return 'flag flag-' + d.code;
})
.call(force.drag)
.on('mouseover', showTooltip)
.on('mouseout', hideTooltip);
force.on('tick', function() {
borders
.attr('x1', function(d) { return d.source.x + margin.left; })
.attr('y1', function(d) { return d.source.y + margin.top; })
.attr('x2', function(d) { return d.target.x + margin.left; })
.attr('y2', function(d) { return d.target.y + margin.top; });
node
.style('left', function(d) {
return d.x + margin.left + 'px'; })
.style('top', function(d) { return d.y + margin.top + 'px'; });
});
}
})();
Also see: Tab Triggers