Skip to content

Instantly share code, notes, and snippets.

@enjalot
Last active November 24, 2015 00:22
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 enjalot/1919bd8c2f574caa17ba to your computer and use it in GitHub Desktop.
Save enjalot/1919bd8c2f574caa17ba to your computer and use it in GitHub Desktop.
State Grid Minimap

Adapting the state grid for use as an overview/minimap. When you zoom in on a state the counties for that state are rendered. This technique could be used to render subsets of larget datasets at the appropriate zoom level.

Map zooming from http://bl.ocks.org/mbostock/2206590

forked from mbostock's block: State Grid

<!DOCTYPE html>
<meta charset="utf-8">
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
#state-grid {
position:absolute;
top: 0;
left: 0;
}
#map {
position: absolute;
width: 100%;
height: 100%;
}
.state {
cursor: pointer;
}
.state rect {
fill: #dedede;
fill-opacity: 0.4;
rx: 3;
ry: 3;
}
.selected rect {
fill: steelblue;
}
.state text {
font: 12px sans-serif;
text-anchor: middle;
}
.state-boundary {
fill: none;
stroke: #111;
}
.county {
fill: #d6fef1;
stroke: #111;
}
</style>
<svg id="map"></svg>
<svg id="state-grid" width=400 height=200></svg>
<script id="grid" type="text/plain">
ME
WI VT NH
WA ID MT ND MN IL MI NY MA
OR NV WY SD IA IN OH PA NJ CT RI
CA UT CO NE MO KY WV VA MD DE
AZ NM KS AR TN NC SC
OK LA MS AL GA
HI AK TX FL
</script>
<script>
var states = [];
d3.select("#grid").text().split("\n").forEach(function(line, i) {
var re = /\w+/g, m;
while (m = re.exec(line)) states.push({
name: m[0],
x: m.index / 3,
y: i
});
});
var minisvg = d3.select("#state-grid");
var miniwidth = 400;
var miniheight = 200;
var mapsvg = d3.select("#map").append("g");
var mapwidth = 960;
var mapheight = 500;
var scale0 = 1000;
var centered;
var selected;
var allCounties = []
var zoom = d3.behavior.zoom()
.translate([mapwidth / 2, mapheight / 2])
.scale(scale0)
.scaleExtent([scale0, 10 * scale0])
.on("zoom", zoomed);
var projection = d3.geo.albersUsa()
.scale(scale0)
.translate([mapwidth / 2, mapheight / 2]);
var path = d3.geo.path()
.projection(projection);
function zoomed() {
projection
.translate(zoom.translate())
.scale(zoom.scale());
mapsvg.selectAll("path")
.attr("d", path);
mapsvg.selectAll("circle.city")
.attr({
cx: getX,
cy: getY
})
}
mapsvg.call(zoom)
function clicked(d) {
var x, y, k;
console.log("clicked", d)
if (d && centered !== d) {
var centroid = path.centroid(d);
x = centroid[0];
y = centroid[1];
k = 4;
centered = d;
} else {
x = mapwidth / 2;
y = mapheight / 2;
k = 1;
centered = null;
}
mapsvg.selectAll("path.state-boundary")
.classed("active", centered && function(d) { return d === centered; });
mapsvg.transition()
.duration(750)
.attr("transform", "translate(" + mapwidth / 2 + "," + mapheight / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
.style("stroke-width", 1.5 / k + "px");
mapsvg.selectAll("path.county")
.transition().duration(300)
.style("opacity", 0)
.remove();
var counties = [];
allCounties.forEach(function(c) {
var sid = d.id+"";
var cid = c.id+"";
if(cid.slice(0,sid.length) === sid && cid.length - sid.length == 3) counties.push(c);
})
console.log("counties", counties)
var countyPaths = mapsvg
.selectAll("path.county")
.data(counties)
countyPaths
.enter().append("path").classed("county", true)
.style("opacity", 0)
countyPaths.attr("d", path)
.transition()
.duration(800)
.style("opacity", 0.6)
}
var gridWidth = d3.max(states, function(d) { return d.x; }) + 1;
var gridHeight = d3.max(states, function(d) { return d.y; }) + 1;
var cellSize = 25;
var state = minisvg.append("g")
.attr("transform", "translate(" + miniwidth / 2 + "," + miniheight / 2 + ")scale(1)")
.selectAll(".state")
.data(states)
.enter().append("g")
.classed("state", true)
.attr("transform", function(d) { return "translate(" + (d.x - gridWidth / 2) * cellSize + "," + (d.y - gridHeight / 2) * cellSize + ")"; });
state.append("rect")
.attr("x", -cellSize / 2)
.attr("y", -cellSize / 2)
.attr("width", cellSize - 2)
.attr("height", cellSize - 2);
state.append("text")
.attr("dy", ".35em")
.attr("dx", "-.1em")
.text(function(d) { return d.name; });
state.on("click", function(d) {
console.log("clicked", d)
var sel = d3.selectAll(".state-boundary").filter(function(a) { return a.properties.code === d.name})
var state = sel.data()[0]
console.log("state", state)
clicked(state);
if(d3.select(this).classed("selected")) {
d3.select(this).classed("selected", false)
} else {
minisvg.selectAll(".state").classed("selected", false)
d3.select(this).classed("selected", true)
}
});
d3.json("us-named.json", function(error, us) {
console.log("COUNTIES", topojson.feature(us, us.objects.counties).features);
allCounties = topojson.feature(us, us.objects.counties).features;
mapsvg
.selectAll("path")
.data(topojson.feature(us, us.objects.states).features)
.enter().append("path").classed("state-boundary", true)
.attr("d", path)
//visualize # of counties
})
</script>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment