feat(#173): BL-Filter im Stimmverhalten-Tab unabhaengig vom globalen

User-Wunsch: Stimmverhalten-Tab soll Querschnitt ueber alle BL zeigen
koennen, auch wenn der globale Header-BL-Filter auf einem einzelnen BL
steht. Bisher: Tab nutzte v2GetGlobalBl() → bei Header=BW wurde nur BW
angezeigt, bei Datensparse 0 Zeilen.

Aenderungen:
- Lokaler BL-Selector im Stimmverhalten-Caveat-Bereich.
  Default-Option: "— Alle Bundeslaender —"
- svGetBl() Helper liest den lokalen Selector
- loadStimmverhalten + loadMatrixHeatmap + downloadStimmverhaltenCsv
  nutzen svGetBl() statt v2GetGlobalBl()
- v2-bl-changed Event triggert das Stimmverhalten-Panel NICHT mehr
  (eigener Filter)

Andere Tabs (BL × Partei, Themen × Fraktion) reagieren weiter auf den
globalen BL-Filter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dotty Dotter 2026-05-06 01:58:03 +02:00
parent 39ef248a66
commit f008570cff

View File

@ -218,6 +218,17 @@ table.modal-table th { background: var(--ecg-bg-subtle); font-weight: 700; }
verzerren. verzerren.
</p> </p>
<div style="display:flex;align-items:center;gap:1rem;margin-top:6px;flex-wrap:wrap;"> <div style="display:flex;align-items:center;gap:1rem;margin-top:6px;flex-wrap:wrap;">
<label style="display:inline-flex;align-items:center;gap:6px;font-size:11px;
font-family:var(--font-mono);cursor:pointer;">
Bundesland:
<select id="sv-bl-filter" onchange="loadStimmverhalten()"
style="font-family:var(--font-mono);font-size:11px;padding:3px 8px;border:1px solid var(--ecg-border);border-radius:3px;background:var(--ecg-card-bg);">
<option value="">— Alle Bundesländer —</option>
{% for code in bl_codes %}
<option value="{{ code }}">{{ code }}</option>
{% endfor %}
</select>
</label>
<label style="display:inline-flex;align-items:center;gap:6px;font-size:11px; <label style="display:inline-flex;align-items:center;gap:6px;font-size:11px;
font-family:var(--font-mono);cursor:pointer;"> font-family:var(--font-mono);cursor:pointer;">
<input type="checkbox" id="sv-exclude-antragsteller" checked <input type="checkbox" id="sv-exclude-antragsteller" checked
@ -387,8 +398,7 @@ function setMatrixAxis(axis) {
} }
function loadMatrixHeatmap() { function loadMatrixHeatmap() {
const blRaw = (window.v2GetGlobalBl && window.v2GetGlobalBl()) || 'ALL'; const bl = svGetBl();
const bl = (blRaw === 'ALL') ? '' : blRaw;
const exclude = document.getElementById('sv-exclude-antragsteller').checked ? '1' : '0'; const exclude = document.getElementById('sv-exclude-antragsteller').checked ? '1' : '0';
if (_svMatrixAxis === 'gruppen') { if (_svMatrixAxis === 'gruppen') {
loadStimmIndexProGruppe(bl, exclude); loadStimmIndexProGruppe(bl, exclude);
@ -413,13 +423,14 @@ function switchTab(id, btn) {
} }
} }
// Bei BL-Wechsel aktive Panels neu laden // Bei globalem BL-Wechsel aktive Panels neu laden — ABER NICHT
// Stimmverhalten, das hat seinen eigenen lokalen BL-Filter (Issue #173).
window.addEventListener('v2-bl-changed', function () { window.addEventListener('v2-bl-changed', function () {
var activePanel = document.querySelector('.auswert-panel.active'); var activePanel = document.querySelector('.auswert-panel.active');
if (!activePanel) return; if (!activePanel) return;
if (activePanel.id === 'panel-bl-partei') loadBlMatrix(); if (activePanel.id === 'panel-bl-partei') loadBlMatrix();
if (activePanel.id === 'panel-themen') loadThemenMatrix(); if (activePanel.id === 'panel-themen') loadThemenMatrix();
if (activePanel.id === 'panel-stimmverhalten') loadStimmverhalten(); // Stimmverhalten reagiert NICHT auf globalen BL-Filter — eigener Selector.
}); });
document.addEventListener('DOMContentLoaded', function () { loadBlMatrix(); }); document.addEventListener('DOMContentLoaded', function () { loadBlMatrix(); });
@ -594,9 +605,15 @@ document.addEventListener('keydown', (e) => {
// ─── Stimmverhalten × Gemeinwohl ──────────────────────────────────────────── // ─── Stimmverhalten × Gemeinwohl ────────────────────────────────────────────
// Lokaler BL-Filter im Stimmverhalten-Tab — eigenstaendig vom globalen
// BL-Filter im Header (Issue #173). Default: "" (alle BL).
function svGetBl() {
const sel = document.getElementById('sv-bl-filter');
return sel ? sel.value : '';
}
async function loadStimmverhalten() { async function loadStimmverhalten() {
const blRaw = (window.v2GetGlobalBl && window.v2GetGlobalBl()) || 'ALL'; const bl = svGetBl();
const bl = (blRaw === 'ALL') ? '' : blRaw;
const exclude = document.getElementById('sv-exclude-antragsteller').checked ? '1' : '0'; const exclude = document.getElementById('sv-exclude-antragsteller').checked ? '1' : '0';
loadStimmIndex(bl, exclude); loadStimmIndex(bl, exclude);
@ -608,8 +625,7 @@ async function loadStimmverhalten() {
} }
function downloadStimmverhaltenCsv() { function downloadStimmverhaltenCsv() {
const blRaw = (window.v2GetGlobalBl && window.v2GetGlobalBl()) || 'ALL'; const bl = svGetBl();
const bl = (blRaw === 'ALL') ? '' : blRaw;
const exclude = document.getElementById('sv-exclude-antragsteller').checked ? '1' : '0'; const exclude = document.getElementById('sv-exclude-antragsteller').checked ? '1' : '0';
let url = `/api/auswertungen/stimmverhalten.csv?exclude_antragsteller=${exclude}`; let url = `/api/auswertungen/stimmverhalten.csv?exclude_antragsteller=${exclude}`;
if (bl) url += '&bundesland=' + encodeURIComponent(bl); if (bl) url += '&bundesland=' + encodeURIComponent(bl);