Lehreransicht: Ampel Farmer=Trefferquote, Vergleich->Fortschritt+Qualitaet, Mini-Balken ueberall

- _liveMood: farmer-Fall (hit_rate >=60 gruen / >=30 gelb / sonst rot) -> Ampel
  spiegelt Qualitaet, nicht mehr nur Fortschritt.
- qualityScore: farmer hit_rate -> "Qualitaet"-Spalte im Fortschritt-View gefuellt.
- "Vergleich"-Button/Titel -> "Fortschritt (& Qualitaet)".
- "Aktuell"-Tabelle: Mini-Balken jetzt fuer ALLE Zahlenspalten aller Sims
  (relativ zum Spalten-Max, neutral), Spalten mit eigenem Balken ausgenommen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-22 14:26:47 +02:00
parent 4e38b27c64
commit 5635fa26b4
+14 -8
View File
@@ -574,7 +574,7 @@ function _liveToggleHtml() {
+ '<div style="display:inline-flex;border:1.5px solid rgba(0,0,0,.08);border-radius:6px;overflow:hidden">'
+ ' <button class="btn-sm" onclick="setLiveMode(\'uebersicht\')" style="padding:.35rem .8rem;border:0;background:'+(_liveMode==='uebersicht'?'#4a7c8a':'transparent')+';color:'+(_liveMode==='uebersicht'?'#fff':'#3d5165')+';font-weight:700;font-size:.74rem">📅 Tag</button>'
+ ' <button class="btn-sm" onclick="setLiveMode(\'aktuell\')" style="padding:.35rem .8rem;border:0;background:'+(_liveMode==='aktuell'?'#4a7c8a':'transparent')+';color:'+(_liveMode==='aktuell'?'#fff':'#3d5165')+';font-weight:700;font-size:.74rem">🔴 Aktuell</button>'
+ ' <button class="btn-sm" onclick="setLiveMode(\'vergleich\')" style="padding:.35rem .8rem;border:0;background:'+(_liveMode==='vergleich'?'#4a7c8a':'transparent')+';color:'+(_liveMode==='vergleich'?'#fff':'#3d5165')+';font-weight:700;font-size:.74rem">📊 Vergleich</button>'
+ ' <button class="btn-sm" onclick="setLiveMode(\'vergleich\')" style="padding:.35rem .8rem;border:0;background:'+(_liveMode==='vergleich'?'#4a7c8a':'transparent')+';color:'+(_liveMode==='vergleich'?'#fff':'#3d5165')+';font-weight:700;font-size:.74rem">📊 Fortschritt</button>'
+ ' <button class="btn-sm" onclick="setLiveMode(\'gesamt\')" style="padding:.35rem .8rem;border:0;border-left:1.5px solid rgba(0,0,0,.08);background:'+(_liveMode==='gesamt'?'#4a7c8a':'transparent')+';color:'+(_liveMode==='gesamt'?'#fff':'#3d5165')+';font-weight:700;font-size:.74rem">📚 Gesamt</button>'
+ '</div>'
+ (_liveMode==='uebersicht' ?
@@ -1284,6 +1284,7 @@ function _liveMood(simId, s) {
if (_liveNeedsHelp(simId, s)) return 'bad';
switch (simId) {
case 'weltkueche': return (s.mistakesInDish||0) <= 2 ? 'good' : (s.mistakesInDish >= 8 ? 'bad' : 'mid');
case 'farmer': return (s.hit_rate==null) ? 'mid' : (s.hit_rate >= 60 ? 'good' : s.hit_rate >= 30 ? 'mid' : 'bad');
case 'klima': case 'klima-3d': return ((s.floodedPct==null?100:s.floodedPct) < 20 && (s.budget||0) >= 0) ? 'good' : 'mid';
case 'busfahrt': case 'fluggesellschaft': return (s.budget==null?0:s.budget) >= 5000 ? 'good' : (s.budget < 0 ? 'bad' : 'mid');
case 'tourismustal': return (s.money==null?0:s.money) >= 4000 ? 'good' : (s.money < 0 ? 'bad' : 'mid');
@@ -1433,14 +1434,13 @@ async function renderLive() {
html += '<th style="width:1.2em"></th>';
html += '</tr></thead><tbody>';
// Spalten-Maxima für relative Mini-Balken (über alle Zeilen dieser Sim).
// Spalten-Maxima für relative Mini-Balken (über alle Zeilen dieser Sim)
// für ALLE Zahlenspalten, damit jede Zahl einen kleinen Vergleichs-Balken bekommt.
var colMax = {};
fields.forEach(function(f) {
if (f.bar && f.bar.kind === 'rel') {
var mx = 0;
grp.rows.forEach(function(r) { var val = (r.state||{})[f.k]; if (typeof val === 'number' && !isNaN(val)) mx = Math.max(mx, Math.abs(val)); });
colMax[f.k] = mx;
}
var mx = 0;
grp.rows.forEach(function(r) { var val = (r.state||{})[f.k]; if (typeof val === 'number' && !isNaN(val)) mx = Math.max(mx, Math.abs(val)); });
colMax[f.k] = mx;
});
grp.rows.forEach(function(ls) {
@@ -1489,6 +1489,10 @@ async function renderLive() {
}
cell = '<div style="line-height:1.1">'+cell+'</div>' + _liveMiniBar(pct, bcol);
}
} else if (typeof s[f.k] === 'number' && !isNaN(s[f.k]) && (colMax[f.k]||0) > 0 && cell.indexOf('border-radius:99px') < 0) {
// Mini-Balken auch für alle übrigen Zahlenspalten: relativ zum Spalten-Max (neutral grau).
var apct = (Math.abs(s[f.k]) / colMax[f.k]) * 100;
cell = '<div style="line-height:1.1">'+cell+'</div>' + _liveMiniBar(apct, '#9aa7b0');
}
html += '<td style="text-align:'+align+';padding:.4rem .5rem;font-variant-numeric:tabular-nums;vertical-align:top">'+cell+'</td>';
});
@@ -1928,6 +1932,8 @@ function _renderGenericCompareBody(rows, simId) {
if (typeof s.planCorrect === 'number' && s.planTotal) return Math.min(100, s.planCorrect / s.planTotal * 100);
// Busfahrt: quizFirstTry / orderIndex
if (typeof s.quizFirstTry === 'number' && s.orderIndex) return Math.min(100, s.quizFirstTry / s.orderIndex * 100);
// Farmer: Trefferquote = Anteil gut geeigneter Anbau-Versuche
if (typeof s.hit_rate === 'number') return s.hit_rate;
return null;
}
var data = rows.map(function(ls, idx){
@@ -1948,7 +1954,7 @@ function _renderGenericCompareBody(rows, simId) {
if (b.progress !== a.progress) return b.progress - a.progress;
return (a.displayName||'').localeCompare(b.displayName||'');
});
var html = '<div class="card"><div class="card-h">'+esc(_compareGroupLabel(simId))+' · Vergleich</div>';
var html = '<div class="card"><div class="card-h">'+esc(_compareGroupLabel(simId))+' · Fortschritt &amp; Qualität</div>';
html += '<p style="font-size:.7rem;color:#8a8a8a;margin-bottom:.5rem">'+data.length+' aktiv · Klick auf Zeile öffnet Detail.</p>';
html += '<div style="overflow-x:auto"><table style="width:100%;border-collapse:collapse;font-size:.78rem">';
html += '<thead><tr>'