Reputation: 51
I'm having an issue specific to scale behavior with a default mercator projection scale value, in my case a pretty ridiculous value (75000), since somehow it was the only way I was able to get my TOPOJson map to be project as anything other than a dot.
I created a projection of a map and want to add zoom and pan. My functions work, all except for the default zoom value. As soon as you scroll to zoom, the value jumps back to the default projection scale value, rather than scaling based on the mouse wheel. I have a feeling that the reason is because in order to get the map to display I needed to make my projection scale value really high (75000).
So when the page loads, the zoom looks fine, like this... but when you try to pan or zoom in or out one mouse wheel click, it jumps to this
I tried to limit the code to just the projection and zoom logic bellow.
<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id = "map" style = "float : left; min-width:320px;width :50%;height : 600px;"></div>
<script>
var width = 900,
height = 800;
var projection = d3.geo.mercator()
.center([-73.94, 40.70])
.scale(75000)
.translate([(width/2), (height/2)]);
var svg = d3.select("#map").append("svg")
.attr("viewBox", "0 0 900 800")
.attr("preserveAspectRatio", "xMidYMid meet");
var path = d3.geo.path()
.projection(projection);
var g = svg.append("g")
.attr("transform", "translate(-793.0489643729818,-630.1796382734433)scale(3.01487286910262)");
d3.json("ny.json", function(error, ny) {
g.append("path")
.attr("id", "boroughs")
.datum(topojson.feature(ny, ny.objects.boroughs))
.attr("d", path);
// zoom and pan
var zoom = d3.behavior.zoom()
.on("zoom",function() {
g.attr("transform","translate("+
d3.event.translate.join(",")+")scale("+d3.event.scale+")");
g.selectAll("path")
.attr("d", path.projection(projection));
});
svg.call(zoom)
});
Upvotes: 2
Views: 1142
Reputation: 38151
I believe your issue is that you set initial scaling and translate values for your g
and then reset them on zoom. For scale, for example:
You set a scale for the g
to 3.01 to start:
var g = svg.append("g")
.attr("transform", "translate(-793.0489643729818,-630.1796382734433)scale(3.01487286910262)");
However, the first time you zoom with d3.event, it'll return 0.607 or 1.647, (zoom out, zoom in) both are zoomed out relative to 3.01:
g.attr("transform","translate("+
d3.event.translate.join(",")+")scale("+d3.event.scale+")");
This creates the jump you are seeing, as both scale and translate are reset and thus independent of your initial values. I think the translate value would be ok but you call it on the svg
and not the g
on which you specify the initial translate.
In any event, it is probably easier to not set an initial transform on your g
, instead using the projection to do this (instead of a two step center and zoom with both a projection and a transform). That way you can leave all your code unchanged, save for removing the line setting the initial g
transform and a modification to your projection.
Upvotes: 1