3

我有一张地图,它已经过翻译,可以正确地放在画布上。

我正在尝试实现一种缩放它的方法并且它确实有效,但是当您放大时它会远离中心,而不是以鼠标甚至画布为中心。

这是我的代码:

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)适用于第一次缩放,但对于所有后续缩放,它会使情况变得更糟。有任何想法吗?

4

1 回答 1

1

这是一个全面的起点: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]];
于 2014-08-06T03:30:38.483 回答