Last active
July 26, 2017 21:20
-
-
Save erikhazzard/6201948 to your computer and use it in GitHub Desktop.
This file contains 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> | |
<meta charset="utf-8"> | |
<style> | |
.background { | |
fill: none; | |
pointer-events: all; | |
} | |
#states { | |
fill: #aaaaaa; | |
} | |
#states .active { | |
fill: #ff0000; | |
fill-opacity: .5; | |
} | |
#state-borders { | |
fill: none; | |
stroke: #ffffff; | |
stroke-width: 1.5px; | |
stroke-linejoin: round; | |
stroke-linecap: round; | |
pointer-events: none; | |
} | |
path.link { | |
fill: none; | |
stroke: #666666; | |
stroke-width: 1.5px; | |
} | |
.stroke { | |
fill: none; | |
stroke: #000; | |
stroke-width: 3px; | |
} | |
.fill { | |
fill: #fff; | |
} | |
.graticule { | |
fill: none; | |
stroke: #777; | |
stroke-width: .5px; | |
stroke-opacity: .5; | |
} | |
.route { | |
fill: none; | |
stroke: blue; | |
stroke-width: 3px; | |
} | |
</style> | |
<body> | |
<h2> | |
<span>NASA Centers</span> | |
</h2> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script> | |
<script src="http://d3js.org/topojson.v1.min.js"></script> | |
<script> | |
var width = 1000, | |
height = 600, | |
centered; | |
var projection = d3.geo.albersUsa() | |
.scale(1070) | |
.translate([width / 2, height / 2]); | |
var path = d3.geo.path() | |
.projection(projection); | |
var graticule = d3.geo.graticule(); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
var g = svg.append("g"); | |
var places = { | |
GSFC: [-76.852587, 38.991621], | |
KSC: [-80.650813, 28.524963] | |
}; | |
var route = { | |
type: "LineString", | |
coordinates: [ | |
places.GSFC, | |
places.KSC | |
] | |
}; | |
// Setup groups | |
// -------------------------------------- | |
// Add groups for arcs and images. If arcs are added before images, they | |
// will appear under the images. | |
// order is important | |
var stateGroup = g.append('g'); | |
var arcGroup = g.append('g'); | |
var imageGroup = g.append('g'); | |
var pointGroup = g.append('g'); | |
// Also, text needs to be added to the `g` group | |
var point = pointGroup.append("g") | |
.attr("class", "points") | |
.selectAll("g") | |
.data(d3.entries(places)) | |
.enter().append("g") | |
.attr("transform", function(d) { return "translate(" + projection(d.value) + ")"; }); | |
point.append("text") | |
.attr("y", 5) | |
.attr("dx", "1em") | |
.text(function(d) { return d.key; }); | |
d3.json("us.json", function(error, us) { | |
// draw states | |
stateGroup.append("g") | |
.attr("id", "states") | |
.selectAll("path") | |
.data(topojson.feature(us, us.objects.states).features) | |
.enter().append("path") | |
.attr("d", path) | |
.on("click", clicked); | |
stateGroup.append("path") | |
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })) | |
.attr("id", "state-borders") | |
.attr("d", path); | |
d3.csv("nasacenters.csv", function(error, data) { | |
// Draw images after drawing paths. | |
imageGroup.selectAll("image").data([0]) | |
.data(data) | |
.enter() | |
.append("image") | |
.attr("xlink:href", "nasalogo.png") | |
.attr("width", "30") | |
.attr("height", "30") | |
.attr("x", function(d) { | |
return projection([d.lon, d.lat])[0]-15; | |
}) | |
.attr("y", function(d) { | |
return projection([d.lon, d.lat])[1]-15; | |
}) | |
// --- Helper functions (for tweening the path) | |
var lineTransition = function lineTransition(path) { | |
path.transition() | |
//NOTE: Change this number (in ms) to make lines draw faster or slower | |
.duration(5500) | |
.attrTween("stroke-dasharray", tweenDash) | |
.each("end", function(d,i) { | |
////Uncomment following line to re-transition | |
//d3.select(this).call(transition); | |
//We might want to do stuff when the line reaches the target, | |
// like start the pulsating or add a new point or tell the | |
// NSA to listen to this guy's phone calls | |
//doStuffWhenLineFinishes(d,i); | |
}); | |
}; | |
var tweenDash = function tweenDash() { | |
//This function is used to animate the dash-array property, which is a | |
// nice hack that gives us animation along some arbitrary path (in this | |
// case, makes it look like a line is being drawn from point A to B) | |
var len = this.getTotalLength(), | |
interpolate = d3.interpolateString("0," + len, len + "," + len); | |
return function(t) { return interpolate(t); }; | |
}; | |
// --- Add paths | |
// Format of object is an array of objects, each containing | |
// a type (LineString - the path will automatically draw a greatArc) | |
// and coordinates | |
var links = [ | |
{ | |
type: "LineString", | |
coordinates: [ | |
[ data[0].lon, data[0].lat ], | |
[ data[1].lon, data[1].lat ] | |
] | |
} | |
]; | |
// you can build the links any way you want - e.g., if you have only | |
// certain items you want to draw paths between | |
// Alterntively, it can be created automatically based on the data | |
links = []; | |
for(var i=0, len=data.length-1; i<len; i++){ | |
// (note: loop until length - 1 since we're getting the next | |
// item with i+1) | |
links.push({ | |
type: "LineString", | |
coordinates: [ | |
[ data[i].lon, data[i].lat ], | |
[ data[i+1].lon, data[i+1].lat ] | |
] | |
}); | |
} | |
// Standard enter / update | |
var pathArcs = arcGroup.selectAll(".arc") | |
.data(links); | |
//enter | |
pathArcs.enter() | |
.append("path").attr({ | |
'class': 'arc' | |
}).style({ | |
fill: 'none', | |
}); | |
//update | |
pathArcs.attr({ | |
//d is the points attribute for this path, we'll draw | |
// an arc between the points using the arc function | |
d: path | |
}) | |
.style({ | |
stroke: '#0000ff', | |
'stroke-width': '2px' | |
}) | |
// Uncomment this line to remove the transition | |
.call(lineTransition); | |
//exit | |
pathArcs.exit().remove(); | |
}); | |
}); | |
function clicked(d) { | |
var x, y, k; | |
if (d && centered !== d) { | |
var centroid = path.centroid(d); | |
x = centroid[0]; | |
y = centroid[1]; | |
k = 4; | |
centered = d; | |
} else { | |
x = width / 2; | |
y = height / 2; | |
k = 1; | |
centered = null; | |
} | |
g.selectAll("path") | |
.classed("active", centered && function(d) { return d === centered; }); | |
g.transition() | |
.duration(750) | |
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")") | |
.style("stroke-width", 1.5 / k + "px"); | |
} | |
</script> | |
</body> | |
</html> |
This file contains 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
code | center | lat | lon | |
---|---|---|---|---|
GSFC | Goddard Space Flight Center | 38.991621 | -76.852587 | |
KSC | Kennedy Space Center | 28.524963 | -80.650813 | |
JPL | Jet Propulsion Laboratory | 34.200463 | -118.176008 | |
DFRC | Dryden Flight Research Center | 34.613714 | -118.076790 | |
GRC | Glenn Research Center | 41.415891 | -81.861774 | |
MSFC | Marshall Space Flight Center | 34.646554 | -86.674368 | |
ARC | Ames Research Center | 37.409574 | -122.064292 | |
LaRC | Langley Research Center | 37.092123 | -76.376230 | |
JSC | Johnson Space Center | 29.551508 | -95.092256 | |
SSC | Stennis Space Center | 30.363692 | -89.600036 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment