diff options
-rw-r--r-- | css/style.css | 13 | ||||
-rw-r--r-- | 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 = ` <div class="day-forecast-text"> <h2><time datetime="${this.date}">${(new Date(this.date)).toLocaleDateString(undefined, DATE_FORMAT)}</h2> @@ -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 = `<polyline class="graph-line" points="${pointstring}" fill="none" stroke="black" />`; + + let dots = points.map( (el)=> ` + <circle cx="${el[0]}" cy="${el[1]}" r="1.5" /> + `).join(""); + + let labels = "" + for( let i in points){ + labels += ` + <text x="${points[i][0]}" y="${points[i][1]-2}" class="temp-label">`+ + `${Math.round(temperature[i])}${temperature_unit}</text>`; + } + + let icons = "" + for( let i in points){ + labels += `<text x="${points[i][0]}" y="10" class="weather-label">` + + `${WEATHER2ICON[WMO_CONVERTER[weathercode[i]]]}</text>`; + } + + let hourly_element = document.createElement("article"); + hourly_element.setAttribute("class", "hourly-forecast"); + + hourly_element.innerHTML = ` + <svg viewBox="0 0 ${xsize} ${ysize}" xmlns="http://www.w3.org/2000/svg"> + ${polyline} + ${dots} + ${labels} + ${icons} + </svg> + `; + 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)); + }); +} |