Bob*_*man 3 charts great-circle d3.js
我用4版本中的D3图书馆和我,对于这一点,无法得出连接上点之间的线条元映射.在该示例中,从库的早期版本,使用以下代码完成绘制连接线:
// calculate the Great Arc between each pair of points
var arc = d3.geo.greatArc()
.source(function(d) { return locationByAirport[d.source]; })
.target(function(d) { return locationByAirport[d.target]; });
[snip]
// Draw the Great Arcs on the Chart.
g.selectAll("path.arc")
.data(function(d) { return linksByOrigin[d.iata] || []; })
.enter().append("svg:path")
.attr("class", "arc")
.attr("d", function(d) { return path(arc(d)); });
Run Code Online (Sandbox Code Playgroud)
评论是我的(可能是错误的),代码来自上面的符号图示例.
在版本4中,d3.geo.greatArc() 似乎已被弃用赞成d3.geoDistance().我不能肯定地说这个,但我greatArc在版本4中找不到引用.不幸的是,我不知道如何设置调用geoDistance()以获取greatArc()过去返回的相同信息.提供geoDistance()的文档不足以让我理解如何使用它.
所以,我的问题是:如何使用库的第4版在D3符号图表上的点(纬度/长对)之间绘制线条?
球形形状的文档有:
要生成一个大弧(一个大圆的一段),只需将GeoJSON LineString几何对象传递给d3.geoPath.D3的投影对中间点使用大弧插值,因此不需要大弧形发生器.
这意味着您可以通过创建LineString包含其coordinates属性中起点和终点坐标的GeoJSON 对象来渲染大弧:
{type: "LineString", coordinates: [[lonStart, latStart], [lonEnd, latEnd]]}
Run Code Online (Sandbox Code Playgroud)
由于这是一个标准的GeoJSON对象,因此路径生成器(d3.geoPath)将能够消化它,并且 - 使用基础投影 - 进行大弧度插值以创建投影的大弧.
有关工作演示,请查看使用D3 v4构建的Mike Bostock的Block,这与您的示例类似.请注意,Block使用MultiLineString对象来计算往返任何特定机场的多个航班,这些航班可以与简单LineString对象相同的方式提供给路径生成器.该示例创建如下的大弧:
在阅读机场信息时,MultiLineString为每个机场创建空物体:
d3.queue()
.defer(d3.csv, "airports.csv", typeAirport)
// ...
function typeAirport(d) {
d[0] = +d.longitude;
d[1] = +d.latitude;
d.arcs = {type: "MultiLineString", coordinates: []};
return d;
}
Run Code Online (Sandbox Code Playgroud)迭代飞行并将源和目标机场的坐标推送到对象的coordinates属性MultiLineString.
flights.forEach(function(flight) {
var source = airportByIata.get(flight.origin),
target = airportByIata.get(flight.destination);
source.arcs.coordinates.push([source, target]);
target.arcs.coordinates.push([target, source]);
});
Run Code Online (Sandbox Code Playgroud)创建合适的地理路径生成器.
var path = d3.geoPath()
.projection(projection)
.pointRadius(2.5);
Run Code Online (Sandbox Code Playgroud)绑定数据使其可用于路径生成器以实际绘制大弧.
var airport = svg.selectAll(".airport")
.data(airports)
.enter().append("g")
.attr("class", "airport");
// ...
airport.append("path")
.attr("class", "airport-arc")
.attr("d", function(d) { return path(d.arcs); }); // great arc's path
Run Code Online (Sandbox Code Playgroud)