Public
Edited
Mar 28
Importers
3 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
Insert cell
quakes = (
await fetch(
"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson"
)
).json()
Insert cell
Insert cell
Insert cell
Insert cell
// Search for the location and time of occurrence of a selected quake fromt the past week.
eventResponses = eventSearch({
lat: selectedQuake.geometry.coordinates[1],
lon: selectedQuake.geometry.coordinates[0],
date: dateFormat(new Date(selectedQuake.properties.time)),
radius: eventRadius // meters
})
Insert cell
Insert cell
quakeRadius = {
const scale = d3.scaleSqrt().domain([0, 100]).range([0, 100]);
return function (quake) {
return scale(Math.exp(quake.properties.mag));
};
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
positionCsv = position({
station: "NIST",
starttime: positionStartDate,
endtime: positionEndDate
})
Insert cell
Insert cell
download(async () => {
await Promises.delay(1000);
return new Blob([positionCsv], { type: "text" }); // CSV file with # header comments
}, "position")
Insert cell
Insert cell
Insert cell
d3.csvParse(removeComments(positionCsv), (d) => {
return {
date: dateFormat(d3.timeParse("%Y-%m-%dT%H:%M:%SZ")(d["Datetime"])),
deltaN: +d[" delta N"], // We can "shim" our data's column names and coerce data types as appropriate
deltaE: +d[" delta E"], // strings forced to become float data type
deltaU: +d[" delta U"],
stdDevN: +d[" Std Dev N"],
stdDevE: +d[" Std Dev E"],
stdDevU: +d[" Std Dev U"],
solution: +d[" Solution"]
};
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
velocityCsv = velocity({
station: "AB02",
starttime: positionStartDate,
endtime: positionEndDate
})
Insert cell
velocityCsv
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
itemsExample = [
{
endDate: "2020-01-31",
gnss: {
position: {
items: ["SC01", "AB33"],
selections: {
analysis_center: ["cwu", "pbo", "nmt"],
reference_frame: ["igs14", "nam14"]
}
},
rinex: {
items: {
"410": "SC01",
"1190": "P123"
},
selections: {
rinex2: ["obs", "nav", "qc"],
rinex3: ["obs", "nav"]
}
}
},
met: ["P123", "BGGY"],
startDate: "2020-01-01"
}
]
Insert cell
Insert cell
summary = fetchProducts({ items: itemsExample, view: "summary" })
Insert cell
Insert cell
// e.g. 10394879 -> 10MB
bytesToString = function (bytes) {
let format = d3.format(".0f");

if (bytes < 1024) {
return format(bytes) + "B";
} else if (bytes < 1024 * 1024) {
return format(bytes / 1024) + "kB";
} else if (bytes < 1024 * 1024 * 1024) {
return format(bytes / 1024 / 1024) + "MB";
} else if (bytes < 1024 * 1024 * 1024 * 1024) {
return format(bytes / 1024 / 1024 / 1024) + "GB";
} else if (bytes < 1024 * 1024 * 1024 * 1024 * 1024) {
return format(bytes / 1024 / 1024 / 1024 / 1024) + "TB";
} else {
return (
d3.format(",")(format(bytes / 1024 / 1024 / 1024 / 1024 / 1024)) + "PB"
);
}
}
Insert cell
Insert cell
fetchProducts({ items: itemsExample, view: "list" })
Insert cell
Insert cell
fetchMetadataExample = fetchProducts({ items: itemsExample, view: "metadata" })
Insert cell
Insert cell
fetchProductsTable = Table(fetchMetadataExample, {
columns: ["path", "file_size", "data_type", "sample_interval"],
format: { file_size: (d) => bytesToString(d) }
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
metadataValues = metadataOptions()
Insert cell
Insert cell
// Notice that this code does not need to know the property names of the object returned by metadataOptions.
metadataTableRows = {
let rows = [];
let max = 0;
let properties = [];

for (let p in metadataValues) {
properties.push(p);
if (metadataValues[p].length >= max) {
max = metadataValues[p].length;
}
}

for (let i = 0; i < max; i++) {
let row = {};
properties.forEach((p) => (row[p] = metadataValues[p][i]));
rows.push(row);
}

return rows;
}
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
metadataDisplay({ station: "P123" })
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
mutable signal = 1
Insert cell
mutable polygons = ({})
Insert cell
Insert cell
polygonSearchResults = {
if (Object.keys(polygons).length) {
return await polygonSearch({
polygons: Object.keys(polygons).map((id) => {
signal; // Force evaluation of this cell to occur.
return polygons[id];
})
});
}
return [];
}
Insert cell
Insert cell
metadataMap = d3.group(
metadataSearchResults.features,
(d) => d.properties.site_code
)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
stationCoverage()
Insert cell
Insert cell
stationAvailabilityTableData = stationCoverage().then((data) => {
return data.features
.map((d, i) => {
let dates = [];
let ranges = JSON.parse(d.properties.ranges);
let firstDate = d3.min(ranges, (d) => d3.timeParse("%s")(d.start_date));
let lastDate = d3.max(ranges, (d) => d3.timeParse("%s")(d.end_date));

let scale = d3
.scaleLinear()
.domain([
parseDate(stationCoverageStartDate),
parseDate(stationCoverageEndDate)
]) // TODO: determine best interval to display
.range([0, 1])
.clamp(true);

let datum = {
site_id: d.properties.site_id,
first_date: firstDate,
last_date: lastDate,
sample_interval: d.properties.sample_interval,
coverage: ranges.map((range) => {
return [
// overlapping intervals
scale(d3.timeParse("%s")(range.start_date)),
scale(d3.timeParse("%s")(range.end_date))
];
})
};

datum.percent = d3.sum(datum.coverage, (d) => d[1] - d[0]);
datum.i = i;

return datum;
})
.filter((d) => d.percent > 0) // Disregard sites with no data in our date range.
.sort((a, b) => d3.descending(a.percent, b.percent));
})
Insert cell
// Returns a canvas element to represent a series of intervals in the range [0, 1].
function sparkline(intervals, { width = 250, height = 20 }) {
const x = d3
.scaleLinear()
.domain([0, 1])
.range([1, width - 1]);
const y = d3
.scaleLinear()
.domain([0, 1])
.range([height / 2, height / 2]);
const context = DOM.context2d(width, height);
const line = d3
.line()
.x((d, i) => x(d))
.y(y)
.context(context);

context.beginPath();
context.rect(0, 0, width, height);
context.stroke();

context.lineWidth = height - 2;
context.strokeStyle = "green";

intervals.forEach((range) => {
context.beginPath();
line(range);
context.stroke();
});

return context.canvas;
}
Insert cell
Insert cell
Plot.rectY(
stationAvailabilityTableData,
Plot.binX({ y: "count" }, { x: "percent" })
).plot()
Insert cell
Insert cell
Insert cell
Insert cell
meteoroglogicalData = meteorologicalAvailability({
startDate: meteorologicalStartDate,
endDate: meteorologicalEndDate
})
Insert cell
meteorologicalTableData = meteoroglogicalData.features.map((d) => {
return {
site_code: d.properties.site_code,
start_date: d.properties.start_date,
end_date: d.properties.end_date,
longitude: d.geometry.coordinates[0],
latitude: d.geometry.coordinates[1]
};
})
Insert cell
Insert cell
Insert cell
meteorological({
station: meteorologicalTable ? meteorologicalTable.site_code : "P005", // Not all stations provide meteorological data!
starttime: meteorologicalStartDate,
endtime: meteorologicalEndDate
})
Insert cell
meteorologicalCoverage()
Insert cell
Insert cell
Insert cell
campaignData = campaigns({
startDate: dateFormat(oneDecadeAgo),
endDate: dateFormat(today),
polygons: [
[
[-127.40280407111175, 39.220112585833874],
[-128.29095730114574, 49.12208889984461],
[-122.69559195193145, 50.66670685596603],
[-115.67918143466305, 41.586847475882706],
[-127.40280407111175, 39.220112585833874]
]
]
})
Insert cell
Insert cell
Insert cell
pod = podStations()
Insert cell
podMap = d3.group(pod.features, (d) => d.properties.fourcharid) // create a convenient constant time lookup table
Insert cell
podMap.has("AB06")
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
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

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