D3.js - 从版本 2 到版本 4 的 path.area 的变化

D3.js - Changes from path.area in version 2 to version 4

我正在尝试更新 d3-cartogram to work with D3.js version 4. So far, everything is going fine — I've just been updating all the functions so that they're written in the flattened namespace of version 4. For example, instead of d3.geo.path(), it's d3.geoPath(). I've also changed a few small things so that the code works with the latest version of TopoJSON。例如,不是 topojson.object(topology, geom).coordinates,而是 topojson.feature(topology, geom).geometry.coordinates.

但是我遇到了一个我似乎无法解决的问题。文件 cartogram.js 有一行内容为 var areas = objects.map(path.area),其中 objects 是 TopoJSON 特征的集合。 path.area 在 D3.js 版本 2 和版本 4 中有所不同,我似乎无法调和它们。如果我在每个版本中控制台登录它,它看起来像这样:

在版本 4 中,它记录错误:Uncaught TypeError: r is not a function。自然地,我已经用谷歌搜索了错误以及我正在尝试做的事情的各种描述,但我没有任何运气。在此先感谢您的帮助。

正如 Mark 所建议的,您应该使用非压缩代码进行调试。来自 path/index.js 的相关非缩小代码如下所示:

path.area = function(object) {
  stream(object, projectionStream(pathArea));
  return pathArea.result();
};

您的错误表明 projectionStream 不是一个函数;它可能是未定义的。投影流由path.projection, and as the documentation says, the projection you specify must implement projection.stream设置。 (当您设置 projection 时,不会贪婪地强制执行此错误。当您尝试使用 path 时,它会延迟抛出。)

这里的问题是 D3 3.x 的 path.projection 支持“后备投影”的概念,这只是一个获取经度的裸函数-latitude 数组作为输入,并返回一个 x-y 数组作为输出。 D3 3.x 会将其隐式包装在默认投影对象中,以添加自适应采样和逆时序切割等功能。 D3 4.0 删除了这个功能,迫使你明确:你必须实现 projection.stream 才能使用 d3.geoPath.

根据 CHANGES:

“Fallback projections”—when you pass a function rather than a projection to path.projection—are no longer supported. For geographic projections, use d3.geoProjection or d3.geoProjectionMutator to define a custom projection. For arbitrary geometry transformations, implement the stream interface; see also d3.geoTransform.

每当您寻求帮助时,我都建议您链接到一个演示您的问题的实例,因为一小段代码和描述通常不足以隔离问题。这里不清楚你试图将 projection 与 d3.geoPath 一起使用。对于平面变换,您很可能希望使用 d3.geoTransform 或 d3.geoIdentity。对于球面到平面的投影,您需要使用 d3.geoProjection 或 d3.geoProjectionMutator。