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

时间:2018-04-11 19:02:55

标签: d3.js geo

我在d3中看到了许多示例地图,其中添加到地图中的点会自动按预期方式对齐,但在代码I中我已经改编了http://bl.ocks.org/bycoffe/3230965我没有添加的点数排列下面的地图。

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

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

1 个答案:

答案 0 :(得分:1)

将地理特征与您的示例对齐将具有挑战性 - 首先您要投射点然后缩放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,你应该将mercator投影的翻译设置为[1800/2,900/2],并将比例设置为类似1800/Math.PI/2

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

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

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

然而,我的第二个想法更多的是保持你的榜样,但去除比例(和累积力)并将力减少到零,以便碰撞功能可以无干扰地工作。基于这些想法,这里有demonstration可能的解决方案。