Package freegressi.fit

Source Code of freegressi.fit.FitModel

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    Copyright (C) 2011-2013  Marchand Eric <ricoh51@free.fr>
   
    This file is part of Freegressi.

    Freegressi is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Freegressi 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Freegressi.  If not, see <http://www.gnu.org/licenses/>.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package freegressi.fit;

import freegressi.fit.Fit.TendanceType;
import freegressi.fit.functions.*;
import freegressi.graphics.GraphicModel;
import freegressi.graphics.GraphicModel.GraphicChangedEvent;
import freegressi.graphics.GraphicModel.GraphicSizeChangedEvent;
import freegressi.graphics.GraphicModel.GraphicStyleChangedEvent;
import freegressi.parser.Verificateur;
import freegressi.tableur.SpreadSheets.ActiveSheetChangedEvent;
import freegressi.tableur.SpreadSheets.SheetAddedEvent;
import freegressi.tableur.SpreadSheets.SheetDeletedEvent;
import freegressi.tableur.SpreadSheets.SheetDescriptionChangedEvent;
import freegressi.tableur.SpreadSheets.SheetsAngleChangedEvent;
import freegressi.tableur.SpreadSheets.SheetsCSChangedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnAddedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnDeletedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnModifiedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnMovedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnSortedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnsEditedEvent;
import freegressi.tableur.SpreadSheets.SheetsListener;
import freegressi.tableur.SpreadSheets.SheetsRenamedEvent;
import freegressi.tableur.*;
import freegressi.tableur.Tableur.SheetCellChangedEvent;
import freegressi.tableur.Tableur.SheetLinesAddedEvent;
import freegressi.tableur.Tableur.SheetLinesDeletedEvent;
import freegressi.tableur.Tableur.TableurChangeListener;
import freegressi.utils.Utils;
import jaolho.data.lma.LMA;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;
import javax.swing.event.EventListenerList;

