00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef MECHSYS_WXGRAPH_H
00023 #define MECHSYS_WXGRAPH_H
00024
00025 #include <sstream>
00026 #include <iomanip>
00027 #include <wx/frame.h>
00028 #include <wx/dcbuffer.h>
00029
00030 #ifdef HAVE_CONFIG_H
00031 #include "config.h"
00032 #else
00033 #ifndef REAL
00034 #define REAL double
00035 #endif
00036 #endif
00037
00038 #include "util/array.h"
00039 #include "util/lineparser.h"
00040
00041 #include "gui/wxcurve.h"
00042 #include "gui/wxruler.h"
00043 #include "gui/wxgrid.h"
00044
00045 class WxGraph : public wxWindow
00046 {
00047 public:
00048
00049 WxGraph (wxFrame * Parent, wxSize Size=wxDefaultSize);
00050 WxGraph (wxFrame * Parent, String const & BgPenColor, String const & BgColor, wxSize Size=wxDefaultSize);
00051 ~WxGraph ();
00052
00053
00054 void RePaint();
00055
00056
00057 void OnPaint (wxPaintEvent & Event);
00058 void OnEraseBackground (wxEraseEvent & Event);
00059 void OnSize (wxSizeEvent & Event);
00060
00061
00062 WxGraph & EqualScales(bool Val=false) { _td.EqScales=Val; return (*this); }
00063
00064
00065 WxCurve & AddCurve (Array<REAL> const & X, Array<REAL> const & Y);
00066 WxCurve & AddCurve (REAL const * X, REAL const * Y, int Size);
00067 WxCurve & AddCurve (REAL x_min, REAL x_max, REAL y_min, REAL y_max, int nDiv, REAL DelPctX=0.1, REAL DelPctY=0.1);
00068 WxCurve & ResetCurve (int i, REAL const * X, REAL const * Y, int Size);
00069 WxCurve & ResetCurve (int i, Array<REAL> const & X, Array<REAL> const & Y);
00070 WxCurve & ResetCurve (int i, REAL x_min, REAL x_max, REAL y_min, REAL y_max, int nDiv, REAL DelPctX=0.1, REAL DelPctY=0.1);
00071 WxCurve & SetContour (int i, int nLevels, REAL const * Levels);
00072 WxCurve & EnableCurve (int i, bool Enabled);
00073 WxRuler & XRuler () { return _x_ruler; }
00074 WxRuler & YRuler () { return _y_ruler; }
00075 WxRuler & X2Ruler () { return _x2_ruler; }
00076 WxRuler & Y2Ruler () { return _y2_ruler; }
00077 WxCurve & GetCurve (int i) { return (*_curves[i]); }
00078 WxGrid & Grid () { return _grid; }
00079 void DelCurve (size_t i) { if (i<_curves.size()) { delete _curves[i]; _curves.erase(_curves.begin()+i); } }
00080
00081 private:
00082
00083 DECLARE_EVENT_TABLE()
00084
00085 WxTransformData _td;
00086 Array<WxCurve*> _curves;
00087 wxPen _bg_pen;
00088 wxBrush _bg_brush;
00089
00090 WxRuler _x_ruler;
00091 WxRuler _y_ruler;
00092 WxRuler _x2_ruler;
00093 WxRuler _y2_ruler;
00094
00095 WxGrid _grid;
00096
00097
00098 void _bounding_box ();
00099 void _paint_background (wxDC & DC);
00100 void _draw_graph (wxDC & DC);
00101 void _calc_size ();
00102 };
00103
00104
00106
00107
00108 inline WxGraph::WxGraph(wxFrame * Parent, wxSize Size)
00109 : wxWindow (Parent, wxID_ANY, wxDefaultPosition, Size, wxFULL_REPAINT_ON_RESIZE),
00110 _bg_pen (_T("blue"),1,wxSOLID),
00111 _bg_brush (static_cast<wxColour>(GetBackgroundColour()), wxSOLID)
00112 {
00113
00114 _td.EqScales = false;
00115
00116
00117 _x_ruler .Position(WxRuler::POS_BOTTOM);
00118 _y_ruler .Position(WxRuler::POS_LEFT );
00119 _x2_ruler.Position(WxRuler::POS_TOP );
00120 _y2_ruler.Position(WxRuler::POS_RIGHT );
00121 }
00122
00123 inline WxGraph::WxGraph(wxFrame * Parent, String const & BgPenColor, String const & BgColor, wxSize Size)
00124 : wxWindow (Parent, wxID_ANY, wxDefaultPosition, Size, wxFULL_REPAINT_ON_RESIZE),
00125 _bg_pen (BgPenColor,1,wxSOLID),
00126 _bg_brush (BgColor,wxSOLID)
00127 {
00128
00129 _td.EqScales = false;
00130
00131
00132 _x_ruler .Position(WxRuler::POS_BOTTOM);
00133 _y_ruler .Position(WxRuler::POS_LEFT );
00134 _x2_ruler.Position(WxRuler::POS_TOP );
00135 _y2_ruler.Position(WxRuler::POS_RIGHT );
00136 }
00137
00138 inline WxGraph::~WxGraph()
00139 {
00140 for (size_t i=0; i<_curves.size(); ++i)
00141 delete _curves[i];
00142 }
00143
00144 inline void WxGraph::RePaint()
00145 {
00146 _calc_size();
00147 this->Refresh();
00148 this->Update();
00149 }
00150
00151 inline void WxGraph::OnPaint(wxPaintEvent & Event)
00152 {
00153
00154 wxBufferedPaintDC dc(this);
00155 PrepareDC(dc);
00156
00157
00158 _paint_background(dc);
00159
00160
00161 _draw_graph(dc);
00162 }
00163
00164 inline void WxGraph::OnEraseBackground(wxEraseEvent & Event)
00165 {
00166
00167 }
00168
00169 inline void WxGraph::OnSize(wxSizeEvent & Event)
00170 {
00171 _calc_size();
00172 }
00173
00174 inline WxCurve & WxGraph::AddCurve(Array<REAL> const & X, Array<REAL> const & Y)
00175 {
00176 WxCurve * C = new WxCurve (X,Y);
00177 _curves.push_back(C);
00178 _bounding_box();
00179 return (*C);
00180 }
00181
00182 inline WxCurve & WxGraph::AddCurve(REAL const * X, REAL const * Y, int Size)
00183 {
00184 WxCurve * C = new WxCurve (X,Y,Size);
00185 _curves.push_back(C);
00186 _bounding_box();
00187 return (*C);
00188 }
00189
00190 inline WxCurve & WxGraph::AddCurve(REAL x_min, REAL x_max, REAL y_min, REAL y_max, int nDiv, REAL DelPctX, REAL DelPctY)
00191 {
00192 WxCurve * C = new WxCurve (x_min,x_max, y_min,y_max, nDiv, DelPctX, DelPctY);
00193 _curves.push_back(C);
00194 _bounding_box();
00195 return (*C);
00196 }
00197
00198 inline WxCurve & WxGraph::ResetCurve(int i, REAL const * X, REAL const * Y, int Size)
00199 {
00200
00201 _curves[i]->ResetData(X, Y, Size);
00202 _bounding_box();
00203
00204
00205 RePaint();
00206
00207
00208 return (*_curves[i]);
00209 }
00210
00211 inline WxCurve & WxGraph::ResetCurve(int i, Array<REAL> const & X, Array<REAL> const & Y)
00212 {
00213
00214 _curves[i]->ResetData(X, Y);
00215 _bounding_box();
00216
00217
00218 RePaint();
00219
00220
00221 return (*_curves[i]);
00222 }
00223
00224 inline WxCurve & WxGraph::ResetCurve(int i, REAL x_min, REAL x_max, REAL y_min, REAL y_max, int nDiv, REAL DelPctX, REAL DelPctY)
00225 {
00226
00227 _curves[i]->ResetData(x_min, x_max, y_min, y_max, nDiv, DelPctX, DelPctY);
00228 _bounding_box();
00229
00230
00231 RePaint();
00232
00233
00234 return (*_curves[i]);
00235 }
00236
00237 inline WxCurve & WxGraph::SetContour(int i, int nLevels, REAL const * Levels)
00238 {
00239 _curves[i]->SetContour(nLevels, Levels);
00240 _bounding_box();
00241
00242
00243 RePaint();
00244
00245
00246 return (*_curves[i]);
00247 }
00248
00249 inline WxCurve & WxGraph::EnableCurve(int i, bool Enabled)
00250 {
00251
00252 _curves[i]->Enable(Enabled);
00253
00254
00255 return (*_curves[i]);
00256 }
00257
00258 inline void WxGraph::_bounding_box()
00259 {
00260 if (_curves.size()==0) return;
00261
00262 _curves[0]->GetRange(_td.xMin, _td.xMax, _td.yMin, _td.yMax);
00263
00264 for (size_t i=1; i<_curves.size(); ++i)
00265 {
00266 REAL min_x; REAL max_x;
00267 REAL min_y; REAL max_y;
00268 _curves[i]->GetRange(min_x, max_x, min_y, max_y);
00269 if (min_x<_td.xMin) _td.xMin=min_x;
00270 if (max_x>_td.xMax) _td.xMax=max_x;
00271 if (min_y<_td.yMin) _td.yMin=min_y;
00272 if (max_y>_td.yMax) _td.yMax=max_y;
00273 }
00274
00275 _td.xRange = _td.xMax - _td.xMin;
00276 _td.yRange = _td.yMax - _td.yMin;
00277 }
00278
00279 inline void WxGraph::_paint_background(wxDC & DC)
00280 {
00281 DC.SetBrush(_bg_brush);
00282 DC.SetPen (_bg_pen);
00283 wxRect win_rect(wxPoint(0,0), GetClientSize());
00284 DC.DrawRectangle(win_rect);
00285 }
00286
00287 inline void WxGraph::_draw_graph(wxDC & DC)
00288 {
00289 if (_curves.size()>0)
00290 {
00291
00292 _grid.Draw(DC);
00293
00294
00295 _x_ruler .Draw(DC);
00296 _y_ruler .Draw(DC);
00297 _x2_ruler.Draw(DC);
00298 _y2_ruler.Draw(DC);
00299
00300
00301 for (size_t i=0; i<_curves.size(); ++i)
00302 {
00303 _curves[i]->DrawLine (DC);
00304 _curves[i]->DrawPoints(DC);
00305 }
00306 }
00307 }
00308
00309 inline void WxGraph::_calc_size()
00310 {
00311
00312 _td.CanvasRect.x = 0;
00313 _td.CanvasRect.y = 0;
00314 GetClientSize(&_td.CanvasRect.width, &_td.CanvasRect.height);
00315
00316
00317 if (_x_ruler .IsActive()) _td.CanvasRect.height -= _x_ruler .Thick();
00318 if (_y_ruler .IsActive()) { _td.CanvasRect.x = _y_ruler .Thick(); _td.CanvasRect.width -= _y_ruler .Thick(); }
00319 if (_x2_ruler.IsActive()) { _td.CanvasRect.y = _x2_ruler.Thick(); _td.CanvasRect.height -= _x2_ruler.Thick(); }
00320 if (_y2_ruler.IsActive()) _td.CanvasRect.width -= _y2_ruler.Thick();
00321
00322
00323 WxCalcScaleFactor(_td);
00324
00325
00326 _x_ruler .UpdateSize(_td);
00327 _y_ruler .UpdateSize(_td);
00328 _x2_ruler.UpdateSize(_td);
00329 _y2_ruler.UpdateSize(_td);
00330
00331
00332 for (size_t i=0; i<_curves.size(); ++i)
00333 _curves[i]->UpdateSize(_td);
00334
00335
00336 _grid.UpdateSize(_td);
00337
00338 }
00339
00340 BEGIN_EVENT_TABLE(WxGraph, wxWindow)
00341 EVT_PAINT ( WxGraph::OnPaint )
00342 EVT_ERASE_BACKGROUND ( WxGraph::OnEraseBackground )
00343 EVT_SIZE ( WxGraph::OnSize )
00344 END_EVENT_TABLE()
00345
00346 #endif // MECHSYS_WXGRAPH_H
00347
00348