I am new to d3.js and am trying something simple. I have drawn a world map that reads in file1 and file2. file2 lists airports by an indexID, lat, and lon. file1 pairs the airports by their indexID. I want to draw an arc, line, or anything to connect them. The idea was to produce something like this: http://mbostock.github.io/d3/talk/20111116/airports.html with a different data set but this example was too hard to follow.
The code below correctly draws the map and plots circles for the airports, but remains to be seen how to connect them.
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script type="text/javascript" src="d3/d3.v3.js"></script>
<script src="js/topojson.v0.min.js"></script>
<script>
var width = 2000, height = 2000;
var projection = d3.geo.mercator().center([0, 5]).scale(100).rotate([0, 0]);
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
var path = d3.geo.path().projection(projection);
var g = svg.append("g");
d3.json("json/world-110m2.json", function(error, topology) {// load and display the World
g.selectAll("path").data(topojson.object(topology, topology.objects.countries).geometries).enter().append("path").attr("d", path)
});
d3.csv("file1", function(flights) { //Attempt to draw arcs
var linksByOrigin = {}, countByAirport = {}, locationByAirport = {}, positions = [];
var arc = d3.geo.greatArc().source(function(d) {
return locationByAirport[d.source];
}).target(function(d) {
return locationByAirport[d.target];
});
flights.forEach(function(flight) {
var origin = flight.origin, destination = flight.destination, links = linksByOrigin[origin] || (linksByOrigin[origin] = []);
links.push({
source : origin,
target : destination
});
countByAirport[origin] = (countByAirport[origin] || 0) + 1;
countByAirport[destination] = (countByAirport[destination] || 0) + 1;
});
d3.csv("file2", function(error, data) {// read in and plot the circles
g.selectAll(".blue.circle").data(data).enter().append("circle").attr("class", "blue circle").attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
}).attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
});
g.selectAll("path.arc").data(function(d) {
return linksByOrigin[data.ctuid] || [];
}).enter().append("svg:path").attr("class", "arc").attr("d", function(d) {
return path(arc(d));
});
});
});
</script>
</body>
</html>
I am new to this so the code may be sloppy, but any hints about connecting points pulled from a CSV would be greatly appreciated. Thank you!
To draw an arc between points why not use a path with arc directive(A). I too tried greatArc, but din't work. But found an alternate from this discussion and the alternate is given below:
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr +
" 0 0,1 " + d.target.x + "," + d.target.y;
});
Replace path(arc(d))
with the above snippet and replace the x and y values according to your values. This worked like charm for me. Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With