/**
* Glossar-Experimente — Gruppe „monsun".
*
* Registrierung via window.GlossarExperiments[key_slug] = fn(root).
* Eigener svgEl-Helper, nur bestehende .ge-*-CSS-Klassen (aus glossar.php).
* Keine Libraries. Mobile-/Tap-freundlich. rAF-Loops stoppen bei geschlossenem
* Modal über den root.isConnected-Guard.
*/
(function () {
'use strict';
const NS = 'http://www.w3.org/2000/svg';
const svgEl = (tag, attrs, parent) => {
const el = document.createElementNS(NS, tag);
if (attrs) for (const k in attrs) el.setAttribute(k, attrs[k]);
if (parent) parent.appendChild(el);
return el;
};
const deAT = (n) => Number(n).toLocaleString('de-AT');
// =====================================================================
// Experiment: Monsun-Regen — Regen pro Monat in Mumbai (Balkendiagramm)
// =====================================================================
function monsunRain(root) {
root.innerHTML = `
🌧 Wann fällt der Regen in Indien?
Jeder Balken ist ein Monat in Mumbai (Indien). Schau, wie riesig die Balken von Juni bis September werden. In dieser kurzen Zeit fällt fast der ganze Jahresregen — davon hängt die Reisernte ab.
`;
const svg = root.querySelector('.ge-mon-svg');
const sharePill = root.querySelector('#ge-mon-share');
const totalPill = root.querySelector('#ge-mon-total');
const noteEl = root.querySelector('#ge-mon-note');
if (!svg || !sharePill || !totalPill || !noteEl) return;
const MONTHS = ['Jän', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'];
// Monsun-Monate (0-basiert): Juni–September
const MONSOON = [5, 6, 7, 8];
// Regen pro Monat in mm.
// Normal: Mumbai (Colaba) 1981–2010, India Meteorological Department.
const NORMAL = [1, 0, 1, 0, 16, 506, 769, 472, 356, 82, 9, 3];
// Schwacher Monsun (Dürre-Jahr): Spitzen-Monate stark reduziert.
const WEAK = [1, 0, 1, 0, 10, 280, 420, 240, 180, 60, 6, 2];
// Vergleich: Wien fällt Monat für Monat ziemlich gleichmäßig (~60 mm).
const WIEN_REF = 60;
const NOTES = {
normal: 'Regen pro Monat in Mumbai, Normalwerte 1981 – 2010. Quelle: India Meteorological Department (über „Climate of Mumbai"). Ganzes Jahr rund 2.215 mm. Die dünne Linie zeigt Wien: dort fallen jeden Monat etwa 60 mm — ziemlich gleichmäßig.',
weak: 'Schwacher Monsun (Dürre-Jahr): geschätzte Werte, in denen die Monsun-Monate viel weniger Regen bringen. So etwas macht Bäuerinnen und Bauern Sorge — der Klimawandel lässt den Monsun unberechenbarer werden. Quelle Normalwerte: India Meteorological Department.'
};
// Layout
const X0 = 58, X1 = 588; // Plot links/rechts
const BASE = 278, TOP = 34; // Baseline / oberer Rand
const PLOT_H = BASE - TOP; // Zeichenhöhe
const MAX_MM = 800; // feste Skala (Balken schrumpfen sichtbar)
const PX_PER_MM = PLOT_H / MAX_MM;
const slot = (X1 - X0) / MONTHS.length;
const BAR_W = slot * 0.66;
const yFor = (mm) => BASE - Math.min(MAX_MM, mm) * PX_PER_MM;
// --- Statische Achsen / Gitter ---
// Y-Gitterlinien + Beschriftung
[0, 200, 400, 600, 800].forEach(mm => {
const y = yFor(mm);
svgEl('line', { x1: X0, y1: y, x2: X1, y2: y, stroke: '#dae8ec', 'stroke-width': mm === 0 ? '1.6' : '1' }, svg);
const t = svgEl('text', { x: X0 - 8, y: y + 4, 'text-anchor': 'end', 'font-size': '11', fill: '#4a4a4a', 'font-weight': '600' }, svg);
t.textContent = mm;
});
svgEl('text', { x: X0 - 8, y: TOP - 14, 'text-anchor': 'end', 'font-size': '11', fill: '#4a4a4a', 'font-weight': '700' }, svg).textContent = 'mm';
// Monat-Beschriftung + farbige Monsun-Markierung am Boden
const barNodes = [];
const valNodes = [];
MONTHS.forEach((m, i) => {
const cx = X0 + slot * i + slot / 2;
const isMon = MONSOON.includes(i);
// Balken (Höhe wird animiert gesetzt)
const bar = svgEl('rect', {
x: cx - BAR_W / 2, y: BASE, width: BAR_W, height: 0, rx: 3,
fill: isMon ? '#2f7d8a' : '#a9c7cd'
}, svg);
barNodes.push(bar);
// Wert-Label über dem Balken (nur für die großen Monsun-Balken sichtbar)
const val = svgEl('text', {
x: cx, y: BASE, 'text-anchor': 'middle', 'font-size': '10',
'font-weight': '800', fill: '#1f4e5a', opacity: '0'
}, svg);
valNodes.push(val);
// Monatsname
const lbl = svgEl('text', {
x: cx, y: BASE + 18, 'text-anchor': 'middle', 'font-size': '11',
'font-weight': isMon ? '800' : '600', fill: isMon ? '#1f4e5a' : '#6a6a6a'
}, svg);
lbl.textContent = m;
});
// „Regenzeit"-Klammer über Jun–Sep
const bx0 = X0 + slot * MONSOON[0] + slot * 0.10;
const bx1 = X0 + slot * (MONSOON[MONSOON.length - 1] + 1) - slot * 0.10;
svgEl('line', { x1: bx0, y1: TOP - 6, x2: bx1, y2: TOP - 6, stroke: '#e8833a', 'stroke-width': '2', 'stroke-linecap': 'round' }, svg);
svgEl('text', { x: (bx0 + bx1) / 2, y: TOP - 12, 'text-anchor': 'middle', 'font-size': '11', 'font-weight': '800', fill: '#e8833a' }, svg).textContent = 'Regenzeit';
// Wien-Vergleichslinie (dünn, gestrichelt) + Label
const wienY = yFor(WIEN_REF);
svgEl('line', { x1: X0, y1: wienY, x2: X1, y2: wienY, stroke: '#c85c4a', 'stroke-width': '2', 'stroke-dasharray': '6 4' }, svg);
svgEl('text', { x: X1, y: wienY - 6, 'text-anchor': 'end', 'font-size': '10.5', 'font-weight': '800', fill: '#c85c4a' }, svg)
.textContent = 'Wien: ~60 mm pro Monat';
// --- Zustand + Animation ---
let animId = null;
let current = NORMAL;
function paint(fromData, toData, scen) {
cancelAnimationFrame(animId);
const dur = 650;
const start = performance.now();
function tick(now) {
if (!root.isConnected) { cancelAnimationFrame(animId); return; }
const t = Math.min(1, (now - start) / dur);
const e = 1 - Math.pow(1 - t, 3);
for (let i = 0; i < barNodes.length; i++) {
const mm = fromData[i] + (toData[i] - fromData[i]) * e;
const y = yFor(mm);
barNodes[i].setAttribute('y', y);
barNodes[i].setAttribute('height', Math.max(0, BASE - y));
// Wert nur bei den großen Balken (> 100 mm) zeigen
if (toData[i] > 100) {
valNodes[i].setAttribute('y', y - 5);
valNodes[i].textContent = Math.round(mm);
valNodes[i].setAttribute('opacity', (t).toFixed(2));
} else {
valNodes[i].setAttribute('opacity', '0');
}
}
if (t < 1) animId = requestAnimationFrame(tick);
}
animId = requestAnimationFrame(tick);
}
function setScenario(scen) {
const data = scen === 'weak' ? WEAK : NORMAL;
const from = current;
current = data;
const total = data.reduce((a, b) => a + b, 0);
const monsoonSum = MONSOON.reduce((a, i) => a + data[i], 0);
const share = Math.round((monsoonSum / total) * 100);
sharePill.innerHTML = `Juni – September: ${share} % vom Jahresregen`;
sharePill.dataset.state = 'warn';
totalPill.innerHTML = `Ganzes Jahr: ${deAT(total)} mm`;
totalPill.dataset.state = scen === 'weak' ? 'bad' : 'good';
noteEl.textContent = NOTES[scen];
root.querySelectorAll('[data-scen]').forEach(b => {
b.classList.toggle('ge-btn-primary', b.dataset.scen === scen);
});
paint(from, data, scen);
}
root.querySelectorAll('[data-scen]').forEach(b => {
b.addEventListener('click', () => setScenario(b.dataset.scen));
});
// Startanimation von 0 hoch
current = NORMAL.map(() => 0);
setScenario('normal');
}
// Registry — Object.assign, damit Ladereihenfolge egal ist.
window.GlossarExperiments = Object.assign(window.GlossarExperiments || {}, {
'monsun': monsunRain
});
})();