revert([2fd88f42]): remove zoom-adaptive legend due to critical errors

This commit is contained in:
2026-02-04 14:09:50 +00:00
parent 1c5db811a8
commit 9e947b6dfb
4 changed files with 127 additions and 65 deletions

View File

@@ -1,15 +1,12 @@
// src/components/MapDisplay.tsx
import React, { useState, useEffect, useCallback } from 'react';
import { MapContainer, TileLayer, CircleMarker, Tooltip, useMapEvents } from 'react-leaflet';
import React from 'react';
import { MapContainer, TileLayer, CircleMarker, Tooltip } from 'react-leaflet';
import { HeatmapLayer } from 'react-leaflet-heatmap-layer-v3';
import 'leaflet/dist/leaflet.css';
import 'leaflet.heat';
import type { HeatmapPoint, MapMode } from '../App';
import MarkerClusterGroup from 'react-leaflet-cluster';
import Legend from './Legend';
import MapBoundsManager from './MapBoundsManager';
import { LatLngBounds } from 'leaflet';
interface MapDisplayProps {
heatmapData: HeatmapPoint[];
@@ -17,48 +14,21 @@ interface MapDisplayProps {
viewMode: MapMode;
}
// This component listens to map events and calls a callback when the view changes
const DynamicLegendHandler = ({ onBoundsChange }: { onBoundsChange: (bounds: LatLngBounds) => void }) => {
const map = useMapEvents({
zoomend: () => onBoundsChange(map.getBounds()),
moveend: () => onBoundsChange(map.getBounds()),
load: () => onBoundsChange(map.getBounds()), // Handle initial load
});
return null;
};
const MapDisplay: React.FC<MapDisplayProps> = ({ heatmapData, radiusMultiplier, viewMode }) => {
const germanyCenter: [number, number] = [51.1657, 10.4515];
const [visibleData, setVisibleData] = useState<HeatmapPoint[]>(heatmapData);
const dynamicMaxCount = Math.max(...visibleData.map(p => p.count), 1);
const maxCount = Math.max(...heatmapData.map(p => p.count), 1);
const calculateRadius = (count: number) => {
return 3 + Math.log(count + 1) * 5 * radiusMultiplier;
};
const getColor = (count: number) => {
const ratio = count / dynamicMaxCount;
const ratio = count / maxCount;
if (ratio > 0.8) return '#d73027'; // Red
if (ratio > 0.5) return '#fdae61'; // Orange
if (ratio > 0.2) return '#fee08b'; // Yellow
return '#66bd63'; // Green
};
const updateVisibleData = useCallback((bounds: LatLngBounds) => {
const visible = heatmapData.filter(p =>
bounds.contains([p.lat, p.lon])
);
setVisibleData(visible.length > 0 ? visible : heatmapData); // Fallback to all data if none are visible
}, [heatmapData]);
// Reset visible data when heatmapData changes
useEffect(() => {
setVisibleData(heatmapData);
}, [heatmapData]);
const renderPoints = () => (
<MarkerClusterGroup>
@@ -95,7 +65,7 @@ const MapDisplay: React.FC<MapDisplayProps> = ({ heatmapData, radiusMultiplier,
intensityExtractor={(p: HeatmapPoint) => p.count}
radius={25}
blur={20}
max={dynamicMaxCount * 0.1}
max={maxCount * 0.1} // Adjust max intensity for better visualization
/>
);
@@ -103,6 +73,7 @@ const MapDisplay: React.FC<MapDisplayProps> = ({ heatmapData, radiusMultiplier,
return (
<div style={{ textAlign: 'center', paddingTop: '50px' }}>
<p>No data to display on the map.</p>
<p>Upload a file and apply filters to see the heatmap.</p>
</div>
);
}
@@ -113,12 +84,10 @@ const MapDisplay: React.FC<MapDisplayProps> = ({ heatmapData, radiusMultiplier,
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
/>
<MapBoundsManager data={heatmapData} />
<DynamicLegendHandler onBoundsChange={updateVisibleData} />
{viewMode === 'points' ? renderPoints() : renderHeatmap()}
{viewMode === 'points' && <Legend getColor={getColor} maxCount={dynamicMaxCount} />}
{viewMode === 'points' && <Legend getColor={getColor} maxCount={maxCount} />}
</MapContainer>
);
};
export default MapDisplay;
export default MapDisplay;