// 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 = '