Skip to content

Commit 0f40e4a

Browse files
authored
Merge pull request #57 from UTSC-CSCC01-Software-Engineering-I/develop
Develop
2 parents e0a3c51 + a5eb8db commit 0f40e4a

File tree

2 files changed

+99
-49
lines changed

2 files changed

+99
-49
lines changed

frontend/src/components/HUDleftPoints.jsx

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,18 @@ function LogoBlock() {
243243
const handleBeachClick = (item) => {
244244
// Also trigger map search if the function exists
245245
if (window.handleMapSearch) {
246-
// Use siteName for API points or coordinates for user points
246+
// Get the exact coordinates, ensuring we're using the right property names
247+
const lat = item.lat || item.Latitude;
248+
const lon = item.lng || item.lon || item.Longitude;
249+
250+
// Get a name for the search
247251
const searchIdentifier = item.siteName ||
248-
(item.isUserPoint ? `User Point (${item.lat},${item.lon})` : 'Unknown Point');
249-
window.handleMapSearch(searchIdentifier, item.lat, item.lon);
252+
(item.isUserPoint ? `User Point (${lat},${lon})` : 'Unknown Point');
253+
254+
// ALWAYS force popup to open with true parameter
255+
window.handleMapSearch(searchIdentifier, lat, lon, true);
256+
257+
console.log(`Clicked point: ${searchIdentifier} at ${lat},${lon}`);
250258
}
251259
};
252260

@@ -293,6 +301,25 @@ function LogoBlock() {
293301
return () => document.removeEventListener('mousedown', handleClickOutside);
294302
}, [showSortMenu]);
295303

