Skip to content

Instantly share code, notes, and snippets.

@mbostock
Forked from mbostock/.block
Last active September 11, 2018 09:45
Show Gist options
  • Select an option

  • Save mbostock/4136647 to your computer and use it in GitHub Desktop.

Select an option

Save mbostock/4136647 to your computer and use it in GitHub Desktop.
U.S. TopoJSON

A demo of TopoJSON using a single file that contains county, state and country boundaries. This example uses topojson.mesh to extract separating lines between states and counties from the geometry collections.

function albersUsa() {
var lower48 = d3.geo.albers().rotate([96, 0]).center([0, 38]).parallels([29.5, 45.5]),
alaska = d3.geo.albers().rotate([160, 0, -35]).center([45, 44]).parallels([55, 65]),
hawaii = d3.geo.albers().rotate([160, 0]).center([0, 20]).parallels([8, 18]);
function albersUsa(coordinates) {
return projection(coordinates)(coordinates);
}
function projection(point) {
var lon = point[0], lat = point[1];
return lat > 50 ? alaska : lon < -140 ? hawaii : lower48;
}
albersUsa.point = function(coordinates, context) {
return projection(coordinates).point(coordinates, context);
};
albersUsa.line = function(coordinates, context) {
return projection(coordinates[0]).line(coordinates, context);
};
albersUsa.polygon = function(coordinates, context) {
return projection(coordinates[0][0]).polygon(coordinates, context);
};
albersUsa.scale = function(x) {
if (!arguments.length) return lower48.scale();
lower48.scale(x);
alaska.scale(x * .35);
hawaii.scale(x);
return albersUsa.translate(lower48.translate());
};
albersUsa.translate = function(x) {
var k = lower48.scale();
if (!arguments.length) {
x = lower48.translate();
return [x[0] - .007 * k, x[1] - .007 * k];
}
lower48.translate([x[0] + .0075 * k, x[1] + .0065 * k]);
alaska.translate([x[0] - .307 * k, x[1] + .187 * k]);
hawaii.translate([x[0] - .206 * k, x[1] + .196 * k]);
return albersUsa;
};
return albersUsa.scale(1056).translate([400, 250]);
}
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body,
svg {
height: 100%;
margin: 0;
width: 100%;
float: left;
}
path {
fill: none;
stroke-linejoin: round;
}
.land-glow {
fill: #000;
fill-opacity: .1;
filter: url(#glow);
}
.land-fill {
fill: #fff;
}
.state-boundary {
stroke: #ccc;
stroke-width: .70px;
}
.land-fill,
.county-boundary {
stroke: #ccc;
stroke-width: .35px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v0.min.js"></script>
<script src="albers-usa.js"></script>
<script>
var width = 800,
height = 500;
var projection = albersUsa();
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("body").append("svg")
.attr("viewBox", "0 0 " + width + " " + height)
.attr("width", width)
.attr("height", height);
svg.append("filter")
.attr("id", "glow")
.append("feGaussianBlur")
.attr("stdDeviation", 5);
d3.json("../4090846/us.json", function(error, us) {
svg.append("path") // translucent outer glow
.datum(topojson.object(us, us.objects.land))
.attr("d", path)
.attr("class", "land-glow");
svg.append("path") // solid white fill
.datum(topojson.object(us, us.objects.land))
.attr("d", path)
.attr("class", "land-fill");
svg.append("path") // thin grey stroke for internal county boundaries
.datum(topojson.mesh(us, us.objects.counties, function(a, b) { return a.id !== b.id && (a.id / 1000 | 0) === (b.id / 1000 | 0); }))
.attr("d", path)
.attr("class", "county-boundary");
svg.append("path") // thick grey stroke for internal state boundaries
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a.id !== b.id; }))
.attr("d", path)
.attr("class", "state-boundary");
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment