Skip to content

Instantly share code, notes, and snippets.

@erich-kuehn
Created December 14, 2016 22:42
Show Gist options
  • Save erich-kuehn/2770a7c7c1cd633f6b47ebb21b640f68 to your computer and use it in GitHub Desktop.
Save erich-kuehn/2770a7c7c1cd633f6b47ebb21b640f68 to your computer and use it in GitHub Desktop.
Mapping
<!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")
// uncomment to add GSFC/KSC labels .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(6500)
.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++){
// item with i+1)
links.push({
type: "LineString",
coordinates: [
[ data[i].lon, data[i].lat ],
[ data[i+1].lon, data[i+1].lat ]
],
status: [
[ data[i].status ]]
});
}
// Standard enter / update
var pathArcs = arcGroup.selectAll(".arc")
.data(links);
//enter
pathArcs.enter()
.append("path").attr({
'class': 'arc'
}).style({
fill: 'none',
});
//update
for(var i=0, len=links.length; i<len; i++){
if (links[i].status[0][0] === 'red') {
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: 'red',
'stroke-width': '2px'
})
// Uncomment this line to remove the transition
.call(lineTransition);
//exit
pathArcs.exit().remove();
}else{
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: 'green',
'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>
code center lat lon status
GSFC Goddard Space Flight Center 38.991621 -76.852587 green
KSC Kennedy Space Center 28.524963 -80.650813 green
JPL Jet Propulsion Laboratory 34.200463 -118.176008 green
DFRC Dryden Flight Research Center 34.613714 -118.076790 green
GRC Glenn Research Center 41.415891 -81.861774 red
MSFC Marshall Space Flight Center 34.646554 -86.674368 red
ARC Ames Research Center 37.409574 -122.064292 red
LaRC Langley Research Center 37.092123 -76.376230 orange
JSC Johnson Space Center 29.551508 -95.092256 orange
SSC Stennis Space Center 30.363692 -89.600036 orange
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment