summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2023-02-10 22:30:20 +0100
committerEkaitz Zarraga <ekaitz@elenq.tech>2023-02-10 23:39:22 +0100
commit0b80dd9da688d9d8d4393cfa31b341c718265179 (patch)
tree8695abbd77bb2e71e7cecd5f2b9d48472acae7a9
parent77d1847e2de8077cea8854a15406a99c14aee2d8 (diff)
Add daily data when user clicks a day:
- Heavy use of function passing - SVG graphs - A lot of fun
-rw-r--r--css/style.css13
-rw-r--r--js/index.js93
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));
+ });
+}