Source: resultatFormatters/mathgraph.js

/**
 * This file is part of Sesatheque.
 *   Copyright 2014-2015, Association Sésamath
 *
 * Sesatheque is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3
 * as published by the Free Software Foundation.
 *
 * Sesatheque is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Sesatheque (LICENCE.txt).
 * @see http://www.gnu.org/licenses/agpl.txt
 *
 *
 * Ce fichier fait partie de lapplication Sésathèque, créée par lassociation Sésamath.
 *
 * Sésathèque est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant
 * les termes de la GNU Affero General Public License version 3 telle que publiée par la
 * Free Software Foundation.
 * Sésathèque est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE
 * sans même la garantie tacite de QUALITÉ MARCHANDE ou d'ADÉQUATION à UN BUT PARTICULIER.
 * Consultez la GNU Affero General Public License pour plus de détails.
 * Vous devez avoir reçu une copie de la GNU General Public License en même temps que Sésathèque
 * (cf LICENCE.txt et http://vvlibri.org/fr/Analyse/gnu-affero-general-public-license-v3-analyse
 * pour une explication en français)
 */

import { hasProp, stringify } from 'sesajstools'

/**
 * Retourne le score à afficher sur la page html des bilans (pas forcément un nombre)
 * @param {Resultat} resultat
 * @return {string}
 */
function getHtmlScore (resultat) {
  const { contenu, score } = resultat
  if (contenu && contenu.isScored) {
    if (typeof score === 'number') {
      if (score === 1) return 'Construction réussie'
      if (score === 0) return 'Construction non réussie'
      return `construction réussie à ${Math.round(score * 100)}%`
    }
    return 'score manquant dans cet exercice de construction'
  }
  return 'figure mathgraph sans score'
}

/**
 * Réponse en pleine page
 * @param {Resultat} resultat
 * @return {string}
 */
function getHtmlFullReponse (resultat) {
  // console.log('getHtmlFullReponse mathgraph avec le résultat', resultat)
  if (!resultat || !resultat.contenu || !resultat.contenu.fig) {
    console.error(Error('Résultat mathghaph sans figure'), resultat)
    return ''
  }
  const resultatContenu = resultat.contenu
  const mtgOptions = {
    fig: resultat.contenu.fig,
    resultatContenu,
    open: false,
    options: false,
    save: false,
    level: hasProp(resultatContenu, 'level') ? resultatContenu.level : 1,
    dys: hasProp(resultatContenu, 'dys') ? resultatContenu.dys : 1
  }
  const mtgOptionsStr = stringify(mtgOptions)

  // dans ce qui suit, on peut mettre de l'es6 dans les ${} mais pas en dehors (les strings
  // mises dans un tag script ne passent pas par babel)
  // Ce code html retourné peut être mis / retiré / remis plusieurs fois dans le même dom,
  return `
<div id="spinner">Chargement en cours…</div>
<div id="main" style="overflow: auto"></div>
<script type="application/javascript">
  (function () {
    // une fct protégée dans une iife, au cas où qqun voudrait lancer plusieurs affichages quasi en même temps
    function loadMtg () {
      if (typeof mtgLoad !== 'function') return alert('mathgraph n’est pas chargé correctement')
      var container = document.getElementById('main')
      var width = (container && container.clientWidth) || 1024
      if (!Number.isInteger(width) || width < 300) width = 300
      var height = Math.round(width * 0.66)
      var svgOptions = {
        width,
        height
      }
      var mtgOptions = ${mtgOptionsStr}
      mtgOptions.callBackAfterReady = function () {
        const spinner = document.getElementById('spinner')
        while (spinner && spinner.firstChild) spinner.removeChild(spinner.firstChild)
        // console.log('figure ready')
      }
      mtgLoad('main', svgOptions, mtgOptions, function (error) {
        if (error) console.error(error)
        console.log('lancement de mathgraph terminé (mais chargement pas forcément terminé)')
      })
    } // loadMtg
    
    if (typeof mtgLoad === 'function') {
      // mtgLoad déjà dans le DOM, rien à charger
      loadMtg()
    } else {
      // on charge le js mathgraph
      // (pour une meilleure compatibilité on crée le tag dans le dom puis ajoute le listener puis ajoute src)
      var body = window.document.getElementsByTagName('body')[0]
      var scriptMtg = window.document.createElement('script')
      scriptMtg.type = 'text/javascript'
      body.appendChild(scriptMtg)
      scriptMtg.addEventListener('load', loadMtg)
      scriptMtg.src = "https://www.mathgraph32.org/js/mtgLoad/mtgLoad.min.js"
    }
  })()
</script>
`
}

/**
 * Exo mathgraph, avec getHtmlFullReponse dispo
 * @type TypeFormatters
 * @memberOf resultatFormatters
 */
export const mathgraph = {
  getHtmlScore,

  /**
   * Retourne la réponse à insérer sur la page html des bilans
   * @param {Resultat} resultat
   * @param {FormatterOptions} [options] isTxt géré
   * @return {string}
   */
  getHtmlReponse: getHtmlScore,

  /**
   * Retourne la réponse à insérer dans un csv
   * @param {Resultat} resultat
   * @return {string}
   */
  getTxtReponse: getHtmlScore,

  getHtmlFullReponse
}