@@ -64,194 +64,196 @@ <h2 class="w-panel__heading">Latest Available Forecast</h2>
6464
6565
6666 document . addEventListener ( "DOMContentLoaded" , function ( ) {
67-
68- // initialize map
69- var forecastMap = new maplibregl . Map ( {
70- container :'forecast_map' ,
71- style : basemap ,
72- center :[ 39.67458166409534 , 8.709054632756391 ] ,
73- zoom :4.5
74- } )
75-
76- // Create a popup object
77- var popup = new maplibregl . Popup ( {
78- closeButton : false ,
79- closeOnClick : false
80- } ) ;
81-
82- forecastMap . addControl ( new maplibregl . NavigationControl ( ) )
83-
84-
85- // initialize table
86- const forecastContainer = document . getElementById ( 'latestForecast' ) ;
87- const forecastTable = new Handsontable ( forecastContainer , {
88- readOnly : true ,
89- width : '100%' ,
90- rowHeaders : true ,
91- colHeaders : [
92- 'City' ,
93- 'Min Temp {{settings.forecastmanager.ForecastSetting.temp_units}}' ,
94- 'Max Temp {{settings.forecastmanager.ForecastSetting.temp_units}}' ,
95- 'Condition' ] ,
96- columns : [
97- {
98- data : 'city_name' ,
99-
100- } ,
101- {
102- data : 'min_temp' ,
103- } ,
104- {
105- data : 'max_temp' ,
106- } ,
107- {
108- data : 'condition' ,
109- } ,
110- ] ,
111- data :[ ] ,
112- // dropdownMenu: true,
113- multiColumnSorting : true ,
114- // filters: true,
115- manualColumnResize : true ,
116- minSpareRows : 1 ,
117- height : 'auto' ,
118- stretchH : "all" ,
119- licenseKey : 'non-commercial-and-evaluation' // for non-commercial use only
120- } ) ;
121-
122-
123- function populateMap ( data ) {
124- forecastMap . addSource ( "city-forecasts" , {
125- type : "geojson" ,
126- data : data
127- } )
12867
129- forecastMap . addLayer ( {
130- "id" :"city-forecasts" ,
131- "type" :"symbol" ,
132- "layout" : {
133- 'icon-image' : [ 'get' , 'condition_icon' ] ,
134- 'icon-size' : 0.3 ,
135- 'icon-allow-overlap' : true
136- } ,
137- source :"city-forecasts"
68+ const static_path = '{% static "forecastmanager/img/" %}'
69+
70+ // initialize map
71+ var forecastMap = new maplibregl . Map ( {
72+ container :'forecast_map' ,
73+ style : basemap ,
74+ center :[ 39.67458166409534 , 8.709054632756391 ] ,
75+ zoom :4.5
13876 } )
13977
140- var bbox = turf . bbox ( data )
141-
142- forecastMap . fitBounds ( bbox , {
143- padding :{ top : 100 , bottom :100 , left : 100 , right : 100 } ,
144- duration :1000 ,
145- easing : function ( t ) {
146- return t * ( 2 - t ) ; // Cubic easing function
147- }
148- } )
78+ // Create a popup object
79+ var popup = new maplibregl . Popup ( {
80+ closeButton : false ,
81+ closeOnClick : false
82+ } ) ;
14983
150- }
84+ forecastMap . addControl ( new maplibregl . NavigationControl ( ) )
85+
86+
87+ // initialize table
88+ const forecastContainer = document . getElementById ( 'latestForecast' ) ;
89+ const forecastTable = new Handsontable ( forecastContainer , {
90+ readOnly : true ,
91+ width : '100%' ,
92+ rowHeaders : true ,
93+ colHeaders : [
94+ 'City' ,
95+ 'Min Temp {{settings.forecastmanager.ForecastSetting.temp_units}}' ,
96+ 'Max Temp {{settings.forecastmanager.ForecastSetting.temp_units}}' ,
97+ 'Condition' ] ,
98+ columns : [
99+ {
100+ data : 'city_name' ,
101+
102+ } ,
103+ {
104+ data : 'min_temp' ,
105+ } ,
106+ {
107+ data : 'max_temp' ,
108+ } ,
109+ {
110+ data : 'condition' ,
111+ } ,
112+ ] ,
113+ data :[ ] ,
114+ // dropdownMenu: true,
115+ multiColumnSorting : true ,
116+ // filters: true,
117+ manualColumnResize : true ,
118+ minSpareRows : 1 ,
119+ height : 'auto' ,
120+ stretchH : "all" ,
121+ licenseKey : 'non-commercial-and-evaluation' // for non-commercial use only
122+ } ) ;
123+
124+
125+ function populateMap ( data ) {
126+ forecastMap . addSource ( "city-forecasts" , {
127+ type : "geojson" ,
128+ data : data
129+ } )
151130
152- function setForecastData ( forecast_date ) {
153- // Make an HTTP GET request to the API endpoint
154- fetch ( `{% url 'forecast-list'%}?forecast_date= ${ forecast_date } ` )
155- . then ( response => response . json ( ) ) // Parse the response as JSON
156- . then ( data => {
157- // Process the retrieved data
158- data . map ( icon => {
159-
160-
161- let img = new Image ( )
131+ forecastMap . addLayer ( {
132+ "id" : "city-forecasts" ,
133+ "type" : "symbol" ,
134+ "layout" : {
135+ 'icon-image' : [ 'get' , 'condition_icon' ] ,
136+ 'icon-size' : 0.3 ,
137+ 'icon-allow-overlap' : true
138+ } ,
139+ source : "city-forecasts"
140+ } )
162141
163- img . onload = ( ) => {
164- if ( ! forecastMap . hasImage ( icon . properties . condition_icon ) ) {
165- return forecastMap . addImage ( `${ icon . properties . condition_icon } ` , img )
166- }
142+ var bbox = turf . bbox ( data )
167143
144+ forecastMap . fitBounds ( bbox , {
145+ padding :{ top : 100 , bottom :100 , left : 100 , right : 100 } ,
146+ duration :1000 ,
147+ easing : function ( t ) {
148+ return t * ( 2 - t ) ; // Cubic easing function
168149 }
169- img . src = `{% static 'forecastmanager/img/${ icon . properties . condition_icon } ' %}`
170- return img . src
171-
172- } )
173- // Access and use the data as needed
174- populateMap ( {
175- type : "FeatureCollection" ,
176- features :data
177- } )
178-
179- var forecasts_props = [ ]
180- data . map ( latest_forecast => {
181- forecasts_props . push ( latest_forecast . properties )
182150 } )
183151
184- forecastTable . loadData ( forecasts_props )
185-
186-
187- } )
188- . catch ( error => {
189- // Handle any errors that occurred during the request
190- console . error ( 'Error:' , error ) ;
191- } ) ;
152+ }
192153
193- }
154+ function setForecastData ( forecast_date ) {
155+ // Make an HTTP GET request to the API endpoint
156+ fetch ( `{% url 'forecast-list'%}?forecast_date=${ forecast_date } ` )
157+ . then ( response => response . json ( ) ) // Parse the response as JSON
158+ . then ( data => {
159+ // Process the retrieved data
160+ data . map ( icon => {
161+
162+
163+ let img = new Image ( )
164+
165+ img . onload = ( ) => {
166+ if ( ! forecastMap . hasImage ( icon . properties . condition_icon ) ) {
167+ return forecastMap . addImage ( `${ icon . properties . condition_icon } ` , img )
168+ }
194169
195- var initDate = document . getElementById ( "forecast_date" ) ;
196- setForecastData ( initDate . value )
197-
170+ }
171+ img . src = `${ static_path } ${ icon . properties . condition_icon } `
172+ return img . src
173+
174+ } )
175+ // Access and use the data as needed
176+ populateMap ( {
177+ type : "FeatureCollection" ,
178+ features :data
179+ } )
180+
181+ var forecasts_props = [ ]
182+ data . map ( latest_forecast => {
183+ forecasts_props . push ( latest_forecast . properties )
184+ } )
185+
186+ forecastTable . loadData ( forecasts_props )
187+
188+
189+ } )
190+ . catch ( error => {
191+ // Handle any errors that occurred during the request
192+ console . error ( 'Error:' , error ) ;
193+ } ) ;
198194
199- forecastMap . on ( "load" , ( ) => {
200-
201- // When a click event occurs on a feature in the places layer, open a popup at the
202- // location of the feature, with description HTML from its properties.
203- forecastMap . on ( "mouseenter" , "city-forecasts" , ( e ) => {
204- // Get the feature that was hovered over
205- var feature = e . features [ 0 ] ;
206- forecastMap . getCanvas ( ) . style . cursor = "pointer" ;
207-
208- // Copy coordinates array.
209- const city_name = feature . properties . city_name ;
210- const condition_desc = feature . properties . condition ;
211- const min_temp = feature . properties . min_temp ;
212- const max_temp = feature . properties . max_temp ;
213-
214-
215- popup . setLngLat ( feature . geometry . coordinates )
216- . setHTML ( `
217- <div class="block" style="margin:10px; width:200px">
218- <h2 class="title" style="font-size:18px;">${ city_name } </h2>
219- <h2 class="subtitle" style="font-size:14px;">${ condition_desc } </h2>
220- <hr>
221- <p><b>Min Temperature: </b>${ min_temp } °C</p>
222- <p><b>Max Temperature: </b>${ max_temp } °C</p>
223- </div>` )
224- . addTo ( forecastMap ) ;
225- } ) ;
195+ }
226196
227- // // Change the cursor to a pointer when the mouse is over the places layer.
228- // forecastMap.on("mouseenter", "city-forecasts", () => {
229- // forecastMap.getCanvas().style.cursor = "pointer";
230- // });
197+ var initDate = document . getElementById ( "forecast_date" ) ;
198+ setForecastData ( initDate . value )
199+
200+
201+ forecastMap . on ( "load" , ( ) => {
202+
203+ // When a click event occurs on a feature in the places layer, open a popup at the
204+ // location of the feature, with description HTML from its properties.
205+ forecastMap . on ( "mouseenter" , "city-forecasts" , ( e ) => {
206+ // Get the feature that was hovered over
207+ var feature = e . features [ 0 ] ;
208+ forecastMap . getCanvas ( ) . style . cursor = "pointer" ;
209+
210+ // Copy coordinates array.
211+ const city_name = feature . properties . city_name ;
212+ const condition_desc = feature . properties . condition ;
213+ const min_temp = feature . properties . min_temp ;
214+ const max_temp = feature . properties . max_temp ;
215+
216+
217+ popup . setLngLat ( feature . geometry . coordinates )
218+ . setHTML ( `
219+ <div class="block" style="margin:10px; width:200px">
220+ <h2 class="title" style="font-size:18px;">${ city_name } </h2>
221+ <h2 class="subtitle" style="font-size:14px;">${ condition_desc } </h2>
222+ <hr>
223+ <p><b>Min Temperature: </b>${ min_temp } °C</p>
224+ <p><b>Max Temperature: </b>${ max_temp } °C</p>
225+ </div>` )
226+ . addTo ( forecastMap ) ;
227+ } ) ;
228+
229+ // // Change the cursor to a pointer when the mouse is over the places layer.
230+ // forecastMap.on("mouseenter", "city-forecasts", () => {
231+ // forecastMap.getCanvas().style.cursor = "pointer";
232+ // });
233+
234+ // Change it back to a pointer when it leaves.
235+ forecastMap . on ( "mouseleave" , "city-forecasts" , ( ) => {
236+ popup . remove ( )
237+ forecastMap . getCanvas ( ) . style . cursor = "" ;
238+ } ) ;
239+ } )
231240
232- // Change it back to a pointer when it leaves.
233- forecastMap . on ( "mouseleave" , "city-forecasts" , ( ) => {
234- popup . remove ( )
235- forecastMap . getCanvas ( ) . style . cursor = "" ;
236- } ) ;
237- } )
238-
239- $ ( '#forecast_date' ) . on ( 'change' , function ( e ) {
240- var optionSelected = $ ( "option:selected" , this ) ;
241- var valueSelected = this . value ;
242-
243- if ( forecastMap . getLayer ( "city-forecasts" ) ) {
244- forecastMap . removeLayer ( "city-forecasts" ) ;
245- }
241+ $ ( '#forecast_date' ) . on ( 'change' , function ( e ) {
242+ var optionSelected = $ ( "option:selected" , this ) ;
243+ var valueSelected = this . value ;
244+
245+ if ( forecastMap . getLayer ( "city-forecasts" ) ) {
246+ forecastMap . removeLayer ( "city-forecasts" ) ;
247+ }
246248
247- if ( forecastMap . getSource ( "city-forecasts" ) ) {
248- forecastMap . removeSource ( "city-forecasts" ) ;
249- }
249+ if ( forecastMap . getSource ( "city-forecasts" ) ) {
250+ forecastMap . removeSource ( "city-forecasts" ) ;
251+ }
250252
251- setForecastData ( valueSelected )
253+ setForecastData ( valueSelected )
252254
253255
254- } )
256+ } )
255257
256258 } )
257259 </ script >
0 commit comments