import $ from 'jquery'
import { j3pAddElt, j3pAjouteBouton, j3pAjouteDiv, j3pVirgule, j3pDetruit, j3pDiv, j3pElement, j3pNombre, j3pPaletteMathquill, j3pStyle, j3pValeurde, j3pEnsureHtmlElement, j3pGetNewId } from 'src/legacy/core/functions'
import { j3pCreeRectangle, j3pCreeSegment } from 'src/legacy/core/functionsSvg'
import { j3pAffiche, mqRestriction } from 'src/lib/mathquill/functions'
import { hasProp } from 'src/lib/utils/object'
/**
* @fileOverview Cet outil ne fait que déclarer la fct j3ptableau_signes_variations
*/
// @todo nettoyer la gestion des inputMq pour la compatibilité avec ValidationZones, ici on a des doublons entre mqList et tabDef.validationZonesInputs (ça devrait être la même liste)
// => il faudrait plutôt ajouter une propriété validationZones à l’objet retourné par tableauSignesVariations si la section le réclame (via des options)
// pour que la section puisse appeler directement tabVar.validationZones.valideReponses() (sans créer elle-même ses zones) plutôt que de les créer par ailleurs.
// Ça suppose que l’objet ValidationZones ait une nouvelle méthode addZone (pour que la section puisse avoir des inputs dans le tableau et hors du tableau dans le même objet ValidationZones)
// @todo finir de documenter tous ces objets et params
/**
* @typedef TabDef
* @type Object
* @property {Object} mef données de mise en forme
* @property {number} mef.L largeur
* @property {number} mef.h hauteur
* @property {string} mef.macouleur la couleur sous la forme #rrvvbb
* @property {string[]} liste_boutons la liste des boutons matquill à afficher
* @property {TabDatasLigne[]} lignes
* @property {HTMLElement[]} [validationZonesInputs] Le contenu de validationZones.zones.inputs
* @property {string[]} [zonesdesaisie_charnieres] Des id de inputMq, affecté par tableauSignesVariations
*/
/**
* @typedef TabDatasLigne
* @type Object
* @property {string} type signes|variations
* @property {number} hauteur
* @property {number[]} imagestheoriques
* @property {HTMLElement[]} liste_deroulante
* @property {string[]} zonesdesaisie des id d'éléments
* @property {string[]} imagesreponses les réponses de l'élève dans les inputMq
* @property {string[]} imagesreponses_x les réponses de l'élève dans les inputMq de la ligne des x
* @property {Object} valeurs_charnieres
* @property {string[]} valeurs_charnieres.valeurs_approchees
* @property {string[]} valeurs_charnieres.valeurs_theoriques
* @property {string[]} valeurs_charnieres.valeurs_affichees
*/
/**
* Crée un tableau de signe ou un tableau de variations.
* Attention à bien fournir tabDef.validationZonesInputs si vous utilisez aussi ValidationZones avec des zones de saisie dans le tableau
* @param {HTMLElement|string} divparent
* @param {string} divId L'id du div qui sera créé pour y mettre le corrigé, peut être vide (il sera généré)
* @param {TabDef} tabDef La définition de base du tableau, une propriété perso sera ajoutée à cet objet.
* @param {boolean} modeCorrection
* @param {boolean} [isDebug=false] passer true pour avoir les messages de debug en console
* @param {function} [finishCallback] une callback éventuelle qui sera appelée quand tout sera terminé
*/
export default function tableauSignesVariations (divparent, divId, tabDef, modeCorrection, isDebug, finishCallback) {
// la création du tableau est scindée en deux parties, pour ajouter une pause après l’affichage des formules de la première colonne
// (necessaire pour que le rendu soit effectué et donc pouvoir calculer la position des éléments pour afficher la première barre verticale
function creationTableau1 () {
let valeur, valeur2, valeurTheorique
// si le tableau valeurs_charnieres.valeurs_affichees n’est pas défini je le déclare égal au tableau valeurs_theoriques
for (let i = 0; i <= tabDef.lignes.length - 1; i++) {
// var est_tableau=tabDef.valeurs_charnieres.valeurs_affichees.constructor.toString().indexOf("Array") > -1
if (!tabDef.lignes[i].valeurs_charnieres.valeurs_affichees) {
tabDef.lignes[i].valeurs_charnieres.valeurs_affichees = []
for (let index = 0; index <= tabDef.lignes[i].valeurs_charnieres.valeurs_theoriques.length - 1; index++) {
tabDef.lignes[i].valeurs_charnieres.valeurs_affichees[index] = tabDef.lignes[i].valeurs_charnieres.valeurs_theoriques[index]
}
}
// si le tab imagestheoriques n’est pas défini je le déclare égal aux coord 0 du tableau images
if (!tabDef.lignes[i].imagestheoriques) {
tabDef.lignes[i].imagestheoriques = []
for (let index = 0; index <= tabDef.lignes[i].images.length - 1; index++) {
tabDef.lignes[i].imagestheoriques[index] = tabDef.lignes[i].images[index][0]
}
}
if (!modeCorrection) {
// pour garder la mémoire des id des listes déroulantes pour pouvoir les geler en correction
tabDef.lignes[i].liste_deroulante = []
// pareil pour les zones de saisie :
tabDef.lignes[i].zonesdesaisie = []
}
}
// pour les zones de saisies de la ligne des x : (on garde les id pour pouvoir les geler en correction
tabDef.zonesdesaisie_charnieres = []
// il faut imposer un minimum de largeur, sinon ça fait n’importe quoi (des flèches de variation qui reviennent en arrière)
const nbCharnieres = tabDef.lignes[0].valeurs_charnieres.valeurs_theoriques.length
const largeurMin = 150 + nbCharnieres * 80
// on modifie l’objet passé en argument (il est utilisé en var globale dans plusieurs fonctions), tant pis…
if (tabDef.mef.L < largeurMin) tabDef.mef.L = largeurMin
svg.setAttribute('width', tabDef.mef.L + 2)
let h = tabDef.mef.h
for (let i = 0; i <= tabDef.lignes.length - 1; i++) {
h += tabDef.lignes[i].hauteur
// console.log("tabDef.lignes[i].hauteur="+tabDef.lignes[i].hauteur)
}
svg.setAttribute('height', h + 2)
// pour accueillir la palette de boutons :
j3pDiv(zoneSvgCorr, divId + 'MepPalette', '', [0, h + 10])
// ASYNC 1
setTimeout(() => {
zoneSvgCorr.appendChild(svg)
// a mon avis pas necessaire
zoneSvgCorr.style.color = tabDef.mef.macouleur
// Affichage de la ligne des x :
j3pCreeRectangle(svg, {
id: divId + 'cadre',
x: 1,
y: 1,
width: tabDef.mef.L,
height: tabDef.mef.h,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
// il me faut la liste ordonnées des valeurs charnières (valeurs qui seront affichées sur la ligne des x):
// REMARQUE : a voir si l’on en fait un (ou des) tableaux de l’objet, si recup souhaitable pour placer un point mobile...
// pour stocker le i dans lignes[i]
charnieresMemoire[0] = []
// pour l’indice correspondant de tabDef.lignes[i].valeurs_charnieres.valeurs_theoriques.length
charnieresMemoire[1] = []
// et enfin je stocke si à l’origine c'était une valeur charnière ou une image (qqfois qu’on demande un antécédent....)
charnieresMemoire[2] = []
for (let i = 0; i <= tabDef.lignes.length - 1; i++) {
charnieresLignes[i] = []
charnieresLignesApprochees[i] = []
if (!modeCorrection) {
// je créé également un tableau qui receuillera les réponses des élèves, stockées dans l’objet général pour récupération ultérieure
tabDef.lignes[i].valeurs_charnieres.reponses = []
// je créé le tableau qui receuillera les réponses de l’élève, si zone de saisie il y a (pour les images)
tabDef.lignes[i].imagesreponses = []
// tableau qui accueillera les reponses des eleves si on demande l’antécédent d’une image'
tabDef.lignes[i].imagesreponses_x = []
}
for (let j = 0; j <= tabDef.lignes[i].valeurs_charnieres.valeurs_theoriques.length - 1; j++) {
valeurTheorique = tabDef.lignes[i].valeurs_charnieres.valeurs_theoriques[j]
valeur2 = tabDef.lignes[i].valeurs_charnieres.valeurs_approchees[j]
if (!estDedans(charnieresApprochees, valeur2)) {
// var valeur3=tabDef.lignes[i].valeurs_charnieres.valeurs_a_afficher[j];
// var valeur3=true;
// var valeur4=tabDef.lignes[i].valeurs_charnieres.valeurs_affichees[j];
valeur = tabDef.lignes[i].valeurs_charnieres.valeurs_affichees[j]
if (modeCorrection && valeur === '?') {
// si l’on corrige et qu’on demandait une zone de saisie, je remplace par la réponse de l’élève
valeur = tabDef.lignes[i].valeurs_charnieres.reponses[j]
}
charnieres.push(valeur)
charnieresApprochees.push(valeur2)
charnieresTheoriques.push(valeurTheorique)
charnieresMemoire[0].push(i)
charnieresMemoire[1].push(j)
charnieresMemoire[2].push('charniere')
}
if (!estDedans(charnieresLignes[i], valeurTheorique)) {
charnieresLignes[i].push(valeurTheorique)
charnieresLignesApprochees[i].push(valeur2)
}
}
// il faut tester aussi les images :
for (let j = 0; j <= tabDef.lignes[i].images.length - 1; j++) {
// ce sera pour garder en mémoire les réponses élèves dans le cas où deux zones de saisies autour de la valeur interdite (voir dans l’écouteur) :
// console.log("-----tabDef.lignes["+i+"].imagesreponses="+tabDef.lignes[i].imagesreponses)
if (!modeCorrection) {
tabDef.lignes[i].imagesreponses[j] = []
}
valeur = tabDef.lignes[i].images[j][0]
valeur2 = tabDef.lignes[i].imagesapprochees[j]
valeurTheorique = tabDef.lignes[i].imagestheoriques[j]
if (!estDedans(charnieresApprochees, valeur2)) {
// var valeur3=tabDef.lignes[i].images_a_afficher[j];
// var valeur=tabDef.lignes[i].images[j][0]
// var valeur3=true;
charnieres.push(valeur)
// charnieresLignes[i].push(valeur)
charnieresApprochees.push(valeur2)
charnieresTheoriques.push(valeurTheorique)
charnieresMemoire[0].push(i)
charnieresMemoire[1].push(j)
charnieresMemoire[2].push('image')
}
if (!estDedans(charnieresLignes[i], valeur)) {
charnieresLignes[i].push(valeur)
}
}
}
if (isDebug) {
console.debug('charnieres_lignes[0]=' + charnieresLignes[0])
console.debug('charnieres_lignes[1]=' + charnieresLignes[1])
console.debug('charnieres?length=' + charnieres.length)
console.debug('charnieres_approchees=' + charnieresApprochees + ' et charnieres=' + charnieres + ' et charnieres_theoriques=' + charnieresTheoriques + ' et ch_m[0]=' + charnieresMemoire[0] + ' et ch_m[1]=' + charnieresMemoire[1])
console.debug(' et charnieres_memoire[2]=' + charnieresMemoire[2])
}
// on trie :
// @todo utiliser ordonnerTableau à la place, et si ça marche supprimer ordonnerTableauAvirer
ordonnerTableauAvirer([charnieresApprochees, charnieres, charnieresTheoriques, charnieresMemoire[0], charnieresMemoire[1], charnieresMemoire[2]])
if (isDebug) {
console.debug('Après ordre : ch_approchees=' + charnieresApprochees + ' et ch=' + charnieres + ' et ch_theoriques=' + charnieresTheoriques + ' et ch_memoire[0]=' + charnieresMemoire[0] + ' et ch_memoire[1]=' + charnieresMemoire[1])
console.debug(' et charnieres_memoire[2]=' + charnieresMemoire[2])
console.debug('charnieres?length=' + charnieres.length)
}
// Affichage des rectangles par ligne :
hauteurTemp = tabDef.mef.h
const txt2Txt = []
for (const [i, ligne] of tabDef.lignes.entries()) {
j3pCreeRectangle(svg, {
id: divId + 'cadre_' + i,
x: 1,
y: hauteurTemp,
width: tabDef.mef.L,
height: ligne.hauteur,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
// placement des textes dans la colonne de gauche (et on détecte la largeur max das largeurSigneDe
if (ligne.type === 'signes') {
// TEXTES A EXTERNALISER
if (ligne.expression === '&1&') {
txt2Txt[i] = 'Signe(s) de &1&'
} else {
txt2Txt[i] = 'Signe(s) de $' + ligne.expression + '$'
}
}
if (ligne.type === 'variations') {
txt2Txt[i] = 'Variation(s)<br/>de $' + ligne.expression + '$'
// j’en profite pour créer un tableau qui contiendra les coordonnées des flèches.
ligne.coord_fleches = []
}
j3pCreeSegment(svg, {
id: divId + 's1' + i,
x1: 0,
y1: hauteurTemp + ligne.hauteur,
x2: tabDef.mef.L,
y2: hauteurTemp + ligne.hauteur,
couleur: tabDef.macouleur,
epaisseur: 1
})
const divSigneDe = j3pAddElt(zoneSvgCorr, 'div', '', {
id: divId + 'signede' + i,
style: {
color: tabDef.mef.macouleur,
position: 'absolute',
top: '0',
left: '0'
}
})
// Voilà ce que j’ai enlevé dans inputmq1 : , correction: j3p.storage.solution[1]
// Le 21/10/21 Rémi
const { inputmqList, parent } = j3pAffiche(divSigneDe, 'Mep' + divId + 'txt2' + i, txt2Txt[i], {
inputmq1: { texte: '' }
})
if (inputmqList.length > 0) {
mqRestriction(inputmqList[0], '\\d,.+-x/', { commandes: ['fraction'] })
mqList.push(inputmqList[0])
}
// var posTxt = h/(nb_lignes_signes+1)+i*h/(nb_lignes_signes+1)-monobj.getBoundingClientRect().height;
// alignés en haut.
let posTxt = hauteurTemp
// pour les centrer :
posTxt += ligne.hauteur / 2
posTxt -= parent.getBoundingClientRect().height / 2
divSigneDe.style.top = posTxt + 'px'
divSigneDe.style.left = '2px'
hauteurTemp += ligne.hauteur
} // boucle lignes
// un pb de détection des largeurs des codes mathquill à cause de son affichage async
// ASYNC 2
setTimeout(() => creationTableau2Etape1(hauteurTemp), 0)
}, 0)
} // creation_tableau1
// fonction appelée à la place de creation_tableau1 lors de l’ajout d’une ligne au tableau'
function creationTableau1bis () {
// si le tableau valeurs_charnieres.valeurs_affichees n’est pas défini je le déclare égal au tableau valeurs_theoriques
for (let i = 0; i <= tabDef.lignes.length - 1; i++) {
if (!tabDef.lignes[i].valeurs_charnieres.valeurs_affichees) {
tabDef.lignes[i].valeurs_charnieres.valeurs_affichees = []
for (let index = 0; index <= tabDef.lignes[i].valeurs_charnieres.valeurs_theoriques.length - 1; index++) {
tabDef.lignes[i].valeurs_charnieres.valeurs_affichees[index] = tabDef.lignes[i].valeurs_charnieres.valeurs_theoriques[index]
}
}
// si le tab imagestheoriques n’est pas défini je le déclare égal aux coord 0 du tableau images
if (!tabDef.lignes[i].imagestheoriques) {
tabDef.lignes[i].imagestheoriques = []
// for (let index = 0; index <= tabDef.lignes[i].images.length - 1; index++) tabDef.lignes[i].imagestheoriques[index]=tabDef.lignes[i].images[index][0];
}
if (!modeCorrection) {
// pour garder la mémoire des id des listes déroulantes pour pouvoir les geler en correction
tabDef.lignes[i].liste_deroulante = []
// pareil pour les zones de saisie :
tabDef.lignes[i].zonesdesaisie = []
}
}
// pour les zones de saisies de la ligne des x : (on garde les id pour pouvoir les geler en correction
svg.setAttribute('width', tabDef.mef.L + 2)
let h = tabDef.mef.h
for (let i = 0; i <= tabDef.lignes.length - 1; i++) {
h += tabDef.lignes[i].hauteur
// console.log("tabDef.lignes[i].hauteur="+tabDef.lignes[i].hauteur)
}
svg.setAttribute('height', h + 2)
// pour accueillir la palette de boutons :
j3pDiv(zoneSvgCorr, divId + 'MepPalette', '', [0, h])
zoneSvgCorr.appendChild(svg)
// a mon avis pas necessaire
zoneSvgCorr.style.color = tabDef.mef.macouleur
// Affichage de la ligne des x :
j3pCreeRectangle(svg, {
id: divId + 'cadre',
x: 1,
y: 1,
width: tabDef.mef.L,
height: tabDef.mef.h,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
hauteurTemp = tabDef.mef.h
const txt2Txt = []
for (let i = 0; i <= tabDef.lignes.length - 1; i++) {
j3pCreeRectangle(svg, {
id: divId + 'cadre_' + i,
x: 1,
y: hauteurTemp,
width: tabDef.mef.L,
height: tabDef.lignes[i].hauteur,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
// placement des textes dans la colonne de gauche (et on détecte la largeur max das largeurSigneDe
if (tabDef.lignes[i].type === 'signes') {
// TEXTES A EXTERNALISER
if (tabDef.lignes[i].expression === '&1&') {
txt2Txt[i] = 'Signe(s) de &1&'
} else {
txt2Txt[i] = 'Signe(s) de $' + tabDef.lignes[i].expression + '$'
}
//
}
if (tabDef.lignes[i].type === 'variations') {
txt2Txt[i] = 'Variation(s) de $' + tabDef.lignes[i].expression + '$'
}
j3pCreeSegment(svg, {
id: divId + 's1' + i,
x1: 0,
y1: hauteurTemp + tabDef.lignes[i].hauteur,
x2: tabDef.mef.L,
y2: hauteurTemp + tabDef.lignes[i].hauteur,
couleur: tabDef.macouleur,
epaisseur: 1
})
const divSigneDe = j3pAjouteDiv(zoneSvgCorr, divId + 'signede' + i, '', {
style: {
color: tabDef.mef.macouleur,
position: 'absolute',
top: '0',
left: '0'
}
})
// Voilà ce que j’ai enlevé dans inputmq1 : , correction: j3p.storage.solution[1]
const { inputmqList, parent } = j3pAffiche(divSigneDe, 'Mep' + divId + 'txt2' + i, txt2Txt[i], {
inputmq1: {
texte: ''
}
})
if (inputmqList.length > 0) {
mqRestriction(inputmqList[0], '\\d,.+-x/', { commandes: ['fraction'] })
mqList.push(inputmqList[0])
}
// var posTxt = h/(nb_lignes_signes+1)+i*h/(nb_lignes_signes+1)-monobj.getBoundingClientRect().height;
// alignés en haut.
let posTxt = hauteurTemp
// pour les centrer :
posTxt += tabDef.lignes[i].hauteur / 2
posTxt -= parent.getBoundingClientRect().height
divSigneDe.style.top = posTxt + 'px'
divSigneDe.style.left = '2px'
hauteurTemp += tabDef.lignes[i].hauteur
}
// un pb de détection des largeurs des codes mathquill à cause du temps d’affichage...
setTimeout(() => {
creationTableau2Etape2(hauteurTemp)
}, 0)
}
// fonction appelée à la place de creation_tableau1 lors de l’ajout d’un intervalle au tableau'
function creationTableau1ter (nbInt) {
let val1, val2, longueur
// on procède différemment : l’utilisateur a la main sur le nb d’intervalles, on part du principe qu’on n’aura pas d’images dans le tableau à placer
// le tableau a déjà été tracé, on ne recommence pas la seconde étape de construction, on récupère la première charnière affichée, la dernière et on complete
for (let i = 0; i <= tabDef.lignes.length - 1; i++) {
// if (tabDef.lignes[i].type=="signes"){
val1 = tabDef.lignes[i].valeurs_charnieres.valeurs_affichees[0]
longueur = tabDef.lignes[i].valeurs_charnieres.valeurs_affichees.length
val2 = tabDef.lignes[i].valeurs_charnieres.valeurs_affichees[longueur - 1]
tabDef.lignes[i].valeurs_charnieres.valeurs_affichees = []
tabDef.lignes[i].valeurs_charnieres.valeurs_affichees.push(val1)
for (let j = 1; j < nbInt; j++) {
tabDef.lignes[i].valeurs_charnieres.valeurs_affichees.push('?')
}
tabDef.lignes[i].valeurs_charnieres.valeurs_affichees.push(val2)
// }
// si le tab imagestheoriques n’est pas défini je le déclare égal aux coord 0 du tableau images
if (!tabDef.lignes[i].imagestheoriques) {
tabDef.lignes[i].imagestheoriques = []
for (let index = 0; index <= tabDef.lignes[i].images.length - 1; index++) {
tabDef.lignes[i].imagestheoriques[index] = tabDef.lignes[i].images[index][0]
}
}
if (!modeCorrection) {
// pour garder la mémoire des id des listes déroulantes pour pouvoir les geler en correction
tabDef.lignes[i].liste_deroulante = []
// pareil pour les zones de saisie :
tabDef.lignes[i].zonesdesaisie = []
}
}
// on reset les charnières en conservant les extrémités et en mettant des ? au milieu
const last = charnieres.pop()
charnieres.splice(1)
for (let j = 1; j < nbInt; j++) {
charnieres.push('?')
}
charnieres.push(last)
if (isDebug) console.debug('tabDef dans j3ptableau_signes_variations', tabDef)
// Il reste à nettoyer le contenu des lignes puis à appeler l’étape2 de creation_tableau2
for (let i = 0; i < charnieres.length; i++) {
if (j3pElement(divId + 'zoneNulle' + i, null)) {
j3pDetruit(divId + 'zoneNulle' + i)
}
}
for (let i = 0; i < divList.length; i++) {
for (let k = 0; k < divList[i].length; k++) {
j3pDetruit(divList[i][k])
}
}
setTimeout(() => {
creationTableau2Etape2(hauteurTemp)
}, 0)
}
// fonction qui teste la présence de element dans tab
function estDedans (tab, element) {
return tab.includes(element)
}
/**
* Retourne un nouveau tableau sans l’élément dont on file l’index (sans modifier le tableau d’origne)
* Rq https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/splice fait ça en natif (en modifiant le tableau)
* @private
* @param {any[]} tab
* @param {number} index
* @return {any[]}
*/
function supprimeElement (tab, index) {
return tab.slice(0, index).concat(tab.slice(index + 1))
}
// fonction qui ordonne de la même façon le tableau2 que le tableau1, on tient compte de la présence éventuelle de -inf et +inf
// Elle a été réécrite dans ordonnerTableau (avec du for & les évals virés)
// À virer quand la remplaçante aura été certifiée bon pour le service
function ordonnerTableauAvirer (tableau) {
let contientMoinsInf, contientPlusInf
const tabs = {}
for (let i = 0; i <= 5; i++) tabs['tableau' + i + '_temp'] = tableau[i]
if (estDedans(tableau[0], '-inf') || estDedans(tableau[0], '-\\infty')) {
contientMoinsInf = true
const lindexDuMoinsInf = Math.max(tableau[0].indexOf('-inf'), tableau[0].indexOf('-\\infty'))
for (let i = 0; i <= 5; i++) tabs['temp_moinsinf' + i] = tabs['tableau' + i + '_temp'][lindexDuMoinsInf]
if (isDebug) console.debug('lindexDuMoinsInf=' + lindexDuMoinsInf)
// on regarde si c’est true ou false pour le remettre à la fin (à mon avis ne sert à rien)
// var affichage_moins_inf=tableau2_temp[lindexDuMoinsInf]
for (let i = 0; i <= 5; i++) tabs['tableau' + i + '_temp'] = supprimeElement(tabs['tableau' + i + '_temp'], lindexDuMoinsInf)
} else {
contientMoinsInf = false
}
if (estDedans(tableau[0], '+inf') || estDedans(tableau[0], '+\\infty')) {
contientPlusInf = true
let lindexDuPlusInf = Math.max(tableau[0].indexOf('+inf'), tableau[0].indexOf('+\\infty'))
if (contientMoinsInf) {
lindexDuPlusInf--
}// car on enlevera un élément...
for (let i = 0; i <= 5; i++) tabs['temp_plusinf' + i] = tabs['tableau' + i + '_temp'][lindexDuPlusInf]
if (isDebug) console.debug('lindexDuPlusInf=' + lindexDuPlusInf)
// on regarde si c’est true ou false pour le remettre à la fin
// var affichage_plus_inf=tableau2_temp[lindexDuPlusInf]
for (let i = 0; i <= 5; i++) tabs['tableau' + i + '_temp'] = supprimeElement(tabs['tableau' + i + '_temp'], lindexDuPlusInf)
} else {
contientPlusInf = false
}
for (let t = 1; t < tabs.tableau0_temp.length; t++) {
for (let i = 0; i < tabs.tableau0_temp.length - 1; i++) {
// console.log("tabs.tableau0_temp["+i+"]="+tabs.tableau0_temp[i]+" et tabs.tableau0_temp["+(i+1)+"]="+tabs.tableau0_temp[i+1])
if (tabs.tableau0_temp[i] > tabs.tableau0_temp[i + 1]) {
// je permute :
for (let k = 1; k <= tableau.length - 1; k++) {
const temp = tabs['tableau' + k + '_temp'][i + 1]
tabs['tableau' + k + '_temp'][i + 1] = tabs['tableau' + k + '_temp'][i]
tabs['tableau' + k + '_temp'][i] = temp
}
const k2 = tabs.tableau0_temp[i] - tabs.tableau0_temp[i + 1]
tabs.tableau0_temp[i] -= k2
tabs.tableau0_temp[i + 1] += k2
}
}
}
const tab = {}
tab.tab0 = []
tab.tab1 = []
tab.tab2 = []
tab.tab3 = []
tab.tab4 = []
tab.tab5 = []
if (contientMoinsInf) {
tab.tab0.push(tabs.temp_moinsinf0)
tab.tab1.push(tabs.temp_moinsinf1)
tab.tab2.push(tabs.temp_moinsinf2)
tab.tab3.push(tabs.temp_moinsinf3)
tab.tab4.push(tabs.temp_moinsinf4)
tab.tab5.push(tabs.temp_moinsinf5)
}
for (let i = 0; i < tabs.tableau0_temp.length; i++) {
tab.tab0.push(tabs.tableau0_temp[i])
tab.tab1.push(tabs.tableau1_temp[i])
tab.tab2.push(tabs.tableau2_temp[i])
tab.tab3.push(tabs.tableau3_temp[i])
tab.tab4.push(tabs.tableau4_temp[i])
tab.tab5.push(tabs.tableau5_temp[i])
}
if (contientPlusInf) {
if (isDebug) console.debug('j’ai du +inf et avant mon tableau= ' + tab.tab1)
tab.tab0.push(tabs.temp_plusinf0)
tab.tab1.push(tabs.temp_plusinf1)
tab.tab2.push(tabs.temp_plusinf2)
tab.tab3.push(tabs.temp_plusinf3)
tab.tab4.push(tabs.temp_plusinf4)
tab.tab5.push(tabs.temp_plusinf5)
if (isDebug) console.debug('APRES : ' + tab.tab1)
}
return tab
}
function affichePaletteMQ (id) {
// j3pEmpty('MepBarreBoutonsMQ') // devenu inutile car j3pPaletteMathquill le détruira s’il existe déjà
j3pPaletteMathquill(divId + 'MepPalette', id, { liste: tabDef.liste_boutons })
}
function positionneZoneCharnieres (id) {
// on passe en paramètre un txt du style divId+"nomzone_nulle"+moni+"inputmq1".
// PB dans la boucle la valeur de i a été incrémentée, en la mettant dans le nom de l’id on peut la récupérer
const pos1 = id.indexOf('nomzone_nulle')
const pos2 = id.indexOf('zone_nulle')
const pos3 = id.indexOf('inputmq1')
const posi = id.indexOf('nomzone_nulle') + 13
const moni = Number(id.charAt(posi))
// pour se rappeler de quelle ligne c'était une charnière...
const ancienI = charnieresMemoire[0][moni - 1]
// et son index dans ce tableau.
const ancienIndice = charnieresMemoire[1][moni - 1]
if (isDebug) console.debug('moni-1=' + (moni - 1) + 'ancienI=' + ancienI + ' et ancienIndice=' + ancienIndice)
const lareponse = $('#' + id).mathquill('latex')
if (charnieresMemoire[2][moni - 1] === 'charniere') {
tabDef.lignes[ancienI].valeurs_charnieres.reponses[ancienIndice] = lareponse
}
if (charnieresMemoire[2][moni - 1] === 'image') {
tabDef.lignes[ancienI].imagesreponses_x[ancienIndice] = lareponse
}
const elt = j3pElement(id.substring(0, pos1) + id.substring(pos2, pos3))
if (isDebug) console.debug('largeurSigneDe=' + largeurSigneDe)
if (isDebug) console.debug('nbRacines=' + nbRacines)
if (moni === 1) {
// console.log('valeur de gauche left à ' + (largeurSigneDe + (moni - 1) * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1)))
elt.style.left = (largeurSigneDe + (moni - 1) * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1)) + 'px'
} else {
if (moni === nbRacines) {
if (isDebug) console.debug('valeur de droite left à ' + (largeurSigneDe + (moni - 1) * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1) - elt.getBoundingClientRect().width - 4))
elt.style.left = (largeurSigneDe + (moni - 1) * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1) - elt.getBoundingClientRect().width - 4) + 'px'
} else {
if (isDebug) console.debug('valeur qcq left à ' + (largeurSigneDe + (moni - 1) * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1) - elt.getBoundingClientRect().width / 2))
elt.style.left = (largeurSigneDe + (moni - 1) * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1) - elt.getBoundingClientRect().width / 2) + 'px'
}
}
if (isDebug) console.debug('elt.style.left=' + elt.style.left)
elt.style.top = ((tabDef.mef.h) / 2 - elt.getBoundingClientRect().height / 2) + 'px'
// j’ajoute également l’écouteur pour la palette car sinon, si on tabule, la palette n’est pas la bonne...
affichePaletteMQ(divId + 'nomzone_nulle' + moni + 'inputmq1')
} // positionneZoneCharnieres
function positionneZoneSignes (id, hauteurTemp) {
// PB i j k virer nom et inputmq1 pour récupérer le bon nom et les bonnes valeurs de i j k (incrémentées) sinon
const pos0 = id.indexOf(divId)
const pos1 = id.indexOf('nomimage_fct')
const pos2 = id.indexOf('imageFct')
const pos3 = id.indexOf('inputmq1')
// la valeur de j était indiquée après nomimage_fct
const posj = pos1 + 12
// A FAIRE : changer les charAt par des substring ? (bug si >9 mais faut pas pousser...)
const monj = id.charAt(posj)
// la valeur de i avant
const moni = Number(id.charAt(pos1 - 1))
// la valeur de k avant :
const monk = Number(id.charAt(3))
if (isDebug) console.debug('===========================')
if (isDebug) console.debug('pos1=' + pos1 + ' et pos2=' + pos2 + ' et pos3=' + pos3 + 'monj=' + monj + ' moni=' + moni + ' monk=' + monk)
const elt = j3pElement(id.substring(pos0, pos1) + id.substring(pos2, pos3))
if (isDebug) console.debug('elt=' + id.substring(pos0, pos1) + id.substring(pos2, pos3))
const laLargeur = elt.offsetLeft
if (isDebug) console.debug('laLargeur=' + laLargeur)
if (monj !== 0) {
// la racine de gauche je décale pas elle est alignée à gauche
// je redéfinis le positionnement...
let leDecalage
if (monj === nbRacines) {
// la racine de droite
if (isDebug) console.debug('Racine de droite')
// var pos3=pos2-elt.getBoundingClientRect().width;
leDecalage = elt.getBoundingClientRect().width
} else {
// cas général
// var pos3=pos2-elt.getBoundingClientRect().width/2
leDecalage = elt.getBoundingClientRect().width / 2
if (isDebug) console.debug('CAS GENERAL ' + leDecalage)
}
// elt.style.left = pos3+"px";
const valeurX = positionValeursSignes[monj]
if (isDebug) console.debug('valeurX=' + valeurX)
elt.style.left = valeurX - leDecalage + 'px'
}
elt.style.top = (j3pNombre(hauteurTemp) + tabDef.lignes[moni].hauteur / 2 - elt.getBoundingClientRect().height / 2) + 'px'
// on renseigne le tableau des réponses :
// const lareponse = $('#' + id).mathquill('latex')
// console.log("lareponse="+lareponse+" id="+id);
tabDef.lignes[moni].imagesreponses[monk] = $('#' + id).mathquill('latex')
// console.log("tabDef.lignes["+moni+"].imagesreponses="+tabDef.lignes[moni].imagesreponses);
// j’ajoute également l’écouteur pour la palette car sinon, si on tabule, la palette n’est pas la bonne...
affichePaletteMQ('tab' + monk + divId + moni + 'nomimage_fct' + monj + 'inputmq1')
} // positionneZoneSignes
function positionneZoneVariations (id) {
// on passe en paramètre un txt du style k+divId+"image_txt"+i+jEquivalent+"inputmq1".
// PB dans la boucle les valeurs de i,j,k ont été incrémentées, en les mettant dans le nom de l’id on peut les récupérer
// var pos0=id.indexOf(divId)
// var pos1=id.indexOf("image_txt")
const pos3 = id.indexOf('inputmq1')
const lareponse = $('#' + id).mathquill('latex')
let leTexte, leDecalage
if (id.includes('image_gauche')) {
// appelé par une zone de texte à gauche de la double barre
leTexte = 'image_gauche'
leDecalage = 12
} else {
if (id.includes('image_droite')) {
leTexte = 'image_droite'
leDecalage = 12
} else {
leTexte = 'image_txt'
leDecalage = 9
}
}
const posi = id.indexOf(leTexte) + leDecalage
const moni = Number(id.charAt(posi))
const monj = Number(id.charAt(posi + 1))
// la valeur de k avant :
const monk = Number(id.charAt(3))
// console.log("moni-1="+(moni-1)+"monj="+monj)
let eltImgGauche, valeurX, valeurY, decalage
if (id.indexOf('image_gauche') !== -1) {
// appelé par une zone de texte à gauche de la double barre
tabDef.lignes[moni].imagesreponses[monk][0] = lareponse
eltImgGauche = j3pElement(divId + 'image_gauche' + id.substring(posi, pos3))
// console.log("tabDef.lignes["+moni+"].imagesreponses["+monk+"][0]="+tabDef.lignes[moni].imagesreponses[monk][0])
valeurX = tabDef.lignes[moni].images_coord_x[monk][0]
valeurY = tabDef.lignes[moni].images_coord_y[monk][0]
decalage = eltImgGauche.getBoundingClientRect().width
} else {
if (id.indexOf('image_droite') !== -1) {
// appelé par une zone de texte à gauche de la double barre
tabDef.lignes[moni].imagesreponses[monk][1] = lareponse
eltImgGauche = j3pElement(divId + 'image_droite' + id.substring(posi, pos3))
// console.log("tabDef.lignes["+moni+"].imagesreponses["+monk+"][1]="+tabDef.lignes[moni].imagesreponses[monk][1])
valeurX = tabDef.lignes[moni].images_coord_x[monk][1]
valeurY = tabDef.lignes[moni].images_coord_y[monk][1]
} else {
tabDef.lignes[moni].imagesreponses[monk] = lareponse
eltImgGauche = j3pElement(divId + 'zone_image' + id.substring(posi, pos3))
valeurX = tabDef.lignes[moni].images_coord_x[monk]
valeurY = tabDef.lignes[moni].images_coord_y[monk]
decalage = eltImgGauche.getBoundingClientRect().width / 2
if (monj === 0) {
// premiere charniere:
decalage = 0
}
if (monj === charnieresTheoriques.length - 1) {
// derniere charniere
decalage = eltImgGauche.getBoundingClientRect().width
}
}
}
// console.log("moni="+moni)tabDef.lignes[ancienI]
// console.log("------id.substring(0,pos1)="+id.substring(0,pos1)+" et id.substring(posi,pos3)="+id.substring(posi,pos3))
// je repositionne ma zone de saisie :
if (!id.includes('image_droite')) eltImgGauche.style.left = valeurX - decalage + 'px'
eltImgGauche.style.top = (valeurY - eltImgGauche.getBoundingClientRect().height / 2) + 'px'
// j’ajoute également l’écouteur pour la palette car sinon, si on tabule, la palette n’est pas la bonne...
affichePaletteMQ('tab' + monk + divId + leTexte + moni + monj + 'inputmq1')
}
function creerFleches (i) {
divList[i] = []
hauteurTemp = tabDef.mef.h
for (let indexI = 0; indexI <= i - 1; indexI++) {
hauteurTemp += tabDef.lignes[indexI].hauteur
}
// les coordonnées des charnières
const tabXCharnieres = []
const tabYCharnieres = []
// les y des débuts de chaque variation
tabYCharnieres[0] = []
// les y des fins de chaque variation
tabYCharnieres[1] = []
// pas forcément utile...
for (let j = 0; j <= tabDef.lignes[i].variations.length - 1; j++) {
tabDef.lignes[i].coord_fleches[j] = {}// pour stocker les coordonnées de la flèche, pour le point mobile.
// une flèche par variation
// console.log("sens="+tabDef.lignes[i].variations[j]+" et j="+j);
if (isDebug) console.debug('tabDef.lignes[' + i + '].intervalles[' + j + '][0]=' + tabDef.lignes[i].intervalles[j][0])
const charniereDebut = tabDef.lignes[i].intervalles[j][0]
const charniereFin = tabDef.lignes[i].intervalles[j][1]
// je récupère la position en x de mes deux charnières
// POSSIBILITE : NE PAS TRACER LES SEGMENTS DANS LE SWITCH, LE FAIRE A LA FIN APRES AVOIR CONSTRUIT LES IMAGES POUR TENIR COMPTE DE LA LARGEUR DES IMAGES
if (isDebug) console.debug('nbRacines=' + nbRacines)
let xdebut = largeurSigneDe
let xfin = tabDef.mef.L
for (let k = 0; k <= charnieres.length - 1; k++) {
if (j3pNombre(charniereDebut) === charnieresApprochees[k]) {
// console.log("le debut est en "+charnieres[k])
xdebut = (largeurSigneDe + k * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1)) + 30
}
if (j3pNombre(charniereFin) === charnieresApprochees[k]) {
// console.log("la fin est en "+charnieres[k])
xfin = (largeurSigneDe + k * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1)) - 30
}
}
tabXCharnieres.push(xdebut - 30)
if (j === tabDef.lignes[i].variations.length - 1) {
tabXCharnieres.push(xfin + 30)
}
if (isDebug) console.debug('&&&&&&&&&&&&&&&&&&&&&& x_debut=' + xdebut + ' et x_fin=' + xfin)
if (isDebug) console.debug('&&&&&&&&&&&&&&&&&&&&&& largeurSigneDe=' + largeurSigneDe + ' et nbRacines=' + nbRacines)
const longFleche = 10
const monepaisseur = 1
// si on redessine les flèches, il faut effacer les anciennes, l’épaisseur est également plus grande pour pouvoir les repérer et cliquer facilement
let monepaisseur2, monepaisseur3
if (tabDef.lignes[i].cliquable[j]) {
monepaisseur2 = monepaisseur + 2
monepaisseur3 = monepaisseur + 8
// on supprime les <line> des anciennes fleches (si elles existent, sinon ça fait rien)
j3pDetruit(
divId + 's5' + i + j,
divId + 's6' + i + j,
divId + 's7' + i + j,
divId + 's8' + i + j
)
} else {
monepaisseur2 = monepaisseur
}
const decalagexFleche = (j === 0) ? 20 : 0
const decalagexFleche2 = (j === tabDef.lignes[i].variations.length - 1) ? 20 : 0
const decalageyFleche = 5
let segment2, longueur, hauteur, decX1, decY1, decX2, decY2, ydebut, yfin
switch (tabDef.lignes[i].variations[j]) {
case 'croit':
ydebut = hauteurTemp + tabDef.lignes[i].hauteur - 15
yfin = hauteurTemp + 15
j3pCreeSegment(svg, {
id: divId + 's5' + i + j,
x1: xdebut + decalagexFleche,
y1: ydebut - decalageyFleche,
x2: xfin - decalagexFleche2,
y2: yfin + decalageyFleche,
couleur: tabDef.mef.macouleur,
epaisseur: monepaisseur2
})
divList[i].push(divId + 's5' + i + j)
segment2 = j3pCreeSegment(svg, {
id: divId + 's8' + i + j,
x1: xdebut,
y1: ydebut - decalageyFleche,
x2: xfin - decalagexFleche2,
y2: yfin + decalageyFleche,
opacite: 0,
couleur: 'rgb(255,0,0)',
epaisseur: monepaisseur3
})
divList[i].push(divId + 's8' + i + j)
// la flèche au bout, avec calcul savant du décalage... :
longueur = xfin - xdebut
hauteur = -yfin + ydebut
decX1 = Math.sin(Math.atan((longueur / hauteur)) - 22.5 * Math.PI / 180) * longFleche
decY1 = Math.cos(Math.atan((longueur / hauteur)) - 22.5 * Math.PI / 180) * longFleche
decX2 = Math.cos(Math.PI / 2 - Math.atan((longueur / hauteur)) - 22.5 * Math.PI / 180) * longFleche
decY2 = Math.sin(Math.PI / 2 - Math.atan((longueur / hauteur)) - 22.5 * Math.PI / 180) * longFleche
// console.log("j="+j+"et xdebut="+xdebut+" et ydebut="+ydebut+" et xfin="+xfin+" et yfin="+yfin)
j3pCreeSegment(svg, {
id: divId + 's6' + i + j,
x1: xfin - decalagexFleche2,
y1: yfin + decalageyFleche,
x2: xfin - decalagexFleche2 - decX1,
y2: yfin + decalageyFleche + decY1,
couleur: tabDef.mef.macouleur,
epaisseur: monepaisseur2
})
divList[i].push(divId + 's6' + i + j)
j3pCreeSegment(svg, {
id: divId + 's7' + i + j,
x1: xfin - decalagexFleche2,
y1: yfin + decalageyFleche,
x2: xfin - decalagexFleche2 - decX2,
y2: yfin + decalageyFleche + decY2,
couleur: tabDef.mef.macouleur,
epaisseur: monepaisseur2
})
divList[i].push(divId + 's7' + i + j)
if (tabDef.lignes[i].cliquable[j] && !modeCorrection) {
segment2.addEventListener('click', reponseClic.bind(null, i, j))
segment2.addEventListener('mouseover', onMouseOver)
}
break
case 'decroit':
yfin = hauteurTemp + tabDef.lignes[i].hauteur - 15
ydebut = hauteurTemp + 15
j3pCreeSegment(svg, {
id: divId + 's5' + i + j,
x1: xdebut + decalagexFleche,
y1: ydebut + decalageyFleche,
x2: xfin - decalagexFleche2,
y2: yfin - decalageyFleche,
couleur: tabDef.mef.macouleur,
epaisseur: monepaisseur2
})
segment2 = j3pCreeSegment(svg, {
id: divId + 's8' + i + j,
x1: xdebut,
y1: ydebut + decalageyFleche,
x2: xfin - decalagexFleche2,
y2: yfin - decalageyFleche,
opacite: 0,
couleur: 'rgb(255,0,0)',
epaisseur: monepaisseur3
})
divList[i].push(divId + 's5' + i + j)
divList[i].push(divId + 's8' + i + j)
// la flèche au bout, avec calcul savant du décalage... :
// console.log("x_debut="+xdebut+" et x_fin="+xfin)
longueur = xfin - xdebut
hauteur = yfin - ydebut
decX1 = Math.sin(Math.atan((longueur / hauteur)) - 22.5 * Math.PI / 180) * longFleche
decY1 = Math.cos(Math.atan((longueur / hauteur)) - 22.5 * Math.PI / 180) * longFleche
decX2 = Math.cos(Math.PI / 2 - Math.atan((longueur / hauteur)) - 22.5 * Math.PI / 180) * longFleche
decY2 = Math.sin(Math.PI / 2 - Math.atan((longueur / hauteur)) - 22.5 * Math.PI / 180) * longFleche
j3pCreeSegment(svg, {
id: divId + 's6' + i + j,
x1: xfin - decalagexFleche2,
y1: yfin - decalageyFleche,
x2: xfin - decalagexFleche2 - decX1,
y2: yfin - decalageyFleche - decY1,
couleur: tabDef.mef.macouleur,
epaisseur: monepaisseur2
})
j3pCreeSegment(svg, {
id: divId + 's7' + i + j,
x1: xfin - decalagexFleche2,
y1: yfin - decalageyFleche,
x2: xfin - decalagexFleche2 - decX2,
y2: yfin - decalageyFleche - decY2,
couleur: tabDef.mef.macouleur,
epaisseur: monepaisseur2
})
divList[i].push(divId + 's6' + i + j)
divList[i].push(divId + 's7' + i + j)
if (tabDef.lignes[i].cliquable[j] && !modeCorrection) {
segment2.addEventListener('click', reponseClic.bind(null, i, j))
segment2.addEventListener('mouseover', onMouseOver)
}
break
case 'const':
ydebut = hauteurTemp + tabDef.lignes[i].hauteur / 2
yfin = ydebut
j3pCreeSegment(svg, {
id: divId + 's5' + i + j,
x1: xdebut,
y1: ydebut,
x2: xfin,
y2: yfin,
couleur: tabDef.mef.macouleur,
epaisseur: monepaisseur2
})
segment2 = j3pCreeSegment(svg, {
id: divId + 's8' + i + j,
x1: xdebut,
y1: ydebut,
x2: xfin,
y2: yfin,
opacite: 0,
couleur: 'rgb(255,0,0)',
epaisseur: monepaisseur3
})
divList[i].push(divId + 's5' + i + j)
divList[i].push(divId + 's8' + i + j)
longueur = xfin - xdebut
hauteur = yfin - ydebut
decX1 = Math.cos(22.5 * Math.PI / 180) * longFleche
decY1 = Math.sin(22.5 * Math.PI / 180) * longFleche
decX2 = decX1
decY2 = decY1
j3pCreeSegment(svg, {
id: divId + 's6' + i + j,
x1: xfin,
y1: yfin,
x2: xfin - decX1,
y2: yfin - decY1,
couleur: tabDef.mef.macouleur,
epaisseur: monepaisseur2
})
j3pCreeSegment(svg, {
id: divId + 's7' + i + j,
x1: xfin,
y1: yfin,
x2: xfin - decX2,
y2: yfin + decY2,
couleur: tabDef.mef.macouleur,
epaisseur: monepaisseur2
})
divList[i].push(divId + 's6' + i + j)
divList[i].push(divId + 's7' + i + j)
if (tabDef.lignes[i].cliquable[j] && !modeCorrection) {
segment2.addEventListener('click', reponseClic.bind(null, i, j))
segment2.addEventListener('mouseover', onMouseOver)
}
break
}
// je mets au chaud mes ordonnées de mes charnières :
tabYCharnieres[0].push(ydebut)
// le yfin peut être différent du ydebut suivant...
tabYCharnieres[1].push(yfin)
/* if (j==tabDef.lignes[i].variations.length-1){
tabYCharnieres.push(yfin);
} */
// je garde au chaud les coordonnées de mes flèches, pour affichage d’un point mobile :
tabDef.lignes[i].coord_fleches[j].x_debut = xdebut
tabDef.lignes[i].coord_fleches[j].x_fin = xfin
tabDef.lignes[i].coord_fleches[j].y_debut = ydebut
tabDef.lignes[i].coord_fleches[j].y_fin = yfin
// A FAIRE : modifier ces coord au clic (à voir)
}
if (isDebug) console.debug(tabXCharnieres)
if (isDebug) console.debug('=====les y des debuts=' + tabYCharnieres[0])
if (isDebug) console.debug('=====les y des fins=' + tabYCharnieres[1])
// tableaux qui me serviront à garder les coord des images
tabDef.lignes[i].images_coord_x = []
tabDef.lignes[i].images_coord_y = []
for (let k = 0; k <= tabDef.lignes[i].images.length - 1; k++) {
const imageX = tabDef.lignes[i].imagestheoriques[k]
let imageY = tabDef.lignes[i].images[k][1]
if (modeCorrection && imageY === '?') {
imageY = tabDef.lignes[i].imagesreponses[k]
}
if (isDebug) console.debug('imageX=' + imageX + ' et imageY=' + imageY)
// je récupère la position en x de mes deux charnières
let premiereCharniere = false
let derniereCharniere = false
// Je balaye les charnières pour savoir quel est l’indice k correspondant'
let jEquivalent = 0
let charniereEnCours = charnieresTheoriques[0]
let xDeLImage = largeurSigneDe
for (let j = 0; j <= charnieresTheoriques.length - 1; j++) {
if (imageX === charnieresTheoriques[j]) {
if (isDebug) console.debug('le debut est en ' + charnieresTheoriques[j] + ' AVEC nbRacines=' + nbRacines)
xDeLImage = (largeurSigneDe + j * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1))
// je garde en mémoire la charnière trouvée
charniereEnCours = charnieresTheoriques[j]
if (j === 0) {
premiereCharniere = true
}
if (j === charnieresTheoriques.length - 1) {
derniereCharniere = true
}
jEquivalent = j
// ce sera donc tabDef.lignes[i].imagestheoriques[k]=charnieres_theoriques[jEquivalent]
}
}
// console.log("xDeLImage="+xDeLImage)
let yDeLImage, yDeLImageGauche
if (estDedans(tabXCharnieres, xDeLImage)) {
// je détermine son ordonnée en y en récupérant d’abord son index dans le tabXCharnieres
const position = tabXCharnieres.indexOf(xDeLImage)
yDeLImage = tabYCharnieres[0][position]
yDeLImageGauche = tabYCharnieres[1][position - 1]
// cas particulier si j’arrive à la dernière charnière :
if (position === tabXCharnieres.length - 1) {
yDeLImage = yDeLImageGauche
}
// console.log("xDeLImage"+xDeLImage+" avec imageX="+imageX+" est une charniere et coord en y="+yDeLImage)
} else {
// je détermine son ordonnée par interpolation affine, il faut d’abord savoir entre quelles valeurs charnières elle se trouve
let compteur = 0
let xCharniere = tabXCharnieres[compteur]
let a = xCharniere
while (xCharniere < xDeLImage) {
compteur++
a = xCharniere
xCharniere = tabXCharnieres[compteur]
}
const b = xCharniere
const position1 = tabXCharnieres.indexOf(a)
const y1 = tabYCharnieres[0][position1]
// var position2 = tabXCharnieres.indexOf(b)
const y2 = tabYCharnieres[1][position1]
// console.log("a="+a+" et b="+b+" y1="+y1+" et y2="+y2)
// l’interpolation affine :
const coeff = (xDeLImage - a) / (b - a)
yDeLImage = y1 + coeff * (y2 - y1)
// console.log("xDeLImage"+xDeLImage+" avec imageX="+imageX+" n' est pas une charniere et coord en y="+yDeLImage)
}
// affichage de l’image :
// d’abord on efface les éventuelles anciennes :
j3pDetruit(
// ATTENTION, lui contient un input, on le supprime ici et on le recrée plus loin, mais ValidationZones l’aura perdu et valideUneZone répondra toujours false
// => il faudra remettre le bon input dans les zones plus loin
divId + 'zone_image' + i + jEquivalent,
divId + 'image_gauche' + i + jEquivalent,
divId + 'image_droite' + i + jEquivalent
)
let lid
if (imageY.indexOf('||') !== -1 || imageY === 'I') {
if (isDebug) console.debug(imageY + ' contient une valeur interdite')
// au cas où il y ait des zones de saisie je garde en 0 et en 1 leurs coordonnées pour les repositionner correctement
tabDef.lignes[i].images_coord_x[k] = []
tabDef.lignes[i].images_coord_y[k] = []
// je regarde si qqchose avant et/ou après
let imageYAvant = ''
let imageYApres = ''
if (imageY.length === 2) {
// pas d’image
if (isDebug) console.debug('pas d’image juste une valeur interdite')
} else {
if (imageY.indexOf('||') !== 0) {
// une image avant :
imageYAvant = imageY.substring(0, imageY.indexOf('||'))
}
if (imageY.indexOf('||') !== imageY.length - 2) {
// une image après :
imageYApres = imageY.substring(imageY.indexOf('||') + 2, imageY.length)
}
}
if (modeCorrection) {
if (imageYAvant === '?') {
imageYAvant = tabDef.lignes[i].imagesreponses[k][0]// imagesreponses est un tableau à un (une seule limite à gauche ou à droite - à verifier) ou deux élements
}
if (imageYApres === '?') {
// console.log("IMAGE Y APRES VAUT ?")
// console.log("tabDef.lignes["+i+"].imagesreponses["+k+"][0]=",tabDef.lignes[i].imagesreponses[k][0]," et tabDef.lignes[i].imagesreponses[k][1]=",tabDef.lignes[i].imagesreponses[k][1])
if (tabDef.lignes[i].imagesreponses[k][1]) {
imageYApres = tabDef.lignes[i].imagesreponses[k][1]
} else {
imageYApres = tabDef.lignes[i].imagesreponses[k][0]// il n’y avait qu’une limite à droite
}
// console.log("IMAGE Y APRES VAUT ",imageYApres)
}
}
if (modeCorrection && isDebug) console.debug('------imageYAvant=' + imageYAvant + ' et imageYApres=' + imageYApres)
if (imageYAvant === '-inf') imageYAvant = '-\\infty'
if (imageYAvant === '+inf') imageYAvant = '+\\infty'
if (imageYApres === '-inf') imageYApres = '-\\infty'
if (imageYApres === '+inf') imageYApres = '+\\infty'
// on trace la double barre
let decalage = -3
if (premiereCharniere) decalage = -5
if (derniereCharniere) decalage = 0
// la double barre
if (!j3pElement(divId + 's2' + i + jEquivalent, null)) {
j3pCreeSegment(svg, {
id: divId + 's2' + i + jEquivalent,
x1: xDeLImage - decalage,
y1: hauteurTemp,
x2: xDeLImage - decalage,
y2: hauteurTemp + tabDef.lignes[i].hauteur,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
}
if (!j3pElement(divId + 's3' + i + jEquivalent, null)) {
j3pCreeSegment(svg, {
id: divId + 's3' + i + jEquivalent,
x1: xDeLImage - decalage - 5,
y1: hauteurTemp,
x2: xDeLImage - decalage - 5,
y2: hauteurTemp + tabDef.lignes[i].hauteur,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
}
divList[i].push(divId + 's2' + i + jEquivalent)
divList[i].push(divId + 's3' + i + jEquivalent)
// les valeurs
const styleImage = {}
styleImage.style = {}
styleImage.style.position = 'absolute'
styleImage.style.top = '0px'
styleImage.style.left = '0px'
styleImage.style.color = tabDef.mef.macouleur
// var imageGauche = j3pAjouteDiv(zoneSvgCorr, divId + 'image_gauche' + i + jEquivalent, '', { style: 'position:absolute;top:0px;left:0px;color:' + tabDef.mef.macouleur })
// var imageDroite = j3pAjouteDiv(zoneSvgCorr, divId + 'image_droite' + i + jEquivalent, '', { style: 'position:absolute;top:0px;left:0px;color:' + tabDef.mef.macouleur })
j3pDetruit(divId + 'image_gauche' + i + jEquivalent)
j3pDetruit(divId + 'image_droite' + i + jEquivalent)
const imageGauche = j3pAjouteDiv(zoneSvgCorr, divId + 'image_gauche' + i + jEquivalent, '', styleImage)
const imageDroite = j3pAjouteDiv(zoneSvgCorr, divId + 'image_droite' + i + jEquivalent, '', styleImage)
divList[i].push(divId + 'image_gauche' + i + jEquivalent)
divList[i].push(divId + 'image_droite' + i + jEquivalent)
if (imageYAvant === '?') {
// une zone de saisie à gauche :
// cas particulier : si l’on clique sur une flèche et qu’une zone de saisie il faut pas effacer le contenu de la zone :
// on teste donc si imagesreponses est pas complété (sinon on récupère son contenu)
let leTexteGauche = ''
if (tabDef.lignes[i].imagesreponses[k][0]) leTexteGauche = tabDef.lignes[i].imagesreponses[k][0]
const zoneImageGauche = j3pAffiche(divId + 'image_gauche' + i + jEquivalent, 'tab' + k + divId + 'image_gauche' + i + jEquivalent, '&1&',
{
style: { color: '#654321' },
inputmq1: { texte: leTexteGauche, correction: tabDef.lignes[i].images[k][2] }
})
mqList.push(zoneImageGauche.inputmqList[0])
mqRestriction(zoneImageGauche.inputmqList[0], restrict, {
commandes: tabDef.liste_boutons
})
const imagegaucheMQ = j3pElement('tab' + k + divId + 'image_gauche' + i + jEquivalent + 'inputmq1')
// je stocke les coordonnées et xDeLImage yDeLImage dans un tableau pour pouvoir m’en servir, notamment lors du repositionnement des
// zones de saisie dans l’écouteur onkeyup
tabDef.lignes[i].images_coord_x[k][0] = xDeLImage
tabDef.lignes[i].images_coord_y[k][0] = yDeLImageGauche
// une feinte de siou, blur permet d’enlever le focus, comme ça on est obligé de cliquer sur la zone, ça fait apparaitre la palette.'
$(imagegaucheMQ).blur()
lid = 'tab' + k + divId + 'image_gauche' + i + jEquivalent + 'inputmq1'
tabDef.lignes[i].zonesdesaisie.push(lid)
// Modification du css pour ajouter un fond blanc à la zone de saisie :
imagegaucheMQ.style.backgroundColor = '#FFFFFF'
// Gestion de la palette :
imagegaucheMQ.addEventListener('mouseup', affichePaletteMQ.bind(null, lid))
imagegaucheMQ.addEventListener('keyup', positionneZoneVariations.bind(null, lid))
imagegaucheMQ.addEventListener('focusin', positionneZoneVariations.bind(null, lid))
// je vais également stocker la réponse à chaque frappe, dans tabDef.lignes[i].imagesreponses mais au même indice et à la première ligne i sur laquelle la charnière se trouve
// comme les charnières ont été réordonnées, on utilise charnieres_memoire qui avait stocké le i de lignes[i] en mémoire ainsi que l’indice correspondant'
// lorsque l’on n’utilise pas le clavier mais uniquement les boutons de la palette... (il faut aussi repositionner la zone et compélter le tableau des réponses
} else {
j3pAffiche(divId + 'image_gauche' + i + jEquivalent, divId + 'image_gauche_txt' + i + jEquivalent, '$' + imageYAvant + '$')
}
imageGauche.style.left = xDeLImage - decalage - imageGauche.getBoundingClientRect().width - 5 - 1 + 'px'
imageGauche.style.top = (yDeLImageGauche - imageGauche.getBoundingClientRect().height / 2) + 'px'
if (imageYApres === '?') {
// une zone de saisie à droite :
// cas particulier : si l’on clique sur une flèche et qu’une zone de saisie il faut pas effacer le contenu de la zone :
// on teste donc si imagesreponses est pas complété (sinon on récupère son contenu)
let leTexteDroite = ''
if (isDebug) console.debug('tabDef.lignes[i].imagesreponses[' + k + '][1]=' + tabDef.lignes[i].imagesreponses[k][1])
// A MODIFIER AJOUTER [1]
if (tabDef.lignes[i].imagesreponses[k][1] !== undefined) {
leTexteDroite = tabDef.lignes[i].imagesreponses[k][1]
}
const zoneImageDroite = j3pAffiche(divId + 'image_droite' + i + jEquivalent, 'tab' + k + divId + 'image_droite' + i + jEquivalent, '&1&',
{
style: { color: '#654321' },
inputmq1: { texte: leTexteDroite, correction: tabDef.lignes[i].images[k][2] }
})
mqList.push(zoneImageDroite.inputmqList[0])
mqRestriction(zoneImageDroite.inputmqList[0], restrict, {
commandes: tabDef.liste_boutons
})
const imagedroiteMQ = j3pElement('tab' + k + divId + 'image_droite' + i + jEquivalent + 'inputmq1')
// je stocke les coordonnées et xDeLImage yDeLImage dans un tableau pour pouvoir m’en servir, notamment lors du repositionnement des
// zones de saisie dans l’écouteur onkeyup
tabDef.lignes[i].images_coord_x[k][1] = xDeLImage
tabDef.lignes[i].images_coord_y[k][1] = yDeLImage
// une feinte de sioux, blur permet d’enlever le focus, comme ça on est obligé de cliquer sur la zone, ça fait apparaître la palette.
$(imagedroiteMQ).blur()
lid = 'tab' + k + divId + 'image_droite' + i + jEquivalent + 'inputmq1'
tabDef.lignes[i].zonesdesaisie.push(lid)
// Modification du css pour ajouter un fond blanc à la zone de saisie :
imagedroiteMQ.style.backgroundColor = '#FFFFFF'
// Gestion de la palette
imagedroiteMQ.addEventListener('mouseup', affichePaletteMQ.bind(null, lid))
// je vais également stocker la réponse à chaque frappe, dans tabDef.lignes[i].imagesreponses mais au même indice et à la première ligne i sur laquelle la charnière se trouve
// comme les charnières ont été réordonnées, on utilise charnieres_memoire qui avait stocké le i de lignes[i] en mémoire ainsi que l’indice correspondant'
imagedroiteMQ.addEventListener('keyup', positionneZoneVariations.bind(null, lid))
// lorsque l’on n’utilise pas le clavier mais uniquement les boutons de la palette... (il faut aussi repositionner la zone et compléter le tableau des réponses
imagedroiteMQ.addEventListener('focusin', positionneZoneVariations.bind(null, lid))
} else {
j3pAffiche(divId + 'image_droite' + i + jEquivalent, divId + 'image_droite_txt' + i + jEquivalent, '$' + imageYApres + '$')
}
imageDroite.style.left = xDeLImage - decalage + 1 + 'px'
imageDroite.style.top = (yDeLImage - imageDroite.getBoundingClientRect().height / 2) + 'px'
} else {
// pas de valeur interdite
// conversion en chaine latex...
if (imageY === '-inf') {
imageY = '-\\infty'
}
if (imageY === '+inf') {
imageY = '+\\infty'
}
let zoneimageMQ
const zoneImage = j3pAddElt(zoneSvgCorr, 'div', '', {
id: divId + 'zone_image' + i + jEquivalent,
style: {
color: tabDef.mef.macouleur,
position: 'absolute',
top: '0',
left: '0'
}
})
if (imageY === '?') {
if (isDebug) console.debug('UNE SEULE ZONE DE SAISIE A AFFICHER, on attend comme réponse : ' + tabDef.lignes[i].images[k][2])
// la correction est dans tabDef.lignes[i].images[k][2], penser à corriger +-inf en code latex
// cas particulier : si l’on clique sur une flèche et qu’une zone de saisie il faut pas effacer le contenu de la zone :
// on teste donc si imagesreponses est pas complété (sinon on récupère son contenu)
let leTexte = ''
if (tabDef.lignes[i].imagesreponses[k]) {
leTexte = tabDef.lignes[i].imagesreponses[k]
}
// avant de recréer un input, faudrait plutôt regarder s’il n’est pas déjà dans tabDef.validationZonesInputs
// on laisse tomber pour le moment vu qu’on le rattrape plus loin
const laZoneImage = j3pAffiche(zoneImage, 'tab' + k + divId + 'image_txt' + i + jEquivalent, '&1&',
{
style: { color: '#654321' },
inputmq1: { texte: leTexte, correction: tabDef.lignes[i].images[k][2] }
})
mqList.push(laZoneImage.inputmqList[0])
mqRestriction(laZoneImage.inputmqList[0], restrict, {
commandes: tabDef.liste_boutons
})
zoneimageMQ = j3pElement('tab' + k + divId + 'image_txt' + i + jEquivalent + 'inputmq1')
zoneimageMQ.style.backgroundColor = 'rgba(255,255,255,0.2)'
} else {
j3pAffiche(zoneImage, divId + 'image_txt' + i + jEquivalent, '$' + imageY + '$')
}
divList[i].push(zoneImage)
if (isDebug) console.debug('imageY=' + imageY)
setTimeout(() => {
// j’attends que zoneImage soit construit pour calculer sa dimension
let decalage = zoneImage.getBoundingClientRect().width / 2
if (premiereCharniere) decalage = 0
if (derniereCharniere) decalage = zoneImage.getBoundingClientRect().width + 6
zoneImage.style.left = xDeLImage - decalage + 'px'
zoneImage.style.top = (yDeLImage - zoneImage.getBoundingClientRect().height / 2) + 'px'
// on créé un segment en pointillé (j’efface d’abord celui qui a été éventuellement construit)
j3pDetruit(divId + 's2' + i + jEquivalent)
j3pCreeSegment(svg, {
id: divId + 's2' + i + jEquivalent,
x1: xDeLImage,
y1: hauteurTemp,
x2: xDeLImage,
y2: yDeLImage - zoneImage.getBoundingClientRect().height / 2,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
}, 0)
divList[i].push(divId + 's2' + i + jEquivalent)
// écouteur si c’est une zone de saisie :
if (imageY === '?') {
// je stocke les coordonnées et xDeLImage yDeLImage dans un tableau pour pouvoir m’en servir, notamment lors du repositionnement des
// zones de saisie dans l’écouteur onkeyup
tabDef.lignes[i].images_coord_x[k] = xDeLImage
tabDef.lignes[i].images_coord_y[k] = yDeLImage
// une feinte de balayeur (©Arnaud), blur permet d’enlever le focus, comme ça on est obligé de cliquer sur la zone et ça fait apparaitre la palette…
$(zoneimageMQ).blur()
lid = 'tab' + k + divId + 'image_txt' + i + jEquivalent + 'inputmq1'
tabDef.lignes[i].zonesdesaisie.push(lid)
// Modification du css pour ajouter un fond blanc à la zone de saisie :
zoneimageMQ.style.backgroundColor = 'rgba(255,255,255,0.4)'
// Gestion de la palette :
zoneimageMQ.addEventListener('mouseup', affichePaletteMQ.bind(null, lid))
zoneimageMQ.addEventListener('keyup', positionneZoneVariations.bind(null, lid))
zoneimageMQ.addEventListener('focusin', positionneZoneVariations.bind(null, lid))
// je vais également stocker la réponse à chaque frappe, dans tabDef.lignes[i].imagesreponses mais au même indice et à la première ligne i sur laquelle la charnière se trouve
// comme les charnières ont été réordonnées, on utilise charnieres_memoire qui avait stocké le i de lignes[i] en mémoire ainsi que l’indice correspondant'
// lorsque l’on n’utilise pas le clavier mais uniquement les boutons de la palette... (il faut aussi repositionner la zone et compélter le tableau des réponses
}
}
// on trace les traits verticaux "précédents" (cad sur les lignes supérieures si ce n’est pas une racine
for (let itemp = 0; itemp <= i - 1; itemp++) {
// je teste si pas une racine
if (!estDedans(charnieresLignes[itemp], charniereEnCours)) {
// la charnière en cours n’est pas une charnière de la ligne
let ydeb = tabDef.mef.h
for (let ktemp = 0; ktemp <= itemp - 1; ktemp++) {
ydeb += tabDef.lignes[ktemp].hauteur
}
const yfin = ydeb + tabDef.lignes[itemp].hauteur
j3pCreeSegment(svg, {
id: divId + 's300' + itemp,
x1: xDeLImage,
y1: ydeb,
x2: xDeLImage,
y2: yfin,
couleur: tabDef.mef.macouleur,
epaisseur: 1,
pointilles: 2
})
divList[i].push(divId + 's300')
}
}
}
// s’il y du ValidationZones qui a la main sur cette zone, faut lui rendre !
if (tabDef.validationZonesInputs?.length) {
// y’a des ValidationZones, on regarde s’il faut en réaffecter
for (const [i, input] of tabDef.validationZonesInputs.entries()) {
if (input?.id) {
const newInput = j3pElement(input.id, null)
if (newInput && newInput !== input) {
// avant de substituer, faut récupérer toutes les props ajoutées par ValidationZones
for (const [p, v] of Object.entries(input)) {
if (!hasProp(newInput, p)) newInput[p] = v
}
// faut réaffecter dans le tableau, pas la variable input
tabDef.validationZonesInputs[i] = newInput
}
}
}
}
} // creerFleches
// listener du mouseOver sur les flèches (this est l’élément svg)
function onMouseOver () {
this.style.cursor = 'pointer'
}
// au clic (mouseup) sur une flèche (attention, this est null)
// FIXME ça marche sur tablette ? Faudrait pas plutôt être sur l’événement click ?
function reponseClic (i, j) {
// console.log("i="+i+" et j="+j)
const tabVariationsPossibles = ['const', 'decroit', 'croit']
// on change la croissance de la flèche, on appelle à nouveau la fonction pour recréer le tabvar
tabDef.perso.variationsModifiees = true
switch (tabDef.lignes[i].variations[j]) {
case 'croit':
// elle va décroitre
tabDef.lignes[i].variations[j] = tabVariationsPossibles[1]
break
case 'decroit':
// elle sera constante
tabDef.lignes[i].variations[j] = tabVariationsPossibles[0]
break
case 'const':
// elle sera croissante
tabDef.lignes[i].variations[j] = tabVariationsPossibles[2]
break
}
// on redessine les flèches
creerFleches(i)
}
function tabSignesCreerLigne (i) {
tabDef.lignes[i] = {}
tabDef.lignes[i].type = 'signes'
// quelle hauteur ?
tabDef.lignes[i].hauteur = 50
tabDef.lignes[i].valeurs_charnieres = {}
tabDef.lignes[i].valeurs_charnieres.valeurs_approchees = []
// les signes
tabDef.lignes[i].signes = []
tabDef.lignes[i].imagesapprochees = []
tabDef.lignes[i].imagesreponses = []
// on peut ajouter des valeurs de x avec leurs images.
tabDef.lignes[i].images = []
// A FAIRE : METTRE UNE ZONE DE SAISIE MQ
tabDef.lignes[i].expression = '&1&'
// A FAIRE : DETECTER LES VALEURS CHARNIERES PRESENTES POUR LES REMETTRE et dpnc le nb d’intervalles par la suite' charnieresTheoriques
tabDef.lignes[i].valeurs_charnieres.valeurs_theoriques = charnieresTheoriques
tabDef.lignes[i].valeurs_charnieres.valeurs_approchees = charnieresApprochees
// je n’ai pas en stock, à voir si cela posera pb...
// tabDef.lignes[i].valeurs_charnieres.valeurs_affichees=tabDef.lignes[tabDef.lignes.length-1].valeurs_charnieres.valeurs_affichees;
// tabDef.lignes[i].valeurs_charnieres.valeurs_approchees=tabDef.lignes[tabDef.lignes.length-1].valeurs_charnieres.valeurs_approchees;
// console.log("NB DE CHARNIERES:"+charnieresTheoriques.length);
// console.log("PB : tabDef.lignes["+i+"].valeurs_charnieres.valeurs_affichees="+ tabDef.lignes[i].valeurs_charnieres.valeurs_affichees);
// console.log("PB : tabDef.lignes["+i+"].valeurs_charnieres.valeurs_theoriques=charnieresTheoriques="+tabDef.lignes[i].valeurs_charnieres.valeurs_theoriques)
// objet_global.lignes[i].signes=["-","+"];
tabDef.lignes[i].signes = []
for (let j = 0; j < charnieresTheoriques.length - 1; j++) {
tabDef.lignes[i].signes.push('?')
}
if (isDebug) console.debug('tabDef.lignes[i].signes.=' + tabDef.lignes[i].signes)
// normalement pas besoin
tabDef.lignes[i].signescorrection = ['']
// zones de saisies pour les images :
const nbCharnieres = charnieresTheoriques.length - 1
// on n’en veut pas à gauche :
tabDef.lignes[i].images.push([charnieresTheoriques[0], ''])
// les autres on veut des zones de saisies :
for (let j = 1; j < nbCharnieres; j++) {
tabDef.lignes[i].images.push([charnieresTheoriques[j], '?'])
}
// on n’en veut pas à gauche :
tabDef.lignes[i].images.push([charnieresTheoriques[nbCharnieres], ''])
// tabDef.lignes[i].imagesapprochees=[];
// on relance la création du tableau :
if (isDebug) console.debug('mes lignes=', tabDef.lignes)
setTimeout(() => {
creationTableau1bis()
}, 0)
}
function tabSignesNettoieLigne () {
if (isDebug) console.debug('lignes', tabDef.lignes)
const nbLignesTemp = tabDef.lignes.length
const objTemp = tabDef.lignes[nbLignesTemp - 1]
tabDef.lignes.pop()
tabDef.lignes.pop()
tabDef.lignes.push(objTemp)
if (isDebug) console.debug(tabDef.lignes)
setTimeout(() => {
creationTableau1bis()
}, 0)
}
function tabSignesAjouteLigne () {
const nbLignesTemp = tabDef.lignes.length
// je limite à 5 lignes, mais ça se dicute...(ça se paramètre ?)
if (nbLignesTemp < 5) {
nbLignesAjoutees++
tabDef.lignes[nbLignesTemp] = {}
tabDef.lignes[nbLignesTemp] = tabDef.lignes[nbLignesTemp - 1]
// on recopie la sauvegarde des charnières par ligne :
charnieresLignes[nbLignesTemp] = charnieresLignes[nbLignesTemp - 1]
// on créé l’avant dernière ligne'
tabSignesCreerLigne(nbLignesTemp - 1)
}
}
function tabSignesSupprimeLigne () {
if (nbLignesAjoutees > 0) {
nbLignesAjoutees--
tabSignesNettoieLigne()
}
}
function tabSignesAjouteIntervalle () {
// je récupère le nb d’intervalles voulus :
const nbIntervalles = j3pValeurde('affiche_tabsignes_varinput1')
// je change les propriétés de mon objet :
// var nbIntervalles=charnieresTheoriques.length-1;
// je limite à 6 intervalles, mais ça se dicute...(ça se paramètre ?)
if (nbIntervalles < 6) {
if (isDebug) console.debug('tabDef', tabDef)
// A FAIRE : ADAPTER POUR QUE SI RANDOM CE SOIT POSITIONNE DE MANIERE ORDONNEE (tjs centré on ne tient pas comte de l’affichage ou non des valeurs extremes)
// tabDef.lignes[i].valeurs_charnieres.valeurs_theoriques.push("random");
// tabDef.lignes[i].valeurs_charnieres.valeurs_affichees.push("?");
// tabDef.lignes[i].valeurs_charnieres.valeurs_approchees.push("random");
for (let i = 0; i <= tabDef.lignes.length - 1; i++) {
// on ajoute une valeur charnière en avant dernier position
if (tabDef.lignes[i].type === 'signes') {
tabDef.lignes[i].signes = []
for (let j = 0; j < nbIntervalles; j++) {
tabDef.lignes[i].signes.push('?')
}
console.debug(tabDef)
// tabDef.lignes[i].signes.push("?");
// images ? imagesapprochees ?
}
if (tabDef.lignes[i].type === 'variations') {
if (isDebug) console.debug('tabDef.lignes[' + i + '].variations=' + tabDef.lignes[i].variations)
tabDef.lignes[i].variations = []
tabDef.lignes[i].cliquable = []
for (let j = 0; j < nbIntervalles; j++) {
tabDef.lignes[i].cliquable.push(true)
tabDef.lignes[i].variations.push('const')
}
// intervalles ? images ? imagesapprochees ?
}
// }
}
// on relance la création du tableau :
setTimeout(() => {
creationTableau1ter()
}, 0)
}
}
// fonction qui, une fois l’affichage des "Signes de..." et "Variations de..." terminée gère la suite de l’affichage :
// le x en haut à gauche, les valeurs de la première ligne
// function creation_tableau2(hauteurTemp){
function creerSignes (i) {
divList[i] = []
let nbChangement = 0
let posTemp = largeurSigneDe
let nbSignesTemp = 1
let nbSignesOld = 0
hauteurTemp = tabDef.mef.h
for (let indexI = 0; indexI <= i - 1; indexI++) {
hauteurTemp += tabDef.lignes[indexI].hauteur
}
// il faut définir le tableau des signes, par exemple si on demande +,-,+ on peut avoir à afficher +,+,-,-,+ si l’on a rajouté deux valeurs intermédiaires...
// var tab_signes=definir_signes(i);
// objet_global.lignes[0].images=[["1","0"],["3","0"],["0","3"],["2","-1"]]
// PLACEMENT DES IMAGES
const styleImage = {}
styleImage.style = {}
styleImage.style.position = 'absolute'
styleImage.style.top = '0px'
styleImage.style.left = '0px'
styleImage.style.color = tabDef.mef.macouleur
for (let j = 0; j <= charnieresTheoriques.length - 1; j++) {
if (isDebug) console.debug('--------------charnieres_theoriques[j]=' + charnieresTheoriques[j])
for (let k = 0; k <= tabDef.lignes[i].images.length - 1; k++) {
if (charnieresTheoriques[j] === tabDef.lignes[i].images[k][0]) {
let valeuDeX = tabDef.lignes[i].images[k][0]
let valeuDeY = tabDef.lignes[i].images[k][1]
if (modeCorrection) {
// console.log("tabDef.lignes["+i+"].imagesreponses="+j3p.stockage[40].lignes[i].imagesreponses)
// si l’on demandait une zone de saisie, on remplace par la réponse élève
if (valeuDeX.includes('?')) valeuDeX = tabDef.lignes[i].valeurs_charnieres.reponses[k]
if (valeuDeY.includes('?')) valeuDeY = tabDef.lignes[i].imagesreponses[k]
}
if (isDebug) console.debug('valeuDeX=' + valeuDeX + ' et valeuDeY=' + valeuDeY)
const pos2 = (largeurSigneDe + j * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1))
// le I c’est pour le cas où l’élève a renseigné I comme interdite
if (valeuDeY.includes('|') || valeuDeY === 'I') {
let pos3
if (j === 0) {
// je suis à gauche du tableau
pos3 = pos2
} else {
if (j === charnieresTheoriques.length - 1) {
// je suis à droite du tableau
pos3 = pos2 - 5
} else {
// cas général
pos3 = pos2 - 2
}
}
// c’est une valeur interdite ! on trace simplement une double barre
j3pCreeSegment(svg, {
id: divId + 's2' + j,
x1: pos3,
y1: hauteurTemp,
x2: pos3,
y2: hauteurTemp + tabDef.lignes[i].hauteur,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
j3pCreeSegment(svg, {
id: divId + 's3' + j,
x1: pos3 + 5,
y1: hauteurTemp,
x2: pos3 + 5,
y2: hauteurTemp + tabDef.lignes[i].hauteur,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
divList[i].push(divId + 's2' + j)
divList[i].push(divId + 's3' + j)
} else {
let imageFct
if (valeuDeY === '?') {
// la position en left de la racine, à décaler pour la dernière...
imageFct = j3pAjouteDiv(zoneSvgCorr, divId + i + 'image_fct' + j, '', styleImage)
const zoneValY = j3pAffiche(imageFct, 'tab' + k + divId + i + 'nomimage_fct' + j, '&1&',
{
style: { color: '#654321' },
inputmq1: { texte: '', correction: tabDef.lignes[i].images[k][2] }
})
mqList.push(zoneValY.inputmqList[0])
mqRestriction(zoneValY.inputmqList[0], restrict, {
commandes: tabDef.liste_boutons
})
let pos3
if (j === 0) {
// je suis à gauche du tableau
pos3 = pos2
} else {
if (j === charnieresTheoriques.length - 1) {
// je suis à droite du tableau
pos3 = pos2 - imageFct.getBoundingClientRect().width
} else {
// cas général
pos3 = pos2 - imageFct.getBoundingClientRect().width / 2
}
}
imageFct.style.left = pos3 + 'px'
// on garde la mémoire du pos2 pour le repositionnement dans l’écouteur : (tester le j...)
positionValeursSignes[j] = pos2
imageFct.style.top = hauteurTemp + tabDef.lignes[i].hauteur / 2 - imageFct.getBoundingClientRect().height / 2 + 'px'
// ecouteur pour positionner correctement le tout :
const imageFctMQ = j3pElement('tab' + k + divId + i + 'nomimage_fct' + j + 'inputmq1')
// une feinte de siou, blur permet d’enlever le focus, comme ça on est obligé de cliquer sur la zone, ça fait apparaitre la palette.
$(imageFctMQ).blur()
const lid = 'tab' + k + divId + i + 'nomimage_fct' + j + 'inputmq1'
tabDef.lignes[i].zonesdesaisie.push(lid)
// Modification du css pour ajouter un fond blanc à la zone de saisie :
imageFctMQ.style.backgroundColor = '#FFFFFF'
// Gestion de la palette :
imageFctMQ.addEventListener('mouseup', affichePaletteMQ.bind(null, lid))
imageFctMQ.addEventListener('keyup', positionneZoneSignes.bind(null, lid, hauteurTemp))
// lorsque l’on n’utilise pas le clavier mais uniquement les boutons de la palette... (il faut aussi repositionner la zone et compléter le tableau des réponses
imageFctMQ.addEventListener('focusin', positionneZoneSignes.bind(null, lid, hauteurTemp))
// on ajoute un trait vertical
j3pCreeSegment(svg, {
id: divId + 's2' + j,
x1: pos2,
y1: hauteurTemp,
x2: pos2,
y2: hauteurTemp + tabDef.lignes[i].hauteur,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
} else {
// la position en left de la racine à décaler pour la dernière...
// var imageFct = j3pAjouteDiv(zoneSvgCorr, divId + i + 'image_fct' + j, '', { style: 'position:absolute;top:0px;left:0px;color:' + tabDef.mef.macouleur + ';' })
imageFct = j3pAjouteDiv(zoneSvgCorr, divId + i + 'image_fct' + j, '', styleImage)
j3pAffiche(imageFct, divId + i + 'l_image_fct' + j, '$' + valeuDeY + '$')
let pos3
if (j === 0) {
// je suis à gauche du tableau
pos3 = pos2
} else {
if (j === charnieresTheoriques.length - 1) {
// je suis à droite du tableau
pos3 = pos2 - imageFct.getBoundingClientRect().width
} else {
// cas général
pos3 = pos2 - imageFct.getBoundingClientRect().width / 2
}
}
imageFct.style.left = pos3 + 'px'
imageFct.style.top = hauteurTemp + tabDef.lignes[i].hauteur / 2 - imageFct.getBoundingClientRect().height / 2 + 'px'
// on ajoute un trait vertical
j3pCreeSegment(svg, {
id: divId + 's2' + j,
x1: pos2,
y1: hauteurTemp,
x2: pos2,
y2: hauteurTemp + tabDef.lignes[i].hauteur,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
divList[i].push(divId + 's2' + j)
}
divList[i].push(divId + i + 'image_fct' + j)
}
// on teste parmi les lignes précédentes si la racine en cours n’est pas une racine, alors ontrace un segment vertical
for (let itemp = 0; itemp <= i - 1; itemp++) {
// je teste si pas une racine
if (!estDedans(charnieresLignes[itemp], charnieresTheoriques[j])) {
// la charnière en cours n’est pas une charnière de la ligne
let ydeb = tabDef.mef.h
for (let ktemp = 0; ktemp <= itemp - 1; ktemp++) {
ydeb += tabDef.lignes[ktemp].hauteur
}
const yfin = ydeb + tabDef.lignes[itemp].hauteur
j3pCreeSegment(svg, {
id: divId + 's200' + itemp,
x1: pos2,
y1: ydeb,
x2: pos2,
y2: yfin,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
divList[i].push(divId + 's200' + itemp)
}
}
}
}
}
if (!modeCorrection) {
// pour stocker éventuellement les signes réponses
tabDef.lignes[i].signesreponses = []
}
// PLACEMENT DES SIGNES
if (isDebug) console.debug('HEREEE')
if (isDebug) console.debug('charnieresApprochees.length=' + charnieresApprochees.length + ' et tabDef.lignes[i].valeurs_charnieres.valeurs_approchees.length-1=' + (tabDef.lignes[i].valeurs_charnieres.valeurs_approchees.length - 1))
if (isDebug) console.debug('charnieresApprochees=' + charnieresApprochees)
if (isDebug) console.debug('tabDef.lignes[' + i + '].valeurs_charnieres.valeurs_approchees=' + tabDef.lignes[i].valeurs_charnieres.valeurs_approchees)
let estCharniere, lesigne, id, divSigneFct
for (let k = 0; k <= charnieresApprochees.length - 1; k++) {
// si c’est une charnière de la ligne on y regarde de plus près...
// if (estDedans(charnieres_lignes_approchees[i],charnieres_approchees[k])
estCharniere = false
for (let j = 0; j <= tabDef.lignes[i].valeurs_charnieres.valeurs_approchees.length - 1; j++) {
// console.log("k="+k+" et charnieres_approchees[k]="+charnieres_approchees[k]+" et tabDef.lignes[i].valeurs_charnieres.valeurs_approchees[j="+tabDef.lignes[i].valeurs_charnieres.valeurs_approchees[j])
// on teste aussi si dans (=["-inf",1,3,"+inf"]), on récupère la position pour placer le + ou -
if (charnieresApprochees[k] === tabDef.lignes[i].valeurs_charnieres.valeurs_approchees[j]) {
estCharniere = true
// pas la première !
if (nbChangement) {
// je place le signe :
lesigne = tabDef.lignes[i].signes[nbChangement - 1]
// en cas de correction, j’affiche la réponse élève'
if (modeCorrection && lesigne === '?') {
lesigne = tabDef.lignes[i].signesreponses[nbChangement - 1]
if (isDebug) console.debug('tabDef.lignes[' + i + '].signesreponses[' + (nbChangement - 1) + ']=' + tabDef.lignes[i].signesreponses[nbChangement - 1])
}
// console.log("lesigne="+lesigne+" nb de fois à placer="+nbSignesTemp);
// nbSignesTemp est le nb de fois où je dois placer le signe...
if (isDebug) console.debug('nbSignesTemp=' + nbSignesTemp + ' et nbSignesOld=' + nbSignesOld)
for (let index = 1; index <= nbSignesTemp; index++) {
// console.log("&&&&&&&j="+j+" et index="+index)outils/j3poutils.js
id = divId + i + 'signe_fct' + j + index
// divSigneFct = j3pAjouteDiv(zoneSvgCorr, id, '', { style: 'position:absolute;top:0px;left:0px;color:' + tabDef.mef.macouleur + ';' })
divSigneFct = j3pAjouteDiv(zoneSvgCorr, id, '', styleImage)
divList[i].push(id)
if (lesigne === '?') {
const signeCorrige = tabDef.lignes[i].signescorrection[nbChangement - 1]
// liste déroulante
// var choix1 = j3pAjouteDiv(zoneSvgCorr, divId+"choix1","",
// {"style":"color:"+macouleur+";position:absolute;top:0px;left:0px;font-size:"+taille_font+"px;"});
j3pAffiche(divSigneFct, divId + i + 'les_listes' + j + (index + nbSignesOld), '#1#', {
style: {
fontSize: '12px',
color: '#654321'
},
liste1: {
texte: [' ', '+', '-'],
correction: signeCorrige
}
})
// code reponse : var reponse_index1 = j3pElement("tableau1les_listesliste1").selectedIndex;
// ecouteur sur la liste pour renseigner la réponse :
const signeFctListe = j3pElement(divId + i + 'les_listes' + j + (index + nbSignesOld) + 'liste1')
tabDef.lignes[i].liste_deroulante.push(signeFctListe)
signeFctListe.onchange = function () {
// on choisit + ou - :
const posi = this.id.indexOf('les_listes')
const posj = this.id.indexOf('liste1')
const moni = this.id.charAt(posi - 1)
const monj = this.id.charAt(posj - 1)
// console.log("MONI="+moni+" et MONJ="+monj)
tabDef.lignes[moni].signesreponses[monj - 1] = j3pElement(this.id).options[j3pElement(this.id).selectedIndex].value
// console.log(tabDef.lignes[moni].signesreponses)
}
} else {
// var divSigneFct = j3pAjouteDiv(zoneSvgCorr, divId+i+"signe_fct"+j+index,"",{"style":"position:absolute;top:0px;left:0px;color:"+tabDef.mef.macouleur+";font-size:"+taille_font+"px;"});
if (lesigne) {
j3pAffiche(divSigneFct, divId + i + 'le_signe_fct' + j + index, '$' + lesigne + '$')
}
}
// scorie du code de Rémi, a priori inutile var signe_fct0=j3pElement(divId+i+"le_signe_fct"+j+"0");
// console.log("=====(nbRacines-1)="+(nbRacines-1)+" et nbSignesTemp="+nbSignesTemp+" et index="+index+" et j="+j)
const pos1 = posTemp + ((tabDef.mef.L - largeurSigneDe) / (nbRacines - 1))
const posSigne = (posTemp + pos1) / 2
divSigneFct.style.left = posSigne + 'px'
if (lesigne === '?') {
// on décale si liste déroulante
const largeurTemp = divSigneFct.getBoundingClientRect().width
divSigneFct.style.left = posSigne + -largeurTemp / 2 + 'px'
}
posTemp = pos1
divSigneFct.style.top = hauteurTemp + tabDef.lignes[i].hauteur / 2 - divSigneFct.getBoundingClientRect().height / 2 + 'px'
}
// je garde la mémoire de l’ancienne valeur :
nbSignesOld += nbSignesTemp
// je reinitialise le nb de signes :
nbSignesTemp = 1
// on ajoute un trait en pointillés si c’est pas une charnière et si c’est pas la premiere/dernière ?
}
nbChangement++
}
}
// c’est donc une image ajoutée, donc on augmente d’un le nb de signes à placer
if (!estCharniere) {
// pas satisfaisant car il faut changer la façon de placer les signes au dessus...
// if (estDedans(tabDef.lignes[i].imagesapprochees,charnieres_approchees[k])){
nbSignesTemp++
// }
// console.log(charnieres_approchees[k]+" est juste une image et donc nbSignesTemp vaut"+nbSignesTemp)
}
}
}
// ETAPE 1 :on définit la largeur de la barre verticale et on affiche 'x' dans la première case
function creationTableau2Etape1 (hauteurTemp) {
largeurSigneDe = 0
for (let i = 0; i <= tabDef.lignes.length - 1; i++) {
const elt = j3pElement('Mep' + divId + 'txt2' + i)
if (elt) {
const largeurTemp = elt.getBoundingClientRect().width + 4
if (largeurTemp > largeurSigneDe) {
largeurSigneDe = largeurTemp
}
}
}
// placement du "x" de la première ligne
const divLeX = j3pAjouteDiv(zoneSvgCorr, divId + 'le_x', '', {
style: {
color: tabDef.mef.macouleur,
position: 'absolute',
top: '0',
left: '0'
}
})
j3pAffiche(divLeX, 'Mep' + divId + 'txt1', '$x$')
const monobj2 = j3pElement('Mep' + divId + 'txt1')
// var pos_txt2 = tabDef.tab_signes.h/4-monobj2.getBoundingClientRect().height/2;
divLeX.style.top = ((tabDef.mef.h) / 2 - divLeX.getBoundingClientRect().height / 2) + 'px'
// je le garde en mémoire pour le point mobile (mais ça aurait pu servir à autre chose...)
const posTxt3 = largeurSigneDe / 2 - monobj2.getBoundingClientRect().width / 2
divLeX.style.left = posTxt3 + 'px'
// j’ajoute la barre verticale :
if (isDebug) console.debug('!!!!!!!!!!!!!!largeurSigneDe=' + largeurSigneDe + ' et hauteurTemp=' + hauteurTemp + ' et divId=' + divId)
j3pCreeSegment(svg, {
id: divId + 's0',
x1: largeurSigneDe,
y1: 0,
x2: largeurSigneDe,
y2: hauteurTemp,
couleur: tabDef.mef.macouleur,
epaisseur: 1
})
// fin ETAPE 1
// ASYNC 3
setTimeout(() => {
creationTableau2Etape2(hauteurTemp)
}, 0)
}
// ETAPE 2 : Affichage des valeurs de la première ligne
function creationTableau2Etape2 (hauteurTemp) {
// je récupère le nb de racines de l’équation en cours
nbRacines = charnieres.length
if (isDebug) console.debug('nbRacines=' + nbRacines)
const mesZeroTxt = []
const mesZonesNulles = []
for (let i = 1; i <= nbRacines; i++) {
mesZonesNulles[i] = j3pAddElt(zoneSvgCorr, 'div', '', { id: divId + 'zone_nulle' + i })
j3pStyle(mesZonesNulles[i], {
color: tabDef.mef.macouleur,
position: 'absolute',
top: '0',
left: '0'
})
let monZeroTxt = ''
if (charnieres[i - 1] !== '?') {
// if (charnieres_affichage[i-1]){
// attention le_zero doit être du type string (un entier ou un décimal ou un nb fractionnaire de la forme a/b
monZeroTxt = (Number.isNaN(Number(charnieres[i - 1]))) ? charnieres[i - 1] : j3pVirgule(charnieres[i - 1])
// conversion en chaine latex...
if (monZeroTxt === '-inf') monZeroTxt = '-\\infty'
if (monZeroTxt === '+inf') monZeroTxt = '+\\infty'
mesZeroTxt.push(monZeroTxt)
j3pAffiche(mesZonesNulles[i], divId + 'le_zero_txt' + i, '$' + monZeroTxt + '$')
// console.log("tabDef.tab_signes.h/(nb_lignes_signes+1="+tabDef.tab_signes.h/(nb_lignes_signes+1))
} else {
mesZeroTxt.push('')
// dans le cas où la valeur en laquelle s’annule la fonction est à donner
// la correction est dans charnieres_theoriques, penser à corriger +-inf en code latex
if (isDebug) console.debug(' on a une zone de saisie :' + charnieres[i - 1] + ' et la correction est :' + charnieresTheoriques[i - 1])
const zoneValZoneNulle = j3pAffiche(mesZonesNulles[i], divId + 'nomzone_nulle' + i, '&1&',
{
style: { color: '#654321' },
inputmq1: { texte: '', correction: charnieresTheoriques[i - 1] }
})
mqList.push(zoneValZoneNulle.inputmqList[0])
mqRestriction(zoneValZoneNulle.inputmqList[0], restrict, {
commandes: tabDef.liste_boutons
})
const zonenulleMQ = j3pElement(divId + 'nomzone_nulle' + i + 'inputmq1')
$(zonenulleMQ).blur()
// je vais également stocker la réponse à chaque frappe, dans tabDef.lignes[i].valeurs_charnieres.reponses (ou tabDef.lignes[i].imagesreponses_x) mais au même indice et à la première ligne i sur laquelle la charnière se trouve
// comme les charnières ont été réordonnées, on utilise charnieres_memoire qui avait stocké le i de lignes[i] en mémoire ainsi que l’indice correspondant'
const eltBulle = divId + 'nomzone_nulle' + i + 'inputmq1'
tabDef.zonesdesaisie_charnieres.push(divId + 'nomzone_nulle' + i + 'inputmq1')
// Modification du css pour ajouter un fond blanc à la zone de saisie :
zonenulleMQ.style.backgroundColor = '#FFFFFF'
// Gestion de la palette :
zonenulleMQ.addEventListener('mouseup', affichePaletteMQ.bind(null, eltBulle))
zonenulleMQ.addEventListener('keyup', positionneZoneCharnieres.bind(null, eltBulle))
zonenulleMQ.addEventListener('focusin', positionneZoneCharnieres.bind(null, eltBulle))
// lorsque l’on n’utilise pas le clavier mais uniquement les boutons de la palette... (il faut aussi repositionner la zone et compléter le tableau des réponses
}
}
// pour garder la mémoire du div pour suppression ultérieure si besoin
// ASYNC 4
setTimeout(() => {
for (let i = 1; i <= nbRacines; i++) {
const { width, height } = mesZonesNulles[i].getBoundingClientRect()
mesZonesNulles[i].style.left = (largeurSigneDe + (i - 1) * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1)) - width / 2 + 'px'
if (i === nbRacines) {
// pas beau... pour éviter que la dernière "racine" sorte du cadre
mesZonesNulles[i].style.left = (largeurSigneDe + (i - 1) * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1) - width - 2) + 'px'
if (mesZeroTxt[i] === '+\\infty') mesZonesNulles[i].style.left = (tabDef.mef.L - 47) + 'px'
}
if (i === 1) {
// pas beau... pour éviter que la dernière "racine" sorte du cadre
mesZonesNulles[i].style.left = (largeurSigneDe + (i - 1) * (tabDef.mef.L - largeurSigneDe) / (nbRacines - 1)) + 'px'
}
mesZonesNulles[i].style.top = ((tabDef.mef.h) / 2 - (height) / 2) + 'px'
}
// fin ETAPE 2
// ASYNC 5
setTimeout(() => {
creationTableau2Etape3(hauteurTemp)
}, 0)
}, 0)
}
// ETAPE 3 : on complète les lignes signes ou variations
function creationTableau2Etape3 (hauteurTemp) {
for (let i = 0; i <= tabDef.lignes.length - 1; i++) {
switch (tabDef.lignes[i].type) {
case 'signes':
creerSignes(i)
break
case 'variations':
// la fonction creer_fleches est à l’exterieure de cette fonction car peut être appelée également au clic sur la flèche
creerFleches(i)
break
}
}
if (tabDef.ajout_lignes_possible) {
// on part du principe que l’on ajoutera que des lignes de signes (pas de variations)
// Ajout d’un bouton en bas à droite : (le -40 est empirique...)
j3pDiv(zoneSvgCorr, { id: 'conteneurbouton_ligne', contenu: '', coord: [tabDef.mef.L - 40, hauteurTemp + 5] })
j3pAjouteBouton('conteneurbouton_ligne', 'bouton1', 'MepBoutons2', '+', tabSignesAjouteLigne)
j3pAjouteBouton('conteneurbouton_ligne', 'bouton2', 'MepBoutons2', '-', tabSignesSupprimeLigne)
}
if (tabDef.ajout_intervalles_possible) {
if (isDebug) console.debug('!!!!!!!!!!!!On peut ajouter des intervalles!!!!!!!!!!!!!!')
const divTxtIntervealle = j3pDiv(zoneSvgCorr, { contenu: '', coord: [0, hauteurTemp + 5] })
j3pAffiche(divTxtIntervealle, '', 'Nombre d’intervalles souhaités : @1@', {
input1: {}
})
const divBtnIntervalle = j3pDiv(zoneSvgCorr, { contenu: '', coord: [0, hauteurTemp + 35] })
j3pAjouteBouton(divBtnIntervalle, 'bouton3', 'MepBoutons2', 'Valider', tabSignesAjouteIntervalle)
}
if (typeof finishCallback === 'function') finishCallback()
} // creationTableau2Etape3
// préparation du contexte
// divparent doit exister
const parent = j3pEnsureHtmlElement(divparent)
// divId facultatif (mais il en faut un, il sert de préfixe un peu partout
if (!divId || typeof divId !== 'string') divId = 'tabvar'
divId = j3pGetNewId(divId)
// le div en question, conteneur du svg
const zoneSvgCorr = j3pAddElt(parent, 'div', '', {
id: divId,
style: {
color: tabDef.mef.macouleur,
position: 'relative'
}
})
// isDebug facultatif
if (typeof isDebug === 'function') {
finishCallback = isDebug
isDebug = false
}
// des variables globales (internes à cette fct, destinées à devenir des propriétés d'une classe)
let nbLignesAjoutees = 0
const positionValeursSignes = []
const restrict = /[\d.,eln/+-]/ // passé à mqRestriction
const divList = []
/** Contient les inputMq créés par cette fct d’après tabDef */
const mqList = []
const charnieres = []
const charnieresApprochees = []
// je garde en mémoire les valeurs théoriques
const charnieresTheoriques = []
// je garde aussi la mémoire des charnières theoriques ligne par ligne :
const charnieresLignes = []
const charnieresLignesApprochees = []
// je garde aussi la mémoire des indices et des lignes afin de compléter tabDef.lignes[i].valeurs_charnieres.reponses (ou tabDef.lignes[i].imagesreponses_x) si zone de saisie il y a
const charnieresMemoire = []
let hauteurTemp = 0
let largeurSigneDe = 0
let nbRacines = 0
// il faut ajouter certaines propriétés locales dans tabdef.perso car certaines sections les utilisent
// variationsModifiees utilisé par tabVarLecture pour savoir si l'élève a répondu
tabDef.perso = { mqList, variationsModifiees: false }
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
// maintenant que les fonctions intermédiaires sont définies, on lance la première qui s’occupe de lancer les autres en cascade
creationTableau1()
} // tableauSignesVariations