This map demonstrates a problem I have animating d3 transitions across the antimeridian. Click the update button to see what I mean. On update the map transitions from .rotate([-160, 0]) (eastern hemisphere) to .rotate([160, 0]) (western hemisphere). Rather than cross the antimeridian, the transition travels the long way round.
Created
April 6, 2014 06:40
-
-
Save powersa/10002291 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"type": "FeatureCollection", "features": [{"geometry": {"type": "Point", "coordinates": [160, 0]}, "type": "Feature", "properties": {"name": "noname"}}, {"geometry": {"type": "Point", "coordinates": [-160, 0]}, "type": "Feature", "properties": {"name": "noname"}}]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
background: #fcfcfa; | |
} | |
.stroke { | |
fill: none; | |
stroke: #000; | |
stroke-width: 3px; | |
} | |
.fill { | |
fill: #fff; | |
} | |
.graticule { | |
fill: none; | |
stroke: #777; | |
stroke-width: .5px; | |
stroke-opacity: .5; | |
} | |
.land { | |
fill: #222; | |
} | |
.points { | |
fill: #3182bd; | |
stroke-width: .1; | |
} | |
.boundary { | |
fill: none; | |
stroke: #fff; | |
stroke-width: .5px; | |
} | |
</style> | |
<body> | |
<div id="option"> | |
<input name="updateButton" | |
type="button" | |
value="Update" | |
onclick="updateData()" /> | |
</div> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="http://d3js.org/topojson.v1.min.js"></script> | |
<script> | |
var width = 425, | |
height =425, | |
rotate = [10, -10], | |
velocity = [.003, -.001], | |
time = Date.now(); | |
var projection = d3.geo.orthographic() | |
.scale(200) | |
.translate([width / 2, height / 2]) | |
.clipAngle(90) | |
.rotate([-160, 0]) | |
.precision(.1); | |
var path = d3.geo.path() | |
.projection(projection); | |
var graticule = d3.geo.graticule(); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
svg.append("defs").append("path") | |
.datum({type: "Sphere"}) | |
.attr("id", "sphere") | |
.attr("d", path); | |
svg.append("use") | |
.attr("class", "stroke") | |
.attr("xlink:href", "#sphere"); | |
svg.append("use") | |
.attr("class", "fill") | |
.attr("xlink:href", "#sphere"); | |
svg.append("path") | |
.datum(graticule) | |
.attr("class", "graticule") | |
.attr("d", path); | |
d3.json("110m_land.json", function(error, world) { | |
svg.insert("path") | |
.datum(topojson.feature(world, world.objects.ne_110m_land)) | |
.attr("class", "land") | |
.attr("d", path); | |
svg.insert("path", ".graticule") | |
.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; })) | |
.attr("class", "boundary") | |
.attr("d", path); | |
}); | |
d3.json("HISPEED_1000.json", function(json) { | |
svg.selectAll("g") | |
.data(json.features) | |
.enter() | |
.append("path") | |
.attr("class", "points") | |
.attr("lat", function(d) { return d.geometry.coordinates[0]; }) | |
.attr("lon", function(d) { return d.geometry.coordinates[1]; }) | |
.attr("d", path); | |
}); | |
var transition = d3.transition() | |
.duration(2500); | |
function updateData() { | |
d3.transition() | |
.duration(3000) | |
.tween("rotate", function() { | |
var r = d3.interpolate(projection.rotate(), [160, 0]); | |
return function(t) { | |
projection.rotate(r(t)); | |
svg.selectAll("path").attr("d", path); | |
}; | |
}) | |
}; | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment