如何在 d3.js 中同步地图和点图层的比例和位置?

How do I synchronize scale and position of map and point layers in d3.js?

我在 d3 中看到过许多示例地图,其中添加到地图的点会按预期自动对齐,但在我改编自 http://bl.ocks.org/bycoffe/3230965 的代码中,我添加的点与下面的地图。

此处示例:https://naltmann.github.io/d3-geo-collision/ (分数应该与美国一些主要城市相匹配)

我很确定差异是由于 scale/range 周围的代码造成的,但我不知道如何在地图和点之间统一它们。

将地理特征与您的示例在地理上对齐将具有挑战性 - 首先您要投影点,然后缩放 x,y:

    node.cx = xScale(projection(node.coordinates)[0]);
    node.cy = yScale(projection(node.coordinates)[1]);

尺度的范围很有趣,因为两个范围的两个极限都是负数,这可能是由于点上力的累积性质而试图纠正点的定位:

            .on('tick', function(e) {
                k = 10 * e.alpha;
                for (i=0; i < nodes.length; i++) {
                nodes[i].x += k * nodes[i].cx  
                nodes[i].y += k * nodes[i].cy

这很有挑战性,就好像我们去掉了刻度,点向右和向下移动的越来越远。这种累积性质意味着随着每一个刻度,这些点都会从可识别的地理坐标中漂移得越来越远。这在处理一组经过相同变换的地理数据时还好,但在处理未经过相同变换的背景时,就有点吃力了。

我会注意到,如果您希望地图宽度为 1800,高度为 900,则应将墨卡托投影的平移设置为 [1800/2,900/2],将比例设置为 1800/Math.PI/2

地理坐标和部队坐标之间的脱节似乎很难纠正。针对此特定布局和尺寸的任何解决方案都可能在不同的布局和尺寸上失败。

相反,我建议尝试仅使用投影来放置坐标,而不是对每个点累积地添加力变化。这是对您问题的简短回答。

对于更长的答案,我的第一个想法是摆脱碰撞功能并使用锚点 linked 为每个城市的浮点,只绘制浮点(使用 link 保持距离)。这可能是一种更简洁的解决方案,但不幸的是,它与您尝试过的完全不同。

然而,我的第二个想法更多的是保持你的例子,但是移除尺度(和累积力)并将力减少到零,这样碰撞函数可以不受干扰地工作。基于这些想法,这里有一个 demonstration 可能的解决方案。