Reproducing the map from Alessandro Sorichetta et al., Mapping internal connectivity through human migration in malaria endemic countries, Nature Scientific Data 3, Article number: 160066 (2016) doi:10.1038/sdata.2016.66.
We use a Force‐Directed Edge Bundling (FDEB) algorithm to make the graph less cluttered.
See Holten, Danny, and Jarke J. Van Wijk. “Force‐Directed Edge Bundling for Graph Visualization” Computer Graphics Forum (Blackwell Publishing Ltd) 28, no. 3 (2009): 983-990. (PDF)
Javascript implementation by Corneliu Sugar.
Compare with the graph without bundling: bolivia internal migrations.
forked from Fil's block: bolivia internal migrations
xxxxxxxxxx
<meta charset="utf-8">
<style>
.stroke {
fill: none;
stroke: #000;
stroke-width: 3px;
}
.fill {
fill: #fff;
}
.graticule {
fill: none;
stroke: #777;
stroke-width: 0.5px;
stroke-opacity: 0.5;
}
.land {
fill: #ccc;
}
.boundary {
fill: none;
stroke: #555;
stroke-width: 0.5px;
}
</style>
<svg width="960" height="484"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//d3js.org/d3-geo-projection.v1.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script type="text/javascript" src="d3-ForceEdgeBundling.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var projection = d3.geoRobinson()
.rotate([66,16.4])
.center([0,0])
.scale(1800)
.translate([width / 2, height / 2])
.precision(0.1);
var graticule = d3.geoGraticule();
var path = d3.geoPath()
.projection(projection);
var defs = svg.append("defs");
defs.append("path")
.datum({type: "Sphere"})
.attr("id", "sphere")
.attr("d", path);
defs.append("clipPath")
.attr("id", "clip")
.append("use")
.attr("xlink:href", "#sphere");
svg.append("use")
.attr("class", "stroke")
.attr("xlink:href", "#sphere");
svg.append("use")
.attr("class", "fill")
.attr("xlink:href", "#sphere");
svg.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("clip-path", "url(#clip)")
.attr("d", path);
var lines = svg.append("g"),
circles = svg.append("g");
var color = d3.scaleQuantize()
.domain([0, 1])
.range(d3.range(6).map(function(i) { return d3.interpolateSpectral(1-i/6)}));
d3.json("https://unpkg.com/visionscarto-world-atlas@0.0.4/world/110m.json", function(error, world) {
if (error) throw error;
if (true)
svg.insert("path", ".graticule")
.datum(topojson.feature(world, world.objects.countries))
.attr("class", "land")
.attr("clip-path", "url(#clip)")
.attr("d", path);
if (true)
svg.insert("path", ".graticule")
.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
.attr("class", "boundary")
.attr("clip-path", "url(#clip)")
.attr("d", path);
var w = topojson.feature(world, world.objects.countries);
w.features.forEach(function(d, i){
});
d3.csv('BOL_5yrs_InternalMigFlows_2010.csv', function(err, migrations){
var sites = d3.map(), links = d3.map();
migrations
.map(function(l) {
var p = projection([+l.LONFR,+l.LATFR]);
sites.set(l.NODEI, { index: +l.NODEI, x: p[0], y: p[1] });
links.set([l.NODEI, l.NODEJ], { i: Math.log(+l.PrdMIG) });
});
color.domain(d3.extent(links.values(), function(d){ return d.i }))
var d3line = d3.line()
.x(function(d){return d.x;})
.y(function(d){return d.y;});
// use geoVoronoi!
var voronoi = d3.voronoi()
.x(d => d.x)
.y(d => d.y);
var delaunay = voronoi(sites.values()).links();
var lines = svg.append('g');
lines
.selectAll('path')
.data(delaunay)
.enter()
.append('path')
.attr('d', d => d3line([sites.get(d.source.index), sites.get(d.target.index)]))
.attr('stroke', function(d) { return color(
links.get([
d.source.index, d.target.index
]).i
); })
.attr('stroke-width', function(d,i) { return (links.get([
d.source.index, d.target.index
]).i)/2; })
//.attr('opacity', 0.4)
.attr('fill', 'none')
svg.append('g')
.selectAll('circle')
.data(sites.values())
.enter()
.append('circle')
.attr('transform', function(d){ return 'translate('+ [d.x, d.y] +')';})
.attr('r', 3)
.attr('fill', 'white')
.attr('stroke', '#777');
});
});
</script>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-geo-projection.v1.min.js
https://d3js.org/topojson.v1.min.js
https://d3js.org/d3-scale-chromatic.v1.min.js