D3.js 放大d3时保持数据位置

D3.js 放大d3时保持数据位置,d3.js,D3.js,我正在使用D3.js在地图上绘制许多小数据点(如圆圈)。没什么大不了的。不过,我想添加缩放和平移功能 我一直在使用此版本的缩放功能: 它在我的地图库(例如国家表格)上非常有效。但它不会移动数据点。(我试图简单地将数据添加到“features”层,但效果不好——它将数据放在地形下面,使其不再触发鼠标悬停事件,可能是因为它们位于查找平移/缩放事件的层下面。) 下面是我的地图的样子: 如果我在平移/缩放时什么也不做,它显然看起来不太好: 我尝试使用缩放/平移事件调整投影,然后重新投影数据点。这对平

我正在使用D3.js在地图上绘制许多小数据点(如圆圈)。没什么大不了的。不过,我想添加缩放和平移功能

我一直在使用此版本的缩放功能:

它在我的地图库(例如国家表格)上非常有效。但它不会移动数据点。(我试图简单地将数据添加到“features”层,但效果不好——它将数据放在地形下面,使其不再触发鼠标悬停事件,可能是因为它们位于查找平移/缩放事件的层下面。)

下面是我的地图的样子:

如果我在平移/缩放时什么也不做,它显然看起来不太好:

我尝试使用缩放/平移事件调整投影,然后重新投影数据点。这对平移非常有效,但对缩放完全无效:

你不能从上面的图片中分辨出来,但是图片之间的相对距离确实随着缩放而移动。但是泛化翻译是完全错误的

下面是我用来处理缩放的函数:

function zoomed() {
features.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
features.select(".state-border").style("stroke-width", 1.5 / d3.event.scale + "px");
features.select(".county-border").style("stroke-width", .5 / d3.event.scale + "px");

projection.scale(projection_scale*d3.event.scale);
projection.translate([((width/2)+d3.event.translate[0]),((height/2)+d3.event.translate[1])]);

for(i in cdata) {
    var ll = cdata[i].LatLng.split(",");
    if(!ll[0]) ll[0]=-500;
    if(!ll[1]) ll[1]=-500;
    positions[cdata[i].id]=(projection([parseFloat(ll[1]),parseFloat(ll[0])]));
}
 svg.selectAll(".data_circle")
    .attr("cx", function(d, i) { return positions[d.id][0]; })
    .attr("cy", function(d, i) { return positions[d.id][1]; })
;  
}

cdata是一个包含所有csv加载数据的对象,包括以逗号分隔的字符串形式显示的lat/lng数据(因此拆分)。零下500只是针对坏数据;它把它放在你看不见的地方(临时修复)。位置是所有预计lat/lng位置的数组

很明显我想的不对。我尝试过按缩放量缩放平移函数(例如((width/2)+d3.event.translate[0])*d3.event.scale),但这也会产生非常奇怪的结果(这似乎有点帮助,但平移/缩放变得有点“不协调”)-就好像这些点在3D空间中悬停在地图上方,左右移动使它们看起来几乎有点立体感……无论如何,这不是我试图产生的效果)

我应该做些什么不同的事情?同样,任何解决方案都需要考虑到点上有鼠标悬停事件,需要能够触发


我在缩放的D3示例中搜索了一些这样做的东西,但没有找到一个,这让我很惊讶,因为这似乎是一种基本的功能(在谷歌地图中很容易做到这一点),但可能我搜索的深度不够或位置不对。

啊,我找到了!我突然想到问题是什么。它所需要的只是改变:

projection.translate([((width/2)+d3.event.translate[0]),((height/2)+d3.event.translate[1])]);

这是有意义的-原始宽度/高度不一样,因为它正在缩放,所以我需要将平移应用于缩放的宽度/高度。现在它工作得很好

projection.translate([((width*d3.event.scale/2)+d3.event.translate[0]),((height*d3.event.scale/2)+d3.event.translate[1])]);