From a559bb2487ab6a62c79aa0347a86b21e02f1a1c4 Mon Sep 17 00:00:00 2001 From: Floke Date: Wed, 4 Feb 2026 14:48:47 +0000 Subject: [PATCH] docs([2fd88f42]): finalize documentation and update tasks for heatmap tool --- heatmap-tool/README.md | 77 ++++++++++++++++--- .../frontend/src/components/PlzSelector.tsx | 42 ++++++++++ tasks.md | 20 +++++ 3 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 heatmap-tool/frontend/src/components/PlzSelector.tsx diff --git a/heatmap-tool/README.md b/heatmap-tool/README.md index f563ee0e..051eac9f 100644 --- a/heatmap-tool/README.md +++ b/heatmap-tool/README.md @@ -1,16 +1,73 @@ -# Heatmap Tool +# Heatmap Tool (Standalone) -This directory contains a standalone web application for visualizing data from XLSX files as a heatmap on a map of Germany. +Eine Webanwendung zur Visualisierung von Excel-Daten (XLSX) auf einer Deutschlandkarte. Das Tool aggregiert Daten basierend auf Postleitzahlen (PLZ) und stellt sie entweder als Punkte-Cluster oder als Heatmap dar. -## Description +## Features -The application allows users to upload an XLSX file containing German postal codes (PLZ). It then aggregates the data by postal code and displays it as a heatmap, where the color and size of the markers represent the density of records. The tool automatically detects other columns in the file and creates dynamic filters, allowing users to slice the data and visualize different segments. +* **Excel Upload:** Lädt beliebige `.xlsx` Dateien. Erkennt automatisch die PLZ-Spalte (oder fragt nach, wenn unklar). +* **Datenschutz:** Daten werden nur temporär im RAM des Containers verarbeitet. Keine Datenbank. +* **Visualisierung:** + * **Punkte-Karte:** Kreise pro PLZ, Radius = Anzahl der Einträge. Mit Marker-Clustering beim Herauszoomen. + * **Heatmap:** Klassische Dichte-Darstellung. +* **Interaktive Filter:** Alle anderen Spalten der Excel-Datei werden automatisch zu Filtern (Checkboxen). +* **Dynamische Tooltips:** Benutzer können per Drag-and-Drop konfigurieren, welche Daten im Tooltip eines Punktes angezeigt werden. -## Getting Started +## Installation & Start -To run the application, navigate to the `heatmap-tool` directory and follow the instructions in its `README.md` file. +Das Projekt ist vollständig dockerisiert. -```bash -cd heatmap-tool -``` -Then follow the instructions in `heatmap-tool/README.md`. \ No newline at end of file +1. In das Verzeichnis wechseln: + ```bash + cd heatmap-tool + ``` + +2. Container starten (im Hintergrund): + ```bash + docker-compose up --build -d + ``` + +3. Anwendung öffnen: + * Browser: `http://:5173` (Frontend) + * Die API läuft intern auf Port 8000, ist aber von außen auf Port `8002` gemappt (wird aber durch den Vite-Proxy auf 5173 getunnelt). + +4. Stoppen: + ```bash + docker-compose down + ``` + +## Architektur + +* **Frontend:** React 19, Vite, Leaflet (`react-leaflet`, `react-leaflet-cluster`, `react-leaflet-heatmap-layer-v3`). +* **Backend:** Python FastAPI, Pandas (für Excel-Processing). +* **Kommunikation:** Das Frontend nutzt einen Proxy (`vite.config.ts`), um Anfragen an `/api` an das Backend weiterzuleiten. + +## Lessons Learned & Known Issues (WICHTIG!) + +### 1. Docker Networking & Vite Proxy +* **Problem:** Frontend-Container konnte Backend nicht unter `localhost` oder `127.0.0.1` erreichen. +* **Lösung:** + 1. Beide Services müssen im selben Docker-Netzwerk sein (`networks: - heatmap-net` in `docker-compose.yml`). + 2. Das Frontend darf **nicht** versuchen, die URL hartcodiert aufzurufen. + 3. Stattdessen muss in `vite.config.ts` ein `server.proxy` eingerichtet werden, der `/api` auf `http://backend:8000` (Service-Name!) weiterleitet. + 4. Im Frontend-Code (`App.tsx`, `axios`) werden dann nur relative Pfade genutzt (z.B. `/api/upload`). + +### 2. React 19 vs. Leaflet Libraries +* **Problem:** Viele Leaflet-Plugins (wie `react-leaflet-heatmap-layer-v3`) haben veraltete Peer-Dependencies (z.B. React 17), was bei `npm install` zu Fehlern führt. +* **Lösung:** + * Lokal: Installation mit `--legacy-peer-deps`. + * **Docker Build:** Im `Dockerfile` des Frontends muss zwingend `RUN npm install --legacy-peer-deps` stehen, sonst schlägt der Build fehl. + +### 3. Import/Export Syntax (TypeScript) +* **Problem:** `Uncaught SyntaxError: The requested module ... does not provide an export named ...` +* **Ursache:** Beim Importieren von TypeScript-Interfaces (z.B. `TooltipColumn`) in einer `.tsx` Datei wurde das Schlüsselwort `type` vergessen. +* **Korrekt:** `import type { TooltipColumn } from '../App';` +* **Falsch:** `import { TooltipColumn } from '../App';` (Führt zu Runtime-Fehlern im Browser, da Vite versucht, es als JS-Code zu kompilieren). + +### 4. Endlosschleifen bei Karten-Events (Vorsicht!) +* **Problem:** Versuch, eine "zoom-adaptive Legende" zu bauen, die den `maxCount` basierend auf dem sichtbaren Ausschnitt neu berechnet. +* **Fehler:** Ein `useEffect` oder Event-Handler (`useMapEvents`), der den State (`visibleData`) aktualisiert, löst ein Re-Render der Karte aus. Das Re-Render löst erneut das Event aus -> **Endlosschleife / Stack Overflow**. +* **Status:** Feature wurde reverted. Wenn wir das wieder einbauen, muss der Handler vom Rendering entkoppelt sein (z.B. via `useCallback` oder komplett außerhalb der Render-Logik der Map-Komponente). + +### 5. Daten-Normalisierung +* **Problem:** `KeyError: 'plz'`. Die Excel-Datei hatte "PLZ" (groß), das Backend erwartete "plz" (klein) oder umgekehrt. +* **Lösung:** Das Backend normalisiert jetzt die Spaltennamen intern, bevor die Daten an das Frontend gesendet werden. Das Frontend verlässt sich strikt auf klein geschrieben `plz`, `lat`, `lon`. diff --git a/heatmap-tool/frontend/src/components/PlzSelector.tsx b/heatmap-tool/frontend/src/components/PlzSelector.tsx new file mode 100644 index 00000000..c0542ab8 --- /dev/null +++ b/heatmap-tool/frontend/src/components/PlzSelector.tsx @@ -0,0 +1,42 @@ +// src/components/PlzSelector.tsx +import React, { useState } from 'react'; + +interface PlzSelectorProps { + columns: string[]; + onSubmit: (selectedColumn: string) => void; + isLoading: boolean; +} + +const PlzSelector: React.FC = ({ columns, onSubmit, isLoading }) => { + const [selectedColumn, setSelectedColumn] = useState(columns[0] || ''); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (selectedColumn) { + onSubmit(selectedColumn); + } + }; + + return ( +
+

