Published
Edited
Sep 2, 2020
4 forks
Importers
66 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
rawPoints = {
// range longitudes from 10 (S) to 55 (N) for every 1 degree
const lons = d3.range(10, 55, 2).reverse()

// range latitudes from -130 (W) to -60 (E) for every 1 degree
const lats = d3.range(-130, -60, 2)
// long / lat points in order from west to east, then north to south, like a wrap
return lons.map((lon, i) => lats.map(lat => [lat, lon])).flat()
}
Insert cell
geojson = rawPoints.map((d,i) => {
return {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": d
},
"properties": {
"index": i
}
}
});
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
gridPoints = rawPoints.map((point,i) => ({
'centroid': projection(point),
'data': get_point_data(point, i)
})).filter(d => d.centroid !== null && d.data !== null)
Insert cell
// we'd like the valleys of the contours (and, the other end of the color scale) to be the minimum number in the data rather than 0, since some regions have negative values.
offset = {
return Math.abs(d3.min(temp_change.map(d => +d['Temperature Change']))) * 10
}
Insert cell
contour_data = gridPoints.reduce((acc, climdiv) => {
// calculate the number of points based on the temp change value, down to 0.1.
const num_points = Math.floor(Math.abs(climdiv.data + offset))
// create an array of that same value repeated to create stacked points tied to the data value
const array = new Array(num_points).fill(climdiv.centroid, 0, num_points)
return [...acc, ...array]
}, [])
Insert cell
contour = d3.contourDensity()
.x(d => d[0])
.y(d => d[1])
.size([width, height])
.cellSize(2)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
linearColorScale = d3.scaleLinear()
.domain(d3.range(0,1,1/colors.length))
.range(colors)
.interpolate(d3.interpolateLab);
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// we use d3.range to make even spaced bins of our temperature values
bins = d3.range(
...temp_values_domain, // it should span the entire domain
(temp_values_domain[1] - temp_values_domain[0]) / density_thresholds.length) // and be evenly spaced, but the same number as our density thresholds
Insert cell
Insert cell
Insert cell
quantz = d3.quantize(linearColorScale, (density_thresholds.length - zero_estimation_index) * 2)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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