feat([2fd88f42]): add adjustable marker radius and collapse filters by default

This commit is contained in:
2026-02-04 13:16:35 +00:00
parent 3aacac97f0
commit 61f7f0586c
3 changed files with 37 additions and 19 deletions

View File

@@ -23,6 +23,7 @@ function App() {
const [heatmapData, setHeatmapData] = useState<HeatmapPoint[]>([]); const [heatmapData, setHeatmapData] = useState<HeatmapPoint[]>([]);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [radiusMultiplier, setRadiusMultiplier] = useState(1);
const handleUploadSuccess = (newFilters: FilterOptions) => { const handleUploadSuccess = (newFilters: FilterOptions) => {
setFilters(newFilters); setFilters(newFilters);
@@ -70,11 +71,25 @@ function App() {
onFilterChange={handleFilterChange} onFilterChange={handleFilterChange}
isLoading={isLoading} isLoading={isLoading}
/> />
<div className="map-controls" style={{ marginTop: '20px', paddingTop: '20px', borderTop: '1px solid #555' }}>
<h3>Map Settings</h3>
<label htmlFor="radius-slider">Marker Size: {radiusMultiplier.toFixed(1)}x</label>
<input
type="range"
id="radius-slider"
min="0.1"
max="5"
step="0.1"
value={radiusMultiplier}
onChange={(e) => setRadiusMultiplier(parseFloat(e.target.value))}
style={{ width: '100%' }}
/>
</div>
</div> </div>
<div className="map-container"> <div className="map-container">
{isLoading && <p>Loading map data...</p>} {isLoading && <p>Loading map data...</p>}
{error && <p className="error">{error}</p>} {error && <p className="error">{error}</p>}
<MapDisplay heatmapData={heatmapData} /> <MapDisplay heatmapData={heatmapData} radiusMultiplier={radiusMultiplier} />
</div> </div>
</main> </main>
</div> </div>

View File

@@ -60,7 +60,7 @@ const FilterPanel: React.FC<FilterPanelProps> = ({ filters, onFilterChange, isLo
<div className="filter-panel"> <div className="filter-panel">
<h3>Filters</h3> <h3>Filters</h3>
{Object.entries(filters).map(([category, options]) => ( {Object.entries(filters).map(([category, options]) => (
<details key={category} className="filter-group" open> <details key={category} className="filter-group">
<summary>{category}</summary> <summary>{category}</summary>
<div className="filter-options"> <div className="filter-options">
{options.map(option => ( {options.map(option => (

View File

@@ -6,23 +6,26 @@ import type { HeatmapPoint } from '../App';
interface MapDisplayProps { interface MapDisplayProps {
heatmapData: HeatmapPoint[]; heatmapData: HeatmapPoint[];
radiusMultiplier: number;
} }
const MapDisplay: React.FC<MapDisplayProps> = ({ heatmapData }) => { const MapDisplay: React.FC<MapDisplayProps> = ({ heatmapData, radiusMultiplier }) => {
const germanyCenter: [number, number] = [51.1657, 10.4515]; const germanyCenter: [number, number] = [51.1657, 10.4515];
// Simple scaling function for marker radius // Simple scaling function for marker radius, now with a multiplier
const calculateRadius = (count: number) => { const calculateRadius = (count: number) => {
return 5 + Math.log(count + 1) * 5; // Ensure a base radius so even single points are visible
// The multiplier is applied to the dynamic part of the radius
return 3 + Math.log(count + 1) * 5 * radiusMultiplier;
}; };
// Simple color scaling function // Simple color scaling function
const getColor = (count: number, maxCount: number) => { const getColor = (count: number, maxCount: number) => {
const ratio = count / maxCount; const ratio = count / maxCount;
if (ratio > 0.8) return 'red'; if (ratio > 0.8) return '#d73027'; // Red
if (ratio > 0.5) return 'orange'; if (ratio > 0.5) return '#fdae61'; // Orange
if (ratio > 0.2) return 'yellow'; if (ratio > 0.2) return '#fee08b'; // Yellow
return 'green'; return '#66bd63'; // Green
} }
const maxCount = Math.max(...heatmapData.map(p => p.count), 1); const maxCount = Math.max(...heatmapData.map(p => p.count), 1);