Postal Code Column Not Found

+

Please select the column containing the postal codes (PLZ) from the list below.

+
+ + +
+
+ ); +}; + +export default PlzSelector; diff --git a/tasks.md b/tasks.md index 6ec719b7..7c2c1c9b 100644 --- a/tasks.md +++ b/tasks.md @@ -38,3 +38,23 @@ - [x] **UI:** Confidence-Ampel und Tooltip für Quellen-Beweise im Frontend implementiert. - [x] **Integrität:** Fehlende API-Endpunkte für Firmen-Erstellung, Bulk-Import und Wiki-Overrides wiederhergestellt. + +## Heatmap Tool (Standalone) + +### Status: Beta (Funktionsfähig mit Basisfunktionen) + +- [x] **Setup:** Projektstruktur mit FastAPI (Backend) und React/Vite (Frontend) aufgesetzt. +- [x] **Daten:** Upload von XLSX-Dateien und automatische PLZ-Erkennung implementiert. +- [x] **Visualisierung:** Leaflet-Karte mit "Points"-Ansicht (CircleMarker) und "Heatmap"-Ansicht (Density) erstellt. +- [x] **Interaktivität:** Dynamische Filterung nach Spaltenwerten implementiert. +- [x] **UI/UX:** Filter-Panel redesignet (Checkboxen, Collapsible) und Tooltip-Manager integriert (Drag & Drop, Sichtbarkeit). +- [x] **Clustering:** Marker Clustering für die Punkte-Ansicht implementiert. +- [x] **Fix:** Docker-Networking Probleme (Vite Proxy) gelöst. +- [x] **Fix:** Infinite-Loop bei zoom-adaptiver Legende durch Revert behoben (Feature als instabil markiert). + +### Offene Punkte & Erweiterungen + +- [ ] **Export:** Funktion "Karte als PNG speichern" implementieren. +- [ ] **Geo-Aggregation:** Aggregation nach Bundesland und Landkreis hinzufügen. +- [ ] **Multi-Layer:** Vergleichsansicht (z.B. Kunden vs. Techniker) durch zweiten Datei-Upload ermöglichen. +