Last active
September 27, 2015 14:13
-
-
Save wilson428/da8c414874780bef3e89 to your computer and use it in GitHub Desktop.
Internal topoJSON borders used .mesh vs .merge
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
var root = this; | |
// create a new SVG element | |
var elasticSVG = function(selector, opts) { | |
opts = opts || {}; | |
// containing DOM element, which defaults to body | |
var parent = document.querySelectorAll(selector || "body"); | |
if (!parent || !parent.length) { | |
console.log("Couldn't find a parent for elasticSVG making the selector '" + selector + "'"); | |
return; | |
} | |
parent = parent[0]; | |
// you can specify a width if you like, or we'll snap to size of container | |
var base = { | |
width: typeof opts.width !== "undefined" ? opts.width : parent.clientWidth, | |
scale: 1 | |
}; | |
// we need to remember the original width for scaling purposes | |
base.original_width = base.width; | |
// you can either specify the height or the aspect ratio. If neither is specified, refaults to roughly the golden ratio | |
if (typeof opts.height !== "undefined") { | |
base.height = opts.height; | |
opts.aspect = base.height / base.width; | |
} else { | |
opts.aspect = typeof opts.aspect !== "undefined" ? opts.aspect : 0.618; | |
base.height = base.width * opts.aspect; | |
} | |
var xmlns = "http://www.w3.org/2000/svg"; | |
var svg = document.createElementNS(xmlns, "svg"); | |
svg.setAttributeNS(null, "width", base.width); | |
svg.setAttributeNS(null, "height", base.height); | |
parent.appendChild(svg); | |
// setting resize to "auto" sets the viewport to the original width and height so that the SVG always scales | |
if (opts.resize && opts.resize == "auto") { | |
svg.setAttributeNS(null, "viewBox", "0 0 " + base.width + " " + base.height); | |
} | |
function resize() { | |
console.log(parent) | |
base.width = parent.clientWidth; | |
base.height = base.width * opts.aspect; | |
base.scale = base.width / base.original_width; | |
svg.setAttributeNS(null, "width", base.width); | |
svg.setAttributeNS(null, "height", base.height); | |
// optional callback | |
if (opts.onResize) { | |
opts.onResize(base.width, base.height, base.scale); | |
} | |
} | |
var resizeTimer; | |
// http://stackoverflow.com/questions/3339825/what-is-the-best-practise-to-not-to-override-other-bound-functions-to-window-onr | |
function addResizeEvent(func, dur) { | |
var oldResize = window.onresize, | |
resizeTimer, | |
dur = typeof dur === "undefined" ? 250 : parseInt(dur, 10); | |
window.onresize = function () { | |
clearTimeout(resizeTimer); | |
if (typeof oldResize === 'function') { | |
oldResize(); | |
} | |
resizeTimer = setTimeout(function() { | |
func(); | |
}, dur); | |
} | |
} | |
addResizeEvent(resize, 250); | |
if (opts.resize && opts.resize === "auto") { | |
resize(); // call this on load since sometimes the initial conditions are wider than container | |
} | |
base.setResize = function(f) { | |
opts.onResize = f; | |
} | |
base.svg = svg; | |
return base; | |
} | |
// support various modular environments | |
if (typeof define === "function" && define.amd) { // RequireJS | |
define(elasticSVG); | |
} else if (typeof module === "object" && module.exports) { // browserify | |
module.exports = elasticSVG; | |
} else { | |
root.elasticSVG = elasticSVG; // directly included | |
} | |
}()); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0"> | |
<title>TopoJSON Counties With Organic Borders</title> | |
<style> | |
path.county { | |
fill: #eee; | |
stroke: #fff; | |
stroke-width: .5px; | |
} | |
path.state { | |
fill: none; | |
stroke: #404040; | |
stroke-width: 1px; | |
} | |
.Example { | |
max-width: 900px; | |
width: 100%; | |
height: 1500px; | |
} | |
.title { | |
font-size: 24px; | |
font-family: Arial; | |
text-align: center; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="Example"> | |
<div class="title">Merged</div> | |
<div id="map_merged"></div> | |
<div class="title">Meshed</div> | |
<div id="map_meshed"></div> | |
</div> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script> | |
<script src="elasticSVG.js"></script> | |
<script> | |
var projection = d3.geo.albersUsa() | |
.scale(1200) | |
.translate([450, 275]); | |
var path = d3.geo.path().projection(projection); | |
d3.json("us.json", function(error, topology) { | |
if (error) throw error; | |
// MESHED | |
// make the SVG responsive | |
var el_meshed = elasticSVG("#map_meshed", { | |
width: 900, | |
aspect: 0.65, | |
resize: "auto" | |
}); | |
var svg_meshed = d3.select(el_meshed.svg).append("g"); | |
//meshed | |
var counties = topojson.feature(topology, topology.objects.counties).features; | |
svg_meshed.selectAll("path") | |
.data(counties) | |
.enter().append("path") | |
.attr("class", "county") | |
.attr("d", path) | |
.on("click", function(d) { | |
console.log(d); | |
}); | |
svg_meshed.append("path") | |
.datum(topojson.mesh(topology, topology.objects.counties, function(a, b) { return a.id - a.id % 1000 !== b.id - b.id % 1000; })) | |
.attr("class", "state") | |
.attr("d", path); | |
// MERGED | |
// make the SVG responsive | |
var el_meshed = elasticSVG("#map_merged", { | |
width: 900, | |
aspect: 0.65, | |
resize: "auto" | |
}); | |
var svg_merged = d3.select(el_meshed.svg).append("g"); | |
//meshed | |
svg_merged.selectAll("path") | |
.data(counties) | |
.enter().append("path") | |
.attr("class", "county") | |
.attr("d", path); | |
// let's get an organic list of fips | |
var fips = {}; | |
counties.forEach(function(county) { fips[county.id - county.id % 1000] = 1; }); | |
var states = []; | |
// and merge by fips | |
Object.keys(fips).forEach(function(fip) { | |
var state = topojson.merge(topology, topology.objects.counties.geometries.filter(function(d) { return d.id - d.id % 1000 == fip; })); | |
states.push(state); | |
}); | |
svg_merged.append("g").attr("id", "states").selectAll(".state").append("path") | |
.data(states) | |
.enter() | |
.append("path") | |
.attr("class", "state") | |
.attr("d", function(d) { | |
return path(d); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment