This is a simple setup of Leaflet (via Mapbox) with d3 to show dots on a map. This can serve as a base for many interesting geographically based visualizations
Nice overview of using d3 + Leaflet. I found this slightly simpler to use than Mike's classic post.
Built with blockbuilder.org
forked from enjalot's block: dots on a map: setup
forked from arimocro's block: dots on a map: setup
forked from abelande's block: dots on a map - Velo'v
xxxxxxxxxx
<html>
<head>
<title>Many many many Points with D3 and leaflet</title>
<meta charset="utf-8">
<style>
body {
font-size: 12px;
}
text {
fill: white;
}
svg {
position: relative;
}
path {
fill: turquoise;
fill-opacity: 1;
}
path:hover {
fill: brown;
fill-opacity: .7;
}
#map {
position: absolute;
height: 100%;
width: 100%;
background-color: #333;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="tooltip">
<svg xmlns="https://www.w3.org/2000/svg" width="100px" height="100px" />
</div>
<link rel="stylesheet" href="https://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.2/leaflet.min.js"></script>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
d3.json('https://gist.githubusercontent.com/abelande/be84801ec76fa3b63809d07de2276d70/raw/d43c90bc628acf2bb9b0a912418960420a585b4b/data.json', function(error, stations) {
var geoData = stations;
var cscale = d3.scale.linear().domain([1, 3]).range(["#ff0000", "#ff6a00", "#ffd800", "#b6ff00", "#00ffff", "#0094ff"]); //"#00FF00","#FFA500"
var leafletMap = L.map('map').setView([45.7531152, 4.827906], 12);
//add base tiles
L.tileLayer("https://{s}.sm.mapstack.stamen.com/(toner-lite,$fff[difference],$fff[@23],$fff[hsl-saturation@20])/{z}/{x}/{y}.png").addTo(leafletMap);
var svg = d3.select(leafletMap.getPanes().overlayPane).append("svg");
var g = svg.append("g").attr("class", "leaflet-zoom-hide");
// Use Leaflet to implement a D3 geometric transformation.
function projectPoint(x, y) {
var point = leafletMap.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
var transform = d3.geo.transform({
point: projectPoint
});
var path = d3.geo.path().projection(transform);
leafletMap.on('moveend', mapmove);
redrawSubset(geoData.features)
function redrawSubset(subset) {
path.pointRadius(3); // * scale);
var bounds = path.bounds({
type: "FeatureCollection",
features: subset
});
var topLeft = bounds[0];
var bottomRight = bounds[1];
svg.attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");
g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
var start = new Date();
var points = g.selectAll("path")
.data(subset, function(d) {
return d.geometry.coordinates;
});
points.enter().append("path");
points.attr("d", path).attr("class", "points");
points.style("fill-opacity", function(d) {
if (d.group) {
return (d.group * 0.1) + 0.2;
}
});
}
function mapmove(e) {
//remove all points
d3.selectAll(".points").remove();
redrawSubset(geoData.features);
}
});
</script>
</body>
</html>
Modified http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js to a secure url
Modified http://d3js.org/d3.v3.min.js to a secure url
https://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js
https://d3js.org/d3.v3.min.js