00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "xysdlg.h"
00013 #include "xyaxlg.h"
00014
00015 const char* xy_id_xyscdtlg_cpp="$Id: xysdlg.cpp,v 1.11 2002/01/23 16:13:05 clinio Exp $";
00016
00017 XYLogScaleDecorator::XYLogScaleDecorator (char *format,
00018 XYText* scale)
00019 : _format(format),
00020 _scale(scale)
00021 {
00022 }
00023
00024 XYLogScaleDecorator::~XYLogScaleDecorator (void)
00025 {
00026 }
00027
00028 void XYLogScaleDecorator::format (char* f)
00029 {
00030 _format = f;
00031 }
00032
00033 char* XYLogScaleDecorator::format (void) const
00034 {
00035 return _format;
00036 }
00037
00038 void XYLogScaleDecorator::draw (const XYAxis *axis, int first_tick,
00039 int last_tick) const
00040 {
00041 XYLogAxis* lgax = (XYLogAxis*) axis;
00042 int last_bxmin = -9, last_bymin = -9, last_bxmax = -9, last_bymax = -9;
00043 int bxmin = -5, bymin = -5, bxmax = -5, bymax = -5;
00044
00045
00046 int xmn, ymn, xmx, ymx;
00047 axis -> getViewport(xmn, xmx, ymn, ymx);
00048
00049
00050 _scale -> setViewport(xmn, xmx, ymn, ymx);
00051
00052 double mn = lgax->min();
00053 double mx = lgax->max();
00054 double step = lgax->step();
00055 double size = lgax->size();
00056
00057
00058 double rot_rad = lgax -> rotation() * XY_PI / 180.0;
00059
00060 if (step > 0.0)
00061 {
00062 double xorigin, yorigin;
00063 lgax->position(&xorigin, &yorigin);
00064
00065 double decade_step;
00066 for( double val = mn; val <= mx; val += decade_step )
00067 {
00068 int current_decade = mtDecade(val);
00069 decade_step = pow( 10, current_decade );
00070 double dx, dy;
00071 mtRotate( (log10(val)-log10(mn))*size / (log10(mx)-log10(mn)), 0.0,
00072 rot_rad, &dx, &dy);
00073
00074 double xtick = xorigin + dx;
00075 double ytick = yorigin + dy;
00076
00077 static char c[80];
00078 sprintf (c, _format, val);
00079
00080 _scale->text (c);
00081 _scale->position(xtick, ytick);
00082 _scale->boundingBox(bxmin,bymin,bxmax,bymax);
00083 if ( !mtIntercept(bxmin,bymin,bxmax,bymax,
00084 last_bxmin,last_bymin,last_bxmax,last_bymax) ) {
00085 _scale->draw(xmn, ymn, xmx, ymx);
00086 int dx = (bxmax-bxmin)/10;
00087 int dy = (bymax-bymin)/10;
00088 last_bxmin = bxmin-dx; last_bxmax = bxmax+dx;
00089 last_bymin = bymin-dy; last_bymax = bymax+dy;
00090 }
00091 }
00092 }
00093 }
00094
00095 void XYLogScaleDecorator::boundingBox (const XYAxis *axis, int& bxmin,
00096 int& bymin, int& bxmax,
00097 int& bymax) const
00098 {
00099 XYLogAxis* eixo = (XYLogAxis*) axis;
00100
00101
00102 double dx, dy;
00103 double rot_rad = eixo -> rotation() * XY_PI / 180.0;
00104
00105 mtRotate ((eixo -> step() * eixo -> size()) / (eixo -> max()
00106 - eixo -> min()), 0.0, rot_rad, &dx, &dy);
00107
00108 double ex1, ey1, ex2, ey2;
00109 eixo -> firstTick (ex1, ey1, ex2, ey2);
00110
00111
00112 int xmn, ymn, xmx, ymx;
00113 eixo -> getViewport(xmn, xmx, ymn, ymx);
00114
00115
00116 _scale -> setViewport(xmn, xmx, ymn, ymx);
00117
00118 double tex2 = ex2;
00119 double tey2 = ey2;
00120
00121 int ftx1, ftx2, fty1, fty2;
00122 int ltx1, ltx2, lty1, lty2;
00123
00124
00125
00126
00127
00128
00129 char c[80];
00130 sprintf (c, _format, (int)(eixo -> min() + pow (10, 0)));
00131
00132 _scale -> text (c);
00133 _scale -> position (tex2, tey2);
00134 _scale -> boundingBox(ftx1, fty1, ftx2, fty2);
00135
00136
00137 int total = (int) log10 (eixo -> max() - eixo -> min());
00138
00139
00140 sprintf (c, _format, (int)(eixo -> min() + pow (10, total)));
00141
00142 _scale -> text (c);
00143 _scale -> position (tex2 + dx * total, tey2 + dy * total);
00144 _scale -> boundingBox(ltx1, lty1, ltx2, lty2);
00145
00146
00147
00148 double mor = ((ltx2 - ltx1) > (ftx2 - ftx1)) ? eixo -> min()
00149 + pow (10, total) : eixo -> min() + pow (10, 0);
00150
00151
00152 sprintf (c, _format, (int) mor);
00153
00154 _scale -> text (c);
00155 _scale -> position (tex2, tey2);
00156 _scale -> boundingBox(ftx1, fty1, ftx2, fty2);
00157
00158
00159 tex2 += dx;
00160 tey2 += dy;
00161
00162
00163 sprintf (c, _format, (int) mor);
00164
00165 _scale -> text (c);
00166 _scale -> position (tex2, tey2);
00167 _scale -> boundingBox(ltx1, lty1, ltx2, lty2);
00168
00169
00170 int test_intercept = 1;
00171
00172
00173
00174 while (mtIntercept (ftx1, fty1, ftx2, fty2, ltx1, lty1, ltx2, lty2) != 0)
00175 {
00176 ++test_intercept;
00177
00178
00179 tex2 += dx;
00180 tey2 += dy;
00181
00182
00183 sprintf (c, _format, (int) mor);
00184
00185 _scale -> text (c);
00186 _scale -> position (tex2, tey2);
00187 _scale -> boundingBox(ltx1, lty1, ltx2, lty2);
00188 }
00189
00190
00191 double xmin = ex2;
00192 double xmax = ex2;
00193 double ymin = ey2;
00194 double ymax = ey2;
00195
00196 int x1, x2, y1, y2;
00197 double wx1, wy1, wx2, wy2;
00198
00199 for (int ntick = 0; ntick <= total; ++ntick)
00200 {
00201 if ((ntick % test_intercept) == 0)
00202 {
00203
00204 sprintf (c, _format, (int)(eixo -> min() + pow (10, ntick)));
00205
00206
00207 _scale -> text (c);
00208 _scale -> position (ex2, ey2);
00209
00210
00211 _scale -> boundingBox (x1, y1, x2, y2);
00212
00213 wdCanvas2World (x1, y1, &wx1, &wy1);
00214 wdCanvas2World (x2, y2, &wx2, &wy2);
00215
00216
00217 xmin = MIN3 (xmin, wx1, wx2);
00218 xmax = MAX3 (xmax, wx1, wx2);
00219 ymin = MIN3 (ymin, wy1, wy2);
00220 ymax = MAX3 (ymax, wy1, wy2);
00221 }
00222
00223
00224 ex2 += dx;
00225 ey2 += dy;
00226 }
00227
00228 wdWorld2Canvas (xmin, ymin, &bxmin, &bymin);
00229 wdWorld2Canvas (xmax, ymax, &bxmax, &bymax);
00230 }
00231