Logo Search packages:      
Sourcecode: labplot version File versions

Plot2D.cc

// LabPlot : Plot2D.cc

#include <qsimplerichtext.h>
#include <klocale.h>
#include <kdebug.h>
#include <iostream>
#include "Plot2D.h"
#include "Plot2DSurface.h"
#include "defs.h"

using namespace std;

inline double MAX(double x,double y) {if (x>y) return x; else return y;}

// general 2D Plot class
Plot2D::Plot2D(Worksheet *p)
      : Plot(p)
{
      axis[0].setLabel(new Label(i18n("x-Axis")));
      axis[1].setLabel(new Label(i18n("y-Axis")));
      axis[2].setLabel(new Label(i18n("y2-Axis")));
      axis[3].setLabel(new Label(i18n("x2-Axis")));

      // grid & border
      for (int i=0;i<4;i++)
            borderenabled[i] = TRUE;
      for (int i=0;i<8;i++)
            gridenabled[i] = FALSE;
      for (int i=2;i<4;i++) {
            axis[i].enable(0);
            borderenabled[i] = FALSE;
      }
}

void Plot2D::setActRanges(LRange* r) {
      // add offset
      LRange tmprange[2];

      // Maybe use offset for actrange
      //but  thats not good for surface plot
      double xoffset=0;//(r[0].rMax()-r[0].rMin())/10;
      double yoffset=0;//(r[1].rMax()-r[1].rMin())/10;

      tmprange[0]=LRange(r[0].rMin()-xoffset,r[0].rMax()+xoffset);
      tmprange[1]=LRange(r[1].rMin()-yoffset,r[1].rMax()+yoffset);
      actrange[0]=tmprange[0];
      actrange[1]=tmprange[1];
}

void Plot2D::setBorder(int item, bool on) {
      const int unit = 5, numunit = 40, numunit2 = 20;
      int w = worksheet->width(), h = worksheet->height();

      int xmin = (int)(w*(size.X()*p1.X()+position.X()));
      int xmax = (int)(w*(size.X()*p2.X()+position.X()));
      int ymin = (int)(h*(size.Y()*p1.Y()+position.Y()));
      int ymax = (int)(h*(size.Y()*p2.Y()+position.Y()));

      if(item == 0) {
            if (on) {
                  if (axis[0].label()->title().length() > 0) ymax -= axis[0].label()->font().pointSize();
                  if (axis[0].MajorTicsEnabled())   ymax -= unit+numunit2;
                  if (axis[0].MinorTicsEnabled())   ymax -= unit;
            }
            else  {
                  if (axis[0].label()->title().length() > 0) ymax += axis[0].label()->font().pointSize();
                  if (axis[0].MajorTicsEnabled())   ymax += unit+numunit2;
                  if (axis[0].MinorTicsEnabled())   ymax += unit;
            }
      }
      if(item == 1) {
            if (on) {
                  if (axis[1].label()->title().length() > 0) xmin += axis[1].label()->font().pointSize();
                  if (axis[1].MajorTicsEnabled())   xmin += unit+numunit;
                  if (axis[1].MinorTicsEnabled())   xmin += unit;
            }
            else {
                  if (axis[1].label()->title().length() > 0) xmin -= axis[1].label()->font().pointSize();
                  if (axis[1].MajorTicsEnabled())   xmin -= unit+numunit;
                  if (axis[1].MinorTicsEnabled())   xmin -= unit;
            }
      }
      if(item == 2) {
            if (on) {
                  if (axis[2].label()->title().length() > 0) xmax -= axis[2].label()->font().pointSize();
                  if (axis[2].MajorTicsEnabled())   xmax -= unit+numunit;
                  if (axis[2].MinorTicsEnabled())   xmax -= unit;
            }
            else {
                  if (axis[2].label()->title().length() > 0) xmax += axis[2].label()->font().pointSize();
                  if (axis[2].MajorTicsEnabled())   xmax += unit+numunit;
                  if (axis[2].MinorTicsEnabled())   xmax += unit;

            }
      }
      if(item == 3) {
            if (on) {
                  if (axis[3].label()->title().length() > 0) ymin += axis[3].label()->font().pointSize();
                  if (axis[3].MajorTicsEnabled())   ymin += unit+numunit2;
                  if (axis[3].MinorTicsEnabled())   ymin += unit;
            }
            else {
                  if (axis[3].label()->title().length() > 0) ymin -= axis[3].label()->font().pointSize();
                  if (axis[3].MajorTicsEnabled())   ymin -= unit+numunit2;
                  if (axis[3].MinorTicsEnabled())   ymin -= unit;
            }
      }
      setXMin(xmin,w);
      setXMax(xmax,w);
      setYMin(ymin,h);
      setYMax(ymax,h);
}

