放大d3时保持数据位置

时间:2014-11-03 15:34:23

标签: d3.js

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

我一直在使用此版本的缩放功能:http://bl.ocks.org/mbostock/2206340

它在我的地图基础上很有用(例如国家表格)。但它不会移动数据点。 (我试图简单地将数据添加到“特征”图层但这不能很好地工作 - 它将它们放在地形下面并使它们不再触发鼠标悬停事件,大概是因为它们位于寻找平底锅的层下面/缩放事件。)

以下是我的地图:

My map

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

My map, zoomed

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

My map, panned and zoomed

你无法从上面的图像中看出,但是图像之间的相对距离确实随着缩放而移动。但泛翻译完全没有了。

这是我用来处理缩放的功能:

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只是为了坏数据;它把它放在你看不到的地方(临时修复)。 position是所有预计lat / lng位置的数组。

显然我正在考虑这个问题。我已经尝试通过缩放量来缩放翻译函数(例如((width / 2)+ d3.event.translate [0])* d3.event.scale))但这也会产生非常奇怪的结果(似乎帮助了一下,但是平移/变焦变得有点“精神错乱” - 几乎就好像点在3D空间中的点在地图上方盘旋,并且左右移动使它们几乎看起来有点立体......无论如何,不​​是效果我试图产生)。

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

我已经在缩放的D3示例中找到了这样做而没有找到的例子,这令我感到惊讶,因为这看起来像是一种基本功能(并且在Google地图中很容易做到一次),但也许我没有足够深入或在正确的位置搜索。

1 个答案:

答案 0 :(得分:2)

啊,我想通了!我突然想到了问题所在。所需要的只是改变:

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])]);

哪个有意义 - 原始宽度/高度不一样,因为它正在被缩放,所以我需要将平移应用于缩放的宽度/高度。现在它很棒。