/** * * @licstart The following is the entire license notice for the * JavaScript code in this page. * * Copyright (C) 2025 Florian Fischer * * * The JavaScript code in this page is free software: you can * redistribute it and/or modify it under the terms of the GNU * General Public License (GNU GPL) as published by the Free Software * Foundation, either version 3 of the License, or (at your option) * any later version. The code is distributed WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. * * As additional permission under GNU GPL version 3 section 7, you * may distribute non-source (e.g., minimized or compacted) forms of * that code without the copy of the GNU GPL normally required by * section 4, provided you include this license notice and a URL * through which recipients can access the Corresponding Source. * * @licend The above is the entire license notice * for the JavaScript code in this page. * */ // Zeichne das Diagramm und erstelle eine Liste aller Events, // wenn die Seite komplett geladen wurde window.onload = function() { zeichne(); zeichneBilder(); listeEvents(); } var diagramm; function zeichne() { // Wir haben keine Daten zum Zeichnen if (!daten || !daten.klassen) return; // Zeige den Indikator, dass das Diagramm gezeichnet wird let zeichnenIndikator = document.getElementById("zeichnen"); zeichnenIndikator.style.display = "block"; let zeichenort = document.getElementById("zeichenort"); zeichenort['aria-busy'] = true; const ctx = document.getElementById('zeichenflaeche'); // Verwerfe ein bereits gezeichnetes Diagramm if (diagramm) diagramm.destroy(); // Erzeuge ein neues Balkendiagramm mit unseren Daten diagramm = new Chart(ctx, { type: 'bar', options: { animation: false, // Deaktiviere die Animation beim Zeichnen der Balken plugins: { legend: { display: false // Wir benötigen keine Legende für den Punktestand }, tooltip: { enabled: false // Deaktiviere die Tooltips, die nur den Punktestand zeigen } } }, data: { // Die Klassenbezeichnungen sind unsere X-Achsen Bezeichner labels: daten.klassen.map(klasse => klasse.bezeichner), datasets: [ { label: 'Punkte', data: daten.klassen.map(klasse => klasse.punkte), backgroundColor: daten.klassen.map(klasse => klasse.farbe) } ] }, }); // Verstecke den Zeichenindikator zeichnenIndikator.style.display = "none"; zeichenort['aria-busy'] = false; } // Lade und zeichne die Bilder der Klassen an die Spitze ihrer jeweiligen Balken async function zeichneBilder() { // Das Objekt, das alle unsere Bilder Annotationen enthält let annotation = {annotations: {}}; for (const i in daten.klassen) { let klasse = daten.klassen[i]; // Die Url des Klassenbildes ist der Klassenbezeichner unter dem Bilderpfad let bildUrl = `${bilder_pfad}/${klasse.bezeichner}.png`; // Teste ob das Bild existiert let ok = (await fetch(bildUrl, {method: 'HEAD'})).ok; // Das Bild existiert nicht if (!ok) { continue; } // Erzeuge ein neues Bild und verwende die Bild URL unter der ein Bild gefunden wurde let bild = new Image(); bild.src = bildUrl; // Zeichne das Bild knapp unter dem oberen Rand des Balkens let klassenAnnotation = { drawTime: 'afterDatasetsDraw', type: 'label', content: bild, width: 75, height: 75, xValue: klasse.bezeichner, yValue: klasse.punkte - 1 }; annotation.annotations[klasse.bezeichner] = klassenAnnotation; } // Ergänze die Diagramm-Optionen um unsere Annotationen diagramm.options.plugins.annotation = annotation; // Zeichne das Diagramm neu mit unseren Annotationen diagramm.update(); } // Erzeuge eine Liste aller Ereignisse. // Die globale Variable ereignisse muss definiert sein und ein Iterable aller // Ereignisse, die angezeigt werden sollen, enthalten. function listeEvents() { let liste = document.getElementById("ereignisse"); for (let ereignis of daten.ereignisse) { // Erzeuge ein Listenelement, das alle Infos des Ereignisses enthält let ereignisNode = document.createElement("li"); ereignisNode.classList.add("ereignis"); // Span, das die Meta-Informationen (Klasse, Datum) eines Ereignisses enthält let ereignisUrsache = document.createElement("span"); ereignisUrsache.innerHTML = `${ereignis.Jahrgang}${ereignis.Bezeichner}` if (ereignis.Datum) { ereignisUrsache.innerHTML += ` ${ereignis.Datum}` } ereignisUrsache.classList.add("ereignis-klasse"); ereignisNode.appendChild(ereignisUrsache); // Die Veränderung des Punktestands durch das Ereignis let ereignisDelta = document.createElement("span"); ereignisDelta.innerHTML = `${ereignis.Delta}`; ereignisDelta.classList.add("ereignis-delta"); // Ergänze positive und negative CSS Klassen if (ereignis.Delta > 0) { ereignisDelta.classList.add("positiv"); } else { ereignisDelta.classList.add("negativ"); } ereignisNode.appendChild(ereignisDelta); // Die Beschreibung des Ereignisses let ereignisBeschreibung = document.createElement("span"); ereignisBeschreibung.innerHTML = `${ereignis.Beschreibung}`; ereignisBeschreibung.classList.add("ereignis-beschreibung"); ereignisNode.appendChild(ereignisBeschreibung); // Füge das neue Ereignis-Listenelement der Ereignis-Liste hinzu. // Jedes neue Element wird als erstes Kind eingefügt, damit // neuere Ereignisse weiter oben in der Liste stehen liste.insertBefore(ereignisNode, liste.firstChild); } }