Index: /trunk/SophyaPI/PI/piaxes.cc
===================================================================
--- /trunk/SophyaPI/PI/piaxes.cc	(revision 2090)
+++ /trunk/SophyaPI/PI/piaxes.cc	(revision 2091)
@@ -9,5 +9,5 @@
 #include "piaxes.h"
 
-inline void dble_SWAP(double a, double b) {double tmp=a; a=b; b=tmp;}
+inline void dble_SWAP(double& a,double& b) {double tmp=a; a=b; b=tmp;}
 
 /* --Methode-- */
@@ -166,9 +166,11 @@
   aYlog = g->isLogScaleY();
 
-  int ntick_x = (aXlog) ? 6 : 10;
-  BestTicks(xMin,xMax,ntick_x,xMajTicks,xMinTicks);
-
-  int ntick_y = (aYlog) ? 6 : 12;
-  BestTicks(yMin,yMax,ntick_y,yMajTicks,yMinTicks);
+  int ntick_x = (aXlog) ? 10 : 10;
+  if(aXlog) BestTicksLog(xMin,xMax,ntick_x,xMajTicks,xMinTicks);
+  else BestTicks(xMin,xMax,ntick_x,xMajTicks,xMinTicks);
+
+  int ntick_y = (aYlog) ? 12 : 12;
+  if(aYlog) BestTicksLog(yMin,yMax,ntick_y,yMajTicks,yMinTicks);
+  else BestTicks(yMin,yMax,ntick_y,yMajTicks,yMinTicks);
 
   yMajTickLen = (xMax-xMin)/100;
