You can recreate the data by running make in the cloned directory.
The key files are: MetroArea.csv us.json and ACS_12_5YR_B01003_with_ann.csv
See the Makefile for how they were created or downloaded.
xxxxxxxxxx
<meta charset="utf-8">
<style>
.land {
fill: #ddd;
}
.border {
fill: none;
stroke: #fff;
stroke-linejoin: round;
stroke-linecap: round;
}
.bubble {
fill: brown;
fill-opacity: .5;
stroke: #fff;
stroke-width: .5px;
}
.bubble :hover {
stroke: #000;
}
.legend circle {
fill: none;
stroke: #ccc;
}
.legend text {
fill: #777;
font: 10px sans-serif;
text-anchor: middle;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/queue.v1.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script>
var width = 960,
height = 600;
var path = d3.geo.path()
.projection(null);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var radius = d3.scale.sqrt()
.domain([0, 1e6])
.range([0, 15]);
var formatNumber = d3.format(",.0f");
var metroAreaByID = d3.map();
var populationByMetroArea = d3.map();
queue(1)
.defer(d3.csv,"MetroArea.csv", function(d) {
if(d["Metropolitan Division Title"]) {
metroAreaByID.set( d["FIPS State Code"] + d["FIPS County Code"],{id: d["Metro Division Code"], name: d["Metropolitan Division Title"]});
} else {
metroAreaByID.set( d["FIPS State Code"] + d["FIPS County Code"],{id: d["CBSA Code"], name: d["CBSA Title"]});
}
})
.defer(d3.csv,"ACS_12_5YR_B01003_with_ann.csv", function(d) {
if(metroAreaByID.has(d["geoid"])) {
var metroName = metroAreaByID.get(d["geoid"]).name;
if(populationByMetroArea.has(metroAreaByID.get(d["geoid"]).id)) {
var current = populationByMetroArea.get(metroAreaByID.get(d["geoid"]).id);
if (Number(d.population) > current.maxpop){
populationByMetroArea.set(metroAreaByID.get(d["geoid"]).id,{ name: metroName, population: current.population + Number(d.population), maxpop: Number(d.population), id: d.geoid });
} else {
populationByMetroArea.set(metroAreaByID.get(d["geoid"]).id,{ name: current.name, population: current.population + Number(d.population), maxpop: current.population, id: current.id });
}
} else {
populationByMetroArea.set(metroAreaByID.get(d["geoid"]).id,{ name: metroName, population: Number(d.population), maxpop: Number(d.population), id: d.geoid });
}
} else {
populationByMetroArea.set(d.geoid,{ name: d.name, population: Number(d.population), maxpop: Number(d.population), id: d.geoid});
}
})
.defer(d3.json,"us.json", function(error, us) {
if (error) return console.error(error);
svg.append("path")
.datum(topojson.feature(us, us.objects.nation))
.attr("class", "land")
.attr("d", path);
svg.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
.attr("class", "border border--state")
.attr("d", path);
svg.append("g")
.attr("class", "bubble")
.selectAll("circle")
.data(topojson.feature(us, us.objects.counties).features
.sort(function(a, b) { return b.properties.population - a.properties.population; }))
.enter().append("circle")
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
.attr("r", function(d) {
if(populationByMetroArea.has(d.id)) {
return radius(populationByMetroArea.get(d.id).population);
} else {
if(d.id === populationByMetroArea.get(metroAreaByID.get(d.id).id).id) {
return radius(populationByMetroArea.get(metroAreaByID.get(d.id).id).population);
} else {
return 0;
}
}
})
.append("title")
.text(function(d) {
if(populationByMetroArea.has(d.id)) {
return populationByMetroArea.get(d.id).name + formatNumber(populationByMetroArea.get(d.id).population);
} else {
if(d.id === populationByMetroArea.get(metroAreaByID.get(d.id).id).id) {
return populationByMetroArea.get(metroAreaByID.get(d.id).id).name + "\nPopulation " + formatNumber(populationByMetroArea.get(metroAreaByID.get(d.id).id).population);
} else {
return "";
}
}
});
});
var legend = svg.append("g")
.attr("class", "legend")
.attr("transform", "translate(" + (width - 50) + "," + (height - 20) + ")")
.selectAll("g")
.data([1e6, 3e6, 6e6])
.enter().append("g");
legend.append("circle")
.attr("cy", function(d) { return -radius(d); })
.attr("r", radius);
legend.append("text")
.attr("y", function(d) { return -2 * radius(d); })
.attr("dy", "1.3em")
.text(d3.format(".1s"));
</script>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/queue.v1.min.js to a secure url
Modified http://d3js.org/topojson.v1.min.js to a secure url
https://d3js.org/d3.v3.min.js
https://d3js.org/queue.v1.min.js
https://d3js.org/topojson.v1.min.js