"use strict";
const DATE_FORMAT = {
weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'
};
const LATITUDE = 43.26271;
const LONGITUDE = -2.92528;
const TIMEZONE = "Europe/Madrid";
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");
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}
- max: ${this.t_max}°c
- min: ${this.t_min}°c
${WEATHER2ICON[this.weather]}`;
return day_element;
}
}
function weather2description(weather){
let str = weather.replaceAll("_"," ").toLowerCase();
return str.charAt(0).toUpperCase() + str.slice(1);
}
function processDaily( response_obj ) {
console.log(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 = 90;
let ymargin = 10;
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 hourly_element = document.createElement("article");
hourly_element.setAttribute("class", "hourly-forecast");
hourly_element.innerHTML = `
`;
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));
});
}