// Export Web/SCORM — port de screens/rendering/render_jauge.py (jauge liée // à une donnée : remplissage % + dégradé de couleur recalculés depuis un // champ numérique d'un objet). Lit gameData.data/fields_meta directement // au lieu d'une requête SQL (voir _read_field_value côté serveur). function forgeHexToRgb(hexColor) { var hex = (hexColor || "#5b8cff").replace(/^#/, ""); if (hex.length !== 6) hex = "5b8cff"; return [parseInt(hex.substr(0, 2), 16), parseInt(hex.substr(2, 2), 16), parseInt(hex.substr(4, 2), 16)]; } function forgeInterpolateColor(lowHex, highHex, ratio) { var lo = forgeHexToRgb(lowHex), hi = forgeHexToRgb(highHex); var mixed = lo.map(function (c, i) { return Math.round(c + (hi[i] - c) * ratio); }); var toHex = function (n) { return n.toString(16).padStart(2, "0"); }; return "#" + mixed.map(toHex).join(""); } // Port de _read_field_value — repli sur la ligne la PLUS RÉCENTE si // row_id est absent/introuvable (comportement historique, un objet à une // seule ligne n'est jamais impacté). function forgeReadFieldValue(gameData, definitionId, rowId, fieldName) { if (!definitionId || !fieldName) return null; definitionId = String(definitionId); var rows = gameData.data && gameData.data[definitionId]; if (!rows || !rows.length) return null; var row = null; if (rowId) row = rows.find(function (r) { return String(r.id) === String(rowId); }); if (!row) row = rows[0]; return row[fieldName]; } function forgeRenderJauge(el, meta, gameData, childrenMap, ctx, parentFlexDirection) { var attrs = el.attributes || {}; var nomPosition = attrs._nom_position || "dessus"; var nomAlignement = attrs._nom_alignement || "centre"; var nomPolice = attrs._nom_police || "inherit"; var nomTaille = attrs._nom_taille || "12"; var nomGras = attrs._nom_gras === "1"; var nomItalique = attrs._nom_italique === "1"; var flexDir = nomPosition === "cote" ? "row" : "column"; var alignItems = nomPosition === "cote" ? "center" : "stretch"; var style = forgeStyleString( el, parentFlexDirection, el.widget ) + " display:flex; flex-direction:" + flexDir + "; align-items:" + alignItems + "; justify-content:center; gap:4px;"; var definitionId = attrs._definition_id; var rowId = attrs._row_id; var fieldName = (attrs._champ || "").trim(); var fieldNameNom = (attrs._champ_nom || "").trim(); var minV = parseFloat(attrs._min); if (isNaN(minV)) minV = 0; var maxV = parseFloat(attrs._max); if (isNaN(maxV)) maxV = 100; var couleurBasse = attrs._couleur_basse || "#e05252"; var couleurHaute = attrs._couleur_haute || "#4caf50"; var afficherValeur = attrs._afficher_valeur === "1"; var rawValue = fieldName ? forgeReadFieldValue(gameData, definitionId, rowId, fieldName) : null; var value = parseFloat(rawValue); if (isNaN(value)) value = minV; var span = (maxV - minV) || 1; var ratio = Math.max(0, Math.min(1, (value - minV) / span)); var percent = Math.round(ratio * 1000) / 10; var fillColor = forgeInterpolateColor(couleurBasse, couleurHaute, ratio); var labelHtml = ""; if (afficherValeur) { labelHtml = '
' + forgeHtmlEscape(rawValue !== null && rawValue !== undefined ? String(rawValue) : "—") + '
'; } var nameHtml = ""; if (fieldNameNom) { var nomValue = forgeReadFieldValue(gameData, definitionId, rowId, fieldNameNom); if (nomValue !== null && nomValue !== undefined && nomValue !== "") { var textAlign = (nomPosition === "dessus" && nomAlignement === "gauche") ? "left" : "center"; nameHtml = '
' + forgeHtmlEscape(String(nomValue)) + '
'; } } var extraClasses = Object.keys(attrs) .filter(function (k) { return k.indexOf("_class_") === 0 && attrs[k]; }) .map(function (k) { return attrs[k]; }).join(" "); var barClass = forgeHtmlEscape(("progress jaugeBar " + extraClasses).trim()); var bar = '' + percent + '%'; var barWrap = '
' + bar + labelHtml + '
'; return '
' + nameHtml + barWrap + '
'; } if (typeof module !== 'undefined' && module.exports) { module.exports = { forgeRenderJauge, forgeHexToRgb, forgeInterpolateColor, forgeReadFieldValue }; var renderMod = require('./render-element.js'); global.forgeStyleString = global.forgeStyleString || renderMod.forgeStyleString; global.forgeHtmlEscape = global.forgeHtmlEscape || renderMod.forgeHtmlEscape; global.forgeAutoId = global.forgeAutoId || renderMod.forgeAutoId; }