d3.js:从文件中绘制地图上两点之间的弧线

时间:2013-06-17 20:29:45

标签: d3.js

我是d3.js的新手,我正在尝试一些简单的事情。我绘制了一个读取file1和file2的世界地图。 file2按indexID,lat和lon列出机场。 file1按其indexID对机场进行配对。我想绘制一个弧形,直线或任何东西来连接它们。我的想法是产生这样的东西:http://mbostock.github.io/d3/talk/20111116/airports.html具有不同的数据集 但是这个例子太难以理解了。

下面的代码正确绘制了地图并绘制了机场的圆圈,但仍有待观察如何连接它们。

<!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>

我是新手,所以代码可能很草率,但任何有关从CSV中提取的连接点的提示都将非常感激。谢谢!

1 个答案:

答案 0 :(得分:7)

要在点之间绘制弧,为什么不使用带有弧指令(A)的路径。我也试过了伟大的A,但是没有用。但是找到了来自this discussion的替代品,下面给出了替代品:

 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值。这对我来说很有魅力。希望这会有所帮助。