"use strict"; const DATE_FORMAT = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; const LATITUDE = 43.26271; const LONGITUDE = -2.92528; const TIMEZONE = "auto"; const WEATHERS = [ "CLEAR_SKY", "MAINLY_CLEAR", "FOG", "DRIZZLE", "FREEZING_DRIZZLE", "RAIN", "FREEZING_RAIN", "SNOW_FALL", "SNOW_GRAINS", "RAIN_SHOWERS", "SNOW_SHOWERS", "THUNDERSTORM", "THUNDERSTORM_HAIL" ]; // We can use some symbols from here: // https://www.alt-codes.net/weather-symbols.php const WEATHER2ICON = { CLEAR_SKY: "🌣", MAINLY_CLEAR: "🌤", FOG: "🌫", DRIZZLE: "🌦", FREEZING_DRIZZLE: "🌦", RAIN: "🌧", FREEZING_RAIN: "🌧", SNOW_FALL: "🌨", SNOW_GRAINS: "🌨", RAIN_SHOWERS: "🌧", SNOW_SHOWERS: "🌨", THUNDERSTORM: "🌩", THUNDERSTORM_HAIL: "🌩", }; const WMO_CONVERTER = { 0: "CLEAR_SKY", 1: "MAINLY_CLEAR", 2: "MAINLY_CLEAR", 3: "MAINLY_CLEAR", 45: "FOG", 48: "FOG", 51: "DRIZZLE", 53: "DRIZZLE", 55: "DRIZZLE", 56: "FREEZING_DRIZZLE", 57: "FREEZING_DRIZZLE", 61: "RAIN", 63: "RAIN", 65: "RAIN", 66: "FREEZING_RAIN", 67: "FREEZING_RAIN", 71: "SNOW_FALL", 73: "SNOW_FALL", 75: "SNOW_FALL", 77: "SNOW_GRAINS", 80: "RAIN_SHOWERS", 81: "RAIN_SHOWERS", 82: "RAIN_SHOWERS", 85: "SNOW_SHOWERS", 86: "SNOW_SHOWERS", 95: "THUNDERSTORM", 96: "THUNDERSTORM_HAIL", 99: "THUNDERSTORM_HAIL" }; function appendDay(date, t_max, t_min, weather){ let week_container = document.querySelector(".forecast"); let day_element = new Day(date, t_max, t_min, weather); week_container.appendChild(day_element.createHTML()); } function Day(date, t_max, t_min, weather){ this.date = date; this.t_max = t_max; this.t_min = t_min; this.weather = weather; this.weather_desc = weather2description(weather); this.createHTML = function (){ let day_element = document.createElement("article"); day_element.setAttribute("class", "day-forecast-container"); day_element.addEventListener("click", dayFetcher(this.date, (html)=>{ document.querySelectorAll(".hourly-forecast").forEach((x)=>x.remove()); day_element.appendChild(html); })); day_element.innerHTML = `

${this.weather_desc}

${WEATHER2ICON[this.weather]}
`; return day_element; } } function weather2description(weather){ let str = weather.replaceAll("_"," "); return str; } function processDaily( response_obj ) { let data = response_obj.daily; // Our variables are here: let time = data.time; let temp_max = data.temperature_2m_max; let temp_min = data.temperature_2m_min; let code = data.weathercode; for(let i = 0; i < time.length; i++){ appendDay(time[i], temp_max[i], temp_min[i], WMO_CONVERTER[code[i]]); } } function dailyURL(){ return `https://api.open-meteo.com/v1/forecast`+ `?latitude=${LATITUDE}` + `&longitude=${LONGITUDE}` + `&timezone=${TIMEZONE}` + `&daily=temperature_2m_max,temperature_2m_min,weathercode` } fetch( dailyURL() ) .then((r)=>r.json()) .then(processDaily) .catch((err)=>console.error(err)); // Hourly data function hourlyURL(date){ return `https://api.open-meteo.com/v1/forecast`+ `?latitude=${LATITUDE}` + `&longitude=${LONGITUDE}` + `&timezone=${TIMEZONE}` + `&hourly=temperature_2m,weathercode`+ `&start_date=${date}`+ `&end_date=${date}`; } function project(v, minv, maxv, min, max){ let r = (v - minv)/(maxv - minv); return ((max-min)*r)+min; } function processHourly(data){ let hourly_data = data.hourly; let temperature_unit = data.hourly_units.temperature_2m; let weathercode = hourly_data.weathercode; let temperature = hourly_data.temperature_2m; let time = hourly_data.time; let points = []; let t_min = Math.min.apply(null, temperature); let t_max = Math.max.apply(null, temperature); let xsize = 300; let xmargin = 15; let ysize = 120; let ymargin = 30; for( let i in temperature ){ points.push( [project(i, 0, temperature.length, xmargin, xsize-xmargin), project(temperature[i], t_min, t_max, ysize-ymargin, 0+20)] ); } let pointstring = points.map((el)=>el[0].toString() + "," + el[1].toString() ).join(" "); let polyline = ``; let dots = points.map( (el)=> ` `).join(""); let labels = "" for( let i in points){ labels += ` `+ `${Math.round(temperature[i])}${temperature_unit}`; } let icons = "" for( let i in points){ labels += `` + `${WEATHER2ICON[WMO_CONVERTER[weathercode[i]]]}`; } let times = "" for( let i in points){ let t = new Date(time[i]); let hours = t.getHours(); let mins = t.getMinutes(); if (hours < 10) { hours = `0${hours}` } else { hours = `${hours}` } if (mins < 10) { mins = `0${mins}` } else { mins = `${mins}` } labels += `${hours}:${mins}`; } let hourly_element = document.createElement("article"); hourly_element.setAttribute("class", "hourly-forecast"); hourly_element.innerHTML = ` ${polyline} ${dots} ${labels} ${icons} ${times} `; return hourly_element; } function dayFetcher(date, insertionFunction){ return (function () { fetch( hourlyURL(date) ) .then((r)=>r.json()) .then(processHourly) .then(insertionFunction) .catch((err)=>console.error(err)); }); }