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:
@@ -11,6 +11,8 @@
|
||||
<link rel="stylesheet" href="/css/mobile.css">
|
||||
<link rel="stylesheet" href="lagebild.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css">
|
||||
</head>
|
||||
<body class="lagebild-page">
|
||||
<!-- Scroll Progress Bar -->
|
||||
@@ -186,6 +188,7 @@
|
||||
<script src="/js/translations.js"></script>
|
||||
<script src="/js/mobile-nav.js"></script>
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<script src="https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js"></script>
|
||||
<script src="lagebild.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1553,3 +1553,17 @@ a.source-detail-article-title:hover {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Marker-Cluster Dark Theme */
|
||||
.marker-cluster-small,
|
||||
.marker-cluster-medium,
|
||||
.marker-cluster-large {
|
||||
background: rgba(21, 29, 46, 0.8);
|
||||
}
|
||||
.marker-cluster-small div,
|
||||
.marker-cluster-medium div,
|
||||
.marker-cluster-large div {
|
||||
background: rgba(200, 168, 81, 0.9);
|
||||
color: #0A1832;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -655,7 +655,7 @@ var Lagebild = {
|
||||
|
||||
renderArticlesTab: function() {},
|
||||
|
||||
/* ===== TAB: KARTE (Pulse Markers) ===== */
|
||||
/* ===== TAB: KARTE (Clustered Pulse Markers) ===== */
|
||||
renderMap: function() {
|
||||
if (this.map) { this.map.remove(); this.map = null; }
|
||||
this.map = L.map('map-container', {
|
||||
@@ -664,7 +664,6 @@ var Lagebild = {
|
||||
maxBoundsViscosity: 1.0
|
||||
}).setView([33.0, 48.0], 5);
|
||||
|
||||
// Deutsche OSM-Kacheln
|
||||
L.tileLayer('https://tile.openstreetmap.de/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
||||
maxZoom: 19,
|
||||
@@ -685,7 +684,6 @@ var Lagebild = {
|
||||
});
|
||||
}
|
||||
|
||||
// Kategorie-Farben
|
||||
var categoryColors = {
|
||||
primary: '#ef4444',
|
||||
secondary: '#f59e0b',
|
||||
@@ -698,7 +696,6 @@ var Lagebild = {
|
||||
tertiary: 'Beteiligte',
|
||||
mentioned: 'Erwaehnt'
|
||||
};
|
||||
// Dynamische Labels aus API verwenden (falls vorhanden)
|
||||
var categoryLabels = {};
|
||||
if (this.data && this.data.category_labels) {
|
||||
var apiLabels = this.data.category_labels;
|
||||
@@ -710,7 +707,6 @@ var Lagebild = {
|
||||
categoryLabels = defaultCategoryLabels;
|
||||
}
|
||||
|
||||
// Locations aus API-Daten laden
|
||||
var locs = (this.data && this.data.locations) ? this.data.locations : [];
|
||||
|
||||
if (locs.length === 0) {
|
||||
@@ -720,22 +716,60 @@ var Lagebild = {
|
||||
document.getElementById('map-container').appendChild(emptyDiv);
|
||||
}
|
||||
|
||||
var clusterGroup = L.markerClusterGroup({
|
||||
maxClusterRadius: 50,
|
||||
spiderfyOnMaxZoom: true,
|
||||
showCoverageOnHover: false,
|
||||
zoomToBoundsOnClick: true,
|
||||
disableClusteringAtZoom: 10
|
||||
});
|
||||
|
||||
var usedCategories = {};
|
||||
var bounds = [];
|
||||
for (var i = 0; i < locs.length; i++) {
|
||||
var l = locs[i];
|
||||
if (!l.lat || !l.lon) continue;
|
||||
var cat = l.category || 'mentioned';
|
||||
var color = categoryColors[cat] || '#7b7b7b';
|
||||
usedCategories[cat] = true;
|
||||
|
||||
// Popup mit Artikel-Links
|
||||
var popupText = '<strong style="color:#E8ECF4;">' + (l.name || '') + '</strong>';
|
||||
if (l.country_code) popupText += ' <span style="color:#8896AB;font-size:0.8rem;">(' + l.country_code + ')</span>';
|
||||
popupText += '<br><span style="font-size:0.85rem;color:#8896AB;">' + (l.article_count || 0) + ' Artikel</span>';
|
||||
L.marker([l.lat, l.lon], { icon: pulseIcon(color) })
|
||||
.addTo(this.map)
|
||||
.bindPopup(popupText);
|
||||
if (l.top_articles && l.top_articles.length > 0) {
|
||||
popupText += '<div style="margin-top:6px;border-top:1px solid #1E2D45;padding-top:6px;">';
|
||||
for (var j = 0; j < l.top_articles.length; j++) {
|
||||
var a = l.top_articles[j];
|
||||
var hl = (a.headline || '').replace(/\*\*/g, '');
|
||||
if (hl.length > 60) hl = hl.substring(0, 60) + '\u2026';
|
||||
if (a.url) {
|
||||
popupText += '<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 {
|
||||
popupText += '<span style="color:#8896AB;font-size:0.8rem;display:block;margin-top:3px;">' + hl + '</span>';
|
||||
}
|
||||
popupText += '<span style="color:#556B7A;font-size:0.7rem;">' + (a.source || '') + '</span>';
|
||||
}
|
||||
popupText += '</div>';
|
||||
}
|
||||
|
||||
var marker;
|
||||
if (cat === 'primary' || cat === 'secondary') {
|
||||
marker = L.marker([l.lat, l.lon], { icon: pulseIcon(color) });
|
||||
} else {
|
||||
marker = L.circleMarker([l.lat, l.lon], {
|
||||
radius: 5, fillColor: color, fillOpacity: 0.7,
|
||||
color: color, weight: 1, opacity: 0.9
|
||||
});
|
||||
}
|
||||
marker.bindPopup(popupText, { maxWidth: 300 });
|
||||
clusterGroup.addLayer(marker);
|
||||
bounds.push([l.lat, l.lon]);
|
||||
}
|
||||
|
||||
// Dark legend (dynamisch)
|
||||
this.map.addLayer(clusterGroup);
|
||||
|
||||
// Dark legend
|
||||
var legend = L.control({ position: 'bottomright' });
|
||||
legend.onAdd = function() {
|
||||
var div = L.DomUtil.create('div', 'map-legend');
|
||||
@@ -751,6 +785,10 @@ var Lagebild = {
|
||||
};
|
||||
legend.addTo(this.map);
|
||||
|
||||
if (bounds.length > 0) {
|
||||
this.map.fitBounds(bounds, { padding: [30, 30], maxZoom: 7 });
|
||||
}
|
||||
|
||||
// Dark popup styling
|
||||
if (!document.getElementById('leaflet-dark-style')) {
|
||||
var style = document.createElement('style');
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren