Skip to content

Instantly share code, notes, and snippets.

@davo
Forked from monsieurBelbo/README.md
Created March 5, 2013 21:32
Show Gist options
  • Save davo/5094476 to your computer and use it in GitHub Desktop.
Save davo/5094476 to your computer and use it in GitHub Desktop.

The Issue

I'm trying to build a map that can be zoomed using the mouse wheel and panned with drag. For that I'm using d3.behavior.zoom() and it works fine for the map. However, I also need to mark some points in the map (which are included in the same topojson used to draw the map). They get rendered just fine, but I'm having trouble handling the zoom behaviour with these points. If you try to zoom or pan, the points get translated abruptly and even seem to change their path!

Any ideas?

<!DOCTYPE html>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.js"></script>
<script src="topojson.v0.min.js"></script>
<html>
<style>
.background {
fill: none;
pointer-events: all;
}
.department {
fill: #aaa;
stroke: #fff;
stroke-width: 1.5px;
}
</style>
<body>
<script>
d3.json("santafe.json", function(error, theProvince) {
var width= 960, height= 500;
var svg = d3.select("body").append("svg");
var departments = topojson.object(theProvince, theProvince.objects.departments);
// The projection
var projection = d3.geo.mercator()
.scale(14000)
.center([-60.951,-31.2])
.translate([width / 2, height / 2]);
// The path
var path = d3.geo.path()
.projection(projection);
// Zoom behavior
var zoom = d3.behavior.zoom()
.translate(projection.translate())
.scaleExtent([height, Infinity])
.scale(projection.scale())
.on("zoom", function() {
projection.translate(d3.event.translate).scale(d3.event.scale)
map.selectAll("path.zoomable").attr("d", path);
});
// The map
var map = svg.append("g")
.classed("provinceMap", true)
.call(zoom);
map.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height);
// Departments
map.selectAll(".department")
.data(departments.geometries)
.enter().append("path")
.classed("department", true)
.classed("zoomable", true)
.attr("d", path);
// Places
map.selectAll(".place-label")
.data(topojson.object(theProvince, theProvince.objects.maternidades).geometries)
.enter().append("path")
.classed("place", true)
.classed("zoomable", true)
.attr("d", d3.svg.symbol().type("cross"))
.attr("transform", function(d) { return "translate(" + projection(d.coordinates.reverse()) + ")"; });
});
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
topojson=function(){function t(t,e){function n(e){var n=t.arcs[e],r=n[0],a=[0,0];return n.forEach(function(t){a[0]+=t[0],a[1]+=t[1]}),[r,a]}var r={},a={},o={};e.forEach(function(t){var e=n(t);(r[e[0]]||(r[e[0]]=[])).push(t),(r[e[1]]||(r[e[1]]=[])).push(~t)}),e.forEach(function(t){var e,r,c=n(t),i=c[0],s=c[1];if(e=o[i])if(delete o[e.end],e.push(t),e.end=s,r=a[s]){delete a[r.start];var u=r===e?e:e.concat(r);a[u.start=e.start]=o[u.end=r.end]=u}else if(r=o[s]){delete a[r.start],delete o[r.end];var u=e.concat(r.map(function(t){return~t}).reverse());a[u.start=e.start]=o[u.end=r.start]=u}else a[e.start]=o[e.end]=e;else if(e=a[s])if(delete a[e.start],e.unshift(t),e.start=i,r=o[i]){delete o[r.end];var f=r===e?e:r.concat(e);a[f.start=r.start]=o[f.end=e.end]=f}else if(r=a[i]){delete a[r.start],delete o[r.end];var f=r.map(function(t){return~t}).reverse().concat(e);a[f.start=r.end]=o[f.end=e.end]=f}else a[e.start]=o[e.end]=e;else if(e=a[i])if(delete a[e.start],e.unshift(~t),e.start=s,r=o[s]){delete o[r.end];var f=r===e?e:r.concat(e);a[f.start=r.start]=o[f.end=e.end]=f}else if(r=a[s]){delete a[r.start],delete o[r.end];var f=r.map(function(t){return~t}).reverse().concat(e);a[f.start=r.end]=o[f.end=e.end]=f}else a[e.start]=o[e.end]=e;else if(e=o[s])if(delete o[e.end],e.push(~t),e.end=i,r=o[i]){delete a[r.start];var u=r===e?e:e.concat(r);a[u.start=e.start]=o[u.end=r.end]=u}else if(r=a[i]){delete a[r.start],delete o[r.end];var u=e.concat(r.map(function(t){return~t}).reverse());a[u.start=e.start]=o[u.end=r.start]=u}else a[e.start]=o[e.end]=e;else e=[t],a[e.start=i]=o[e.end=s]=e});var c=[];for(var i in o)c.push(o[i]);return c}function e(e,r,a){function o(t){0>t&&(t=~t),(l[t]||(l[t]=[])).push(f)}function c(t){t.forEach(o)}function i(t){t.forEach(c)}function s(t){f=t,d[t.type](t.arcs)}var u=[];if(arguments.length>1){var f,l=[],d={LineString:c,MultiLineString:i,Polygon:i,MultiPolygon:function(t){t.forEach(i)}};"GeometryCollection"===r.type?r.geometries.forEach(s):s(r),l.forEach(3>arguments.length?function(t,e){u.push([e])}:function(t,e){a(t[0],t[t.length-1])&&u.push([e])})}else for(var h=0,v=e.arcs.length;v>h;++h)u.push([h]);return n(e,{type:"MultiLineString",arcs:t(e,u)})}function n(t,e){function n(t,e){e.length&&e.pop();for(var n,a=h[0>t?~t:t],o=0,c=a.length,i=0,s=0;c>o;++o)e.push([(i+=(n=a[o])[0])*u+l,(s+=n[1])*f+d]);0>t&&r(e,c)}function a(t){return[t[0]*u+l,t[1]*f+d]}function o(t){for(var e=[],r=0,a=t.length;a>r;++r)n(t[r],e);return e}function c(t){return t.map(o)}function i(t){return t=Object.create(t),t.coordinates=v[t.type](t),t}var s=t.transform,u=s.scale[0],f=s.scale[1],l=s.translate[0],d=s.translate[1],h=t.arcs,v={Point:function(t){return a(t.coordinates)},MultiPoint:function(t){return t.coordinates.map(a)},LineString:function(t){return o(t.arcs)},MultiLineString:function(t){return c(t.arcs)},Polygon:function(t){return c(t.arcs)},MultiPolygon:function(t){return t.arcs.map(c)}};return"GeometryCollection"===e.type?(e=Object.create(e),e.geometries=e.geometries.map(i),e):i(e)}function r(t,e){for(var n,r=t.length,a=r-e;--r>a;)n=t[a],t[a++]=t[r],t[r]=n}function a(t,e){for(var n=0,r=t.length;r>n;){var a=n+r>>>1;e>t[a]?n=a+1:r=a}return n}function o(t,e){function n(t,e){t.forEach(function(t){0>t&&(t=~t);var n=c[t]||(c[t]=[]);n[e]||(n.forEach(function(t){var n,r;r=a(n=i[e],t),n[r]!==t&&n.splice(r,0,t),r=a(n=i[t],e),n[r]!==e&&n.splice(r,0,e)}),n[e]=e)})}function r(t,e){t.forEach(function(t){n(t,e)})}function o(t,e){s[t.type](t.arcs,e)}var c=[],i=e.map(function(){return[]}),s={LineString:n,MultiLineString:r,Polygon:r,MultiPolygon:function(t,e){t.forEach(function(t){r(t,e)})}};return e.forEach(o),i}return{version:"0.0.8",mesh:e,object:n,neighbors:o}}();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment