var width = 960, height = 500; var places = [ { name: "Puerto Montt", lat: -41.47, lng: -72.94 }, { name: "Mexico", lat: 19.43, lng: -99.13 }, { name: "Jamaïque", lat: 17.98, lng: -76.8 }, { name: "Madère", lat: 32.75, lng: -17 }, { name: "Lisbonne", lat: 38.71, lng: -9.14 }, { name: "Paris", lat: 48.86, lng: 2.35 }, { name: "Allemagne", lat: 50.73, lng: 7.1 }, { name: "New York", lat: 40.71, lng: -74.01 }, { name: "Bâton-Rouge", lat: 30.42, lng: -91.1 }, { name: "Santa Fe", lat: -31.64, lng: -60.70 }, { name: "Santiago", lat: -33.44, lng: -70.65 }, { name: "Valparaíso", lat: -33.05, lng: -71.62 }, { name: "Chambord", lat: 47.61, lng: 1.52 }, { name: "Hollande", lat: 51.63, lng: 4.67 }, { name: "Castel di Tusa", lat: 38.01, lng: 14.25 }, { name: "Taiwan", lat: 25.04, lng: 121.55 } ]; var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .attr("viewBox", "0, 0, " + width + ", " + height); var proj = d3.geo.orthographic() .center([0, 0]) .rotate([50, -20, 0]) .scale(250) .clipAngle(90) .translate([(width / 2), (height / 2)]); var path = d3.geo.path().projection(proj); d3.json("https://d3js.org/world-110m.v1.json", function(error, world) { if (error) return console.log(error); svg.append("path") // Globe .datum({ type: "Sphere" }) .attr("class", "globe") .attr("d", path); svg.append("path") // Topography .datum(topojson.feature(world, world.objects.countries)) .attr("class", "land") .attr("d", path); svg.selectAll(".arc") // Arcs .data(arcs(voyages(places))) .enter().append("path") .attr("class", "arc") .attr("d", path); svg.selectAll(".pin") // Places .data(geoPlaces(places)) .enter().append("path") .attr("class", "pin") .attr("d", path); }); function geoPlaces(places) { return places.map(function(d) { return { type: "Point", coordinates: [d.lng, d.lat] }; }); } function arcs(data) { return _.map(data, function (i) { return { type: "LineString", coordinates: i }; }); } function voyages(places) { var v = []; for (var i = 0; i < places.length; i++) { v.push([(i === 0 ? [null, null] : [places[i - 1].lng, places[i - 1].lat]), [places[i].lng, places[i].lat]]); } return v.slice(1); }