A real-time planetary monitoring dashboard on an interactive 3D globe. No backend required — every data layer fetches directly from live public APIs in the browser, refreshing on its own schedule.
Live: https://dr.eamer.dev/datavis/dashboards/live-earth/
The globe renders 16 stacked data layers in real time:
Hazards
- Seismic events — USGS M2.5+ earthquakes from the past 24 hours, refreshed every 5 minutes. Circle size scales with magnitude.
- Volcanoes — USGS elevated-alert volcanoes, updated hourly.
- Wildfires — NASA FIRMS VIIRS satellite fire detections worldwide, refreshed every 30 minutes.
- Hurricanes — Active tropical cyclones from NOAA NHC, with storm intensity.
- Weather alerts — Active NWS alerts for the US with polygon overlays, refreshed every 5 minutes.
Atmosphere
- Aurora — NOAA OVATION aurora probability across ~65,000 lat/lon grid points, refreshed every 10 minutes. Points below 15% probability are culled.
- Air quality — Open-Meteo AQI for major cities globally, refreshed every 30 minutes.
- Space weather — Kp index (geomagnetic activity) and solar wind speed/density from NOAA SWPC, refreshed every 10 minutes.
- Tides — Water levels at 10 US coastal NOAA CO-OPS stations (San Francisco, NYC Battery, Seattle, Honolulu, and more), updated every 6 minutes.
Traffic
- Flights — Live aircraft positions from OpenSky Network via a server-side CORS proxy, refreshed every 60 seconds. Color-coded by altitude phase: cruising (blue), climb/descent (yellow), approach (orange). Filter by commercial, private, or helicopter.
- ISS — International Space Station position updated every 10 seconds via wheretheiss.at, with an orbital trail of the last 50 positions.
- Satellites — Starlink (50), GPS (30), and weather (20) satellites tracked using TLE data from tle.ivanstanojevic.me, propagated in real time with satellite.js. TLE data refreshes every 6 hours; positions update every frame.
Earth View
- Day/night terminator — Calculated astronomically from current UTC time.
- City lights — Natural Earth populated places rendered on the night side.
- Major cities — 20 reference cities with labels.
A scrolling ticker at the bottom surfaces earthquake alerts, weather warnings, active fire counts, and space weather readings as they come in.
Static HTML — no build step:
cd /path/to/live-earth
python3 -m http.server 8000
# Open http://localhost:8000/Everything lives in index.html (~2,600 lines): CSS custom properties for the dark terminal theme, D3.js orthographic projection on a Canvas 2D context, and async fetch loops for each data layer.
The globe uses D3's orthographic projection with drag rotation. All drawing goes through a single Canvas 2D context. d3.geoDistance() handles backface visibility culling so points behind the globe don't render. Layer order matters — ISS renders on top of everything; ocean fill renders first.
All browser-direct (no proxy needed except where noted):
| Layer | Source | Refresh |
|---|---|---|
| Earthquakes | USGS GeoJSON feed | 5 min |
| Volcanoes | USGS HANS public API | 1 hour |
| Wildfires | NASA FIRMS VIIRS NRT | 30 min |
| Hurricanes | NOAA NHC (via CORS proxy) | 30 min |
| Weather alerts | NWS api.weather.gov | 5 min |
| Aurora | NOAA OVATION JSON | 10 min |
| Air quality | Open-Meteo AQI API | 30 min |
| Kp index + solar wind | NOAA SWPC | 10 min |
| Tides | NOAA CO-OPS tides API | 6 min |
| Flights | OpenSky Network (via proxy) | 60 sec |
| ISS | wheretheiss.at | 10 sec |
| Satellites | tle.ivanstanojevic.me + satellite.js | TLE: 6h / pos: per-frame |
- D3.js v7
- TopoJSON v3
- satellite.js v5
- world-atlas 110m
- Google Fonts: Share Tech Mono, Inter
TLE data comes from the ivanstanojevic.me API. satellite.js converts it to real-time lat/lon:
const satrec = satellite.twoline2satrec(sat.line1, sat.line2);
const now = new Date();
const gmst = satellite.gstime(now);
const posVel = satellite.propagate(satrec, now);
const geo = satellite.eciToGeodetic(posVel.position, gmst);
const lon = satellite.degreesLong(geo.longitude);
const lat = satellite.degreesLat(geo.latitude);- Confirm the API sends
Access-Control-Allow-Origin: *(or route through the proxy) - Add the endpoint to the
APIobject - Write an async
fetchNewLayer()function and call it ininit() - Set a
setIntervalusing the appropriateREFRESHconstant - Write a
drawNewLayer()function and call it insiderender() - Add a toggle row to the Data Layers panel in the HTML
- Left panel: Data Layers — toggle switches for each layer, zoom controls, flight type filters
- Right panel: Global Status — live counters (seismic events, active fires, aircraft tracked, ISS altitude, Kp index, solar wind speed, satellites, and more)
- Bottom ticker: scrolling feed of current alerts and readings
- Hover tooltips on earthquake, fire, flight, volcano, and weather alert markers
- Mobile: panels collapse behind a hamburger toggle; ticker font scales down; stats grid reflows
Luke Steuber — dr.eamer.dev — @lukesteuber.com
MIT