This block is in response to a stack overflow question on multiple data sources and d3 maps. It may however be more useful in showing how to use named nodes. Uses d3v4.
xxxxxxxxxx
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
.arcs{
fill:none;
stroke:orange;
}
</style>
</head>
<body>
<script>
var width = 900;
var height = 500;
var projection = d3.geoMercator()
.center([80,25])
.scale(800)
.translate([width/2,height/2]);
var path = d3.geoPath().projection(projection);
var svg = d3.select('body').append('svg')
.attr('width',width)
.attr('height',height);
// for layering:
var g0 = svg.append('g');
var g1 = svg.append('g');
var g2 = svg.append('g');
d3.json("india.geojson", function(error,india) {
g0.selectAll('path')
.data(india.features)
.enter()
.append('path')
.attr('d',path)
.attr('fill','green')
.attr('fill-opacity',0.4)
});
d3.json("cities.json", function(error,cities) {
// append some cities:
g2.selectAll('.cities')
.data(d3.entries(cities))
.enter()
.append('circle')
.attr('transform',function(d) { console.log(d.value); return 'translate('+ projection(d.value) + ')'; })
.attr('r',6)
.attr('fill','white')
.attr('stroke','steelblue')
// now load the route data:
d3.json("routes.json", function(error, routes) {
g1.selectAll('.routes')
.data(routes)
.enter()
.append('path')
.attr('class','arcs')
.attr('d', function(d) {
return lngLatToArc(cities, d.source,d.target, 0);
});
});
});
function lngLatToArc(d, sourceName, targetName, bend){
// If no bend is supplied, then do the plain square root
bend = bend || 1;
// `d[sourceName]` and `d[targetname]` are arrays of `[lng, lat]`
// Note, people often put these in lat then lng, but mathematically we want x then y which is `lng,lat`
var sourceLngLat = d[sourceName],
targetLngLat = d[targetName];
if (targetLngLat && sourceLngLat) {
var sourceXY = projection( sourceLngLat ),
targetXY = projection( targetLngLat );
// Uncomment this for testing, useful to see if you have any null lng/lat values
// if (!targetXY) console.log(d, targetLngLat, targetXY)
var sourceX = sourceXY[0],
sourceY = sourceXY[1];
var targetX = targetXY[0],
targetY = targetXY[1];
var dx = targetX - sourceX,
dy = targetY - sourceY,
dr = Math.sqrt(dx * dx + dy * dy)*bend;
// To avoid a whirlpool effect, make the bend direction consistent regardless of whether the source is east or west of the target
var west_of_source = (targetX - sourceX) < 0;
if (west_of_source) return "M" + targetX + "," + targetY + "A" + dr + "," + dr + " 0 0,1 " + sourceX + "," + sourceY;
return "M" + sourceX + "," + sourceY + "A" + dr + "," + dr + " 0 0,1 " + targetX + "," + targetY;
} else {
return "M0,0,l0,0z";
}
}
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js