2014-11-03 61 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])]); 

這是有道理的 - 因爲它被放大了原始的寬/高分別不一樣的,所以我需要翻譯應用到放大寬度/高度。現在它運作良好。