Published
Edited
Dec 6, 2019
Insert cell
Insert cell
globe = {
// Set up the <canvas> to draw into.
const context = this ? this.getContext("2d") : DOM.context2d(w, w);
const canvas = context.canvas;
canvas.angle = canvas.angle || 0;
canvas.style.display = "block"; //display: "block" and margin: "auto" together make the globe centered
canvas.style.margin = "auto";
// color for quakes
const color = d3.color(quakeColor);
color.opacity = quakeOpacity;
// Use an orthographic projection of the world. For fun, try changing `Ortho` to `Stereo`.
const projection = d3.geoOrthographic().scale(r).translate([w / 2, w / 2]);
const path = d3.geoPath(projection, context);
// create an inspection function
function inspection(name, value){
context.font = "50px";
context.fillStyle = "red";
context.fillText(name + " : " + value, w/2, w/2);
}
// For every frame.
while (true) {
// Rotate the earth. For fun, try replacing the `0` in the following line with `canvas.angle`.
projection.rotate([canvas.angle += spinSpeed, 0]);
context.clearRect(0, 0, w, w);
// Draw the seas.
context.lineWidth = 1.5;
context.fillStyle = oceanColor;
context.beginPath(), context.arc(w / 2, w / 2, r, 0, 2 * Math.PI), context.fill(), context.stroke();
// Draw the land.
context.lineWidth = lineWidth;
context.fillStyle = landColor;
context.beginPath(), path(earth), context.fill(), context.stroke();
// Draw the earthquakes, either as projected circles on the surface, or flat circles in space.
context.fillStyle = color;
let circles = dots == "projected" ? quakeCircles : quakes.features;
if (dots == "unprojected") path.pointRadius(magnitudeRadius);
circles.forEach(d => {context.beginPath(), path(d); context.fill()});
path.pointRadius(null);
// debugging canvas.angle
inspection("canvas.angle", canvas.angle);
yield canvas;
}
}
Insert cell
viewof timeFrame = {
const select = DOM.select(["past-day", "past-week", "past-month"]);
select.value = "past-week";
return select;
}
Insert cell
viewof dots = DOM.select(["projected", "unprojected"])
Insert cell
viewof land = DOM.select(["countries", "land"])
Insert cell
viewof lineWidth = slider({min: 0.01, max: 5, value: 0.35, title: "lineWidth", description: "lineWidth for land"})
Insert cell
viewof quakeSize = slider({min: 1, max: 20, value: 10, title: "quakeSize", description: "set max magnitudue"})
Insert cell
viewof padding = slider({min: 1, max: 100, value: 10, title: "padding", description: "add padding to shrink the size of globe, use w and padding to set the globe radius"})
Insert cell
viewof spinSpeed = slider({min: 0, max: 3, value: 0.4, title: "spinSpeed", description: "add spinSpeed in while loop to rotate automatically"})
Insert cell
Insert cell
viewof oceanColor = color({value: "#74fbfd", title: "oceanColor"})
Insert cell
viewof landColor = color({value: "#fefafa", title: "landColor"})
Insert cell
viewof quakeColor = color({value: "#f11707", title: "quakeColor"})
Insert cell
md`## filter out quakes below 0.25 magnitudes`
Insert cell
Insert cell
Insert cell
Insert cell
urls = ({
"past-day": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson",
"past-week": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson",
"past-month": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_month.geojson"
})
Insert cell
Insert cell
timeFrame
Insert cell
quakes = (await fetch(urls[timeFrame])).json()
Insert cell
Insert cell
Insert cell
quakeCircles = {
const circle = d3.geoCircle();
return quakes.features.map(quake => {
return circle.center(quake.geometry.coordinates).radius(magnitudeRadius(quake) / 5).precision(25)();
});
}
Insert cell
Insert cell
Insert cell
world = (await fetch("https://unpkg.com/world-atlas@1/world/110m.json")).json()
Insert cell
Insert cell
earth = topojson.feature(world, world.objects[land])
Insert cell
Insert cell
Insert cell
magnitudeRadius = {
const scale = d3.scaleSqrt().domain([0, 100]).range([0, quakeSize]);
return function(quake) {
return scale((Math.exp(quake.properties.mag)));
}
}
Insert cell
Insert cell
exampleQuakeData = quakes.features[30].properties
Insert cell
exampleQuakeMagnitude = magnitudeRadius({properties: exampleQuakeData})
Insert cell
Insert cell
Insert cell
w = Math.min(680, width)
Insert cell
r = w / 2 - 2 - padding // use w and padding to set the globe radius
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more