Visualization bl.ocks link: /jaimeps/0ba238bd74c5c7e0876ab65c518efcfb/example/
Datasets:
Resources:
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.8/d3.min.js"></script>
<script src="https://d3js.org/d3-queue.v2.min.js"></script>
<style>
body, html {
width: 1300px;
height: 100%;
font: 16px Arial;
}
svg {
width:35%;
height:64%;
float: left;
border:1px solid darkblue;
}
circle.airbnb {
fill: #710606;
opacity: 0.6;
}
.axis {
font-family: arial;
font-size: 0.7em;
}
text {
fill: black;
stroke: none;
}
.title {
fill: black;
font: 16px Arial;
font-weight: bold;
}
.footnote{
fill: black;
stroke: none;
font-size: 10px;
}
.label {
font-size: 1.5em;
}
path {
fill: none;
stroke: black;
stroke-width: 2px;
}
.tick {
fill: none;
stroke: black;
}
circle {
opacity: 0.9;
stroke: none;
fill: #710606;
}
.line {
fill: none;
stroke: #4374DE;
stroke-width: 2px;
}
</style>
<script>
function draw(error, data) {
"use strict";
// important: First argument it expects is error
if (error) throw error;
/*
D3.js setup code
*/
var margin = {top: 150, right: 50, bottom: 50, left: 50},
width = 350 - margin.left,
height = 400 - margin.top;
var margin2 = 50,
width2 = 420 - margin2,
height2 = 420 - margin2;
var format = d3.time.format("%m/%d/%Y");
// create a projection properly scaled for SF
var projection = d3.geo.mercator();
// create a path to draw the neighborhoods
var path = d3.geo.path()
.projection(projection);
// create and append the map of SF neighborhoods
var map = d3.select('#map').selectAll('path')
.data(data[0].features)
.enter()
.append('path')
.attr('d', path)
.style('stroke', 'darkblue')
.style('stroke-width', 1);
// normalize neighborhood names
map.datum(function(d) {
var normalized = d.properties.name
.replace(/ /g, '_')
.replace(/\//g, '_');
d.properties.neighbourhood = normalized;
return d;
});
d3.select('#map').append("text")
.attr("y", 440)
.attr("x", 20)
.text("Bubble size: Current worldwide relative popularity (of 'Zika virus' searches on Google)")
.attr('class', 'footnote');
d3.select('#map').append('svg').append("rect")
.attr("y", 280)
.attr("x", 20)
.attr("width", 245)
.attr("height", 75)
.attr("fill", "aliceblue")
.attr("stroke", "black");
d3.select('#map').append("text")
.attr("y", 300)
.attr("x", 45)
.text("TRACKING THE SPREAD ")
.attr('class', 'title');
d3.select('#map').append("text")
.attr("y", 320)
.attr("x", 65)
.text("OF THE ZIKA VIRUS")
.attr('class', 'title');
d3.select('#map').append("text")
.attr("y", 340)
.attr("x", 30)
.text("THROUGH GOOGLE TRENDS")
.attr('class', 'title');
// add the neighborhood name as its class
map.attr('class', function(d) {
return d.properties.neighbourhood;
});
// find the min/max of listing per neighborhood
var listings_extent = d3.extent(d3.values(data[1]));
// append a bubble to each neighborhood
var bubbles = d3.select('#map').append("g")
.attr("class", "bubble")
.selectAll("circle")
.data(data[0].features)
.enter()
.append("circle")
.attr('class', 'airbnb');
// add the listing data to each neighborhood datum
bubbles.datum(function(d) {
d.count = data[1][d.properties.neighbourhood];
return d;
});
// scale each bubble with a sqrt scale
var radius = d3.scale.pow().exponent(.5)
.domain(listings_extent)
.range([0, 20]);
// transform each bubbles' attributes according to the data
bubbles
.attr("cx", function(d) { return path.centroid(d.geometry)[0]; })
.attr("cy", function(d) { return path.centroid(d.geometry)[1]; })
.attr("r", function(d) { return radius(d.count); });
// initialize the Jamaica as the default country
var field = "Jamaica";
// maximum reviews
var max_y = d3.max(data[2], function(d) {
var max = 0;
d3.values(d).forEach(function(i) {
if (+i && (+i > max)) {
max = +i;
}
});
return max;
});
// Create y-axis scale mapping price -> pixels
var measure_scale = d3.scale.linear()
.range([height2, 60])
.domain([0, max_y]);
// Create D3 axis object from measure_scale for the y-axis
var measure_axis = d3.svg.axis()
.scale(measure_scale)
.orient("right");
// Append SVG to page corresponding to the D3 y-axis
d3.select('#chart').append('g')
.attr('class', 'y axis')
.attr("transform", "translate(" + width2 + " , -15)")
.call(measure_axis);
// add label to y-axis
d3.select(".y.axis")
.append("text")
.attr('class', 'label')
.text("Searches of 'Zika virus' on Google*")
.attr("transform", "translate(45,70) rotate(90)");
d3.select('#chart').append("text")
.attr("y", 440)
.attr("x", 10)
.text("* Index of country's relative popularity of the topic in the search engine")
.attr('class', 'footnote');
d3.select('#chart').append("text")
.attr("y", 420)
.attr("x", 40)
.text("Source: Google Trends")
.attr('class', 'footnote');
// create a function to draw the timeseries for each neighborhood
var drawChart = function(field) {
// remove the previous chart
d3.select('#chart').select('.x.axis').remove();
d3.select('#chart').select('path').remove();
// update the title
d3.select('#heading')
.text(field.replace(/_/g, ' '));
// remove missing values
var neigh_data = data[2].filter(function(d) {
return d[field];
});
// get min/max dates
var time_extent = d3.extent(neigh_data, function(d){
return format.parse(d['timestamp']);
});
// Create x-axis scale mapping dates -> pixels
var time_scale = d3.time.scale()
.range([0, width2 - margin2])
.domain(time_extent);
// Create D3 axis object from time_scale for the x-axis
var time_axis = d3.svg.axis()
.scale(time_scale)
.tickFormat(d3.time.format("%b '%y"));
// Append SVG to page corresponding to the D3 x-axis
d3.select('#chart').append('g')
.attr('class', 'x axis')
.attr('transform', "translate(" + margin2 + ',' + (height2 - 15) + ")")
.call(time_axis)
.selectAll("text")
.attr("y", 0)
.attr("x", 9)
.attr("dy", ".35em")
.attr("transform", "rotate(90)")
.style("text-anchor", "start");
// define the values to map for x and y position of the line
var line = d3.svg.line()
.x(function(d) { return time_scale(format.parse(d['timestamp'])); })
.y(function(d) { return measure_scale(+d[field]); });
// append a SVG path that corresponds to the line chart
d3.select('#chart').append("path")
.datum(neigh_data)
.attr("class", "line")
.attr("d", line)
.attr('transform', 'translate(' + margin2 + ', -15)');
d3.select('#rect').selectAll('path')
.attr("width", 200)
.attr("height", 300);
};
drawChart(field);
// create a callback for the neighborhood hover
var mover = function(d) {
var neigh = d.properties.neighbourhood;
d3.select('#map path.' + neigh).style('fill', '#ACBEE6');
drawChart(neigh);
};
// create a callback for the neighborhood hover
var mout = function(d) {
var neigh = d.properties.neighbourhood;
d3.select('path.' + neigh).style('fill', '#D0AD81');
}
// attach events to neighborhoods in map
map.on("mouseover", mover);
map.on("mouseout", mout);
// attach events to bubbles on map
bubbles.on('mouseover', mover);
bubbles.on('mouseout', mout);
}
</script>
</head>
<body>
<svg id="map"></svg>
<svg id="chart">
<text x="50%" y="30" id="heading" font-size="1.5em" text-anchor="middle" font-family="Arial">Brazil</text>
</svg>
<script>
// load data with queue
var url1 = "countries.geo.json"
var url2 = "bubbles.json";
var url3 = "time_series_zika.csv";
var q = d3_queue.queue(3)
.defer(d3.json, url1)
.defer(d3.json, url2)
.defer(d3.csv, url3)
.awaitAll(draw);
</script>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.8/d3.min.js
https://d3js.org/d3-queue.v2.min.js