2014-11-03 54 views
1

我正在使用D3.js在地图上绘制大量小数据点(如圆圈)。那里没什么大不了的。不过,我想添加缩放和平移功能。在放大d3时维护数据位置

我一直在使用这个版本的缩放功能: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加载数据,包括纬度/经度数据作为一个对象逗号分隔的字符串(因此分裂)。 -500的东西只是为了不好的数据;它把它放在你看不到的地方(一个临时修复)。位置是所有投影经纬度位置的数组。

显然我在想这个不对。我试过缩放翻译功能的缩放量(例如((宽度/ 2)+ d3.event.translate [0])* d3.event.scale)),但这也产生了非常奇怪的结果(它似乎有点帮助,但是平移/缩放变得有点“虚晃” - 就好像点在三维空间中盘旋在地图上方,左右移动使它们几乎看起来有点立体......反正,不是效果我试图产生)。

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

我已经搜索了缩放D3的例子,这样做,没有找到一个,这让我感到惊讶,因为这似乎是一种基本功能(并且在Google地图中很容易做到),但是也许我没有足够深入或正确的地方进行搜索。

回答

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

这是有道理的 - 因为它被放大了原始的宽/高分别不一样的,所以我需要翻译应用到放大宽度/高度。现在它运作良好。