Karte: MarkerCluster mit Popups, Hero-CTAs scrollen zu Demos

Lagebild-Karte auf geclusterte Marker umgebaut (primary/secondary als Pulse, rest als CircleMarker). Popups zeigen jetzt Top-Artikel mit Links. Vorschau Hero-Buttons scrollen zum Demo-Karussell statt direkt zu den Lagen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
Claude Code
2026-04-11 18:18:31 +02:00
Ursprung 3cd5623fa6
Commit 0a6ec07374
6 geänderte Dateien mit 130 neuen und 25 gelöschten Zeilen

Datei anzeigen

@@ -292,7 +292,7 @@ function mdToHtml(md) {
/* ==================== LEAFLET MAP ==================== */
function clearMarkers() {
if (markerLayer) markerLayer.clearLayers();
if (markerLayer) { mapInstance.removeLayer(markerLayer); markerLayer = null; }
if (legendControl && mapInstance) { mapInstance.removeControl(legendControl); legendControl = null; }
}
@@ -311,7 +311,6 @@ function mdToHtml(md) {
maxZoom: 19, noWrap: true
}).addTo(mapInstance);
markerLayer = L.layerGroup().addTo(mapInstance);
setTimeout(function () { mapInstance.invalidateSize(); }, 500);
}
@@ -327,11 +326,31 @@ function mdToHtml(md) {
});
}
function buildPopup(loc) {
var html = '<strong style="color:#E8ECF4;">' + (loc.name || '') + '</strong>';
if (loc.country_code) html += ' <span style="color:#8896AB;font-size:0.8rem;">(' + loc.country_code + ')</span>';
html += '<br><span style="font-size:0.85rem;color:#8896AB;">' + (loc.article_count || 0) + ' Artikel</span>';
if (loc.top_articles && loc.top_articles.length > 0) {
html += '<div style="margin-top:6px;border-top:1px solid #1E2D45;padding-top:6px;">';
loc.top_articles.forEach(function (a) {
var hl = (a.headline || '').replace(/\*\*/g, '');
if (hl.length > 60) hl = hl.substring(0, 60) + '\u2026';
if (a.url) {
html += '<a href="' + a.url + '" target="_blank" rel="noopener" style="color:#C8A851;font-size:0.8rem;display:block;margin-top:3px;text-decoration:none;">' + hl + '</a>';
} else {
html += '<span style="color:#8896AB;font-size:0.8rem;display:block;margin-top:3px;">' + hl + '</span>';
}
html += '<span style="color:#556B7A;font-size:0.7rem;">' + (a.source || '') + '</span>';
});
html += '</div>';
}
return html;
}
function showMarkers(locations, apiLabels) {
if (!mapInstance) createMap();
clearMarkers();
var categoryColors = {
primary: '#ef4444',
secondary: '#f59e0b',
@@ -343,7 +362,7 @@ function mdToHtml(md) {
primary: 'Hauptgeschehen',
secondary: 'Reaktionen',
tertiary: 'Beteiligte',
mentioned: 'Erwähnt'
mentioned: 'Erw\u00e4hnt'
};
var categoryLabels = {};
@@ -351,6 +370,14 @@ function mdToHtml(md) {
categoryLabels[k] = (apiLabels && apiLabels[k]) || defaultLabels[k];
});
var clusterGroup = L.markerClusterGroup({
maxClusterRadius: 50,
spiderfyOnMaxZoom: true,
showCoverageOnHover: false,
zoomToBoundsOnClick: true,
disableClusteringAtZoom: 10
});
var usedCategories = {};
var bounds = [];
@@ -360,17 +387,23 @@ function mdToHtml(md) {
var color = categoryColors[cat] || '#7b7b7b';
usedCategories[cat] = true;
var popup = '<strong style="color:#E8ECF4;">' + (loc.name || '') + '</strong>';
if (loc.country_code) popup += ' <span style="color:#8896AB;font-size:0.8rem;">(' + loc.country_code + ')</span>';
popup += '<br><span style="font-size:0.85rem;color:#8896AB;">' + (loc.article_count || 0) + ' Artikel</span>';
L.marker([loc.lat, loc.lon], { icon: pulseIcon(color) })
.addTo(markerLayer)
.bindPopup(popup);
var marker;
if (cat === 'primary' || cat === 'secondary') {
marker = L.marker([loc.lat, loc.lon], { icon: pulseIcon(color) });
} else {
marker = L.circleMarker([loc.lat, loc.lon], {
radius: 5, fillColor: color, fillOpacity: 0.7,
color: color, weight: 1, opacity: 0.9
});
}
marker.bindPopup(buildPopup(loc), { maxWidth: 300 });
clusterGroup.addLayer(marker);
bounds.push([loc.lat, loc.lon]);
});
// Dark legend (exact lagebild style)
markerLayer = clusterGroup;
mapInstance.addLayer(markerLayer);
var legend = L.control({ position: 'bottomright' });
legend.onAdd = function () {
var div = L.DomUtil.create('div');