@@ -183,6 +185,7 @@
 			double tickDown, vector<double>& xticks)
 {
-  if(xticks.size()<=0) return;
+  if(xticks.size()==0) return;
   for(unsigned int i=0;i<xticks.size();i++) {
+    if(xticks[i]<xMin) continue;
     if(xticks[i]>xMax) break;
     g->DrawLine(xticks[i],g->DeltaUCY(y,-tickDown),xticks[i],g->DeltaUCY(y,tickUp));
@@ -194,6 +197,7 @@
 			double tickRight, vector<double>& yticks)
 {
-  if(yticks.size()<=0) return;
+  if(yticks.size()==0) return;
   for(unsigned int i=0;i<yticks.size();i++) {
+    if(yticks[i]<yMin) continue;
     if(yticks[i]>yMax) break;
     g->DrawLine(g->DeltaUCX(x,-tickLeft),yticks[i],g->DeltaUCX(x,tickRight),yticks[i]);
@@ -204,33 +208,35 @@
 void PIAxes::DrawHLabels(PIGraphicUC* g, double y, vector<double>& xticks, unsigned long just)
 {
-
-  if(xticks.size()<=1) return;
-  // Choix du bon format pour les labels des axes;
-  char label[64]; string format; double fac=1.; bool p10=false;
-  double xstep=xticks[1]-xticks[0];
-  int npuiss = BonFormatAxes(xticks[0],xMax,xstep,format,2,1);
-  if(npuiss<-2 || npuiss>3) {p10 = true; fac=pow(10.,(double)npuiss);}
-  else BonFormatAxes(xticks[0],xMax,xstep,format,0,1);
-
-  double xOffset = 0;
-  double xlastlabelfin = xticks[0] - 2.*(xMax-xticks[0]);
+  if(xticks.size()==0) return;
+
+  // Choix du bon format pour les labels des axes
+  string format; double xstep;
+  int npuiss = Le_Bon_Format(xticks,format,xstep);
+  double fac=(npuiss!=0)? fac=pow(10.,(double)npuiss): 1.;
+
+  char label[64];
+  double dum,xpixdeb,xpixfin,largpix;
+  g->UC2GrC(xMin-2.*(xMax-xMin),y,xpixfin,dum);
   for(unsigned int i=0;i<xticks.size();i++) {
+    if(xticks[i]<xMin) continue;
     if(xticks[i]>xMax) break;
     //Attention erreur d'arrondi x->0 (on code 5.1698e-26 au lieu de 0)
     double xx = (fabs(xticks[i]/xstep)<1.e-5) ? 0.: xticks[i];
-    sprintf(label,format.c_str(),xx/fac);
-    Arrange_Label(label);
+    sprintf(label,format.c_str(),xx/fac); Arrange_Label(label);
     double largeur = g->CalcStringWidth(label);
-    if(aXdir) xOffset = largeur/2; else xOffset=-largeur/2;
-    if(xticks[i]+xOffset > xlastlabelfin) {
+    g->DUC2GrC(largeur,0.,largpix,dum);
+    g->UC2GrC(xticks[i],y,xpixdeb,dum);   xpixdeb -= largpix/2.;
+    //cout<<"xticks="<<xticks[i]<<" largpix="<<largpix
+    //    <<" xpixdeb="<<xpixdeb<<" xpixfin="<<xpixfin<<endl;
+    if((aXdir && xpixdeb<xpixfin) || (!aXdir && xpixdeb>xpixfin)) {
       g->DrawString(xticks[i],y,label,PI_HorizontalCenter|just);
-      xlastlabelfin = xticks[i] + xOffset + 1.1*largeur;
-    }
-  }
-
-  if(p10) {
+      xpixfin = xpixdeb + 1.1*largpix;
+    }
+  }
+
+  if(npuiss!=0) {
     PIGrCoord asc,desc;
     double h = g->GetFontHeight(asc,desc);
-    if((aYdir && (just&PI_VerticalBottom)) || (!aYdir && (just&PI_VerticalTop)) ) h = -h; 
+    if((aYdir && (just&PI_VerticalBottom)) || (!aYdir && (just&PI_VerticalTop))) h=-h; 
     double xm = (aXdir)? xMin: xMax;
     double ym = g->DeltaUCY(y,1.5*h);
@@ -244,26 +250,36 @@
 void PIAxes::DrawVLabels(PIGraphicUC* g, double x, vector<double>& yticks, unsigned long just)
 {
-
-  if(yticks.size()<=1) return;
+  if(yticks.size()==0) return;
+
   // Choix du bon format pour les labels des axes;
-  char label[64]; string format; double fac=1.; bool p10=false;
-  double ystep=yticks[1]-yticks[0];
-  int npuiss = BonFormatAxes(yticks[0],yMax,ystep,format,2,1);
-  if(npuiss<-2 || npuiss>3) {p10 = true; fac=pow(10.,(double)npuiss);}
-  else BonFormatAxes(yticks[0],yMax,ystep,format,0,1);
-
+  string format; double ystep;
+  int npuiss = Le_Bon_Format(yticks,format,ystep);
+  double fac=(npuiss!=0)? fac=pow(10.,(double)npuiss): 1.;
+
+  char label[64];
+  PIGrCoord asc,desc;
+  double dum,ypixdeb,ypixfin,hautpix,hauteur=g->GetFontHeight(asc,desc);
+  g->DUC2GrC(0.,hauteur,dum,hautpix);
+  g->UC2GrC(x,yMin-2.*(yMax-yMin),dum,ypixfin);
   for(unsigned int i=0;i<yticks.size();i++) {
+    if(yticks[i]<yMin) continue;
     if(yticks[i]>yMax) break;
     double yy = (fabs(yticks[i]/ystep)<1.e-5) ? 0.: yticks[i];
-    sprintf(label,format.c_str(),yy/fac);
-    Arrange_Label(label);
-    g->DrawString(x,yticks[i],label,PI_VerticalCenter|just);
-  }
-
-  if(p10) {
-    PIGrCoord asc,desc;
-    double h = g->GetFontHeight(asc,desc);
-    if(aYdir) h = -h; 
-    double ym = (aYdir)? yMin: yMax; ym = g->DeltaUCY(ym,h);
+    sprintf(label,format.c_str(),yy/fac); Arrange_Label(label);
+    g->UC2GrC(x,yticks[i],dum,ypixdeb);   ypixdeb -= hautpix/2.;
+    // -- Attention: ypix=0 est en haut de l'ecran
+    //               (ypix croissants vers le bas de l'ecran)
+    //    donc bien que yMin<yMax on a yMinPix>yMaxPix
+    //cout<<"yticks="<<yticks[i]<<" hautpix="<<hautpix
+    //    <<" ypixdeb="<<ypixdeb<<" ypixfin="<<ypixfin<<endl;
+    if((aYdir && ypixdeb>ypixfin) || (!aYdir && ypixdeb<ypixfin)) {
+      g->DrawString(x,yticks[i],label,PI_VerticalCenter|just);
+      ypixfin = ypixdeb + 1.1*hautpix;
+    }
+  }
+
+  if(npuiss!=0) {
+    if(aYdir) hauteur = -hauteur; 
+    double ym = (aYdir)? yMin: yMax; ym = g->DeltaUCY(ym,hauteur);
     sprintf(label,"%d",npuiss);
     g->DrawCompString(x,ym,"x 10",label,NULL,PI_VerticalBottom|just);
@@ -293,53 +309,144 @@
 }
 
-
-///////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+//////////////////// METHODES STATIQUES ////////////////////////////////
+////////////////////////////////////////////////////////////////////////
 /* --Methode-Static-- */
 void PIAxes::BestTicks(double xmin,double xmax,int nticks
                       ,vector<double>& majticks,vector<double>& minticks)
 // *** Calcul de l'intervalle entre les ticks et de la valeur du premier tick
-{
- double d=xmax-xmin; if(d<1.e-100) d=1.e-100; //if (d<1.e-39) d=1.e-39;
+//     pour un axe lineaire
+{
+ if(nticks<=0) nticks = 1;
+
+ double d=xmax-xmin; if(d<1.e-100) d=1.e-100;
  double ld  = log10(d);
  double fld = floor( ((ld<0.)? -ld: ld) );
  double del,del0;
- majticks.resize(0); minticks.resize(0);
- if(ld>=0.) {fld-=1.; del0=del=pow(10.,fld);}
-   else     {fld+=2.; del0=del=pow(10.,-fld);}
+ fld = (ld>=0.)? fld-2.: -(fld+2.);
+ del0 = del = pow(10.,fld);
  // *** Intervalle entre les ticks
  // xmin  xmax    d       ld       fld -->fld  del0
- // 1     1500    1499    3.17     3      2    10^2
- // 1     9500    9499    3.98     3      2    10^2
- // 1     1.005   0.005   -2.3     2      4    10^-4
- // 1     1.995   0.995   -0.0022  0      2    10^-2
- // - Et recherche de la valeur del={del0,2*del0,...,20*del0}
- // telle que "nticks*del" soit le plus petit nombre ">=d"
- // Par exemple, si nticks=10:
- // 1-/ pour le 2sd cas ou d=9499 et del0=100 :
- // del        =    100    200    500    1000    2000
- // nticks*del =   1000   2000   5000   10000   20000
- // d/del      =   94.9   47.4   18.9 | 9.499   4.749  ==> majt = 1000
- // 2-/ pour le 3ieme cas ou d=5e-3 et del0=1e-4 :
- // del        =  1e-4   2e-4   5e-4  1e-3   2e-3
- // nticks*del =  1e-3   2e-3   5e-3  1e-2   2e-2
- // d/del      =  50     25   | 10    5      2.5       ==> majt = 5e-4
- int k=0;
- double fac[4] = {2.,5.,10.,20.};
- while(d/del>(double)nticks && k<4 ) {del=fac[k]*del0; k++;}
+ // 1     1500    1499    3.17     3      1    10^1
+ // 1     9500    9499    3.98     3      1    10^1
+ // 1     1.005   0.005  -2.3      3     -5    10^-5
+ // 1     1.995   0.995  -0.0022   1     -3    10^-3
+ // - Et recherche de la valeur del={del0,2*del0,...,20*del0,...}
+ // telle que "nticks*del" soit le plus petit nombre ">=xmax-xmin"
+ double fac[9] = {2.,5.,10.,20.,50.,100.,200.,500.,1000.};
+ for(int k=0;k<9;k++) {
+   //cout<<"BestTicks: "<<k<<" del="<<del<<" d/del="<<d/del<<"<"<<nticks<<endl;
+   if(d/del < (double)nticks) break;
+   del=fac[k]*del0;
+ }
  double steptick=del;
  //***  Valeur du premier tick
- double xfirsttick = floor(xmin/steptick); if(xmin<0.) xfirsttick+=1.;
- xfirsttick *= steptick;
+ majticks.resize(0);
+ double xfirsttick = floor(fabs(xmin)/steptick)*steptick;
+   if(xmin<0.) xfirsttick *= -1.;
  if(xfirsttick<xmin) xfirsttick += steptick;
- majticks.push_back(xfirsttick);
- while(xfirsttick<=xmax)
-   {xfirsttick+= steptick; majticks.push_back(xfirsttick);}
+ while(xfirsttick<=xmax+steptick/10.)
+   {majticks.push_back(xfirsttick); xfirsttick+= steptick;}
  //***  Gestion des ticks mineurs
- double steptickmin = steptick/5.;
- double xfirsttickmin = floor(xmin/steptickmin) * steptickmin;
- if(xfirsttickmin<xmin) xfirsttickmin += steptickmin;
- minticks.push_back(xfirsttickmin);
- while(xfirsttickmin<=xmax)
-   {xfirsttickmin+= steptickmin; minticks.push_back(xfirsttickmin);}
+ minticks.resize(0);
+ if(majticks.size()>1) {
+   double steptickmin = steptick/5.;
+   double xfirsttickmin = majticks[0];
+   while(xfirsttickmin<=xmax+steptickmin/10.)
+     {minticks.push_back(xfirsttickmin); xfirsttickmin+= steptickmin;}
+ }
+}
+/* --Methode-Static-- */
+void PIAxes::BestTicksLog(double xmin,double xmax,int nticks
+                      ,vector<double>& majticks,vector<double>& minticks)
+// *** Calcul des ticks pour un axe logarithmique
+{
+ if(nticks<=0) nticks = 1;
+ //cout<<"BestTicksLog: xmin="<<xmin<<" xmax="<<xmax<<" nticks="<<nticks<<endl;
+
+ // CMV_BUG: quand on fait func 1 100 ..., Reza renvoit xmin=-0.9602 !!!
+ // Ceci est un bricolo qui permet d'obtenir un resultat moyen.
+ // A CORRIGER: pour Reza, ne pas surdimensionner la fenetre
+ //       vers les xmin,ymin SI on demande une echelle log
+ //       pour etre sur que xmin,ymin sera bien ce qui est demande.
+ if(xmin<=0.) {
+   cout<<"Error_BestTicksLog: xmin="<<xmin;
+   double percor=0.05;
+   // On suppose que: xmin = xmin0 - percor*(xmax0-xmin0)
+   xmin = fabs((xmin+percor*xmax)/(1.+percor));
+   cout<<" corrected to xmin="<<xmin<<endl
+       <<"      ===> First labels may be WRONG"<<endl;
+ }
+
+ // Si xmax<=0 ou si dynamique trop faible on garde BestTicks
+ if(xmax<=0. || xmax/xmin<5.) {
+   //cout<<"Choix de BestTicks xmax="<<xmax<<" xmax/xmin="<<xmax/xmin<<" <5"<<endl;;
+   BestTicks(xmin,xmax,nticks,majticks,minticks);
+   return;
+ }
+
+ int dmin=int(floor(log10(xmin)));
+ int dmax=int(floor(log10(xmax)));
+ if(dmax==dmin) dmax++; else if(dmax<dmin) dmax=dmin+1;
+ int inc = (dmax-dmin+1)/nticks; if(inc<1) inc=1;
+ //cout<<" dmin="<<dmin<<" dmax="<<dmax<<" inc="<<inc<<endl;
+
+ majticks.resize(0);
+ for(int i=dmin;i<=dmax;i+=inc) {
+   double x = pow(10.,(double)i);
+   if(x<xmin || x>xmax) continue;
+   majticks.push_back(x);
+ }
+ //cout<<"majticks.size()="<<majticks.size()<<endl;
+
+ // Pas de puissance de 10 dans l'intervalle
+ if(majticks.size()==0) {
+   BestTicks(xmin,xmax,nticks,majticks,minticks);
+   return;
+ }
+
+ // Pas suffisamment de ticks majeurs
+ if((int)majticks.size()<=nticks/2) {
+   int nins = nticks/(majticks.size()+1);
+   if(nins<=0) nins=1;
+   //cout<<"nins="<<nins<<endl;
+   // Sequence judicieuse pour remplir les ticks manquants
+   // nins = 1 on insere 3
+   //        2           2 5
+   //        3           2 4 6
+   //        4           1.5 2 4 6
+   //      >=5 on reste au cas precedent  
+   double seqmaj[4][4] = {{3.,0,0,0},{2.,5.,0,0},{2.,4.,6.,0},{1.5,2.,4.,6.}};
+   if(nins>4) nins=4;
+   vector<double> tmp;
+   for(unsigned int i=0;i<=majticks.size();i++) {
+     double xt;
+     if(i<majticks.size()) xt = majticks[i]/10.;
+       else                xt = majticks[i-1];
+     for(int n=0;n<nins;n++) {
+       double xins = seqmaj[nins-1][n]*xt;
+       if(xins<xmin || xins>xmax) continue;
+       tmp.push_back(xins);
+     }
+     if(i<majticks.size()) tmp.push_back(majticks[i]);
+   }
+   majticks = tmp;
+ }
+ //cout<<"...majticks.size()="<<majticks.size()<<endl;
+
+ // Les ticks mimneurs
+ minticks.resize(0);
+ for(unsigned int i=0;i<majticks.size()-1;i++) {
+   double dx = (majticks[i+1]-majticks[i])/10.;
+   minticks.push_back(majticks[i]);
+   for(int j=2;j<=8;j+=2)  {
+     double x = majticks[i] + j*dx;
+     if(x<xmin || x>xmax) continue;
+     minticks.push_back(x);
+   }
+ }
+ minticks.push_back(majticks[majticks.size()-1]);
+ //cout<<"...minticks.size()="<<minticks.size()<<endl;
+
 }
 
@@ -440,5 +547,33 @@
 }
 
+/* --Methode-- */
+int PIAxes::Le_Bon_Format(vector<double>& xticks,string& format,double& xstep)
+// Methode static de decision du bon format
+// Decide quel format est le mieux adapte pour ecrire les labels des axes
+// Decide si une puissance de 10 doit etre deportee en bout d'axe
+// - Input:
+//   xticks : vecteur des ticks a ecrire (calcule par BestTicks)
+// - Output:
+//   format : format a utiliser
+//   xstep  : step entre 2 graduations
+// - Return:
+//   npuiss : si format choisit avec ecriture
+//            avec label des puissances de 10 deporte
+//   0      : sinon
+{
+ format="%g"; xstep=1.;
+ if(xticks.size()<=1) return 0;
+
+ xstep=xticks[1]-xticks[0];
+ int npuiss = BonFormatAxes(xticks[0],xticks[xticks.size()-1],xstep,format,2,1);
+ if(npuiss>=-2 && npuiss<=3) {
+   npuiss = 0;
+   BonFormatAxes(xticks[0],xticks[xticks.size()-1],xstep,format,0,1);
+ }
+ return npuiss;
+}
+
 void PIAxes::Arrange_Label(char *label)
+// --- Mise en forme optimale du label numerique
 // Enleve les blancs et les zeros inutiles a la fin d'un label
 {
Index: /trunk/SophyaPI/PI/piaxes.h
===================================================================
--- /trunk/SophyaPI/PI/piaxes.h	(revision 2090)
+++ /trunk/SophyaPI/PI/piaxes.h	(revision 2091)
@@ -45,15 +45,19 @@
   static void BestTicks(double xmin,double xmax,int nticks
 			,vector<double>& majticks,vector<double>& minticks);
+  static void BestTicksLog(double xmin,double xmax,int nticks
+			   ,vector<double>& majticks,vector<double>& minticks);
 
-//  Calcul du format optimal pour les axes (STATIC)
+//  Calcul du format optimal (STATIC)
   static int BonFormatAxes(double xmin,double xmax,double xstep
 			   ,string& format,int typf=0,int add_digit=0);
 
-//  Mise en forme optimale du format (STATIC)
+//  Decision du format optimal pour les axes (STATIC)
+  static int Le_Bon_Format(vector<double>& xticks,string& format,double& xstep);
+
+//  Mise en forme optimale du label numerique (STATIC)
   static void Arrange_Label(char *label);
 
 protected:
-  void Setup(PIGraphicUC* g, double xmin, double xmax, 
-	     double ymin, double ymax);
+  void Setup(PIGraphicUC* g,double xmin,double xmax,double ymin,double ymax);
 
   void DrawHTicks(PIGraphicUC* g, double y, double tickUp, double tickDown, vector<double>& xticks);
Index: /trunk/SophyaPI/PI/piversion.h
===================================================================
--- /trunk/SophyaPI/PI/piversion.h	(revision 2090)
+++ /trunk/SophyaPI/PI/piversion.h	(revision 2091)
@@ -2,5 +2,5 @@
 #define PIVERSION_H_SEEN
 
-#define PI_VERSIONNUMBER  3.68
+#define PI_VERSIONNUMBER  3.69
 
 #endif
