4

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!

4

1 回答 1

9

要在点之间绘制弧线,为什么不使用带有弧指令(A)的路径。我也尝试过greatArc,但没有用。但是从这个讨论中找到了一个替代方案,下面给出了替代方案:

 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;
  });

替换path(arc(d))为上面的代码片段并根据您的值替换 x 和 y 值。这对我来说就像魅力一样。希望这可以帮助。

于 2014-09-20T07:31:27.253 回答