Last active
August 29, 2015 14:17
-
-
Save mbertrand/34abee79acba54251801 to your computer and use it in GitHub Desktop.
D3.js + Google Maps: USGS Earthquake data
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
body, html, #map { | |
font-family: Arial, Helvetica, sans-serif; | |
margin: 0; | |
width: 100%; | |
height: 100%; | |
} | |
.SvgOverlay { | |
position: relative; | |
width: 100%; | |
height: 100%; | |
} | |
.SvgOverlay svg { | |
position: absolute; | |
top: -4000px; | |
left: -4000px; | |
width: 8000px; | |
height: 8000px; | |
} | |
.SvgOverlay path { | |
fill: #000; | |
fill-opacity: .2; | |
stroke: #fff; | |
stroke-width: 1.5px; | |
} | |
.highlight{ | |
fill: red; | |
fill-opacity: .6; | |
stroke: yellow; | |
stroke-width: 1.5px; | |
} | |
.SvgOverlay path:hover { | |
fill: red; | |
fill-opacity: .7; | |
} | |
div#quake-pop-up { | |
display: none; | |
position:absolute; | |
color: white; | |
font-size: 14px; | |
background: rgba(0,0,0,0.5); | |
padding: 5px 10px 5px 10px; | |
-moz-border-radius: 5px 5px; | |
border-radius: 5px 5px; | |
z-index: 99; | |
} | |
div#quake-pop-up-title { | |
font-size: 15px; | |
width:300px; | |
margin-bottom: 4px; | |
font-weight: bolder; | |
} | |
div#quake-pop-up-content { | |
font-size: 14px; | |
} | |
div#quake-pop-desc { | |
margin-left: 10px; | |
width: 300px; | |
color: white; | |
} | |
div#quake-pop-img { | |
font-size: 30px; | |
font-weight: bolder; | |
color: white; | |
} | |
.hist { | |
position: absolute; | |
right:0; | |
bottom:0; | |
z-index: 9000; | |
color: white; | |
font-size: 10px; | |
background: rgba(250,250,250,0.7); | |
padding: 5px 10px 5px 10px; | |
-moz-border-radius: 5px 5px; | |
border-radius: 5px 5px; | |
z-index: 95; | |
} | |
.bar rect { | |
fill: blue; | |
shape-rendering: crispEdges; | |
} | |
.bar rect:hover { | |
fill: red; | |
} | |
.bar text { | |
fill: #000; | |
font-size: 10px; | |
} | |
.axis path, .axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} |
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
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> | |
<meta name="apple-mobile-web-app-capable" content="yes"> | |
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script> | |
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script> | |
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/d3/2.10.0/d3.v2.min.js"></script> | |
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> | |
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/themes/blitzer/jquery-ui.css" type="text/css"> | |
<link rel="stylesheet" href="gmap_d3.css" type="text/css"> | |
<script> | |
$(function () { | |
var $map = $("#map"); | |
var map = new google.maps.Map($map[0], { | |
zoom: 2, | |
mapTypeId: google.maps.MapTypeId.ROADMAP, | |
center: {lat:33.045579573575154, lng:-96.97189523828126} | |
}); | |
var overlay = new google.maps.OverlayView(); | |
d3.json("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson", function (collection) { | |
overlay.onAdd = function () { | |
var layer = d3.select(this.getPanes().overlayMouseTarget).append("div").attr("class", "SvgOverlay"); | |
var svg = layer.append("svg"); | |
var quakes = svg.append("g").attr("class", "Quakes"); | |
overlay.draw = function () { | |
var markerOverlay = this; | |
var overlayProjection = markerOverlay.getProjection(); | |
// Turn the overlay projection into a d3 projection | |
var googleMapProjection = function (coordinates) { | |
var googleCoordinates = new google.maps.LatLng(coordinates[1], coordinates[0]); | |
var pixelCoordinates = overlayProjection.fromLatLngToDivPixel(googleCoordinates); | |
return [pixelCoordinates.x + 4000, pixelCoordinates.y + 4000]; | |
} | |
path = d3.geo.path().projection(googleMapProjection); | |
quakes.selectAll("path") | |
.data(collection.features) | |
.attr("d", path.pointRadius(function (d) { | |
return Math.sqrt((Math.exp(parseFloat(d.properties.mag)))); | |
})) | |
.attr("class","myPathClass") | |
.enter().append("svg:path") | |
.attr("d", path.pointRadius(function (d) { | |
return Math.sqrt((Math.exp(parseFloat(d.properties.mag)))); | |
})) | |
.on("mouseover", function (d) { | |
var mousePosition = d3.svg.mouse(this); | |
var format = d3.time.format("%Y-%m-%d %HH:%MM:%SS"); | |
$("#quake-pop-up").fadeOut(100, function () { | |
// Popup content | |
$("#quake-pop-up-title").html(format(new Date(parseInt(d.properties.time)))); | |
$("#quake-pop-img").html(d.properties.mag); | |
$("#quake-pop-desc").html(d.properties.place); | |
$("#quake-pop-up").css({ | |
"right": 0, | |
"top": 50 | |
}); | |
$("#quake-pop-up").fadeIn(100); | |
}); | |
}). | |
on("mouseout", function () { | |
//$("#quake-pop-up").fadeOut(50); | |
}); | |
}; | |
createHistogram(collection, quakes); | |
}; | |
overlay.setMap(map); | |
}); | |
}); | |
function createHistogram(dataset, svgclass) { | |
var formatCount = d3.format(",.0f"); | |
var values = dataset.features.map(function (d) {return d.properties.mag;}); | |
var margin = {top: 10, right: 30, bottom: 40, left: 30}, | |
width = 500 - margin.left - margin.right, | |
height = 200 - margin.top - margin.bottom; | |
var x = d3.scale.linear() | |
.domain([0, 10]) | |
.range([0, width]); | |
// Generate a histogram using twenty uniformly-spaced bins. | |
var data = d3.layout.histogram() | |
.bins(x.ticks(10)) | |
(values); | |
var y = d3.scale.linear() | |
.domain([0, d3.max(data, function(d) { return d.y; })]) | |
.range([height, 0]); | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.orient("bottom") | |
var svgbar = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.attr("class", "hist") | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
svgbar.append("text") | |
.attr("font-size", "14px") | |
.attr("font-weight", "bold") | |
.attr("y", 5) | |
.attr("x", 300) | |
.attr("text-anchor", "middle") | |
.text("Earthquakes over the past 30 days"); | |
var bar = svgbar.selectAll(".bar") | |
.data(data) | |
.enter().append("g") | |
.attr("class", "bar") | |
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + y(d.y) + ")"; }) | |
.on("mouseover", function(d, i) { | |
d3.selectAll(".SvgOverlay path").filter(function(e) { | |
return d3.min(d) <= e.properties.mag && e.properties.mag < d3.max(d) | |
}).style({'fill': 'red', 'stroke': 'yellow'}) | |
}) | |
.on("mouseout", function(d, i) { | |
d3.selectAll(".SvgOverlay path").filter(function(e) { | |
return d3.min(d) <= e.properties.mag && e.properties.mag < d3.max(d) | |
}).style({'fill': '', 'stroke': ''}); | |
}); | |
bar.append("rect") | |
.attr("x", 1) | |
.attr("width", x(data[0].dx) - 1) | |
.attr("height", function(d) { return height - y(d.y); }); | |
bar.append("text") | |
.attr("dy", ".75em") | |
.attr("y", -10) | |
.attr("x", x(data[0].dx) / 2) | |
.attr("text-anchor", "middle") | |
.text(function(d) { return formatCount(d.y); }); | |
svgbar.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis) | |
.append("text") | |
.attr("font-size", "12px") | |
.attr("y", 30) | |
.attr("x", 200) | |
.attr("text-anchor", "middle") | |
.text("Magnitude");; | |
return svgbar; | |
} | |
</script> | |
</head> | |
<body > | |
<div id="map"></div> | |
<div id="quake-pop-up"> | |
<div id="quake-pop-up-title"></div> | |
<div id="quake-pop-up-content"> | |
<table> <tr> | |
<td><div id="quake-pop-img"></div></td> | |
<td><div id="quake-pop-desc"></div></td> | |
</tr> </table> | |
</div> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment