Created
March 6, 2012 10:59
-
-
Save bobuss/1985684 to your computer and use it in GitHub Desktop.
d3 great arcs over polymaps
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> | |
<html> | |
<head> | |
<title>D3 over Polymap example</title> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<link rel="stylesheet" href="map.css" /> | |
</head> | |
<body onload="init();"> | |
<div id="map_container"></div> | |
<script type="text/javascript" src="http://polymaps.org/polymaps.min.js?2.5.0"></script> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.v2.min.js"></script> | |
<script type="text/javascript" src="map.js"></script> | |
<script> | |
var points = []; | |
var map ; | |
function createMap() { | |
map = new Map({ | |
container: "map_container", | |
zoom: 3, | |
zoom_range: [1,9], | |
points_limit: 10, | |
arcs_limit: 9 | |
}); | |
} | |
function updateMap(longitude, latitude) { | |
console.log(longitude + ' - ' + latitude); | |
points.push(map.addPoint(longitude, latitude)); | |
if (points.length >= 2) { | |
map.addGreatArc(points[points.length-1], points[points.length-2]); | |
points.shift(); | |
} | |
} | |
function init() { | |
createMap(); | |
setInterval(function(){ | |
updateMap(300 * Math.random() - 150, 150 * Math.random() - 75); | |
}, 1000); | |
} | |
</script> | |
</body> | |
</html> |
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
#map_container svg.map { | |
background-color: #2F2C2B; | |
} | |
.compass .back { | |
fill: #eee; | |
fill-opacity: .8; | |
} | |
.compass .fore { | |
stroke: #999; | |
stroke-width: 1.5px; | |
} | |
.compass rect.back.fore { | |
fill: #999; | |
fill-opacity: .3; | |
stroke: #eee; | |
stroke-width: 1px; | |
shape-rendering: crispEdges; | |
} | |
.compass .direction { | |
fill: none; | |
} | |
.compass .chevron { | |
fill: none; | |
stroke: #999; | |
stroke-width: 5px; | |
} | |
.compass .zoom .chevron { | |
stroke-width: 4px; | |
} | |
.compass .active .chevron, .compass .chevron.active { | |
stroke: #fff; | |
} | |
.compass.active .active .direction { | |
fill: #999; | |
} | |
circle.marker { | |
fill: #E03434; | |
stroke-width : 1px; | |
stroke: #444; | |
} | |
text.label { | |
font-size: 11px; | |
fill: #FFF; | |
font-weight: bold; | |
text-anchor: middle; | |
} | |
path.label { | |
fill: #000; | |
} | |
circle.point:hover { | |
fill: #C90134; | |
} | |
path.great_arc { | |
fill: none; | |
stroke: #000; | |
stroke-width: 0.5px; | |
stroke-opacity: 0.5; | |
} |
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
var Map = function(options) { | |
this.options = options; | |
var po = org.polymaps; | |
var center = {lat: 39, lon: 10}; | |
this.map = po.map() | |
.container(document.getElementById(this.options.container).appendChild(po.svg("svg"))) | |
.center(center) | |
.zoom(undefined != this.options.zoom ? this.options.zoom : 3) | |
.zoomRange(undefined != this.options.zoom_range ? this.options.zoom_range : [3, 9]) | |
.add(po.interact()); | |
this.map.add(po.image() | |
.url(po.url("http://{S}tile.cloudmade.com" | |
+ "/1a1b06b230af4efdbb989ea99e9841af" | |
+ "/998/256/{Z}/{X}/{Y}.png") | |
.hosts(["a.", "b.", "c.", ""]))); | |
this.map.add(po.compass() | |
.pan("none")); | |
this.d3layer = d3.select("#"+this.options.container+" svg").insert("svg:g", ".compass"); | |
this.points = []; | |
this.arcs = []; | |
}; | |
Map.prototype.addGreatArc = function(source, target) { | |
var that = this; | |
var path = function(arc) { | |
var scale = Math.pow(2, that.map.zoom()) * 256; | |
var lp = that.map.locationPoint({lat:0, lon:0}); | |
var projection = d3.geo.mercator().scale(scale).translate([lp.x, lp.y]); | |
// check the arc to prevent some display bugs | |
var sanitized = { | |
type : "MultiLineString", | |
coordinates : [] | |
}; | |
var coords = [arc.coordinates[0]]; | |
var s1, s2 = 0; | |
for (var i=1 ; i<arc.coordinates.length ; i++) { | |
if (Math.abs(arc.coordinates[i][0] - arc.coordinates[i-1][0]) > 180) { | |
sanitized.coordinates.push(coords); | |
coords = []; | |
} | |
coords.push(arc.coordinates[i]); | |
} | |
sanitized.coordinates.push(coords); | |
return d3.geo.path().projection(projection)(sanitized); | |
}; | |
var id = ("arc_" + source[0] + "_" + source[1] + "_" + target[0] + "_" + target[1]).replace(/[^0-9a-z_]/g, ''); | |
this.arcs.push({ | |
id: id, | |
source: source, | |
target: target | |
}); | |
// optionnaly trim the arcs array | |
if (undefined != this.options.arcs_limit && this.arcs.length >= this.options.arcs_limit) { | |
this.arcs.shift(); | |
} | |
var arc = d3.geo.greatArc().precision(1); | |
var elements = this.d3layer.selectAll("path.great_arc") | |
.data(this.arcs, function(d) { return d.id; }); | |
elements.enter().append("path") | |
.attr("class", "great_arc") | |
.attr("d", function(d) { return path(arc(d)); }); | |
elements.exit().remove(); | |
// interactions | |
this.map.on("move", function() { | |
that.d3layer.selectAll(".great_arc").attr("d", function(d) { return path(arc(d)); }); | |
}); | |
this.map.on("resize", function() { | |
that.d3layer.selectAll(".great_arc").attr("d", function(d) { return path(arc(d)); }); | |
}); | |
}; | |
// from polymaps to d3 | |
// https://gist.github.com/899670 | |
Map.prototype.addPoint = function(longitude, latitude) { | |
var that = this; | |
var transform = function(d) { | |
var td = that.map.locationPoint({lon: d.longitude, lat: d.latitude}); | |
return "translate(" + td.x + "," + td.y + ")"; | |
}; | |
var id = ("mark_" + longitude + "_" + latitude).replace(/[^0-9a-z_]/g, ''); | |
this.points.push({id: id, longitude: longitude, latitude: latitude}); | |
// optionnaly trim the points array | |
if (undefined != this.options.points_limit && this.points.length >= this.options.points_limit) { | |
this.points.shift(); | |
} | |
// Add an svg:g for each station. | |
var markers = this.d3layer.selectAll(".marker") | |
.data(this.points, function(d) { return d.id; }); | |
markers.enter().append("circle") | |
.attr("class", "marker") | |
.attr("transform", transform) | |
.attr("r", 4.5); | |
markers.exit().transition() | |
.duration(200) | |
.attr("r", 0) | |
.remove(); | |
// interactions | |
this.map.on("move", function() { | |
that.d3layer.selectAll(".marker").attr("transform", transform); | |
}); | |
this.map.on("resize", function() { | |
that.d3layer.selectAll(".marker").attr("transform", transform); | |
}); | |
return [longitude, latitude]; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment