Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

sxy_axis.cpp

Go to the documentation of this file.
00001 // =======================================================================
00002 
00003 char *axis_cpp = "$Id: sxy_axis.cpp,v 1.7 2003/03/10 19:27:11 clinio Exp $";
00004 
00005 // =======================================================================
00006 
00007 #include <math.h>
00008 #include <float.h>
00009 
00010 extern "C" {
00011 #include <iup.h>
00012 #include <cd.h>
00013 #include <cdiup.h>
00014 }
00015 
00016 #include "sxy_chart.h"
00017 #include "sxy_axis.h"
00018 #include "sxy_utils.h"
00019 
00020 // =======================================================================
00021 
00022 static const double A_SECOND = 1.0;
00023 static const double A_MINUTE = A_SECOND*60;
00024 static const double A_HOUR = A_MINUTE*60;
00025 static const double A_DAY = A_HOUR*24;
00026 static const double A_MONTH = A_DAY*30;
00027 static const double A_YEAR = A_MONTH*12;
00028 
00029 // .......................................................................
00030 
00034 SXYAxis::SXYAxis(SXYChart* cht, SXYAxisOrientation orient, SXYAxisType atype, 
00035 double xpos, double ypos, double size) {
00036   orientation = orient;
00037   type = atype;
00038   chart = cht;
00039   precision = 0;
00040 
00041   XYCartesian* graph = cht->getXyGraph();
00042   assert(graph);
00043 
00044   int ref_font_size = SXYChart::getFontSizeReference();
00045   double angle;
00046 
00047   if (orientation==HORIZONTAL_AXIS) {
00048     angle = 00.0;
00049     xy_decor_text = new XYMultiRasterText(XY_BLACK, 
00050          ref_font_size, XYRasterText::helvetica, XYRasterText::plain,
00051          XYRasterText::north, XYRasterText::horizontal);
00052 
00053     xy_label = new XYRasterText("x",
00054          XYCoordinate(0.5), XYCoordinate(ypos),
00055          XY_BLUE, ref_font_size+2, XYRasterText::helvetica,
00056          XYRasterText::plain, XYRasterText::center,
00057          XYRasterText::horizontal); 
00058   } 
00059   else {
00060     angle = 90.0;
00061     xy_decor_text = new XYMultiRasterText(XY_BLACK, 
00062          ref_font_size, XYRasterText::helvetica, XYRasterText::plain,
00063          XYRasterText::south, XYRasterText::vertBotTop);
00064 
00065     xy_label = new XYRasterText("y",
00066           XYCoordinate(xpos), XYCoordinate((double)0.5),
00067           XY_BLUE, ref_font_size+2, XYRasterText::helvetica,
00068           XYRasterText::plain, XYRasterText::center,
00069           XYRasterText::vertBotTop); 
00070   }
00071 
00072   assert(xy_decor_text);
00073   assert(xy_label);
00074 
00075   buildDecoratorAxis(angle, xpos, ypos, size);
00076 
00077   assert(xy_decor);
00078   assert(xy_axis);
00079 
00080   title_style = AT_MIDDLE;
00081   scale_orientation = ALIGNED;
00082 
00083   updateTitleStyle();
00084   updateScaleOrientation();
00085 
00086   xy_axis->leftTick((orientation==HORIZONTAL_AXIS ? xyfalse : xytrue));
00087   //xy_axis->leftTick(xytrue);
00088 
00089   graph->insert( xy_axis );
00090   tryScalesAdjust();
00091   graph->calcMaskArea();
00092 }
00093 
00094 // .......................................................................
00095 
00096 SXYAxisType SXYAxis::getType() { 
00097   return type;
00098 }
00099 
00100 // .......................................................................
00101 
00102 void SXYAxis::setPrecision(int p) {
00103   if (p < 0) return;
00104   precision = p;
00105 }
00106 
00107 // .......................................................................
00108 
00109 int SXYAxis::getPixelValue( double position ) {
00110   int xp, yp;
00111   xy_axis->pointInValue(position,xp,yp);
00112   SXYAxisOrientation ori = getOrientation();
00113 
00114   if (ori==HORIZONTAL_AXIS) return xp;
00115   if (ori==VERTICAL_AXIS) return yp;
00116 
00117   assert(0);
00118   return -9999;
00119 }
00120 
00121 // .......................................................................
00122 
00123 double SXYAxis::getPositionValue( int pix ) {
00124   SXYAxisOrientation ori = getOrientation();
00125   int xp, yp;
00126 
00127   if (ori==HORIZONTAL_AXIS) {
00128     xp = pix; yp = -999;
00129     return xy_axis->valueInPoint(xp,yp);
00130   }
00131   else if (ori==VERTICAL_AXIS) {
00132     xp = -999; yp = pix;
00133     return xy_axis->valueInPoint(xp,yp);
00134   }
00135 
00136   assert(0);
00137   return FLT_MAX;
00138 }
00139 
00140 // .......................................................................
00141 
00142 SXYAxisOrientation SXYAxis::getOrientation() { 
00143   return orientation;
00144 }
00145 
00146 // .......................................................................
00147 
00148 void SXYAxis::setColor(long int col) { 
00149    xy_axis->color(col); 
00150 }
00151 
00152 // .......................................................................
00153 
00154 void SXYAxis::buildDecoratorAxis(double angle, double xpos, double ypos,
00155 double size) {
00156   SXYAxisType type = getType();
00157 
00158   if (type == LINEAR_AXIS) {
00159      xy_decor = new XYNumericalScaleDecorator("%.2f", xy_decor_text);
00160 
00161      xy_axis = new XYLinearAxis(0, 10.0, xpos, ypos, XY_BLACK,
00162            size, angle, 1.0, xy_decor, xy_label, xytrue, xytrue);
00163       
00164      xy_axis->min(0);
00165      xy_axis->max(100);
00166      xy_axis->step(10);
00167   }
00168   else if (type == LOG_AXIS) {
00169      xy_decor = new XYLogScaleDecorator("%.2f", xy_decor_text);
00170 
00171      xy_axis = new XYLogAxis(0, 10.0, xpos, ypos, XY_BLACK,
00172            size, angle, 1.0, xy_decor, xy_label, xytrue, xytrue);
00173 
00174      xy_axis->min(1);
00175      xy_axis->max(10);
00176      xy_axis->step(1);
00177   }
00178   else if (type == TIME_AXIS) {
00179      xy_decor = new XYDateScaleDecorator(xy_decor_text);
00180 
00181      xy_axis = new XYLinearAxis(0, 10.0, xpos, ypos, XY_BLACK,
00182            size, angle, 1.0, xy_decor, xy_label, xytrue, xytrue);
00183       
00184      xy_axis->min(0);
00185      xy_axis->max(A_DAY);
00186      xy_axis->step(A_HOUR);
00187   }
00188   else {
00189      assert(0);
00190   }
00191 }
00192 
00193 // .......................................................................
00194 
00195 void SXYAxis::updateScaleOrientation(void) {
00196    if (orientation == HORIZONTAL_AXIS) {
00197       if (scale_orientation == ALIGNED) {
00198          xy_decor_text->orientation( XYText::horizontal );
00199          xy_decor_text->align( XYText::north );
00200       }
00201       else {
00202          xy_decor_text->orientation( XYText::vertBotTop );
00203          xy_decor_text->align( XYText::east );
00204       }
00205    }
00206    else {
00207       if (scale_orientation == ALIGNED) {
00208          xy_decor_text->orientation( XYText::vertBotTop );
00209          xy_decor_text->align( XYText::south );
00210       }
00211       else {
00212          xy_decor_text->orientation( XYText::horizontal );
00213          xy_decor_text->align( XYText::east );
00214       }
00215    }
00216 }
00217 
00218 // .......................................................................
00219 
00220 void SXYAxis::updateTitleStyle(void) {
00221    double aposx, aposy;
00222    if (xy_axis == NULL) return;
00223    xy_axis->position(&aposx, &aposy); 
00224    double as = xy_axis->size(); 
00225 
00226    if (orientation == HORIZONTAL_AXIS) {
00227       if (title_style == AT_MIDDLE) {
00228          xy_label->position( aposx + as/2, aposy*2/3 );
00229          xy_label->align( XYText::north );
00230          xy_label->orientation( XYText::horizontal );
00231       }
00232       else if (title_style == AT_END) {
00233          xy_label->position( aposx+as+aposx/3, aposy );
00234          xy_label->align( XYText::west );
00235          xy_label->orientation( XYText::horizontal );
00236       }
00237       else if (title_style == AT_END_ROTATED) {
00238          xy_label->position( aposx+as+aposx/2, aposy );
00239          xy_label->align( XYText::west );
00240          xy_label->orientation( XYText::vertBotTop );
00241       }
00242    }
00243    else {
00244       if (title_style == AT_MIDDLE) {
00245          xy_label->position( aposx*2/3, aposy + as/2 );
00246          xy_label->align( XYText::south );
00247          xy_label->orientation( XYText::vertBotTop );
00248       }
00249       else if (title_style == AT_END) {
00250          xy_label->position( aposx, aposy+as+aposy/3 );
00251          xy_label->align( XYText::west );
00252          xy_label->orientation( XYText::vertBotTop );
00253       }
00254       else if (title_style == AT_END_ROTATED) {
00255          xy_label->position( aposx, aposy+as+aposy/2 );
00256          xy_label->align( XYText::west );
00257          xy_label->orientation( XYText::horizontal );
00258       }
00259    }
00260 }
00261 
00262 // .......................................................................
00263 
00264 void  SXYAxis::setScaleOrientation(SXYAxisScaleOrientation ori) {
00265    scale_orientation = ori;
00266    updateScaleOrientation();
00267 }
00268 
00269 // .......................................................................
00270 
00271 SXYAxisScaleOrientation SXYAxis::getScaleOrientation(void) {
00272    return scale_orientation;
00273 }
00274 
00275 // .......................................................................
00276 
00277 void SXYAxis::setDirection(SXYAxisDirection direction) {
00278   assert(xy_axis!=NULL);
00279   double ang = 45.0;
00280   if (orientation == HORIZONTAL_AXIS) {
00281     if (direction == NORMAL_AXIS) {
00282         ang = 0.0;
00283         xy_axis->leftTick(xyfalse);
00284     }
00285     else {
00286        ang = 180.0;
00287        xy_axis->leftTick(xyfalse);
00288     }
00289   }
00290   else {
00291      if (direction == NORMAL_AXIS) {
00292         xy_axis->leftTick(xytrue);
00293         ang = 90.0;
00294      }
00295      else {
00296         ang = 270.0;
00297         xy_axis->leftTick(xytrue);
00298      }
00299   }
00300   xy_axis->rotation(ang); 
00301   updateScaleOrientation();
00302 }
00303 
00304 // .......................................................................
00305 
00306 SXYAxisDirection SXYAxis::getDirection(void) {
00307   assert(xy_axis!=NULL);
00308   if (orientation == HORIZONTAL_AXIS) {
00309      double ang = xy_axis->rotation();
00310      return ang == 0.0 ? NORMAL_AXIS : INVERTED_AXIS;
00311   }
00312   else {
00313      double ang = xy_axis->rotation();
00314      return ang == 90.0 ? NORMAL_AXIS : INVERTED_AXIS;
00315   }
00316 }
00317 
00318 // .......................................................................
00319 
00320 void  SXYAxis::setTitleStyle(SXYAxisTitleStyle sty) {
00321    title_style = sty;
00322    updateTitleStyle();
00323 }
00324 
00325 // .......................................................................
00326 
00327 SXYAxisTitleStyle SXYAxis::getTitleStyle(void) {
00328    return title_style;
00329 }
00330 
00331 // .......................................................................
00332 
00333 long int SXYAxis::getColor(void) { 
00334    return xy_axis->color(); 
00335 }
00336 
00337 // .......................................................................
00338 
00339 void SXYAxis::setTitleColor(long int col) { 
00340    xy_label->color(col); 
00341 }
00342 
00343 // .......................................................................
00344 
00345 long int SXYAxis::getTitleColor(void) { 
00346    return xy_label->color(); 
00347 }
00348 
00349 // .......................................................................
00350 
00351 void SXYAxis::setScaleColor(long int col) { 
00352    xy_decor_text->color(col); 
00353 }
00354 
00355 // .......................................................................
00356 
00357 long int SXYAxis::getScaleColor(void) { 
00358    return xy_decor_text->color(); 
00359 }
00360 
00361 // .......................................................................
00362 
00363 void SXYAxis::setPosition(double posx, double posy) { 
00364    xy_axis->position( posx, posy ); 
00365    updateTitleStyle();
00366    updateScaleOrientation();
00367 }
00368 
00369 // .......................................................................
00370 
00371 void SXYAxis::getPosition(double& posx, double& posy) { 
00372    double px, py;
00373    xy_axis->position(&px, &py); 
00374    posx = px;
00375    posy = py;
00376 }
00377 
00378 // .......................................................................
00379 
00380 void SXYAxis::setArrowVisibility(int vis) { 
00381    xy_axis->arrow(vis == 1 ? xytrue : xyfalse); 
00382 }
00383 
00384 // .......................................................................
00385 
00386 int SXYAxis::getArrowVisibility(void) { 
00387    return xy_axis->arrow() == xytrue ? 1 : 0; 
00388 }
00389 
00390 
00391 // .......................................................................
00392 
00393 void SXYAxis::setSize(double siz) { 
00394    xy_axis->size(siz); 
00395 }
00396 
00397 // .......................................................................
00398 
00399 double SXYAxis::getSize(void) { 
00400    return xy_axis->size(); 
00401 }
00402 
00403 // .......................................................................
00404 
00406 SXYAxis::~SXYAxis() {
00407    delete xy_decor_text;
00408    xy_decor_text = NULL;
00409 
00410    delete xy_decor;
00411    xy_decor = NULL;
00412 
00413    delete xy_label;
00414    xy_label = NULL;
00415 
00416    delete xy_axis;
00417    xy_axis = NULL;
00418 }
00419 
00420 // .......................................................................
00421 
00422 void SXYAxis::setTitle(char* txt) {
00423   xy_label->text( (const char*)txt );
00424 }
00425 
00426 // .......................................................................
00427 
00428 char* SXYAxis::getTitle(void) {
00429   return xy_label->text();
00430 }
00431 
00432 // .......................................................................
00433 
00434 void SXYAxis::getScales(double& minimum, double& maximum) {
00435   assert(xy_axis != NULL);
00436 //minimum = getDirection() == INVERTED_AXIS ? xy_axis->max() : xy_axis->min();
00437 //maximum = getDirection() == INVERTED_AXIS ? xy_axis->min() : xy_axis->max();
00438   minimum = xy_axis->min();
00439   maximum = xy_axis->max();
00440 }
00441 
00442 // .......................................................................
00443 
00444 void SXYAxis::setZoom(double ratio) {
00445   double vmin, vmax;
00446   getScales(vmin, vmax);
00447 
00448   if ( getType() == LOG_AXIS ) {
00449     double va = log10(vmin);
00450     double vb = log10(vmax);
00451     double dv = ( vb - va ) * -ratio;
00452     va = va - dv;
00453     vb = vb + dv;
00454     vmin = pow( 10, va );
00455     vmax = pow( 10, vb );
00456     if (vmin < 1) setScales(1, vmax);
00457     else setScales(vmin, vmax);
00458   } 
00459   else {
00460     double dv = (vmax - vmin) * -ratio;
00461     setScales(vmin-dv, vmax+dv);
00462   }
00463 }
00464 
00465 // .......................................................................
00466 
00467 void SXYAxis::calcPrecision() {
00468   SXYAxisType type = getType();
00469   if (type == LOG_AXIS) {
00470      setFormat("%.0f");
00471   }
00472   else if (type == LINEAR_AXIS){
00473     double min, max;
00474     getScales(min, max);
00475     char prec[30];
00476     int precision = SXYUtil::calcPrecision(min, max);
00477     sprintf(prec, "%%.%df", precision);
00478     setFormat(prec);
00479   }
00480 }
00481 
00482 // .......................................................................
00483 
00484 double SXYAxis::getStep(void) {
00485   assert(xy_axis != NULL);
00486   return xy_axis->step();
00487 }
00488 
00489 // .......................................................................
00490 
00491 void SXYAxis::tryStepAdjust(void) {
00492   SXYAxisType type = getType();
00493   if (type == LOG_AXIS) {
00494      setStep(1.0);
00495   }
00496   else if (type == LINEAR_AXIS) {
00497     double vmin, vmax;
00498     getScales(vmin, vmax);
00499     double dv = fabs(vmax - vmin) / 10;
00500     setStep(dv);
00501   }
00502   else if (type == TIME_AXIS) {
00503     double vmin, vmax;
00504     getScales(vmin, vmax);
00505     double dv = fabs(vmax - vmin);
00506     if (dv >= A_YEAR) dv = A_MONTH;
00507     else if (dv >= A_MONTH) dv = A_DAY;
00508     else if (dv >= A_DAY) dv = A_HOUR;
00509     else if (dv >= A_HOUR) dv = A_MINUTE;
00510     else dv = dv/6;
00511     setStep(dv);
00512   }
00513 }
00514 
00515 // .......................................................................
00516 
00517 void SXYAxis::tryScalesAdjust(void) {
00518   SXYAxisType type = getType();
00519   if (type == LOG_AXIS) {
00520     double vmin, vmax;
00521     getScales(vmin, vmax);
00522     int imin = (int)floor(log10(vmin));
00523     int imax = (int)ceil(log10(vmax));
00524     if (imin == imax) imax = imin +1;
00525     vmin = pow(10, imin);
00526     vmax = pow(10, imax);
00527     setScales(vmin, vmax);
00528   }
00529   else if (type == LINEAR_AXIS) {
00530     double vmin, vmax;
00531     getScales(vmin, vmax);
00532     double dv = (vmax - vmin) / 10;
00533     if (dv > 1) {
00534        vmin = floor(vmin);
00535        vmax = ceil(vmax);
00536     }
00537     setScales(vmin, vmax);
00538   }
00539   else if (type == TIME_AXIS) {
00540     double vmin, vmax;
00541     getScales(vmin, vmax);
00542     double dv = (vmax - vmin);
00543     if (dv < A_HOUR) {
00544        vmin = floor(vmin/A_MINUTE)*A_MINUTE;
00545        vmax = ceil(vmax/A_MINUTE)*A_MINUTE;
00546     }
00547     else if (dv < A_DAY) {
00548        vmin = floor(vmin/A_HOUR)*A_HOUR;
00549        vmax = ceil(vmax/A_HOUR)*A_HOUR;
00550     }
00551     else {
00552        vmin = floor(vmin/A_DAY)*A_DAY;
00553        vmax = ceil(vmax/A_DAY)*A_DAY;
00554     }
00555     setScales(vmin, vmax);
00556   }
00557 
00558   tryStepAdjust();
00559   if (precision == 0) {
00560      calcPrecision();
00561   }
00562   else {
00563     SXYAxisType type = getType();
00564     if (type == LOG_AXIS) {
00565        setFormat("%.0f");
00566     }
00567     else if (type == LINEAR_AXIS) {
00568       char prec[30];
00569       sprintf(prec, "%%.%df", precision);
00570       setFormat(prec);
00571     }
00572   }
00573 }
00574 
00575 // .......................................................................
00576 
00577 void SXYAxis::setVisibility(int flag) {
00578   assert(xy_axis);
00579   xy_axis->visible(flag ? xytrue : xyfalse);
00580 }
00581 
00582 // .......................................................................
00583 
00584 int SXYAxis::getVisibility(void) {
00585   assert(xy_axis);
00586   return xy_axis->visible() == xytrue ? 1 : 0;
00587 }
00588 
00589 // .......................................................................
00590 
00591 void SXYAxis::setFormat(char* fmt) {
00592   assert(xy_decor);
00593   if (type == LINEAR_AXIS) {
00594       ((XYNumericalScaleDecorator*)xy_decor)->format(fmt);
00595   }
00596   else if (type == LOG_AXIS) {
00597      ((XYLogScaleDecorator*)xy_decor)->format(fmt);
00598   }
00599   else {
00600     assert(type != TIME_AXIS);
00601     assert(0);
00602   }
00603 }
00604 
00605 // .......................................................................
00606 
00607 char* SXYAxis::getFormat(void) {
00608   assert(xy_decor);
00609   if (type == LINEAR_AXIS) 
00610      return ((XYNumericalScaleDecorator*)xy_decor)->format();
00611   else 
00612      return ((XYLogScaleDecorator*)xy_decor)->format();
00613 
00614   assert(0);
00615   return NULL;
00616 }
00617 
00618 
00619 // .......................................................................
00620 
00621 void SXYAxis::setScales(double minimum, double maximum) {
00622   assert(xy_axis != NULL);
00623   assert(minimum < maximum);
00624   if (type == LOG_AXIS && minimum < 1e-15) minimum = 1;
00625 // double mi = getDirection() == INVERTED_AXIS ? maximum : minimum;
00626 // double ma = getDirection() == INVERTED_AXIS ? minimum : maximum;
00627 //printf( "%d) min=%f, max=%f\n", (int)orientation, mi, ma );
00628 //fflush(stdout);
00629   xy_axis->min(minimum);
00630   xy_axis->max(maximum);
00631 }
00632 
00633 // .......................................................................
00634 
00635 void SXYAxis::setStep(double step) {
00636   assert(xy_axis != NULL);
00637   xy_axis->step( fabs(step) );
00638 }
00639 
00640 // .......................................................................
00641 
00642 XYRasterText* SXYAxis::getXyDecorator(void) { 
00643   return xy_decor_text; 
00644 }
00645 
00646 // .......................................................................
00647 
00648 XYRasterText* SXYAxis::getXyTitle(void) { 
00649   return xy_label; 
00650 }
00651 
00652 // .......................................................................
00653 
00654 XYAxis* SXYAxis::getXyAxis(void) { 
00655   return xy_axis; 
00656 }
00657 
00658 // .......................................................................
00659 
00660 void SXYAxis::setLayoutFrom(SXYAxis* other) {
00661    setTitle( other->getTitle() );
00662    setVisibility( other->getVisibility() );
00663    setArrowVisibility( other->getArrowVisibility() );
00664    setTitleStyle( other->getTitleStyle() );
00665    setScaleOrientation( other->getScaleOrientation() );
00666 
00667    setSize( other->getSize() );
00668 
00669    double posx, posy;
00670    other->getPosition(posx, posy);
00671    setPosition(posx, posy);
00672    setDirection(other->getDirection());
00673 
00674    setColor( other->getColor() );
00675    setScaleColor( other->getScaleColor() );
00676    setTitleColor( other->getTitleColor() );
00677 }
00678 
00679 // .......................................................................
00680 
00681 SXYChart* SXYAxis::getChart(void) { 
00682   return chart; 
00683 }
00684 
00685 // .......................................................................
00686 // .......................................................................
00687 // .......................................................................
00688 // .......................................................................
00689 // .......................................................................

SXY
Tecgraf / PUC-Rio - Computer Graphics Technology Group