@@ -29,11 +29,23 @@ const {
2929 updateLayers,
3030} = useMap ()
3131
32- useDownloadGrid ()
32+ const { hoveredGridCell, hoveredGridPosition } = useDownloadGrid ()
3333
3434const { addMapClickHandler } = useAreaOfInterest ()
3535const { setAvailableModels, settings } = useSettings ()
3636
37+ function formatDeg(value : number , isLat : boolean ): string {
38+ const abs = Math .abs (value )
39+ const dir = isLat ? (value >= 0 ? ' N' : ' S' ) : value >= 0 ? ' E' : ' W'
40+ return ` ${abs }°${dir } `
41+ }
42+
43+ function formatBytes(bytes : number ): string {
44+ if (bytes >= 1024 * 1024 ) return ` ${(bytes / (1024 * 1024 )).toFixed (1 )} MB `
45+ if (bytes >= 1024 ) return ` ${(bytes / 1024 ).toFixed (1 )} KB `
46+ return ` ${bytes } B `
47+ }
48+
3749const clearResults = () => {
3850 geoJsonResults .value = []
3951 hidePropertiesBox ()
@@ -121,6 +133,50 @@ defineExpose({
121133 />
122134
123135 <GlobalFeedbackWidget v-if =" map && settings.mode === 'global'" />
136+
137+ <!-- Download grid hover tooltip -->
138+ <div
139+ v-if =" hoveredGridCell && hoveredGridPosition && settings.downloads"
140+ class =" download-grid-tooltip"
141+ :style =" { left: hoveredGridPosition.x + 16 + 'px', top: hoveredGridPosition.y + 16 + 'px' }"
142+ >
143+ <div class =" download-grid-tooltip__title" >
144+ {{ settings.year }}_{{ hoveredGridCell.tile_id }}.parquet
145+ </div >
146+ <div class =" download-grid-tooltip__row" >
147+ <span class =" download-grid-tooltip__label" >Year</span >
148+ {{ settings.year }}
149+ </div >
150+ <div class =" download-grid-tooltip__row" >
151+ <span class =" download-grid-tooltip__label" >Lat</span >
152+ {{ formatDeg(hoveredGridCell.lat_min, true) }} –
153+ {{ formatDeg(hoveredGridCell.lat_min + 1, true) }}
154+ </div >
155+ <div class =" download-grid-tooltip__row" >
156+ <span class =" download-grid-tooltip__label" >Lon</span >
157+ {{ formatDeg(hoveredGridCell.lon_min, false) }} –
158+ {{ formatDeg(hoveredGridCell.lon_min + 1, false) }}
159+ </div >
160+ <template v-if =" hoveredGridCell .years .includes (settings .year )" >
161+ <div
162+ v-if =" hoveredGridCell.feature_counts?.[String(settings.year)] != null"
163+ class =" download-grid-tooltip__row"
164+ >
165+ <span class =" download-grid-tooltip__label" >Fields</span >
166+ {{ hoveredGridCell.feature_counts![String(settings.year)].toLocaleString() }}
167+ </div >
168+ <div
169+ v-if =" hoveredGridCell.size_bytes?.[String(settings.year)] != null"
170+ class =" download-grid-tooltip__row"
171+ >
172+ <span class =" download-grid-tooltip__label" >Download size</span >
173+ {{ formatBytes(hoveredGridCell.size_bytes![String(settings.year)]) }}
174+ </div >
175+ </template >
176+ <div v-else class =" download-grid-tooltip__unavailable" >
177+ Not available for {{ settings.year }}
178+ </div >
179+ </div >
124180 </div >
125181
126182 <!-- Properties Box -->
@@ -195,6 +251,47 @@ defineExpose({
195251 height : 100% ;
196252}
197253
254+ /* Download Grid Tooltip */
255+ .download-grid-tooltip {
256+ position : absolute ;
257+ z-index : 9000 ;
258+ pointer-events : none ;
259+ background-color : rgba (0 , 0 , 0 , 0.9 );
260+ border : 1px solid rgba (0 , 136 , 136 , 0.7 );
261+ border-radius : 6px ;
262+ padding : 0.5rem 0.75rem ;
263+ min-width : 180px ;
264+ font-size : 0.8rem ;
265+ color : #eee ;
266+ box-shadow : 0 2px 10px rgba (0 , 0 , 0 , 0.5 );
267+ backdrop-filter : blur (6px );
268+ }
269+
270+ .download-grid-tooltip__title {
271+ font-weight : 600 ;
272+ color : rgb (0 , 200 , 200 );
273+ margin-bottom : 0.35rem ;
274+ font-size : 0.85rem ;
275+ }
276+
277+ .download-grid-tooltip__row {
278+ display : flex ;
279+ justify-content : space-between ;
280+ gap : 0.75rem ;
281+ line-height : 1.6 ;
282+ }
283+
284+ .download-grid-tooltip__label {
285+ color : #aaa ;
286+ white-space : nowrap ;
287+ }
288+
289+ .download-grid-tooltip__unavailable {
290+ color : #f87171 ;
291+ margin-top : 0.25rem ;
292+ font-size : 0.75rem ;
293+ }
294+
198295/* Properties Box Styles */
199296.properties-box {
200297 position : fixed ;
0 commit comments