void Plot2D::draw(QPainter *p,int w,int h) {
      kdDebug()<<"Plot2D::draw() w/h : "<<w<<' '<<h<<endl;
      kdDebug()<<" TYPE = "<<type<<endl;
      int xmin = (int)(w*(size.X()*p1.X()+position.X()));
      int xmax = (int)(w*(size.X()*p2.X()+position.X()));
      int ymin = (int)(h*(size.Y()*p1.Y()+position.Y()));
      int ymax = (int)(h*(size.Y()*p2.Y()+position.Y()));

      //kdDebug()<<"XMIN/MXAX/YMIN/YMAX = "<<xmin<<','<<xmax<<','<<ymin<<','<<ymax<<endl;
      //kdDebug()<<"p1 = "<<p1.X()<<'/'<<p1.Y()<<" p2 = "<<p2.X()<<'/'<<p2.Y()<<endl;

      if (!transparent) {
            // background color
            p->setBrush(bgcolor);
            p->setPen(Qt::NoPen);
            p->drawRect((int)(w*position.X()),(int)(h*position.Y()),(int)(w*size.X()),(int)(h*size.Y()));

            // graph background color
            p->setBrush(gbgcolor);
            p->setPen(Qt::NoPen);
            p->drawRect(xmin,ymin,xmax-xmin,ymax-ymin);
      }

      //kdDebug()<<"PLOT2D : title->draw() pos:"<<position.X()<<' '<<position.Y()<<endl;
      //kdDebug()<<"                size:"<<size.X()<<' '<<size.Y()<<endl;
      title->draw(p,position,size,w,h,0);

      drawBorder(p,w,h);
      drawAxes(p,w,h);

      drawCurves(p,w,h);

      if (baseline_enabled) {
            double min = actrange[1].rMin();
            double max = actrange[1].rMax();
            int y = ymax - (int) ((baseline-min)/(max-min)*(double)(ymax-ymin));

            //kdDebug()<< "BASLINE @ "<<y<<endl;

            p->drawLine(xmin,y,xmax,y);
      }

      if (region_enabled) {
            double min = actrange[0].rMin();
            double max = actrange[0].rMax();
            int minx = xmin + (int) ((region.rMin()-min)/(max-min)*(double)(xmax-xmin));
            int maxx = xmin + (int) ((region.rMax()-min)/(max-min)*(double)(xmax-xmin));

            //kdDebug()<<"REGION : "<<minx<<" "<<maxx<<endl;

            if(minx != maxx) {
                  p->drawLine(minx,ymin,minx,ymax);
                  p->drawLine(maxx,ymin,maxx,ymax);
            }

            if (maxx-minx > 20) {
                  int y = (ymax+ymin)/2;
                  p->drawLine(minx+5,y,maxx-5,y);
                  p->drawLine(minx+5,y,minx+10,y+5);
                  p->drawLine(minx+5,y,minx+10,y-5);
                  p->drawLine(maxx-5,y,maxx-10,y+5);
                  p->drawLine(maxx-5,y,maxx-10,y-5);
            }
      }

      if(legend.enabled()) {
            if (type == PSURFACE) {       // legend can't do this :-(
                  Plot2DSurface *plot = (Plot2DSurface *)this;
                  int x = (int) (w*(size.X()*legend.X()+position.X()));
                  int y = (int) (h*(size.Y()*legend.Y()+position.Y()));

                  int j= plot->Palette();
                  if(plot->densityEnabled()) {
                        for (int i=0;i<255;i++) {
                              int tmpy=y+(int)((40+i)*size.Y());
                              p->setPen(plot->Color(255-i,j));
                              p->drawLine((int)(x+5*size.X()),tmpy,(int)(x+30*size.X()),tmpy);
                        }
                  }

                  p->setPen(Qt::black);
                  int level = plot->Number();
                  // draw contour
                  if (plot->contourEnabled()) {
                        for (int i=0;i<level;i++) {
                              if (plot->ColoredContour())
                                    p->setPen(plot->Color((int)(255-i*255.0/level),j));
                              int tmpy = (int) (y+size.Y()*(40+255/(double)(level-1)*i));
                              p->drawLine(x+(int)(5*size.X()),tmpy,x+(int)(30*size.X()),tmpy);
                        }
                  }

                  // draw label
                  p->setPen(Qt::black);
                  if (level>11)
                        level = 11;
                  for (int i=0;i<level;i++) {
                        GraphM *graph = graphlist->getGraphM(0);
                        LRange r = graph->Range(2);
                        double zmax, zmin;
                        if(plot->Relative()) {
                              zmin = r.rMin();
                              zmax = r.rMax();
                        }
                        else {
                              zmin = - MAX(fabs(r.rMax()),fabs(r.rMin()));
                              zmax = MAX(fabs(r.rMax()),fabs(r.rMin()));
                        }
                        
                        // resize font for contour level in legend with size
                        QFont tmpfont = legend.font();
                        tmpfont.setPointSize((int)(legend.font().pointSize()*size.X()));
                        p->setFont(tmpfont);

                        double value = zmax-i/(double)(level-1)*(zmax-zmin);
                        p->drawText(x+(int)(50*size.X()),y+(int)(size.Y()*(46+(255/(level-1))*i)),
                              QString::number(value,'g',3));
                  }

            }
            //kdDebug()<<" drawing legend with pos = "<<position.X()<<' '<<position.Y()<<endl;
            //kdDebug()<<"    size.X()*w/size.Y()*h = "<<size.X()*w<<' '<<size.Y()*h<<endl;
            legend.draw(p,type,graphlist,position,size,w,h);
      }

      // reset ranges
      //kdDebug()<<"Plot2D::draw() reset ranges"<<endl;
}

void Plot2D::drawBorder(QPainter *p,int w,int h) {
      kdDebug()<<"drawBorder()"<<endl;
      int xmin = (int)(w*(size.X()*p1.X()+position.X()));
      int xmax = (int)(w*(size.X()*p2.X()+position.X()));
      int ymin = (int)(h*(size.Y()*p1.Y()+position.Y()));
      int ymax = (int)(h*(size.Y()*p2.Y()+position.Y()));
      kdDebug()<<"xmin/xmax ymin/ymax "<<xmin<<'/'<<xmax<<' '<<ymin<<'/'<<ymax<<endl;

      if (borderenabled[1]) {
            p->setPen(axis[1].BorderColor());
            p->drawLine(xmin,ymin,xmin,ymax);
      }
      if (borderenabled[3]) {
            p->setPen(axis[3].BorderColor());
            p->drawLine(xmin,ymin,xmax,ymin);
      }
      if (borderenabled[2]) {
            p->setPen(axis[2].BorderColor());
            p->drawLine(xmax,ymin,xmax,ymax);
      }
      if (borderenabled[0]) {
            p->setPen(axis[0].BorderColor());
            p->drawLine(xmin,ymax,xmax,ymax);
      }
}

void Plot2D::drawAxes(QPainter *p,int w, int h) {
//    kdDebug()<<"Plot2D::drawAxes()"<<endl;
      const int unit = (int)(5*size.X());
      const int numunit = (int)(40*size.X()), numunit2 = (int)(20*size.X());

      int xmin = (int)(w*(size.X()*p1.X()+position.X()));
      int xmax = (int)(w*(size.X()*p2.X()+position.X()));
      int ymin = (int)(h*(size.Y()*p1.Y()+position.Y()));
      int ymax = (int)(h*(size.Y()*p2.Y()+position.Y()));
      //kdDebug()<<"xmin/xmax ymin/ymax : "<<xmin<<'/'<<xmax<<' '<<ymin<<'/'<<ymax<<endl;
      //kdDebug()<<"width/height : "<<w<<'/'<<h<<endl;

      //AxesLabel
      if (axis[3].enabled()) {            // x2
            Label *label = axis[3].label();
            if (label->X()==0 && label->Y()==0) // default
                  label->setPosition((xmin+(xmax-xmin)/2)/(double)w,
                        (ymin-(unit+3*numunit2)*axis[3].MajorTicsEnabled()-2*unit)/(double)h);
            label->draw(p,position,size,w,h,0);
      }
      if (axis[0].enabled()) {            // x
            Label *label = axis[0].label();
            if (label->X()==0 && label->Y()==0) // default
                  label->setPosition((xmin+(xmax-xmin)/2)/(double)w,
                        (ymax+(unit+numunit2)*axis[0].MajorTicsEnabled())/(double)h);
            label->draw(p,position,size,w,h,0);
      }
      if (axis[1].enabled()) {            // y
            Label *label = axis[1].label();
            p->save();
            if (label->X()==0 && label->Y()==0) // default
                  label->setPosition(0.01, (ymin+(ymax-ymin)/2)/(double)h);
            label->draw(p,position,size,w,h,270);
            p->restore();
      }
      if (axis[2].enabled()) {            // y2
            Label *label = axis[2].label();
            p->save();
            if (label->X()==0 && label->Y()==0) // default
                  label->setPosition((xmax+(2*unit+numunit)*axis[2].MajorTicsEnabled())/(double)w,
                        (ymin+(ymax-ymin)/2)/(double)h);
            label->draw(p,position,size,w,h,270);
            p->restore();
      }

      // axes tics and grid
      for (int k=0;k<4;k++) {
            if(k==0 || k==3) {      // x,x2
                  int tmpi=0;
                  (k==0)?tmpi=0:tmpi=4;

                  if (axis[k].MajorTicsEnabled() && axis[k].enabled()) {
                        int t=-1;         // number of major tics
                        TScale scale = axis[k].Scale();
                        double min = actrange[0].rMin();
                        double max = actrange[0].rMax();
                        switch (scale) {
                        case LINEAR: t = axis[k].MajorTics(); break;
                        case LOG10: t = (int) log10(max/min)+2; break;
                        case LOG2: t = (int) log2(max/min)+2; break;
                        case LN: t = (int) log(max/min)+2; break;
                        case SQRT: t = (int) (pow(max,2)-pow(min,2))+1; break;
                        }
                        if(t==0) t=-1;

                        for (int i=0;i <= t;i++) {
                              int x1=0, x2=0;
                              switch(scale) {
                              case LINEAR: {
                                    x1 = xmin+i*(xmax-xmin)/t;
                                    x2 = xmin+(i+1)*(xmax-xmin)/t;
                                    } break;
                              case LOG10: {
                                    double gap = 1.0-log10(pow(10,ceil(log10(min)))/min); // fragment of decade to shift left
                                    double decade = (xmax-xmin)/(log10(max/min));         // width of decade
                                    x1 = xmin+(int)((i-gap)*decade);
                                    x2 = (int) (x1+decade+ceil(fabs(log10(max))));
                                    } break;
                              case LOG2: {
                                    double gap = 1.0-log2(pow(2,ceil(log2(min)))/min);          // fragment of decade to shift left
                                    double decade = (xmax-xmin)/(log2(max/min));          // width of decade
                                    x1 = xmin+(int)((i-gap)*decade);
                                    x2 = (int) (x1+decade+ceil(fabs(log2(max))));
                                    } break;
                              case LN: {
                                    double gap = 1.0-log(pow(M_E,ceil(log(min)))/min);    // fragment of decade to shift left
                                    double decade = (xmax-xmin)/(log(max/min));           // width of decade
                                    x1 = xmin+(int)((i-gap)*decade);
                                    x2 = (int) (x1+decade+ceil(fabs(log(max))));
                                    } break;
                              case SQRT: {
                                    x1 = xmin+(int)((sqrt(min*min+i)-min)/(max-min)*(xmax-xmin));
                                    x2 = xmin+(int)((sqrt(min*min+i+1)-min)/(max-min)*(xmax-xmin));
                                    } break;
                              }

                              if(x1<=xmax+1 && x1>=xmin-1) { // major tics
                                    p->setPen(axis[k].TicsColor());
                                    if(k==0) {  // x
                                          switch(axis[k].TicsPos()) {
                                          case 0: p->drawLine(x1,ymax,x1,ymax+10); break;
                                          case 1: p->drawLine(x1,ymax-10,x1,ymax); break;
                                          case 2:p->drawLine(x1,ymax-10,x1,ymax+10); break;
                                          case 3: break;
                                          }
                                    }
                                    else {            // x2
                                          switch(axis[k].TicsPos()) {
                                          case 0: p->drawLine(x1,ymin-10,x1,ymin); break;
                                          case 1: p->drawLine(x1,ymin,x1,ymin+10); break;
                                          case 2: p->drawLine(x1,ymin-10,x1,ymin+10); break;
                                          case 3: break;
                                          }
                                    }

                                    if (gridenabled[tmpi]) {
                                          p->setPen(QPen(axis[k].GridColor(),0,Qt::DashLine));
                                          p->drawLine(x1,ymin,x1,ymax);
                                          p->setPen(Qt::SolidLine);
                                    }
                              }
                              if (graphlist->getNumber() > 0) {         // Numbers
                                    QColor c = axis[k].TicsLabelColor();
                                    QFont f = axis[k].TicsFont();
                                    double dx = max-min, value=0;
                                    
                                    switch(scale) {
                                    case LINEAR: value = min + i*dx/t; break;
                                    case LOG10: value = pow(10,ceil(log10(min)))*pow(10.0,i-1); break;
                                    case LOG2: value = pow(2,ceil(log2(min)))*pow(2.0,i-1); break;
                                    case LN: value = pow(M_E,ceil(log(min)))*pow(M_E,i-1); break;
                                    case SQRT: value = min + i*dx/t; break;
                                    }

                                    // apply scale and shift value
                                    value = value*axis[k].Scaling()+axis[k].Shift();

                                    TFormat atlf = axis[k].TicsLabelFormat();

                                    QString label = TicLabel(k,atlf,axis[k].TicsLabelPrecision(), 
                                          axis[k].DateTimeFormat(),value);

                                    // apply prefix & suffix
                                    label.prepend(axis[k].TicsLabelPrefix());
                                    label.append(axis[k].TicsLabelSuffix());

                                    // draw tic label
                                    QFontMetrics fm(f);
                                    int y1;
                                    int gap = axis[k].TicsLabelGap();
                                    
                                    if(k==0)
                                          y1=ymax+gap+fm.ascent()/2;
                                    else
                                          y1=ymin-gap-fm.ascent()/2;
                                    
                                    p->save();
                                    p->translate(x1,y1);
                                    p->rotate(axis[k].TicsLabelRotation());
                                    f.setPointSize((int)(f.pointSize()*size.X()));  // resize tic label
                                    if (atlf == AUTO || atlf == NORMAL || atlf == SCIENTIFIC) {
                                          p->setPen(c);
                                          p->setFont(f);

                                          if(x1<=xmax+1 && x1>=xmin-1)
                                                p->drawText(-fm.width(label)/2,fm.ascent()/2,label);
                                    }
                                    else {      // rich text label
                                          QSimpleRichText *richtext = new QSimpleRichText(label,f);
                                          if(x1<=xmax+1 && x1>=xmin-1) {
                                                QColorGroup cg;
                                                cg.setColor(QColorGroup::Text,c);
                                                richtext->draw(p,-richtext->width()/4, -fm.ascent()/2,QRect(),cg);
                                          }
                                    }
                                    p->restore();
                              }
                              if (axis[k].MinorTicsEnabled() && i != t )
                                    for (int j=1;j <= axis[k].MinorTics()+1;j++) {
                                          int x=0;
                                          if(scale == LINEAR)
                                                x = x1+j*(x2-x1)/(axis[0].MinorTics()+1);
                                          else if (scale == LOG10)
                                                x=(int)(x1+(x2-x1)*log10((double)(j)));
                                          // other scales have no minor tics

                                          if(x<=xmax+1 && x>=xmin-1) { // minor tics
                                                p->setPen(axis[k].TicsColor());
                                                if(k==0) {  // x
                                                      switch(axis[k].TicsPos()) {
                                                      case 0: p->drawLine(x,ymax,x,ymax+5); break;
                                                      case 1: p->drawLine(x,ymax-5,x,ymax); break;
                                                      case 2: p->drawLine(x,ymax-5,x,ymax+5); break;
                                                      case 3: break;
                                                      }
                                                }
                                                else {            // x2
                                                      switch(axis[k].TicsPos()) {
                                                      case 0: p->drawLine(x,ymin-5,x,ymin); break;
                                                      case 1: p->drawLine(x,ymin,x,ymin+5); break;
                                                      case 2: p->drawLine(x,ymin-5,x,ymin+5); break;
                                                      case 3: break;
                                                      }
                                                }
                                                if (gridenabled[tmpi+1]) {
                                                      p->setPen(QPen(axis[k].GridColor(),0,Qt::DotLine));
                                                      p->drawLine(x,ymin,x,ymax);
                                                      p->setPen(Qt::SolidLine);
                                                }
                                          }
                                    }
                        }
                  }
            }
            if(k==1 || k==2) {      // y,y2
                  int tmpi=0;
                  (k==0)?tmpi=2:tmpi=6;

                  if (axis[k].MajorTicsEnabled() && axis[k].enabled()) {
                        int t = axis[k].MajorTics();  // number of major tics
                        int scale = axis[k].Scale();
                        double min = actrange[1].rMin();
                        double max = actrange[1].rMax();
                        switch(scale) {
                        case LOG10: t = (int) log10(max/min)+2; break;
                        case LOG2: t = (int) log2(max/min)+2; break;
                        case LN: t = (int) log(max/min)+2; break;
                        case SQRT : t = (int) (pow(max,2)-pow(min,2))+1; break;
                        }
                        if(t==0) t=-1;

                        for (int i=0;i <= t;i++) {
                              int y1=0,y2=0;

                              switch(scale) {
                              case LINEAR:
                                    y1 = ymin+i*(ymax-ymin)/t;
                                    y2 = ymin+(i+1)*(ymax-ymin)/t;
                                    break;
                              case LOG10: {
                                    double gap = 1.0-log10(pow(10,ceil(log10(min)))/min); // fragment of decade to shift left
                                    double decade = (ymax-ymin)/(log10(max/min));         // width of decade
                                    y1 = ymax-(int)((i-gap)*decade);
                                    y2 = (int) (y1-decade-ceil(fabs(log10(max))));
                                    } break;
                              case LOG2: {
                                    double gap = 1.0-log2(pow(2,ceil(log2(min)))/min);    // fragment of decade to shift left
                                    double decade = (ymax-ymin)/(log2(max/min));          // width of decade
                                    y1 = ymax-(int)((i-gap)*decade);
                                    y2 = (int) (y1-decade-ceil(fabs(log2(max))));
                                    } break;
                              case LN:{
                                    double gap = 1.0-log(pow(M_E,ceil(log(min)))/min);    // fragment of decade to shift left
                                    double decade = (ymax-ymin)/(log(max/min));           // width of decade
                                    y1 = ymax-(int)((i-gap)*decade);
                                    y2 = (int) (y1-decade-ceil(fabs(log(max))));
                                    } break;
                              case SQRT:
                                    y1 = ymax-(int)((sqrt(min*min+i)-min)/(max-min)*(ymax-ymin));
                                    y2 = ymax-(int)((sqrt(min*min+i+1)-min)/(max-min)*(ymax-ymin));
                                    break;
                              }

                              if(y1<=ymax+1 && y1>=ymin-1) { // major tics
                                    p->setPen(axis[k].TicsColor());
                                    if(k==1) {  // y
                                          switch(axis[k].TicsPos()) {
                                          case 0: p->drawLine(xmin-10,y1,xmin,y1); break;
                                          case 1: p->drawLine(xmin,y1,xmin+10,y1); break;
                                          case 2: p->drawLine(xmin-10,y1,xmin+10,y1); break;
                                          case 3: break;
                                          }
                                    }
                                    else {            // y2
                                          switch(axis[k].TicsPos()) {
                                          case 0: p->drawLine(xmax,y1,xmax+10,y1); break;
                                          case 1: p->drawLine(xmax-10,y1,xmax,y1); break;
                                          case 2: p->drawLine(xmax-10,y1,xmax+10,y1); break;
                                          case 3: break;
                                          }
                                    }
                                    if (gridenabled[tmpi]) {
                                          p->setPen(QPen(axis[k].GridColor(),0,Qt::DashLine));
                                          p->drawLine(xmin,y1,xmax,y1);
                                          p->setPen(Qt::SolidLine);
                                    }
                              }
                              if (graphlist->getNumber() > 0) {
                                    QColor c = axis[k].TicsLabelColor();
                                    QFont f = axis[k].TicsFont();
                                    double dy = max-min, value=0;

                                    switch(scale) {
                                    case LINEAR: value = min + (t-i)*dy/t; break;
                                    case LOG10: value = pow(10,ceil(log10(min)))*pow(10.0,i-1); break;
                                    case LOG2: value = pow(2,ceil(log2(min)))*pow(2.0,i-1); break;
                                    case LN: value = pow(M_E,ceil(log(min)))*pow(M_E,i-1); break;
                                    case SQRT: value = min + (t-i)*dy/t; break;
                                    }

                                    // scale and shift value
                                    value = value*axis[k].Scaling()+axis[k].Shift();

                                    int atlf = axis[k].TicsLabelFormat();

                                    QString label = TicLabel(k,atlf,axis[k].TicsLabelPrecision(),
                                          axis[k].DateTimeFormat(),value);

                                    // apply prefix & suffix
                                    label.prepend(axis[k].TicsLabelPrefix());
                                    label.append(axis[k].TicsLabelSuffix());

                                    // draw tic label
                                    QFontMetrics fm(f);
                                    int x1;
                                    int gap = axis[k].TicsLabelGap();
                                    if(k==1)
                                          x1=xmin-gap-fm.ascent();
                                    else
                                          x1=xmax+gap+fm.ascent();
                                          
                                    p->save();
                                    p->translate(x1,y1);
                                    p->rotate(axis[k].TicsLabelRotation());
                                    f.setPointSize((int)(f.pointSize()*size.X()));  // resize tic label
                                    if (atlf == AUTO || atlf == NORMAL || atlf == SCIENTIFIC) {
                                          p->setPen(c);
                                          p->setFont(f);

                                          if(y1<=ymax+1 && y1>=ymin-1)
                                                p->drawText(-fm.width(label)/2,fm.ascent()/2-1,label);
                                    }
                                    else {            // rich text label
                                          QSimpleRichText *richtext = new QSimpleRichText(label,f);
                                          if(y1<=ymax+1 && y1>=ymin-1) {
                                                QColorGroup cg;
                                                cg.setColor(QColorGroup::Text,c);
                                                richtext->draw(p,-richtext->width(),(int)(-richtext->height()/2.0-1), QRect(),cg);
                                          }
                                    }
                                    p->restore();
                              }
                              if (axis[k].MinorTicsEnabled() && i != t )
                                    for (int j=1;j <= axis[k].MinorTics()+1;j++) {
                                          int y=0;
                                          if(scale == LINEAR)
                                                y = y1+j*(y2-y1)/(axis[k].MinorTics()+1);
                                          else if (scale == LOG10)
                                                y=(int)(y1+(y2-y1)*log10((double)(j)));
                                          // all other scales have minor tics = 0
                                          
                                          if(y<=ymax+1 && y>=ymin-1) { // minor tics
                                                p->setPen(axis[k].TicsColor());
                                                if(k==1) {  // y
                                                      switch(axis[k].TicsPos()) {
                                                      case 0: p->drawLine(xmin-5,y,xmin,y); break;
                                                      case 1: p->drawLine(xmin,y,xmin+5,y); break;
                                                      case 2: p->drawLine(xmin-5,y,xmin+5,y); break;
                                                      case 3: break;
                                                      }
                                                }
                                                else {            // y2
                                                      switch(axis[k].TicsPos()) {
                                                      case 0: p->drawLine(xmax,y,xmax+5,y); break;
                                                      case 1: p->drawLine(xmax-5,y,xmax,y); break;
                                                      case 2: p->drawLine(xmax-5,y,xmax+5,y); break;
                                                      case 3: break;
                                                      }
                                                }
                                                if (gridenabled[tmpi+1]) {
                                                      p->setPen(QPen(axis[k].GridColor(),0,Qt::DotLine));
                                                      p->drawLine(xmin,y,xmax,y);
                                                      p->setPen(Qt::SolidLine);
                                                }
                                          }
                                    }
                              }
                        }
                  }
      }
}

void Plot2D::saveAxes(QTextStream *t) {
      for (int i = 0; i < 4; i++)
            saveAxis(t,&axis[i],gridenabled[2*i],borderenabled[i],gridenabled[2*i+1]);
}

void Plot2D::openAxes(QTextStream *t, int version) {
      for(int i = 0;i<4;i++)
            openAxis(t,version, &axis[i],&gridenabled[2*i],&borderenabled[i],&gridenabled[2*i+1]);
}


Generated by  Doxygen 1.6.0   Back to index