From 0b80dd9da688d9d8d4393cfa31b341c718265179 Mon Sep 17 00:00:00 2001 From: Ekaitz Zarraga Date: Fri, 10 Feb 2023 22:30:20 +0100 Subject: Add daily data when user clicks a day: - Heavy use of function passing - SVG graphs - A lot of fun --- css/style.css | 13 +++++++++ js/index.js | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/css/style.css b/css/style.css index cf7626d..50d1abb 100644 --- a/css/style.css +++ b/css/style.css @@ -17,6 +17,7 @@ body{ .day-forecast { border-radius: 5px; border: 1px solid lightgrey; + cursor: pointer; } .day-forecast h2 { @@ -48,3 +49,15 @@ footer{ margin-right: 1rem; margin-left: 1rem; } + +.temp-label{ + font-size: 4px; + text-anchor: middle; +} +.weather-label{ + font-size: 8px; + text-anchor: middle; +} +.graph-line{ + stroke: lightgrey; +} diff --git a/js/index.js b/js/index.js index c13882f..459a22c 100644 --- a/js/index.js +++ b/js/index.js @@ -84,6 +84,12 @@ function Day(date, t_max, t_min, 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 = `

@@ -103,7 +109,7 @@ function weather2description(weather){ return str.charAt(0).toUpperCase() + str.slice(1); } -function processResponse( response_obj ) { +function processDaily( response_obj ) { console.log(response_obj); let data = response_obj.daily; @@ -128,5 +134,88 @@ function dailyURL(){ fetch( dailyURL() ) .then((r)=>r.json()) - .then(processResponse) + .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 = ` + + ${polyline} + ${dots} + ${labels} + ${icons} + + `; + 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)); + }); +} -- cgit v1.2.3