Published
Edited
Apr 13, 2020
Importers
Also listed in…
demo
weather
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const date = d3.timeFormat("%e %b %Y %H:%M (" + hours + "-hour window)")(new Date(t));
d3.select(pirep).select("text").text(date)
return date
}
Insert cell
times = d3.range(extent[0], extent[1], 3 * 60 * 60 * 1000).map(d => new Date(d))
Insert cell
Insert cell
Insert cell
pireps = {
// This cell returns an Array of time-filtered PIREPS data
// let t0 = Math.floor(scl(map[0]));
const t0 = t.valueOf();
const t1 = t0.valueOf() + hours * 3600000 // Add "hours" offset
let pireps = csv.filter(d => (d.t > t0) && (d.t < t1))
.map(d => [d.LON, d.LAT, d.TURBULENCE, d.color, d.REPORT]);
return pireps;
}
Insert cell
extent = d3.extent(csv.map(d => d.t))
Insert cell
scl = d3.scaleLinear().domain([0, width]).range(d3.extent(csv, d => d.t))
Insert cell
mutable z = "Mouse over map for pilot reports"
Insert cell
Insert cell
pirep = {
const mysvg = svg`<svg
width=960
height=600
viewBox="0,0,960,600"
style="max-width:100%;height:auto;position:absolute;top:0;left:0">`

d3.timeFormat("%e %b %Y %H:%M:%S GMT (" + hours + " hours)")(new Date(t0));

// Add the text label
d3.select(mysvg).append("text")
.attr("x", 960 / 2)
.attr("dx", "5rem")
.attr("y", "2rem")
.attr("font-family", "sans-serif")
.attr("font-size", "2rem")
.attr("text-anchor", "middle")
.style("user-select", "none")
.text(d3.timeFormat("%e %b %Y %H:%M:%S GMT (" + hours + " hours)")(t0));
d3.select(mysvg).selectAll("path")
.data(pireps)
.join("path")
.classed('pirep', true)
.sort((a,b) => (a[3] > b[3]) ? 1 : -1)
.attr("x", (d, i) => i * 16)
.attr("d", d => path({"type": "Point", "coordinates": d}))
.attr('fill', d => colors[d[3]])
.on('mouseover', function(d) { mutable z = d[4]; d3.select(this).attr('stroke', 'black') })
.on('mouseout', function() { mutable z = ""; d3.select(this).attr('stroke', null) })

return mysvg;
}
Insert cell
Insert cell
colors = ["lightgray", "orange", "red"]
Insert cell
csv = {
let csv = d3.csvParse(await FileAttachment("pireps-2020.csv").text(), d3.autoType);

// Remove rows that have no TURBULENCE info
csv = csv.filter(d => (d.REPORT.includes("UUA") || (d.TURBULENCE)));
// Add time in milliseconds since epoch
const specifier = "%Y-%m-%d %H:%M:%S";
const timeParse = d3.timeParse(specifier);
csv.forEach(d => d.t = timeParse(d.VALID).getTime());
// Add color based on turbulence intensity
csv.forEach(d => {
d.color = 0;
d.color = (d.TURBULENCE) && d.TURBULENCE.includes("MOD") ? 1 : d.color;
d.color = (d.TURBULENCE) && d.TURBULENCE.includes("EXT") ? 2 : d.color;
d.color = d.REPORT.includes("UUA") ? 2 : d.color;
})

return csv;
}
Insert cell
Insert cell
path = d3.geoPath(projection);
Insert cell
Insert cell
import {chart, projection, d3} from "@pbogden/zip-codes"
Insert cell
import {Scrubber} from "@mbostock/scrubber"
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