|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<title>CTA Line Simplification</title> |
|
<style type="text/css"> |
|
body { |
|
padding: 0; |
|
margin: 0; |
|
} |
|
|
|
path { |
|
stroke-linejoin: round; |
|
fill: none; |
|
} |
|
|
|
circle { |
|
fill: white; |
|
stroke: black; |
|
display: none; |
|
stroke-width: 1px; |
|
} |
|
|
|
</style> |
|
</head> |
|
<body> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script> |
|
<script src="readme-simplify.js"></script> |
|
<script type="text/javascript"> |
|
config = {"simplification": 9, "interpolation" : "cardinal", "strokeWidth": 4, "showStops": false}; |
|
gui = new dat.GUI(); |
|
var examples = gui.addFolder('Examples'); |
|
examples.open() |
|
config.random = function(){ |
|
gui.__controllers.forEach(function(c){ |
|
if(typeof(c.__select) != 'undefined') { |
|
c.setValue(c.__select[Math.floor(Math.random()*(c.__select.length-1))].value) |
|
} else { |
|
if(c.property!="random" && c.property!="strokeWidth" && c.property!="showStops"){ |
|
c.setValue(Math.floor(Math.random() * c.__max) + c.__min) |
|
} |
|
} |
|
}) |
|
draw() |
|
} |
|
examples.add(config, "random") |
|
config.accurate = function(){ |
|
config["interpolation"] = "linear" |
|
config["simplification"] = 0 |
|
draw() |
|
} |
|
examples.add(config, "accurate") |
|
config.curly = function(){ |
|
config["interpolation"] = "cardinal" |
|
config["simplification"] = 9 |
|
draw() |
|
} |
|
examples.add(config, "curly") |
|
config.minimal = function(){ |
|
config["interpolation"] = "linear" |
|
config["simplification"] = 100 |
|
draw() |
|
} |
|
examples.add(config, "minimal") |
|
maxSimplification = 53 |
|
simplificationChanger = gui.add(config, "simplification", 0, 100).step(.1).listen() |
|
simplificationChanger.onChange(function(value) { |
|
draw() |
|
}); |
|
interpolationChanger = gui.add(config, "interpolation", ["linear", "step-before", "step-after", "basis", "basis-open", "basis-closed", "cardinal", "cardinal-open", "cardinal-closed", "monotone"]).listen() |
|
interpolationChanger.onChange(function(value) { |
|
draw() |
|
}) |
|
strokeWidthChanger = gui.add(config, "strokeWidth", 1, 20).listen() |
|
strokeWidthChanger.onChange(function(value) { |
|
d3.selectAll(".routes path").style("stroke-width", value) |
|
d3.selectAll(".stops circle").attr("r", value/2) |
|
}); |
|
showStopsChanger = gui.add(config, "showStops").listen() |
|
showStopsChanger.onChange(function(value) { |
|
d3.selectAll(".stops circle").style("display", value ? "block" : "none") |
|
}); |
|
|
|
width = window.innerWidth |
|
height = window.innerHeight - 5 |
|
|
|
line = d3.svg.line() |
|
.interpolate(config["interpolation"]) |
|
|
|
zoom = d3.behavior.zoom() |
|
.scaleExtent([0, 100]) |
|
.on("zoom", function () { |
|
config["simplification"] = d3.event.scale |
|
draw() |
|
}) |
|
|
|
svg = d3.select("body").append("svg") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.call(zoom) |
|
|
|
var projection = d3.geo.mercator() |
|
.scale(54596) |
|
.translate([83920, 44300]) |
|
|
|
d3.json("chicago-transit-authority_20121228_1318.json", function(json) { |
|
routes = svg.append("g").attr("class", "routes").selectAll("path").data(json.features.filter(function(d) { return d["geometry"]["type"] == "LineString" })) |
|
|
|
routes.enter().append("path") |
|
.attr("id", function(d) { return d.properties.route_id }) |
|
.style("stroke", function(d) { return "#"+d.properties.route_color }) |
|
.style("stroke-width", config["strokeWidth"]) |
|
.on("mouseover", function(d) { |
|
d3.select(this).style("stroke-width", config["strokeWidth"] * 2) |
|
}) |
|
.on("mouseout", function(d) { |
|
d3.select(this).style("stroke-width", config["strokeWidth"]) |
|
}) |
|
//.attr("d", function(d) { return line(d.geometry.coordinates.map(projection)) }) |
|
|
|
stops = svg.append("g").attr("class", "stops").selectAll("circle").data(json.features.filter(function(d) { return d["geometry"]["type"] == "Point" })) |
|
|
|
stops.enter().append("circle") |
|
.attr("id", function(d) { return d.properties.stop_id }) |
|
.attr("class", function(d) { return d.properties.route_id }) |
|
.attr("r", config["strokeWidth"]/2) |
|
.on("mouseover", function(d) { |
|
d3.select(this).attr("r", config["strokeWidth"]/2 * 2) |
|
}) |
|
.on("mouseout", function(d) { |
|
d3.select(this).attr("r", config["strokeWidth"]/2) |
|
}) |
|
.attr("transform", function(d) { |
|
xy = projection(d.geometry.coordinates) |
|
return "translate("+xy[0]+","+xy[1]+")" |
|
}) |
|
.append("svg:title") |
|
.text(function(d, i) { return d.properties.name }) |
|
|
|
draw() |
|
|
|
// intro animation |
|
//var interpolator = d3.interpolateNumber(0, config["simplification"]) |
|
//svg.transition().duration(1000).tween("withchange", function() { |
|
// return function(t) { |
|
// config["simplification"] = interpolator(t) |
|
// draw() |
|
// }; |
|
//}) |
|
}) |
|
|
|
function draw() { |
|
zoom.scale(config["simplification"]) |
|
line.interpolate(config["interpolation"]) |
|
|
|
routes.attr("d", function(d) { |
|
return line(simplify(d.geometry.coordinates.map(projection), maxSimplification*(config["simplification"]*.01), true)) |
|
}) |
|
} |
|
|
|
</script> |
|
</body> |
|
</html> |