📄 plotxy.h
字号:
if (!_cptbr) fl_draw (_blbl, X+W/2, yi+len+3*_ticfsz/2+1, 0, 0, FL_ALIGN_CENTER); // draw label } if (_lrt>0) // left ruler { // variables int Y = y()+_trt; // position int H = h()-_trt-_brt-_blegh; // height // background fl_color (FL_WHITE); fl_rectf (x(), Y, _lrt, H); // ticks const int len = 9; // tick length Array<double> ticks; // ticks position char buf[256]; // buffer for ticks text _pretty (_Ymin, _Ymax, _lnt, ticks); // find ticks position fl_color (FL_BLACK); // set color fl_line_style (FL_SOLID, 1); // set line style fl_font (0,_ticfsz); // set font for ticks for (size_t i=0; i<ticks.Size(); ++i) { int xi = x()+_lrt-len; // tick initial x-position (screen coordinates) int yi = _y(ticks[i]); // tick initial y-position (screen coordinates) if (yi>=Y && yi<=Y+H) { snprintf (buf, 256, _ltifmt, ticks[i]); // format text fl_line (xi, yi, xi+len, yi); // draw tick mark fl_draw (buf, x()+_lrt-len-2, yi, 0, 0, FL_ALIGN_RIGHT); // draw tick text } } } if (_trt>0) // top ruler { // background fl_color (FL_WHITE); fl_rectf (x(), y(), w(), _trt); // (x()+_lrt, y(), w()-_rrt-_lrt, _trt) // left ruler label and title fl_color (FL_BLACK); // set color fl_font (0,_lblfsz); // set font for label fl_draw (_llbl, x()+2, y()+_trt-2); // draw left label fl_font (0,_titfsz); // set font for title fl_draw (_title, x()+w()/2, y()+_trt-_titfsz/2-2, 0, 0, FL_ALIGN_CENTER); // draw title } if (_rrt>0) // right ruler { // background fl_color (FL_WHITE); fl_rectf (x()+w()-_rrt-_rlegw, y()+_trt, _rrt, h()-_trt-_brt-_blegh); }}inline void PlotXY::DrawLegend(){ // Variables char buf[256]; int xi = x()+5; int yi = y()+h()-_blegh/2; int len = 30; // line length int tlen = 30; // text width int nc = _X.Size(); // number of curves int ilen = 5+len+2+tlen; // icon length int dx = (_cptbr ? 20 : static_cast<int>(static_cast<double>(w()-ilen*nc)/static_cast<double>(nc-1))); int xf = xi+30; // Draw legend fl_font (0,_lblfsz); // set font for labels if (_legatbot) // bottom legend { // background fl_color (FL_WHITE); fl_rectf (x(), y()+h()-_blegh, w(), _blegh); // Draw legend if (_X.Size()>=1 && _Y.Size()>=1) { size_t k = 0; while (k<_X.Size()) { // Check if (_X[k]==NULL || _Y[k]==NULL) return; if (_X[k]->Size()!=_Y[k]->Size()) throw new Fatal("PlotXY::DrawLegend(): (%s) X(%s)[%d] and Y(%s)[%d] must have the same size",_title,_blbl,_X[k]->Size(),_llbl,_Y[k]->Size()); // Draw points if (_C[k].Typ==CT_POINTS || _C[k].Typ==CT_BOTH) { fl_color (_C[k].Clr); fl_line_style (FL_SOLID, 1); if (_C[k].Pch==1) // Open circle { fl_circle (xi+len/2, yi, _C[k].Psz/2); } else if (_C[k].Pch==16) // Filled circle { int r = _C[k].Psz/2; for (size_t i=0; i<_X[k]->Size(); ++i) fl_pie (xi+len/2-r, yi-r, 2*r+1, 2*r+1, 0,360); } } // Draw lines if (_C[k].Typ==CT_LINES || _C[k].Typ==CT_BOTH) { if (_X[k]->Size()>1) { fl_color (_C[k].Clr); fl_line_style (_C[k].Lty, _C[k].Lwd); fl_line (xi, yi, xf, yi); } } // Draw names snprintf (buf, 256, "%s", _C[k].Nam); // format text fl_color (FL_BLACK); fl_draw (buf, xf+2, yi, 0, 0, FL_ALIGN_LEFT); // draw name // Next curve xi += ilen+dx; xf = xi+len; k++; } } if (_cptbr) fl_draw (_blbl, x()+w()-3, y()+h()-_ticfsz/2-3, 0, 0, FL_ALIGN_RIGHT); // draw label } else { }}inline PlotXY & PlotXY::BRuler(bool Visible, int nTicks){ _brt = (Visible ? 27+12 : 0); // +12 to account for the label _bnt = nTicks; return (*this);}inline PlotXY & PlotXY::LRuler(bool Visible, int nTicks){ _lrt = (Visible ? 27 : 0); _lnt = nTicks; return (*this);}inline PlotXY & PlotXY::SetBTicksFmt(char const * Fmt, int Size){ strncpy (_btifmt, Fmt, Size); _btifmt[Size]='\0'; return (*this);}inline PlotXY & PlotXY::SetLTicksFmt(char const * Fmt, int Size){ strncpy (_ltifmt, Fmt, Size); _ltifmt[Size]='\0'; return (*this);}inline void PlotXY::draw(){ // Clear the background fl_color (FL_WHITE); fl_rectf (x()+_lrt, y()+_trt, w()-_bhpad, h()-_bvpad); // Calculate scale factors and draw rulers if (_recsf || !_sfok) { CalcSF (); DrawRulers (); DrawLegend (); _sfok = true; } // Draw Curves if (_X.Size()>=1 && _Y.Size()>=1) { size_t k = 0; while (k<_X.Size()) { // Check if (_X[k]==NULL || _Y[k]==NULL) break; if (_X[k]->Size()!=_Y[k]->Size()) throw new Fatal("PlotXY::draw(): (%s) X(%s)[%d] and Y(%s)[%d] must have the same size",_title,_blbl,_X[k]->Size(),_llbl,_Y[k]->Size()); // Draw points if (_C[k].Typ==CT_POINTS || _C[k].Typ==CT_BOTH) { fl_color (_C[k].Clr); fl_line_style (FL_SOLID, 1); if (_C[k].Pch==1) // Open circle { for (size_t i=0; i<_X[k]->Size(); ++i) fl_circle (_x((*_X[k])[i]), _y((*_Y[k])[i]), _C[k].Psz/2); } else if (_C[k].Pch==16) // Filled circle { int r = _C[k].Psz/2; for (size_t i=0; i<_X[k]->Size(); ++i) fl_pie (_x((*_X[k])[i])-r, _y((*_Y[k])[i])-r, 2*r+1, 2*r+1, 0,360); } } // Draw lines if (_C[k].Typ==CT_LINES || _C[k].Typ==CT_BOTH) { if (_X[k]->Size()>1) { fl_color (_C[k].Clr); fl_line_style (_C[k].Lty, _C[k].Lwd); for (long i=0; i<_X[k]->Size()-1; ++i) fl_line (_x((*_X[k])[i]), _y((*_Y[k])[i]), _x((*_X[k])[i+1]), _y((*_Y[k])[i+1])); } } // Next curve k++; } } // Draw border fl_color (FL_BLACK); fl_line_style (FL_SOLID, 1); fl_rect (x()+_lrt, y()+_trt, w()-_bhpad, h()-_bvpad); // Draw an all-around frame if (_wframe) fl_rect (x(), y(), w(), h());}/* private */inline void PlotXY::_pretty(double Lo, double Hi, int nDiv, Array<double> & Vals){ // Constants const double rounding_eps = 1.0e-7; const double eps_correction = 0.0; const double shrink_sml = 0.75; const double h = 1.5; const double h5 = 0.5+1.5*h; // Local variables int min_n = static_cast<int>(nDiv)/static_cast<int>(3); double lo = Lo; double hi = Hi; double dx = hi-lo; double cell = 1; // cell := "scale" here double ub = 0; // upper bound on cell/unit bool isml = true; // is small ? // Check range if (!(dx==0 && hi==0)) // hi=lo=0 { cell = (fabs(lo)>fabs(hi) ? fabs(lo) : fabs(hi)); ub = (1+(h5>=1.5*h+.5) ? 1/(1+h) : 1.5/(1+h5)); isml = (dx<cell*ub*(nDiv>1 ? nDiv : 1)*DBL_EPSILON*3); // added times 3, as several calculations here } // Set cell if (isml) { if (cell>10) cell = 9 + cell/10; cell *= shrink_sml; if (min_n>1) cell /= min_n; } else { cell = dx; if (nDiv>1) cell /= nDiv; } if (cell<20*DBL_MIN) cell = 20*DBL_MIN; // very small range.. corrected else if (cell*10>DBL_MAX) cell = .1*DBL_MAX; // very large range.. corrected // Find base and unit double base = pow(10., floor(log10(cell))); // base <= cell < 10*base double unit = base; if ((ub = 2*base)-cell < h*(cell-unit)) { unit = ub; if ((ub = 5*base)-cell < h5*(cell-unit)) { unit = ub; if ((ub =10*base)-cell < h*(cell-unit)) unit = ub; }} // Find number of double ns = floor (lo/unit+rounding_eps); double nu = ceil (hi/unit-rounding_eps); if (eps_correction && (eps_correction>1 || !isml)) { if (lo) lo *= (1-DBL_EPSILON); else lo = -DBL_MIN; if (hi) hi *= (1+DBL_EPSILON); else hi = +DBL_MIN; } while (ns*unit>lo+rounding_eps*unit) ns--; while (nu*unit<hi-rounding_eps*unit) nu++; // Find number of divisions int ndiv = static_cast<int>(.5+nu-ns); if (ndiv<min_n) { int k = min_n-ndiv; if (ns>=0.0) { nu += k/2; ns -= k/2 + k%2; } else { ns -= k/2; nu += k/2 + k%2; } ndiv = min_n; } ndiv++; // Ensure that result covers original range if (ns*unit<lo) lo = ns * unit; if (nu*unit>hi) hi = nu * unit; // Fill array Vals.Resize(ndiv); Vals[0] = lo; for (int i=1; i<ndiv; ++i) { Vals[i] = Vals[i-1]+unit; if (fabs(Vals[i])<MINZERO) Vals[i] = 0.0; }}#endif // MPM_PLOTXY_H/* 2008 (c) Dorival M. Pedroso */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -