Public
Edited
Nov 14, 2023
Paused
1 fork
9 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
Insert cell
Insert cell
localizedData
X
lon
Y
lat
Color
datetime
Size
magnitude
Facet X
Facet Y
Mark
Auto
Type Chart, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
cleanData
X
datetime
Y
mean
magnitude
Color
Size
Facet X
Facet Y
Mark
line
Type Chart, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
Insert cell
directionLabelMap = (angle) => {
const label = (a, b) =>
`← ${a} ${b} →`;
if (angle < 0 + 45 / 2) {
return label("SOUTH", "NORTH");
}
if (angle < 0 + (45 / 2) * 3) {
return label("SOUTHWEST", "NORTHEAST");
}
if (angle < 90 + 45 / 2) {
return label("WEST", "EAST");
}
if (angle < 90 + (45 / 2) * 3) {
return label("NORTHWEST", "SOUTHEAST");
}
if (angle < 180 + 45 / 2) {
return label("NORTH", "SOUTH");
}
if (angle < 180 + (45 / 2) * 3) {
return label("NORTHEAST", "SOUTHWEST");
}
if (angle < 270 + 45 / 2) {
return label("EAST", "WEST");
}
if (angle < 270 + (45 / 2) * 3) {
return label("SOUTHEAST", "NORTHWEST");
}
return label("SOUTH", "NORTH");
}
Insert cell
function projectOntoAxis(latitude, longitude) {
// Convert the angle to radians
const angleRadians = (angle * Math.PI) / 180;

// Calculate the slope of the line
const slope = Math.tan(angleRadians);

// Assuming the line passes through the origin (0,0),
// calculate the x-coordinate of the projection point
const xProjection = (latitude + slope * longitude) / (1 + slope * slope);

// Calculate the y-coordinate of the projection point
const yProjection = slope * xProjection;

// Calculate the value along the axis (distance from the origin)
const valueAlongAxis = Math.sqrt(
xProjection * xProjection + yProjection * yProjection
);

return valueAlongAxis;
}
Insert cell
Insert cell
update = {
const oldKeys = this || new Set();
const newKeys = new Set(
[...timeGeoJSONLayer.keys()].filter((k) => k < scrubTime1)
);
let leaving = [...oldKeys].filter((x) => !newKeys.has(x));
let entering = [...newKeys].filter((x) => !oldKeys.has(x));
leaving.forEach((k) =>
timeGeoJSONLayer.get(k).setStyle({ opacity: 0, fillOpacity: 0 })
);
entering.forEach((k) =>
timeGeoJSONLayer.get(k).setStyle({ opacity: 1, fillOpacity: 0.2 })
);
return newKeys;
}
Insert cell
initialize = {
[...timeGeoJSONLayer.entries()].forEach(([k, v]) =>
v.addTo(map).setStyle({ opacity: 0, fillOpacity: 0 })
);
}
Insert cell
timeGeoJSONLayer = new Map(
[...timeGeoJSONData].map(([k, v]) => [
k,
L.geoJSON(
d3.sort(v, (d) => d.magnitude),
{
pointToLayer: (feature, latlng) =>
L.circleMarker(latlng, {
// fill: false,
radius: eqRadius(feature.magnitude),
weight: 0.5,
color: depthScale(feature.depth)
}).bindPopup(
`Time: ${feature.datetime.toISOString()}
<br>
Magnitude: ${feature.magnitude}
<br>
Depth: ${feature.depth}`
)
}
)
])
)
Insert cell
depthScale = d3.scaleSequentialSymlog(
[
d3.quantile(cleanData, 0.25, (d) => d.depth),
d3.quantile(cleanData, 0.75, (d) => d.depth)
],
d3.interpolateRdYlBu
)
Insert cell
eqRadius = (magnitude) => {
return Math.sqrt(2 ** (1.5 * magnitude));
}
Insert cell
timeGeoJSONData = new Map(
[...timeData].map(([k, v]) => [
k,
v.map((d) => ({
type: "Point",
coordinates: [d.lon, d.lat],
...d
}))
])
)
Insert cell
timeData = new Map(
timeIntervals.map((d) => [
d,
cleanData.filter((t) => t.datetime < d && t.datetime > d - timeIntervalMS)
])
)
Insert cell
timeIntervals = d3.range(timeExtent[0], timeExtent[1], timeIntervalMS)
Insert cell
timeExtent = d3.extent(cleanData, (d) => d.datetime)
Insert cell
timeIntervalMS = 1000 * 60 * 6
Insert cell
smallScreen = width < 800
Insert cell
width
Insert cell
Insert cell
cleanData
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
data
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Icelandic Earthquakes.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
import { isMobile } from "@flimsyhat/mobile-device-check"
Insert cell
import { Scrubber } from "@mbostock/scrubber"
Insert cell
import { footer } from "@rlesser/footer"
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more