最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Constraining map panning with zoom.translateExtent in D3 v4 - Stack Overflow

programmeradmin4浏览0评论

I'm trying to display a map of a single state, with zooming and panning constrained to the boundaries of the state. It's mostly working, except for the panning constraint when the state path is scaled to fit a smaller container. I think this es down to me not understanding what arguments to use for zoom.translateExtent (although I'm very new to this, so it could be something else).

Live example on bl.ocks, with links to prior art.

One notable thing is that I'm using a null projection for d3.geoPath, because I used ogr2ogr to generate a shapefile in projected coordinates for each state. That's why I used a zoom transform to fit the map to its container.

I'm trying to display a map of a single state, with zooming and panning constrained to the boundaries of the state. It's mostly working, except for the panning constraint when the state path is scaled to fit a smaller container. I think this es down to me not understanding what arguments to use for zoom.translateExtent (although I'm very new to this, so it could be something else).

Live example on bl.ocks, with links to prior art.

One notable thing is that I'm using a null projection for d3.geoPath, because I used ogr2ogr to generate a shapefile in projected coordinates for each state. That's why I used a zoom transform to fit the map to its container.

Share Improve this question asked Jul 25, 2016 at 2:03 bhrutledgebhrutledge 711 silver badge4 bronze badges 2
  • The ask here is a little confusing. Could you elaborate on the issue you are having? I am not seeing the issue you are talking about! – Tekill Commented Jul 27, 2016 at 12:31
  • Sorry, I've updated my example to be more clear. Basically, when I transform the state to fit a smaller container, the drag-to-pan functionality breaks. I think there's something wrong with the way I'm using the transform calculated by zoomBounds in conjunction with translateExtent. If I remove the translateExtent line, the panning is smooth, but not constrained to the container. – bhrutledge Commented Jul 31, 2016 at 14:59
Add a ment  | 

2 Answers 2

Reset to default 5

@McGiogen's solution is almost correct but misses that MIN needs to vary depending on the zoom scale factor transform.k.

I drew a diagram to see how I needed to constrain my svg to always be contained inside the zoomed view (depicted in my drawing as the LARGER of the boxes, only a portion of which is visible to the user):

(since the constraint x+kw >= w is equivalent to x >= (1-k)w, with a similar argument for y)

thus assuming your svg container size [w, h]:

function zoomed() {
    var t = d3.event.transform;

    t.x = d3.min([t.x, 0]);
    t.y = d3.min([t.y, 0]);
    t.x = d3.max([t.x, (1-t.k) * w]);
    t.y = d3.max([t.y, (1-t.k) * h]);

    svg.attr("transform", t);
}

I'm facing the same problem today and I've done some tests.

I've noticed that it's the same weird behaviour happening when you have a translateExtent box smaller than the content's elements.

In your (and mine) code the same behaviour is triggered by zooming out: it doesn't matter if you have the translateExtent box correctly set with no zoom, if you zoom out the box is reduced at higher rate than the elements and at some point you will have translateExtent box smaller than the content (and the weird behaviour).

I temporary solved this as said here D3 pan+ zoom constraints

var MIN = {x: 0, y: -500},     //top-left corner
    MAX = {x: 2000, y: 500};   //bottom-right corner

function zoomed() {
   var transform = d3.event.transform;

   // limiting tranformation by MIN and MAX bounds
   transform.x = d3.max([transform.x, MIN.x]);
   transform.y = d3.max([transform.y, MIN.y]);
   transform.x = d3.min([transform.x, MAX.x]);
   transform.y = d3.min([transform.y, MAX.y]);

   container.attr("transform", transform);
}

I'm still a d3 newbie but I think that this is a bug in translateExtent code.

发布评论

评论列表(0)

  1. 暂无评论