304+
// NEW: dispatch filterchange event
305+
const handleApplyFilter = () => {
306+
const min = parseFloat(tempFilter.min);
307+
const max = parseFloat(tempFilter.max);
308+
window.dispatchEvent(new CustomEvent('filterchange', {
309+
detail: { min: isNaN(min) ? NaN : min, max: isNaN(max) ? NaN : max }
310+
}));
311+
setShowFilterModal(false);
312+
};
313+
314+
// NEW: reset filter AND dispatch
315+
const handleResetFilter = () => {
316+
setTempFilter({ min: '', max: '' });
317+
window.dispatchEvent(new CustomEvent('filterchange', {
318+
detail: { min: NaN, max: NaN }
319+
}));
320+
setShowFilterModal(false);
321+
};
322+
296323
return (
297324
<div
298325
className="boxwithpoints"
@@ -404,7 +431,7 @@ function LogoBlock() {
404431
position: 'absolute',
405432
top: 'calc(100% + 0.25rem)',
406433
right: 0,
407-
backgroundColor: theme === 'light' ? '#e6e6e6bb' : '#00000086',
434+
backgroundColor: theme === 'light' ? '#dadadae1' : '#242424f1',
408435
boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
409436
color: theme === 'light' ? '#000' : '#fff',
410437
borderRadius: '1rem',
@@ -789,8 +816,8 @@ function LogoBlock() {
789816
theme={theme}
790817
tempFilter={tempFilter}
791818
setTempFilter={setTempFilter}
792-
applyTempFilter={tempFilter}
793-
resetTempFilter={setTempFilter}
819+
applyTempFilter={handleApplyFilter} // use handler
820+
resetTempFilter={handleResetFilter} // use handler
794821
/>
795822
</div>
796823
);

frontend/src/components/MapComponent.jsx

Lines changed: 66 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -255,19 +255,31 @@ export default function MapComponent() {
255255

256256
const historicalData = await fetchHistoricalData(name);
257257

258+
// add once at top of click‐handler so you can reuse
259+
const popupOffset = [17, -32]; // x=0 (center), y=−45px (above marker)
260+
258261
if (historicalData.length === 0) {
259262
marker.bindPopup(`
260263
<div role="dialog" aria-labelledby="popup-title-${i}">
261264
<h3 id="popup-title-${i}">${name}</h3>
262265
<p>No historical data available</p>
263266
<p>Current temperature: ${formattedTemp} (${tempCategory})</p>
264267
</div>
265-
`).openPopup();
268+
`, {
269+
offset: popupOffset,
270+
className: 'custom-popup'
271+
}).openPopup();
266272
return;
267273
}
268274

269275
if (historicalData.length < 2) {
270-
marker.bindPopup(`<strong>${name}</strong><br/>Not enough data to generate a graph`).openPopup();
276+
marker.bindPopup(
277+
`<strong>${name}</strong><br/>Not enough data to generate a graph`,
278+
{
279+
offset: popupOffset,
280+
className: 'custom-popup'
281+
}
282+
).openPopup();
271283
return;
272284
}
273285

@@ -442,7 +454,7 @@ export default function MapComponent() {
442454

443455
// Open popup
444456
const popup = L.popup({
445-
offset: [10, -20],
457+
offset: popupOffset,
446458
maxWidth: 650,
447459
maxHeight: 470,
448460
className: 'custom-popup'
@@ -602,44 +614,45 @@ export default function MapComponent() {
602614
const removeUnitListener = UnitManager.addUnitChangeListener((newUnit) => {
603615
setUnit(newUnit); // Update local state for legend
604616

605-
markersRef.current.forEach(({ marker, tempC, name }) => {
606-
// Use formatTemperature utility for consistent formatting
617+
markersRef.current.forEach(({ marker, tempC }) => {
618+
// 1) compute the new label
607619
const formattedTemp = formatTemperature(tempC, newUnit);
608-
const tempColor = getTemperatureColor(tempC, 'C'); // Always calculate color from Celsius
609-
610-
// Update marker icon
611-
marker.setIcon(window.L.divIcon({
612-
className: 'custom-temp-marker',
613-
html: `<div class="temp-label" style="background-color: ${tempColor};">${formattedTemp}</div>`,
614-
iconSize: [40, 40],
615-
iconAnchor: [20, 20],
616-
}));
617620

618-
// Update the graph if it exists
619-
if (marker.chartInstance && marker.chartData) {
620-
const chart = marker.chartInstance;
621-
622-
// Convert original data to new unit with time structure
623-
const newTimeBasedData = marker.chartData.map((d) => ({
624-
x: new Date(d.timestamp),
625-
y: newUnit === 'F' ? (d.temp * 9) / 5 + 32 : d.temp
626-
}));
621+
// 2) find the existing <span class="temp-value"> and update it
622+
const el = marker.getElement();
623+
if (el) {
624+
const valueSpan = el.querySelector('.temp-value');
625+
if (valueSpan) valueSpan.textContent = formattedTemp;
626+
}
627627

628-
// Update dataset with time-based data
629-
chart.data.datasets[0].data = newTimeBasedData;
628+
// 3) leave the background‐color alone so it never “snaps back” after a refresh
629+
// (skip marker.setIcon entirely)
630+
});
630631

631-
// Update the y-axis title
632-
chart.options.scales.y.title.text = `Temperature (°${newUnit})`;
633-
634-
// Update y-axis tick callback
635-
chart.options.scales.y.ticks.callback = function(value) {
636-
return `${value}°${newUnit}`;
637-
};
632+
// Update the graph if it exists
633+
if (marker.chartInstance && marker.chartData) {
634+
const chart = marker.chartInstance;
635+
636+
// Convert original data to new unit with time structure
637+
const newTimeBasedData = marker.chartData.map((d) => ({
638+
x: new Date(d.timestamp),
639+
y: newUnit === 'F' ? (d.temp * 9) / 5 + 32 : d.temp
640+
}));
638641

639-
// Apply the updates
640-
chart.update();
641-
}
642-
});
642+
// Update dataset with time-based data
643+
chart.data.datasets[0].data = newTimeBasedData;
644+
645+
// Update the y-axis title
646+
chart.options.scales.y.title.text = `Temperature (°${newUnit})`;
647+
648+
// Update y-axis tick callback
649+
chart.options.scales.y.ticks.callback = function(value) {
650+
return `${value}°${newUnit}`;
651+
};
652+
653+
// Apply the updates
654+
chart.update();
655+
}
643656
});
644657

645658
// Listen for theme changes
@@ -762,7 +775,7 @@ export default function MapComponent() {
762775
// }, []);
763776

764777
// Handle beach search by name or coordinates
765-
function handleSearch(selectedName, lat, lon) {
778+
function handleSearch(selectedName, lat, lon, forcePopup = false) {
766779
if (!mapInstanceRef.current) return;
767780

768781
// If direct coordinates are provided, use them
@@ -773,6 +786,16 @@ export default function MapComponent() {
773786
const offsetX = 0;
774787
const targetLatLng = [lat, lon];
775788

789+
// Find the marker that matches these coordinates before animation starts
790+
let targetMarker = null;
791+
markersRef.current.forEach(({marker, lat: markerLat, lon: markerLon}) => {
792+
// Use a larger tolerance for coordinate matching (0.005 is about 500m)
793+
if (Math.abs(markerLat - lat) < 0.005 && Math.abs(markerLon - lon) < 0.005) {
794+
console.log('Found matching marker at', markerLat, markerLon);
795+
targetMarker = marker;
796+
}
797+
});
798+
776799
// Calculate offset points for smooth animation
777800
const currentZoom = map.getZoom();
778801
const pointAtCurrentZoom = map.project(targetLatLng, currentZoom);
@@ -783,10 +806,10 @@ export default function MapComponent() {
783806
map.once('moveend', function() {
784807
// After panning completes, smoothly zoom in
785808
map.once('zoomend', function() {
786-
// Find and open any popup that might be at this location
787-
markersRef.current.forEach(({marker, lat: markerLat, lon: markerLon}) => {
809+
// replace marker.openPopup() with marker.fire('click')
810+
markersRef.current.forEach(({ marker, lat: markerLat, lon: markerLon }) => {
788811
if (Math.abs(markerLat - lat) < 0.0001 && Math.abs(markerLon - lon) < 0.0001) {
789-
marker.openPopup();
812+
marker.fire('click');
790813
}
791814
});
792815
});
@@ -832,13 +855,13 @@ export default function MapComponent() {
832855
map.once('moveend', function() {
833856
// After panning completes, smoothly zoom in
834857
map.once('zoomend', function() {
835-
// After zooming completes, open the popup
836-
match.marker.openPopup();
858+
// fire the click event so your click-handler builds the popup & chart
859+
match.marker.fire('click');
837860
});
838861

839862
// Animate zoom with a duration in ms
840863
map.flyTo(offsetLatLng, targetZoom, {
841-
duration: 0.5, // seconds
864+
duration: 0.5,
842865
easeLinearity: 0.2
843866
});
844867
});

0 commit comments

Comments
 (0)