/**
*
* @author marchand
*/
public class FitModel implements TableurChangeListener,
         SheetsListener, GraphicModel.GraphicListener{
  /** La liste des écouteurs */
  private EventListenerList listeners = new EventListenerList();
  /** Le nombre de pixels de large du graphe */
  private int nombrePixels = 0;
  /** La liste des tendances du JPanelTendance */
  private List<Fit> listeTendance = new ArrayList<>();
  /** Le nombre de chiffres significatifs dans l'expression du résultat */
  private int nombreCS = 2;
  private int numeroTendance = 0;
  private static FitModel tendanceModel;

  /**
   * Constructeur privé pour singleton
   * @param tableur
   */
  private FitModel() {
   
  }
  /**
   * Return l'instance du singleton
   * @return
   */
  public static FitModel getInstance() {
    if (tendanceModel == null) {
      tendanceModel = new FitModel();
    }
    return tendanceModel;
  }

  public int donneProchainNumeroTendance() {
    numeroTendance++;
    return numeroTendance;
  }

  public void setTableur(Tableur tableur) {
    //this.tableur = tableur;
  }

  public List<Fit> getListTendances(){
    return listeTendance;
  }
//  /**
//   * Le controller nous informe qu'une variable vient d'être supprimée
//   * Il faut alors supprimer les tendances et les courbes associées à
//   * cette variable
//   * @param tableur
//   */
//  public void variableSupprimee(Tableur tableur, String nom) {
//    for (Fit tendance : listeTendance) {
//      if (tendance.getNomX().equals(nom) || tendance.getNomY().equals(nom)) {
//        fireTendanceDeleted(tendance, true);
//      }
//    }
//  }



  /**
   * Définit le nombre de pixel de large du graphique, utile pour calculer
   * le tableau de valeurs des courbes de tendance
   * @param nombrePixels
   */
  public void setNombrePixels(int nombrePixels) {
    this.nombrePixels = nombrePixels;
    System.out.println("Nombre pixels : " + nombrePixels);
    // recalculer la liste de points des courbes de tendance
    for (Fit tendance : listeTendance) {
      calculeListePointsTendance(tendance);
      // et informer les écouteurs
      if (tendance != null) {
        fireTendanceChanged(tendance, tendance, false);
      }
    }
  }

//  @Override
//  public void tailleChangee(GraphiqueTailleChangeeEvent event) {
//    //throw new UnsupportedOperationException("Not supported yet.");
//    //@TODO à Implémenter
//    setNombrePixels(event.getGraphique().getLargeur());
//  }
//
//  @Override
//  public void doitSeRepeindre(GraphiqueDoitSeRepeindreEvent event) {
//    // ne rien faire, cet évenement est pour les graphiques
//  }
//
//  @Override
//  public void graphicStyleChanged(GraphicStyleChangedEvent event) {
//    //throw new UnsupportedOperationException("Not supported yet.");
//  }

  @Override
  public void activeSheetChanged(ActiveSheetChangedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void sheetAdded(SheetAddedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void sheetDeleted(SheetDeletedEvent event) {
    // Supprimer toutes les tendances s'il n'y a plus de feuille
    if (SpreadSheets.getInstance().getList().isEmpty()){
      for (int i = listeTendance.size() - 1; i > -1; i--){
        notifySupprimeTendance(listeTendance.get(i));
      }
    }
  }

  @Override
  public void columnAdded(SheetsColumnAddedEvent event) {
//    throw new UnsupportedOperationException("Not supported yet.");
  }
  @Override
  public void columnDeleted(SheetsColumnDeletedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void sheetRenamed(SheetsRenamedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }
  @Override
  public void angleChanged(SheetsAngleChangedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }
  @Override
  public void columnModified(SheetsColumnModifiedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void columnSorted(SheetsColumnSortedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void columnMoved(SheetsColumnMovedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void columnsEdited(SheetsColumnsEditedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void sheetDescriptionChanged(SheetDescriptionChangedEvent event) {
//    throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void sheetsCSChanged(SheetsCSChangedEvent event) {
    nombreCS = event.getNewCS();
  }

  @Override
  public void graphicSizeChanged(GraphicSizeChangedEvent event) {
    nombrePixels = event.getNewWidth();
  }

  @Override
  public void graphicChanged(GraphicChangedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }

  @Override
  public void graphicStyleChanged(GraphicStyleChangedEvent event) {
    //throw new UnsupportedOperationException("Not supported yet.");
  }


  /* **********************************************************************
   *
   *                     Les calculs
   *
   *********************************************************************** */
  private int indexParametre = -1;
  public void setIndexParameter(int index){
    indexParametre = index;
  }
  // pas chouette, ce sont des calculs, ils devraient être dans le tableur
  // et c'est spécifique aux tendances, ça a donc sa place ici...
  // et le code est redondant avec calculeNoeud de tableur!
  public double calculeTendance(Noeud noeud, double x, double[] a) {
    //@TODO Vérifier les calculs, redondant
    int type = noeud.getType();
    Noeud filsG = noeud.getFilsG();
    Noeud filsD = noeud.getFilsD();
    // si c'est un ID, c'est forcément x
    if (type == Sym.ID) {
      return x;
    }
    if (type == Sym.PARAMETRE) {
      indexParametre++;
      return a[indexParametre];
    }
    if (type == Sym.NOMBRE) {
      return noeud.getValeur();
    }
    double d1 = (filsG == null) ? 0 : calculeTendance(filsG, x, a);
    double d2 = (filsD == null) ? 0 : calculeTendance(filsD, x, a);
    switch (type) {
      case Sym.PLUS:
        return d1 + d2;
      case Sym.MOINS:
        return d1 - d2;
      case Sym.FOIS:
        return d1 * d2;
      case Sym.DIVISE:
        return d1 / d2;
      case Sym.SIN:
        return Math.sin(d2);
      case Sym.COS:
        return Math.cos(d2);
      case Sym.TAN:
        return Math.tan(d2);
      case Sym.ASIN:
        return Math.asin(d2);
      case Sym.ACOS:
        return Math.acos(d2);
      case Sym.ATAN:
        return Math.atan(d2);
      case Sym.LOG:
        return Math.log10(d2);
      case Sym.LN:
        return Math.log(d2);
      case Sym.EXP:
        return Math.exp(d2);
      case Sym.PUIS:
        return Math.pow(d1, d2);
      case Sym.PUISN:
        return Math.pow(d1, d2);
      case Sym.PI:
        return Math.PI;

      default: {
        System.err.println("Erreur de calcul (calculeTendance)!! (pas d'opération définie) : " + type);
        return Double.NaN;
      }
    }

  }

  /**
   * Calcule la tendance et remplit les champs :
   * - resultat
   * - ecart
   * - noeud
   * - listeX
   * - listeY
   */
  private void calculerTendance(Fit tendance) {
    if (tendance == null) {
      System.err.println("Tendance null à calculer!!");
      return;
    }
    Tableur tableur = tendance.getTableur();
    FreegressiFunction func = null;
    String nomY = tendance.getNomY();
    String nomX = tendance.getNomX();
    TendanceType type = tendance.getType();

    double params[];
    boolean ok = true;
    Noeud racineManuelle;

    switch (type) {
      case LINEAR: func = new LinearFunc(); break;
      case AFFINE: func = new AffineFunc(); break;
      case POLYNOMIAL: func = new PolyFunc(tendance.getDegrePolynome()); break;
      case ANTOINE1: func = new Antoine1Func(); break;       
      case EXPO1: func = new Expo1Func(); break;
      case EXPO2: func = new Expo2Func(); break;        
      case HAND:
        racineManuelle = Verificateur.parseExpressionTendance(tendance.getExpression(), nomX);
        if (racineManuelle != null && racineManuelle.getType() != Sym.ERROR
                && racineManuelle.getType() != Sym.PARSER_COHERENCE_ERROR
                && racineManuelle.getType() != Sym.PARSER_ERROR) {
          func = new AnyFunc(racineManuelle, tendance.getExpression());
        } else {
          ok = false;
        }
        break;
      default:
        break;
    }
    int nombreParams = func.getParamNumber();
    if (ok) {
      params = new double[nombreParams];
      for (int i = 0; i < params.length; i++) {
        params[i] = 1;
      }
      double[][] tabXY = tableur.donneTableau(nomX, nomY);
      LMA lma = new LMA(func, params, tabXY);
      lma.verbose = true;
      try {
        lma.fit();

        double[] vraie = tabXY[1];
        double[] abcisse = tabXY[0];
        double[] fausse = func.generateData(abcisse, lma.parameters);
        double erreur = Stats.getErreur(vraie, fausse);

        String str = func.getTextToDisplay(lma.parameters, nomX, nombreCS);
        tendance.setResultat(nomY + " = " + str);
        Noeud noeud = func.getNode(tableur, lma.parameters, nomX);       
        tendance.setNoeud(noeud);
        tendance.setEcart(Utils.formatteNombre(erreur, 2) + " %");
        calculeListePointsTendance(tendance);

      } catch (Exception e) {
        tendance.setResultat("Données non valides");
        tendance.setEcart("Données non valides");
      }
    }
  }


  /**
   * Calcule deux listes de valeurs listeX et listeY (des double) qui
   * permettront de tracer la courbe de tendance.
   * Ce calcul se base sur la largeur du graphique (nombrePixels) et, pour
   * gagner du temps d'affichage :
   * - ne calcule que deux points pour les droites
   * - calcule un point tous les 10 pixels
   * @param tendance la tendance à calculer
   */
  private void calculeListePointsTendance(Fit tendance) {
    if (tendance == null || nombrePixels < 2) {
      return;
    }

    // @TODO Ne calculer que deux points dans le cas des droites

    // récupérer les bornes de l'axe x
    double x1 = tendance.getMinX();
    double x2 = tendance.getMaxX();
    System.out.println("x1 = " + x1 + " ; x2 = " + x2);
    int nombrePoints = nombrePixels / 10;

    double pas = (x2 - x1) / (nombrePoints - 1);
    double x, y;
    Noeud noeud = tendance.getNoeud();
    ArrayList<Double> listeX = new ArrayList<>();
    ArrayList<Double> listeY = new ArrayList<>();
    for (int i = 0; i < nombrePoints; i++) {
      x = x1 + i * pas;
      listeX.add(x);
      y = calculeTendance(noeud, x);
      listeY.add(y);
    }

    tendance.setListeX(listeX);
    tendance.setListeY(listeY);
  }

  /**
   * Renvoit une valeur, calculée à l'aide de l'entrée x
   * et du noeud de calcul noeud
   * @param noeud
   * @param x
   * @return
   */
  public double calculeTendance(Noeud noeud, double x) {
    // @TODO A VIRER
    int type = noeud.getType();
    Noeud filsG = noeud.getFilsG();
    Noeud filsD = noeud.getFilsD();
    // si c'est un ID, c'est forcément x
    if (type == Sym.ID) {
      return x;
    }
//    if (type == Sym.PARAMETRE) {
//      indexParametre++;
//      return a[indexParametre];
//    }
    if (type == Sym.NOMBRE) {
      return noeud.getValeur();
    }
    double d1 = (filsG == null) ? 0 : calculeTendance(filsG, x);
    double d2 = (filsD == null) ? 0 : calculeTendance(filsD, x);
    switch (type) {
      case Sym.PLUS:
        return d1 + d2;
      case Sym.MOINS:
        return d1 - d2;
      case Sym.FOIS:
        return d1 * d2;
      case Sym.DIVISE:
        return d1 / d2;
      case Sym.SIN:
        return Math.sin(d2);
      case Sym.COS:
        return Math.cos(d2);
      case Sym.TAN:
        return Math.tan(d2);
      case Sym.ASIN:
        return Math.asin(d2);
      case Sym.ACOS:
        return Math.acos(d2);
      case Sym.ATAN:
        return Math.atan(d2);
      case Sym.LOG:
        return Math.log10(d2);
      case Sym.LN:
        return Math.log(d2);
      case Sym.EXP:
        return Math.exp(d2);
      case Sym.PUIS:
        return Math.pow(d1, d2);
      case Sym.PUISN:
        return Math.pow(d1, d2);
      case Sym.PI:
        return Math.PI;

      default: {
        System.err.println("Erreur de calcul!! (pas d'opération définie) : " + type);
        return Double.NaN;
      }
    }

  }


  /* **********************************************************************
   *
   *                          Gestion des évenements
   *
   *********************************************************************** */
  /**
   * Ajoute un écouteur à la liste
   * @param listener l'écouteur à ajouter
   */
  public final void addTendanceListener(FitListener listener) {
    listeners.add(FitListener.class, listener);
  }

  /**
   * Retire un écouteur de la liste
   * @param listener l'écouteur à retirer
   */
  public void removeTendanceListener(FitListener listener) {
    listeners.remove(FitListener.class, listener);
  }


  private void recalculeToutesLesTendances() {
    System.out.println("********** recalculeToutesLesTendances");
    for (Fit tendance : listeTendance) {
      // Mettre à jour le minX et le maxX de chaque tendance
      String nomX = tendance.getNomX();
      Colonne colonneX = tendance.getTableur().donneColonne(nomX);
      tendance.setMinX(colonneX.getMin());
      tendance.setMaxX(colonneX.getMax());
      String nomY = tendance.getNomY();
      Colonne colonneY = tendance.getTableur().donneColonne(nomY);
      tendance.setMinY(colonneY.getMin());
      tendance.setMaxY(colonneY.getMax());     
      calculerTendance(tendance);
      fireTendanceChanged(tendance, tendance, false);
    }
  }

  @Override
  public void sheetCellChanged(SheetCellChangedEvent event) {
    recalculeToutesLesTendances();
  }

  @Override
  public void sheetLinesAdded(SheetLinesAddedEvent event) {
    recalculeToutesLesTendances();
  }

  @Override
  public void sheetLinesDeleted(SheetLinesDeletedEvent event) {
    recalculeToutesLesTendances();
  }

//  @Override
//  public void bornesTendanceChangees(GraphiqueBornesTendanceChangeesEvent event) {
//    throw new UnsupportedOperationException("Not supported yet.");
//  }


  /* **********************************************************************
   *
   *               Creation d'une regression
   *
   *********************************************************************** */

  /**
   *
   * @author marchand
   */
  public class TendanceCreatedEvent extends EventObject {

    private Fit newTendance;
    private final boolean undoable;

    public TendanceCreatedEvent(Object source, Fit newTendance, boolean undoable) {
      super(source);
      this.newTendance = newTendance;
      this.undoable = undoable;
    }

    public Fit getNewTendance() {
      return newTendance;
    }

    public boolean isUndoable() {
      return undoable;
    }
    public String getTexte() {
      return "Ajouter une regression " + newTendance.getNomY() + "=f(" + newTendance.getNomX() + ")";
    }
  }

  private Fit createNewTendance(Tableur tableur){
    // @TODO vérifier qu'il y a deux colonnes
    String nomY = tableur.getListeColonnes().get(1).getColonneDescription().getNom();
    String nomX = tableur.getListeColonnes().get(0).getColonneDescription().getNom();
    Fit tendance = new Fit(tableur, donneProchainNumeroTendance(),
            false, TendanceType.LINEAR,
            nomY,
            nomX,
            null, null,
            null,
            null, null,
            null,
            tableur.donneColonne(nomX).getMin(),
            tableur.donneColonne(nomX).getMax(),
            tableur.donneColonne(nomY).getMin(),
            tableur.donneColonne(nomY).getMax(),
            nombrePixels, 2, true, null, true);
    return tendance;
  }

  /**
   * Une tendance vient d'être ajoutée, il faut la calculer et
   * informer les écouteurs
   * @param newTendance la nouvelle tendance
   */
  public void notifyAjouteTendance(Tableur tableur) {
    Fit newTendance = createNewTendance(tableur);
    listeTendance.add(newTendance);
    calculerTendance(newTendance);
    fireTendanceCreated(newTendance, true);
    //System.out.println("Creer tendance");
  }

  /**
   * Envoit du message "Une tendance vient d'être créée" à tous les écouteurs
   * @param tendance la tenace qui vient d'être créée
   */
  private void fireTendanceCreated(Fit tendance, boolean undoable) {
    FitListener[] listenerList = (FitListener[]) listeners.getListeners(FitListener.class);
    for (FitListener listener : listenerList) {
      listener.tendanceCreated(new TendanceCreatedEvent(this, tendance, undoable));
    }
  }

  public void undoRegressionAdded(TendanceCreatedEvent event) {
    Fit tendance = event.getNewTendance();
    listeTendance.remove(tendance);
    // supprimer cet écouteur
    FitListener tendanceListener = tendance.getTendanceListener();
    removeTendanceListener(tendanceListener);
    // Informer les écouteurs
    fireTendanceDeleted(tendance, false);
  }

  public void redoRegressionAdded(TendanceCreatedEvent event) {
    Fit tendance = event.getNewTendance();
    listeTendance.add(tendance);
    //addTendanceListener(tendance.getTendanceListener()); //@TODO A VERIFIER
    calculerTendance(tendance);
    fireTendanceCreated(tendance, false);
  }

  /* **********************************************************************
   *
   *               Destruction d'une regression
   *
   *********************************************************************** */
  /**
   *
   * @author marchand
   */
  public class TendanceDeletedEvent extends EventObject {

    private Fit tendance;
    private final boolean undoable;

    public TendanceDeletedEvent(Object source, Fit tendance, boolean undoable) {
      super(source);
      this.tendance = tendance;
      this.undoable = undoable;
    }

    public boolean isUndoable() {
      return undoable;
    }

    public Fit getTendance() {
      return tendance;
    }
    public String getTexte() {
      return "Supprimer la regression " + tendance.getNomY() + "=f(" + tendance.getNomX() + ")";
    }
  }

  /**
   * Une tendance doit être supprimée, on la retire de la liste,
   * on informe les écouteurs et on retire l'écouteur associé de la
   * liste des écouteurs
   * @param tendance la tendance à retirer
   * @param tendanceListener l'écouteur de cette tendance
   */
  public void notifySupprimeTendance(Fit tendance) {
    listeTendance.remove(tendance);
    // supprimer cet écouteur
    FitListener tendanceListener = tendance.getTendanceListener();
    removeTendanceListener(tendanceListener);
    // Informer les écouteurs
    fireTendanceDeleted(tendance, true);

  }

  /**
   * Envoit du message "Une tendance vient d'être détruite" à tous les écouteurs
   * @param tendance la tendance détruite
   */
  private void fireTendanceDeleted(Fit tendance, boolean undoable) {
    FitListener[] listenerList = (FitListener[]) listeners.getListeners(FitListener.class);

    for (FitListener listener : listenerList) {
      listener.tendanceDeleted(new TendanceDeletedEvent(this, tendance, undoable));
    }
  }
  public void undoRegressionDeleted(TendanceDeletedEvent event) {
    Fit tendance = event.getTendance();
    listeTendance.add(tendance);
    //addTendanceListener(tendance.getTendanceListener()); //@TODO A VERIFIER
    calculerTendance(tendance);
    fireTendanceCreated(tendance, false);
  }

  public void redoRegressionDeleted(TendanceDeletedEvent event) {
    Fit tendance = event.getTendance();
    listeTendance.remove(tendance);
    // supprimer cet écouteur
    FitListener tendanceListener = tendance.getTendanceListener();
    removeTendanceListener(tendanceListener);
    // Informer les écouteurs
    fireTendanceDeleted(tendance, false);
  }

  /* **********************************************************************
   *
   *               Modification d'une regression
   *
   *********************************************************************** */


  /**
   * Classe qui définit l'évenement :
   *  - tendance changée
   * @author marchand
   */
  public class TendanceChangedEvent extends EventObject {
    private final Fit newTendance;
    private final boolean undoable;
    private final Fit oldTendance;

    public TendanceChangedEvent(Object source, Fit oldTendance,
            Fit newTendance, boolean undoable) {
      super(source);
      this.newTendance = newTendance;

      this.undoable = undoable;
      this.oldTendance = oldTendance;
    }

    public Fit getNewTendance() {
      return newTendance;
    }

    public Fit getOldTendance() {
      return oldTendance;
    }

    public boolean isUndoable() {
      return undoable;
    }


    public String getTexte() {
      return "Changer la regression " + oldTendance.getNomY() + "=f(" + oldTendance.getNomX() + ")";
    }
  }

  /**
   * Envoit du message "Une tendance a changé" à tous les écouteurs
   * @param tendance la tendance qui a changé
   */
  private void fireTendanceChanged(Fit oldTendance, Fit newTendance, boolean undoable) {
    FitListener[] listenerList = (FitListener[]) listeners.getListeners(FitListener.class);
    for (FitListener listener : listenerList) {
      listener.tendanceChanged(new TendanceChangedEvent(this, oldTendance, newTendance, undoable));
    }
  }

  private void deleteRegressionByNumber(int number){
    for (Fit t: listeTendance){
      if (t.getNumero() == number){
        listeTendance.remove(t);
        break;
      }
    }
  }


  /**
   * Un des paramètres de la tendance a été modifiée, il
   * faut la recalculer et informer les écouteurs
   * @param tendance la tendance modifiée
   */
  public void notifyModifieTendance(Fit oldTendance, Fit newTendance) {
    // supprimer la tendance possedant le même numero
    int numero = oldTendance.getNumero();
    deleteRegressionByNumber(numero);
    // Ajouter cette tendance
    listeTendance.add(newTendance);
    // ici je dois recalculer la nouvelle tendance
    calculerTendance(newTendance);
    // et informer les écouteurs
    fireTendanceChanged(oldTendance, newTendance, true);
    System.out.println("Modifie tendance");
  }

  public void undoRegressionChanged(TendanceChangedEvent event){
    Fit oldTendance = event.getOldTendance();
    Fit newTendance = event.getNewTendance();

    // supprimer la newTendance
    listeTendance.remove(newTendance);
    // recalculer et retablir la old
    calculerTendance(oldTendance);
    listeTendance.add(oldTendance);
    fireTendanceChanged(newTendance, oldTendance, false);
  }
  public void redoRegressionChanged(TendanceChangedEvent event){
    Fit oldTendance = event.getOldTendance();
    Fit newTendance = event.getNewTendance();

    // supprimer la oldTendance
    boolean b = listeTendance.remove(oldTendance);
    // recalculer et retablir la new
    calculerTendance(newTendance);
    listeTendance.add(newTendance);
    fireTendanceChanged(oldTendance, newTendance, false);
  }

  public String toXML(String tab) {
    String tab2 = tab + "\t";
    String str = "";
    for (Fit tendance : listeTendance) {
      str += tendance.toXML(tab2);
    }
    return str;
  }
}
TOP

Related Classes of freegressi.fit.FitModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.