feat([2fd88f42]): add marker clustering to points view

This commit is contained in:
2026-02-04 13:31:11 +00:00
parent 3a7b7afe9a
commit 4ffb52afbf
4 changed files with 76 additions and 22 deletions

View File

@@ -14,11 +14,13 @@
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-leaflet": "^5.0.0",
"react-leaflet-cluster": "^4.0.0",
"react-leaflet-heatmap-layer-v3": "^3.0.3-beta-1"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
"@types/leaflet": "^1.9.21",
"@types/leaflet.markercluster": "^1.5.6",
"@types/node": "^24.10.1",
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
@@ -1459,6 +1461,16 @@
"@types/geojson": "*"
}
},
"node_modules/@types/leaflet.markercluster": {
"version": "1.5.6",
"resolved": "https://registry.npmjs.org/@types/leaflet.markercluster/-/leaflet.markercluster-1.5.6.tgz",
"integrity": "sha512-I7hZjO2+isVXGYWzKxBp8PsCzAYCJBc29qBdFpquOCkS7zFDqUsUvkEOyQHedsk/Cy5tocQzf+Ndorm5W9YKTQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/leaflet": "^1.9"
}
},
"node_modules/@types/node": {
"version": "24.10.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.10.tgz",
@@ -2855,6 +2867,15 @@
"resolved": "https://registry.npmjs.org/leaflet.heat/-/leaflet.heat-0.2.0.tgz",
"integrity": "sha512-Cd5PbAA/rX3X3XKxfDoUGi9qp78FyhWYurFg3nsfhntcM/MCNK08pRkf4iEenO1KNqwVPKCmkyktjW3UD+h9bQ=="
},
"node_modules/leaflet.markercluster": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz",
"integrity": "sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA==",
"license": "MIT",
"peerDependencies": {
"leaflet": "^1.3.1"
}
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -3178,6 +3199,22 @@
"react-dom": "^19.0.0"
}
},
"node_modules/react-leaflet-cluster": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/react-leaflet-cluster/-/react-leaflet-cluster-4.0.0.tgz",
"integrity": "sha512-Lu75+KOu2ruGyAx8LoCQvlHuw+3CLLJQGEoSk01ymsDN/YnCiRV6ChkpsvaruVyYBPzUHwiskFw4Jo7WHj5qNw==",
"license": "SEE LICENSE IN <LICENSE>",
"dependencies": {
"leaflet.markercluster": "^1.5.3"
},
"peerDependencies": {
"@react-leaflet/core": "^3.0.0",
"leaflet": "^1.9.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-leaflet": "^5.0.0"
}
},
"node_modules/react-leaflet-heatmap-layer-v3": {
"version": "3.0.3-beta-1",
"resolved": "https://registry.npmjs.org/react-leaflet-heatmap-layer-v3/-/react-leaflet-heatmap-layer-v3-3.0.3-beta-1.tgz",

View File

@@ -16,11 +16,13 @@
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-leaflet": "^5.0.0",
"react-leaflet-cluster": "^4.0.0",
"react-leaflet-heatmap-layer-v3": "^3.0.3-beta-1"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
"@types/leaflet": "^1.9.21",
"@types/leaflet.markercluster": "^1.5.6",
"@types/node": "^24.10.1",
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",

View File

@@ -1,6 +1,8 @@
import { useState } from 'react';
import axios from 'axios';
import './App.css';
import 'react-leaflet-cluster/dist/assets/MarkerCluster.css';
import 'react-leaflet-cluster/dist/assets/MarkerCluster.Default.css';
import FileUpload from './components/FileUpload';
import FilterPanel from './components/FilterPanel';
import MapDisplay from './components/MapDisplay';

View File

@@ -28,31 +28,44 @@ const MapDisplay: React.FC<MapDisplayProps> = ({ heatmapData, radiusMultiplier,
return '#66bd63'; // Green
};
import MarkerClusterGroup from 'react-leaflet-cluster';
// ... (imports and interface definitions)
const MapDisplay: React.FC<MapDisplayProps> = ({ heatmapData, radiusMultiplier, viewMode }) => {
// ... (helper functions and state)
const renderPoints = () => (
heatmapData.map((point, idx) => (
<CircleMarker
key={idx}
center={[point.lat, point.lon]}
radius={calculateRadius(point.count)}
pathOptions={{
color: getColor(point.count),
fillColor: getColor(point.count),
fillOpacity: 0.7
}}
>
<Tooltip>
PLZ: {point.plz} <br />
Count: {point.count}
{point.attributes_summary && Object.entries(point.attributes_summary).map(([attr, values]) => (
<div key={attr}>
<strong>{attr}:</strong> {values.join(', ')}
</div>
))}
</Tooltip>
</CircleMarker>
))
<MarkerClusterGroup>
{heatmapData.map((point, idx) => (
<CircleMarker
key={idx}
center={[point.lat, point.lon]}
radius={calculateRadius(point.count)}
pathOptions={{
color: getColor(point.count),
fillColor: getColor(point.count),
fillOpacity: 0.7
}}
>
<Tooltip>
PLZ: {point.plz} <br />
Count: {point.count}
{point.attributes_summary && Object.entries(point.attributes_summary).map(([attr, values]) => (
<div key={attr}>
<strong>{attr}:</strong> {values.join(', ')}
</div>
))}
</Tooltip>
</CircleMarker>
))}
</MarkerClusterGroup>
);
// ... (rest of the component)
};
const renderHeatmap = () => (
<HeatmapLayer
points={heatmapData}