D3.js + Google Maps - Vietnam: area, population and population density in 2011 by province
by Kieran Dang
HTML
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=visualization,places,geometry&key=AIzaSyDEs_f9851pMMMKuusSpwovQjoBHVkOk5E&language=vi"></script>
<div id="wrapper">
<div class="scatterplot-wrapper"></div>
<div class="legend-wrapper">
<h1>Population density</h1>
<div class="index-level-bar">
<div class="bar-legend"></div>
<div class="bar-label">Lower denisty</div>
<div class="bar-label second">Higher denisty</div>
<div style="clear: both;"></div>
</div>
</div>
<div id="info">
<div id="header-info">
<span>Area, population and population density in 2011 by province (https://www.gso.gov.vn)</span>
<table id="feature-info">
<tbody>
<tr>
<th class="name" style="width:25%;">Name</th>
<th class="population" style="width:20%;">Population</th>
<th class="area" style="width:15%;">Area</th>
<th class="density" style="width:15%;">Density</th>
<th class="capital" style="width:25%;">Capital</th>
</tr>
</tbody>
</table>
</div>
<div id="loading" class="hidden">
<a class="fa fa-spinner"></a>
</div>
</div>
<div id="map-canvas"></div>
</div>
CSS
#wrapper {
padding-top: 15px;
}
.bar-label {
float: left;
margin-top: 5px;
line-height: 12px;
font-size: 12px;
font-family: 'Helvetica';
}
.bar-label.second {
float: right;
}
table {
display: table;
border-collapse: separate;
border-spacing: 2px;
border-color: grey;
padding: 0px;
}
th {
font-size: 18px;
font-weight: bold;
text-align: left;
}
th {
font-size: 16px;
font-family: sans-serif;
font-weight: normal;
text-align: left;
}
th.name {
color: #E7BA52;
}
th.area {
color: #FC9E27;
}
th.population {
color: #3A7FA3;
}
th.density {
color: #B5CF6B;
}
th.capital {
color: #D6616B;
}
th,
td {
color: #555;
}
.h2,
h2 {
font-size: 30px;
}
.h1,
.h2,
.h3,
h1,
h2,
h3 {
margin-top: 20px;
margin-bottom: 10px;
color: #555;
}
.scatterplot-wrapper {
position: fixed;
z-index: 2;
left: 15px;
bottom: 300px;
width: 270px;
text-align: center;
}
.axis path,
.axis line {
fill: none;
stroke-width: 1px;
stroke: #e7e7e7;
stroke-opacity: .5;
shape-rendering: crispEdges;
}
.axis text {
line-height: 12px;
font-size: 12px;
font-family: 'Helvetica';
fill: #666;
}
.label {
line-height: 12px;
font-size: 12px;
font-family: 'Helvetica';
}
.scatterplot-wrapper circle {
fill-opacity: .75;
}
.scatterplot-wrapper circle:hover {
fill-opacity: 1;
}
.bubble.highlight {
stroke: #3A7FA3;
fill-opacity: .75;
}
.legend-wrapper {
position: fixed;
z-index: 2;
left: 15px;
bottom: 150px;
width: 270px;
text-align: center;
}
.legend-wrapper h1 {
font: 22px 'oswaldregular';
}
#map-canvas {
height: 600px;
width: 900px;
margin-left: 290px;
}
#info {
height: 90px;
}
#header-info {
margin-left: 290px;
}
#feature-info {
width: 650px;
}
#loading {
width: 50px;
margin: 0 auto;
}
.states {
fill: #ccc;
stroke: #fff;
stroke-linejoin: round;
}
.feature,
.legend {
cursor: pointer;
}
/* On mouse hover, lighten state color */
path:hover {
fill-opacity:...
JavaScript
if (!google.maps.Polygon.prototype.getBounds) {
google.maps.Polygon.prototype.getBounds = function(latLng) {
var bounds = new google.maps.LatLngBounds();
var paths = this.getPaths();
var path;
for (var p = 0; p < paths.getLength(); p++) {
path = paths.getAt(p);
for (var i = 0; i < path.getLength(); i++) {
bounds.extend(path.getAt(i));
}
}
return bounds;
}
}
if (!google.maps.Polyline.prototype.getBounds) {
google.maps.Polyline.prototype.getBounds = function(latLng) {
var bounds = new google.maps.LatLngBounds();
var path = this.getPath();
for (var i = 0; i < path.getLength(); i++) {
bounds.extend(path.getAt(i));
}
return bounds;
}
}
var _gp = {
map: null,
infoWindow: new google.maps.InfoWindow,
// Strict bounds, by Geocoder (sw, ne)
/*
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address' : 'Viet Nam'
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var viewport = results[0].geometry.viewport;
console.log(viewport);
}
});
*/
strictBounds: new google.maps.LatLngBounds(
new google.maps.LatLng(8.412729, 102.14441),
new google.maps.LatLng(23.393395, 109.468977)),
rangeColor: function(className) {
var colors = {
'q0-9': '#F7FCF0',
'q1-9': '#E0F3DB',
'q2-9': '#CCEBC5',
'q3-9': '#A8DDB5',
'q4-9': '#BBF3FF',
'q5-9': '#A1D9FF',
'q6-9': '#87BFFF',
'q7-9': '#6EA6E7',
'q8-9': '#558DCE'
};
return colors[className];
},
initialize: function(options) {
var self = this;
self.tooltip = d3.select('body').append('div')
.attr('class', 'tooltip')
.style('opacity', 0);
self.quantiles = d3.scale.quantile()
.range(d3.range(9).map(function(i) {
return 'q' + i + '-9';
}));
var legend = d3.select('.bar-legend').append('svg')
.attr('width', 240)
...