Skip to content

Instantly share code, notes, and snippets.

@mimno
Last active November 8, 2016 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mimno/ca9c339ca9ab0987332918eefd33df55 to your computer and use it in GitHub Desktop.
Save mimno/ca9c339ca9ab0987332918eefd33df55 to your computer and use it in GitHub Desktop.
Clone of Financial Times dot map
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<style>
path { stroke: #555; fill: none; }
</style>
</head>
<body>
<svg></svg>
<script>
var stateIDs = [{ name: "Alabama", fips: "01", postal: "AL" },
{ name: "Alaska", fips: "02", postal: "AK" },
{ name: "Arizona", fips: "04", postal: "AZ" },
{ name: "Arkansas", fips: "05", postal: "AR" },
{ name: "California", fips: "06", postal: "CA" },
{ name: "Colorado", fips: "08", postal: "CO" },
{ name: "Connecticut", fips: "09", postal: "CT" },
{ name: "Delaware", fips: "10", postal: "DE" },
{ name: "District of Columbia", fips: "11", postal: "DC" },
{ name: "Florida", fips: "12", postal: "FL" },
{ name: "Georgia", fips: "13", postal: "GA" },
{ name: "Hawaii", fips: "15", postal: "HI" },
{ name: "Idaho", fips: "16", postal: "ID" },
{ name: "Illinois", fips: "17", postal: "IL" },
{ name: "Indiana", fips: "18", postal: "IN" },
{ name: "Iowa", fips: "19", postal: "IA" },
{ name: "Kansas", fips: "20", postal: "KS" },
{ name: "Kentucky", fips: "21", postal: "KY" },
{ name: "Louisiana", fips: "22", postal: "LA" },
{ name: "Maine", fips: "23", postal: "ME" },
{ name: "Maryland", fips: "24", postal: "MD" },
{ name: "Massachusetts", fips: "25", postal: "MA" },
{ name: "Michigan", fips: "26", postal: "MI" },
{ name: "Minnesota", fips: "27", postal: "MN" },
{ name: "Mississippi", fips: "28", postal: "MS" },
{ name: "Missouri", fips: "29", postal: "MO" },
{ name: "Montana", fips: "30", postal: "MT" },
{ name: "Nebraska", fips: "31", postal: "NE" },
{ name: "Nevada", fips: "32", postal: "NV" },
{ name: "New Hampshire", fips: "33", postal: "NH" },
{ name: "New Jersey", fips: "34", postal: "NJ" },
{ name: "New Mexico", fips: "35", postal: "NM" },
{ name: "New York", fips: "36", postal: "NY" },
{ name: "North Carolina", fips: "37", postal: "NC" },
{ name: "North Dakota", fips: "38", postal: "ND" },
{ name: "Ohio", fips: "39", postal: "OH" },
{ name: "Oklahoma", fips: "40", postal: "OK" },
{ name: "Oregon", fips: "41", postal: "OR" },
{ name: "Pennsylvania", fips: "42", postal: "PA" },
{ name: "Rhode Island", fips: "44", postal: "RI" },
{ name: "South Carolina", fips: "45", postal: "SC" },
{ name: "South Dakota", fips: "46", postal: "SD" },
{ name: "Tennessee", fips: "47", postal: "TN" },
{ name: "Texas", fips: "48", postal: "TX" },
{ name: "Utah", fips: "49", postal: "UT" },
{ name: "Vermont", fips: "50", postal: "VT" },
{ name: "Virginia", fips: "51", postal: "VA" },
{ name: "Washington", fips: "53", postal: "WA" },
{ name: "West Virginia", fips: "54", postal: "WV" },
{ name: "Wisconsin", fips: "55", postal: "WI" },
{ name: "Wyoming", fips: "56", postal: "WY" }];
var width = 950;
var height = 700;
var svg = d3.select("svg").attr("height", height).attr("width", width);
var circles;
var path = d3.geoPath();
var features, usJSON, geoFeatures, centroids;
var fipsMap = {};
function xForce(node, i) {
return centroids[ fipsMap[node.fips] ][0];
}
function yForce(node, i) {
return centroids[ fipsMap[node.fips] ][1];
}
var nodes = [];
stateIDs.forEach(function (state) {
state.name.toLowerCase().split("").forEach(function (letter) {
nodes.push({ fips: state.fips, letter: letter });
});
});
function isVowel(letter) {
return ["a", "e", "i", "o", "u", "y"].indexOf(letter) != -1;
}
d3.json("https://d3js.org/us-10m.v0.json", function(error, us) {
if (error) throw error;
usJSON = us;
us.objects.states.geometries.forEach(function (state, i) {
fipsMap[state.id] = i;
});
geoFeatures = topojson.feature(us, us.objects.states).features;
centroids = geoFeatures.map(path.centroid);
console.log(geoFeatures);
console.log(centroids);
svg.selectAll("path")
.data(geoFeatures)
.enter()
.append("path")
.attr("d", path);
// Run the simulation without displaying, based on http://bl.ocks.org/mbostock/6526445e2b44303eebf21da3b6627320
var simulation = d3.forceSimulation(nodes)
.force("x", d3.forceX(xForce))
.force("y", d3.forceY(yForce))
.force("collide", d3.forceCollide(4))
.stop();
// Run to convergence
for (var i = 0; i < 120; i++) {
simulation.tick();
}
circles = svg.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r", 3)
.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; })
.style("fill", function (d) { return isVowel(d.letter) ? "#f1a340" : "#998ec3"; });
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment