Public
Edited
May 28
Insert cell
Insert cell
API_TOKEN = "XULIaoTCVbLgMXhXzwUFXfHJGZNtMQUc";
Insert cell
aapl
Insert cell
Plot.lineY(dataMerged, {x: "date", y: "temp", stroke: "city"}).plot({y: {grid: true}, color: {legend: true}})
Insert cell
Plot.lineY(bostonDataClean, {x: "date", y: "temp", stroke: () => "red"}).plot({y: {grid: true}})
Insert cell
Plot.lineY(brnoDataClean, {x: "date", y: "temp", stroke: () => "blue"}).plot({y: {grid: true}})
Insert cell
dataMerged = {
const all = [];
for (const d of brnoDataClean) {
all.push({...d, city: "Brno"});
}
for (const d of bostonDataClean) {
all.push({...d, city: "Boston"});
}
return all;
}
Insert cell
bostonDataClean = {
const newData = [];
for (const res of bostonData.results) {
newData.push({
date: new Date(res.date),
temp: res.value,
});
res.date;
res.value;
}
return newData;
}
Insert cell
// Plot.lineY(aapl, {x: "Date", y: "Close"}).plot({y: {grid: true}})
Insert cell
brnoweather = FileAttachment("brnoWeather.json").json()
Insert cell
brnoDataClean = brnoweather.data.map(d => ({date: new Date(d.date), temp: d.tavg}));
Insert cell
bostonData = fetchHistoricalWeather(API_TOKEN);
Insert cell
async function fetchHistoricalWeather(token) {
const baseUrl = "https://www.ncei.noaa.gov/cdo-web/api/v2/data";
const params = new URLSearchParams({
datasetid: "GHCND", // Daily summaries
locationid: "CITY:US250001", // Boston's location ID
startdate: "2023-12-01", // Start date
enddate: "2024-12-31", // End date
datatypeid: "TMAX", // Maximum temperature
units: "metric", // Metric units
limit: "1000", // Max results per request
});

try {
const response = await fetch(`${baseUrl}?${params.toString()}`, {
headers: {
token: token, // Include your NOAA API token in the headers
},
});

if (!response.ok) {
throw new Error(`HTTP Error: ${response.status} - ${response.statusText}`);
}

const data = await response.json();
console.log("Historical Weather Data:", data);
return data;
} catch (error) {
console.error("Error fetching weather data:", error.message);
}
}
Insert cell
// brno coords: 49.217305, 16.571804
Insert cell
{
// Botanic Gardens: 42.382406, -71.126514
const url = await getURLForCoords(42.3824, -71.1265);
const response = await fetch(url);
const data = await response.json();

let formattedString = "";
for (const forecast of data.properties.periods) {
formattedString += `${forecast.name}: ${forecast.detailedForecast}\n`;
}
console.log(formattedString);
return formattedString;
}
Insert cell
async function getURLForCoords(lat, long) {
const url = `https://api.weather.gov/points/${lat},${long}`;
const response = await fetch(url);
const data = await response.json();
const forecastUrl = data.properties.forecast;
return forecastUrl;
}
Insert cell
// brnoUrl = await getURLForCoords(49.2173, 16.5718);
Insert cell
openmeteo = import('https://cdn.skypack.dev/openmeteo@1.1.4?min')
Insert cell
fetchWeatherApi = openmeteo.default.fetchWeatherApi;
Insert cell
// {
// const params = {
// "latitude": 42.3824, // 42.382406, -71.126514
// "longitude": -71.1265,
// "start_date": "2024-01-01",
// "end_date": "2024-12-31",
// "hourly": "temperature_2m"
// };
// const url = "https://archive-api.open-meteo.com/v1/archive";
// const responses = await fetchWeatherApi(url, params);

// // Helper function to form time ranges
// const range = (start, stop, step) =>
// Array.from({ length: (stop - start) / step }, (_, i) => start + i * step);

// console.log(responses);
// console.log("status:");
// console.log(responses.status);

// // Process first location. Add a for-loop for multiple locations or weather models
// const response = responses[0];
// console.log("response");
// console.log(response);
// console.log(response.daily());

// // Attributes for timezone and location
// const utcOffsetSeconds = response.utcOffsetSeconds();
// const timezone = response.timezone();
// const timezoneAbbreviation = response.timezoneAbbreviation();
// const latitude = response.latitude();
// const longitude = response.longitude();

// const hourly = response.hourly();
// if ((hourly === null) || (hourly === undefined)) {
// console.log("problem......");
// return;
// }

// // Note: The order of weather variables in the URL query and the indices below need to match!
// const weatherData = {

// hourly: {
// time: range(Number(hourly.time()), Number(hourly.timeEnd()), hourly.interval()).map(
// (t) => new Date((t + utcOffsetSeconds) * 1000)
// ),
// temperature2m: hourly.variables(0).valuesArray(),
// },

// };

// // `weatherData` now contains a simple structure with arrays for datetime and weather data
// for (let i = 0; i < weatherData.hourly.time.length; i++) {
// console.log(
// weatherData.hourly.time[i].toISOString(),
// weatherData.hourly.temperature2m[i]
// );
// }
// }
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