2012-12-10 45 views
3

我有一張翻譯好的地圖,可以正確地放在畫布上。如何準確地縮放已經翻譯過的d3地圖

我試圖實現一種縮放它的方式,它可以工作,但是放大時會遠離中心,而不是集中在鼠標或畫布上。

這是我的代碼:

function map(data, total_views) { 
    var xy = d3.geo.mercator().scale(4350), 
     path = d3.geo.path().projection(xy), 
     transX = -320, 
     transY = 648, 
     init = true; 

    var quantize = d3.scale.quantize() 
    .domain([0, total_views*2/Object.keys(data).length]) 
    .range(d3.range(15).map(function(i) { return "map-colour-" + i; })); 

    var map = d3.select("#map") 
     .append("svg:g") 
     .attr("id", "gb-regions") 
     .attr("transform","translate("+transX+","+transY+")") 
     .call(d3.behavior.zoom().on("zoom", redraw)); 

    d3.json(url_prefix + "map/regions.json", function(json) { 
    d3.select("#regions") 
     .selectAll("path") 
      .data(json.features) 
     .enter().append("svg:path") 
      .attr("d", path) 
      .attr("class", function(d) { return quantize(data[d.properties.fips]); }); 
    }); 

    function redraw() { 
    var trans = d3.event.translate; 
    var scale = d3.event.scale; 

    if (init) { 
     trans[0] += transX; 
     trans[1] += transY; 
     init = false; 
    } 
    console.log(trans); 

    map.attr("transform", "translate(" + trans + ")" + " scale(" + scale + ")"); 
    } 
} 

我發現,增加初始轉換到新的翻譯(trans)適用於第一變焦,但對於所有後續縮放這使情況變得更糟。有任何想法嗎?

回答

1

這裏有一個全面的起點:semantic zooming of force directed graph in d3

而且這個例子讓我特別(只是撕裂了所有的微縮的東西,使其更簡單):http://codepen.io/billdwhite/pen/lCAdi?editors=001

var zoomHandler = function(newScale) { 
     if (!zoomEnabled) { return; } 
     if (d3.event) { 
      scale = d3.event.scale; 
     } else { 
      scale = newScale; 
     } 
     if (dragEnabled) { 
      var tbound = -height * scale, 
       bbound = height * scale, 
       lbound = -width * scale, 
       rbound = width * scale; 
      // limit translation to thresholds 
      translation = d3.event ? d3.event.translate : [0, 0]; 
      translation = [ 
       Math.max(Math.min(translation[0], rbound), lbound), 
       Math.max(Math.min(translation[1], bbound), tbound) 
      ]; 
     } 

     d3.select(".panCanvas, .panCanvas .bg") 
      .attr("transform", "translate(" + translation + ")" + " scale(" + scale + ")"); 

     minimap.scale(scale).render(); 
    }; // startoff zoomed in a bit to show pan/zoom rectangle 

雖然我不得不調整這爲我的案件工作一點點,但這個想法就在那裏。這是我的一部分。 (E.range(min,max,value)只是限制valuemin/max內。這些變化大多是因爲我治療0,0作爲屏幕在這種情況下中心。

// limit translation to thresholds 
      var offw = width/2*scale; 
      var offh = height/2*scale; 
      var sw = width*scale/2 - zoomPadding; 
      var sh = height*scale/2- zoomPadding; 

      translate = d3.event ? d3.event.translate : [0, 0]; 
      translate = [ 
       E.range(-sw,(width+sw), translate[0]+offw), 
       E.range(-sh,(height+sh), translate[1]+offh) 
      ]; 
     } 


     var ts = [translate[0], translate[1]]; 
     var msvg = [scale, 0, 0, scale, ts[0], ts[1]];