1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: mathplot.cpp 3 // Purpose: Framework for plotting in wxWindows 4 // Original Author: David Schalig 5 // Maintainer: Davide Rondini 6 // Contributors: Jose Luis Blanco, Val Greene 7 // Created: 21/07/2003 8 // Last edit: 22/02/2009 9 // Copyright: (c) David Schalig, Davide Rondini 10 // Licence: wxWindows licence 11 ///////////////////////////////////////////////////////////////////////////// 12 13 #ifndef _MP_MATHPLOT_H_ 14 #define _MP_MATHPLOT_H_ 15 16 /** @file mathplot.h */ 17 /** @mainpage wxMathPlot 18 wxMathPlot is a framework for mathematical graph plotting in wxWindows. 19 20 The framework is designed for convenience and ease of use. 21 22 @section screenshots Screenshots 23 <a href="http://wxmathplot.sourceforge.net/screenshot.shtml">Go to the screenshots page.</a> 24 25 @section overview Overview 26 The heart of wxMathPlot is mpWindow, which is a 2D canvas for plot layers. 27 mpWindow can be embedded as subwindow in a wxPane, a wxFrame, or any other wxWindow. 28 mpWindow provides a zoomable and moveable view of the layers. The current view can 29 be controlled with the mouse, the scrollbars, and a context menu. 30 31 Plot layers are implementations of the abstract base class mpLayer. Those can 32 be function plots, scale rulers, or any other vector data visualisation. wxMathPlot provides two mpLayer implementations for plotting horizontal and vertical rulers: mpScaleX and mpScaleY. 33 For convenient function plotting a series of classes derived from mpLayer are provided, like mpFX, mpProfile, mpLegend and so on. These base classes already come with plot code, user's own functions can be implemented by overriding just one member for retrieving a function value. 34 35 mpWindow has built-in support for mouse-based pan and zoom through intuitive combinations of buttons and the mouse wheel. It also incorporates an optional double buffering mechanism to avoid flicker. Plots can be easily sent to printer evices or exported in bitmap formats like PNG, BMP or JPEG. 36 37 @section coding Coding conventions 38 wxMathPlot sticks to wxWindow's coding conventions. All entities defined by wxMathPlot have the prefix <i>mp</i>. 39 40 @section author Author and license 41 wxMathPlot is published under the terms of the wxWindow license.<br> 42 The original author is David Schalig <mrhill@users.sourceforge.net>.<br> 43 From June 2007 the project is maintained by Davide Rondini <cdron77@users.sourceforge.net>.<br> 44 Authors can be contacted via the wxMathPlot's homepage at 45 https://sourceforge.net/projects/wxmathplot<br> 46 Contributors:<br> 47 Jose Luis Blanco, Val Greene.<br> 48 */ 49 50 //this definition uses windows dll to export function. 51 //WXDLLIMPEXP_MATHPLOT definition definition changed to WXDLLIMPEXP_MATHPLOT 52 //mathplot_EXPORTS will be defined by cmake 53 #ifdef mathplot_EXPORTS 54 #define WXDLLIMPEXP_MATHPLOT WXEXPORT 55 #define WXDLLIMPEXP_DATA_MATHPLOT(type) WXEXPORT type 56 #else // not making DLL 57 #define WXDLLIMPEXP_MATHPLOT 58 #define WXDLLIMPEXP_DATA_MATHPLOT(type) type 59 #endif 60 61 #if defined(__GNUG__) && !defined(__APPLE__) 62 #pragma interface "mathplot.h" 63 #endif 64 65 #include <vector> 66 67 // #include <wx/wx.h> 68 #include <wx/defs.h> 69 #include <wx/menu.h> 70 #include <wx/scrolwin.h> 71 #include <wx/event.h> 72 #include <wx/dynarray.h> 73 #include <wx/pen.h> 74 #include <wx/dcmemory.h> 75 #include <wx/string.h> 76 #include <wx/print.h> 77 #include <wx/image.h> 78 79 80 #include <deque> 81 82 // For memory leak debug 83 #ifdef _WINDOWS 84 #ifdef _DEBUG 85 #include <crtdbg.h> 86 #define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__) 87 #else 88 #define DEBUG_NEW new 89 #endif // _DEBUG 90 #endif // _WINDOWS 91 92 // Separation for axes when set close to border 93 #define X_BORDER_SEPARATION 40 94 #define Y_BORDER_SEPARATION 60 95 96 //----------------------------------------------------------------------------- 97 // classes 98 //----------------------------------------------------------------------------- 99 100 class WXDLLIMPEXP_MATHPLOT mpLayer; 101 class WXDLLIMPEXP_MATHPLOT mpFX; 102 class WXDLLIMPEXP_MATHPLOT mpFY; 103 class WXDLLIMPEXP_MATHPLOT mpFXY; 104 class WXDLLIMPEXP_MATHPLOT mpFXYVector; 105 class WXDLLIMPEXP_MATHPLOT mpScaleX; 106 class WXDLLIMPEXP_MATHPLOT mpScaleY; 107 class WXDLLIMPEXP_MATHPLOT mpWindow; 108 class WXDLLIMPEXP_MATHPLOT mpText; 109 class WXDLLIMPEXP_MATHPLOT mpPrintout; 110 111 /** Command IDs used by mpWindow */ 112 enum 113 { 114 mpID_FIT = 2000, //!< Fit view to match bounding box of all layers 115 mpID_ZOOM_IN, //!< Zoom into view at clickposition / window center 116 mpID_ZOOM_OUT, //!< Zoom out 117 mpID_CENTER, //!< Center view on click position 118 mpID_LOCKASPECT, //!< Lock x/y scaling aspect 119 mpID_HELP_MOUSE //!< Shows information about the mouse commands 120 }; 121 122 //----------------------------------------------------------------------------- 123 // mpLayer 124 //----------------------------------------------------------------------------- 125 126 typedef enum __mp_Layer_Type { 127 mpLAYER_UNDEF, //!< Layer type undefined 128 mpLAYER_AXIS, //!< Axis type layer 129 mpLAYER_PLOT, //!< Plot type layer 130 mpLAYER_INFO, //!< Info box type layer 131 mpLAYER_BITMAP //!< Bitmap type layer 132 } mpLayerType; 133 134 /** Plot layer, abstract base class. 135 Any number of mpLayer implementations can be attached to mpWindow. 136 Examples for mpLayer implementations are function graphs, or scale rulers. 137 138 For convenience mpLayer defines a name, a font (wxFont), a pen (wxPen), 139 and a continuity property (bool) as class members. 140 The default values at constructor are the default font, a black pen, and 141 continuity set to false (draw separate points). 142 These may or may not be used by implementations. 143 */ 144 class WXDLLIMPEXP_MATHPLOT mpLayer : public wxObject 145 { 146 public: 147 mpLayer(); 148 ~mpLayer()149 virtual ~mpLayer() {}; 150 151 /** Check whether this layer has a bounding box. 152 The default implementation returns \a TRUE. Override and return 153 FALSE if your mpLayer implementation should be ignored by the calculation 154 of the global bounding box for all layers in a mpWindow. 155 @retval TRUE Has bounding box 156 @retval FALSE Has not bounding box 157 */ HasBBox()158 virtual bool HasBBox() { return TRUE; } 159 160 /** Check whether the layer is an info box. 161 The default implementation returns \a FALSE. It is overrided to \a TRUE for mpInfoLayer 162 class and its derivative. It is necessary to define mouse actions behaviour over 163 info boxes. 164 @return whether the layer is an info boxes 165 @sa mpInfoLayer::IsInfo */ IsInfo()166 virtual bool IsInfo() { return false; }; 167 168 /** Get inclusive left border of bounding box. 169 @return Value 170 */ GetMinX()171 virtual double GetMinX() { return -1.0; } 172 173 /** Get inclusive right border of bounding box. 174 @return Value 175 */ GetMaxX()176 virtual double GetMaxX() { return 1.0; } 177 178 /** Get inclusive bottom border of bounding box. 179 @return Value 180 */ GetMinY()181 virtual double GetMinY() { return -1.0; } 182 183 /** Get inclusive top border of bounding box. 184 @return Value 185 */ GetMaxY()186 virtual double GetMaxY() { return 1.0; } 187 188 /** Plot given view of layer to the given device context. 189 An implementation of this function has to transform layer coordinates to 190 wxDC coordinates based on the view parameters retrievable from the mpWindow 191 passed in \a w. 192 Note that the public methods of mpWindow: x2p,y2p and p2x,p2y are already provided 193 which transform layer coordinates to DC pixel coordinates, and <b>user code should rely 194 on them</b> for portability and future changes to be applied transparently, instead of 195 implementing the following formulas manually. 196 197 The passed device context \a dc has its coordinate origin set to the top-left corner 198 of the visible area (the default). The coordinate orientation is as shown in the 199 following picture: 200 <pre> 201 (wxDC origin 0,0) 202 x-------------> ascending X ----------------+ 203 | | 204 | | 205 V ascending Y | 206 | | 207 | | 208 | | 209 +-------------------------------------------+ <-- right-bottom corner of the mpWindow visible area. 210 </pre> 211 Note that Y ascends in downward direction, whereas the usual vertical orientation 212 for mathematical plots is vice versa. Thus Y-orientation will be swapped usually, 213 when transforming between wxDC and mpLayer coordinates. This change of coordinates 214 is taken into account in the methods p2x,p2y,x2p,y2p. 215 216 <b> Rules for transformation between mpLayer and wxDC coordinates </b> 217 @code 218 dc_X = (layer_X - mpWindow::GetPosX()) * mpWindow::GetScaleX() 219 dc_Y = (mpWindow::GetPosY() - layer_Y) * mpWindow::GetScaleY() // swapping Y-orientation 220 221 layer_X = (dc_X / mpWindow::GetScaleX()) + mpWindow::GetPosX() // scale guaranteed to be not 0 222 layer_Y = mpWindow::GetPosY() - (dc_Y / mpWindow::GetScaleY()) // swapping Y-orientation 223 @endcode 224 225 @param dc Device context to plot to. 226 @param w View to plot. The visible area can be retrieved from this object. 227 @sa mpWindow::p2x,mpWindow::p2y,mpWindow::x2p,mpWindow::y2p 228 */ 229 virtual void Plot(wxDC & dc, mpWindow & w) = 0; 230 231 /** Get layer name. 232 @return Name 233 */ GetName()234 wxString GetName() const { return m_name; } 235 236 /** Get font set for this layer. 237 @return Font 238 */ GetFont()239 const wxFont& GetFont() const { return m_font; } 240 241 /** Get pen set for this layer. 242 @return Pen 243 */ GetPen()244 const wxPen& GetPen() const { return m_pen; } 245 246 /** Set the 'continuity' property of the layer (true:draws a continuous line, false:draws separate points). 247 * @sa GetContinuity 248 */ SetContinuity(bool continuity)249 void SetContinuity(bool continuity) {m_continuous = continuity;} 250 251 /** Gets the 'continuity' property of the layer. 252 * @sa SetContinuity 253 */ GetContinuity()254 bool GetContinuity() const {return m_continuous;} 255 256 /** Shows or hides the text label with the name of the layer (default is visible). 257 */ ShowName(bool show)258 void ShowName(bool show) { m_showName = show; }; 259 260 /** Set layer name 261 @param name Name, will be copied to internal class member 262 */ SetName(wxString name)263 void SetName(wxString name) { m_name = name; } 264 265 /** Set layer font 266 @param font Font, will be copied to internal class member 267 */ SetFont(wxFont & font)268 void SetFont(wxFont& font) { m_font = font; } 269 270 /** Set layer pen 271 @param pen Pen, will be copied to internal class member 272 */ SetPen(wxPen pen)273 void SetPen(wxPen pen) { m_pen = pen; } 274 275 /** Set Draw mode: inside or outside margins. Default is outside, which allows the layer to draw up to the mpWindow border. 276 @param drawModeOutside The draw mode to be set */ SetDrawOutsideMargins(bool drawModeOutside)277 void SetDrawOutsideMargins(bool drawModeOutside) { m_drawOutsideMargins = drawModeOutside; }; 278 279 /** Get Draw mode: inside or outside margins. 280 @return The draw mode */ GetDrawOutsideMargins()281 bool GetDrawOutsideMargins() { return m_drawOutsideMargins; }; 282 283 /** Get a small square bitmap filled with the colour of the pen used in the layer. Useful to create legends or similar reference to the layers. 284 @param side side length in pixels 285 @return a wxBitmap filled with layer's colour */ 286 wxBitmap GetColourSquare(int side = 16); 287 288 /** Get layer type: a Layer can be of different types: plot lines, axis, info boxes, etc, this method returns the right value. 289 @return An integer indicating layer type */ GetLayerType()290 mpLayerType GetLayerType() { return m_type; }; 291 292 /** Checks whether the layer is visible or not. 293 @return \a true if visible */ IsVisible()294 bool IsVisible() {return m_visible; }; 295 296 /** Sets layer visibility. 297 @param show visibility bool. */ SetVisible(bool show)298 void SetVisible(bool show) { m_visible = show; }; 299 300 /** Get brush set for this layer. 301 @return brush. */ GetBrush()302 const wxBrush& GetBrush() const { return m_brush; }; 303 304 /** Set layer brush 305 @param brush brush, will be copied to internal class member */ SetBrush(wxBrush brush)306 void SetBrush(wxBrush brush) { m_brush = brush; }; 307 308 protected: 309 wxFont m_font; //!< Layer's font 310 wxPen m_pen; //!< Layer's pen 311 wxBrush m_brush; //!< Layer's brush 312 wxString m_name; //!< Layer's name 313 bool m_continuous; //!< Specify if the layer will be plotted as a continuous line or a set of points. 314 bool m_showName; //!< States whether the name of the layer must be shown (default is true). 315 bool m_drawOutsideMargins; //!< select if the layer should draw only inside margins or over all DC 316 mpLayerType m_type; //!< Define layer type, which is assigned by constructor 317 bool m_visible; //!< Toggles layer visibility 318 DECLARE_DYNAMIC_CLASS(mpLayer) 319 }; 320 321 322 //----------------------------------------------------------------------------- 323 // mpInfoLayer 324 //----------------------------------------------------------------------------- 325 326 /** @class mpInfoLayer 327 @brief Base class to create small rectangular info boxes 328 mpInfoLayer is the base class to create a small rectangular info box in transparent overlay over plot layers. It is used to implement objects like legends. 329 */ 330 class WXDLLIMPEXP_MATHPLOT mpInfoLayer : public mpLayer 331 { 332 public: 333 /** Default constructor. */ 334 mpInfoLayer(); 335 336 /** Complete constructor. 337 @param rect Sets the initial size rectangle of the layer. 338 @param brush pointer to a fill brush. Default is transparent */ 339 mpInfoLayer(wxRect rect, const wxBrush* brush = wxTRANSPARENT_BRUSH); 340 341 /** Destructor */ 342 virtual ~mpInfoLayer(); 343 344 /** Updates the content of the info box. Should be overidden by derived classes. 345 Update may behave in different ways according to the type of event which called it. 346 @param w parent mpWindow from which to obtain informations 347 @param event The event which called the update. */ 348 virtual void UpdateInfo(mpWindow& w, wxEvent& event); 349 350 /** mpInfoLayer has not bounding box. @sa mpLayer::HasBBox 351 @return always \a FALSE */ HasBBox()352 virtual bool HasBBox() { return false; }; 353 354 /** Plot method. Can be overidden by derived classes. 355 @param dc the device content where to plot 356 @param w the window to plot 357 @sa mpLayer::Plot */ 358 virtual void Plot(wxDC & dc, mpWindow & w); 359 360 /** Specifies that this is an Info box layer. 361 @return always \a TRUE 362 @sa mpLayer::IsInfo */ IsInfo()363 virtual bool IsInfo() { return true; }; 364 365 /** Checks whether a point is inside the info box rectangle. 366 @param point The point to be checked 367 @return \a true if the point is inside the bounding box */ 368 virtual bool Inside(wxPoint& point); 369 370 /** Moves the layer rectangle of given pixel deltas. 371 @param delta The wxPoint container for delta coordinates along x and y. Units are in pixels. */ 372 virtual void Move(wxPoint delta); 373 374 /** Updates the rectangle reference point. Used by internal methods of mpWindow to correctly move mpInfoLayers. */ 375 virtual void UpdateReference(); 376 377 /** Returns the position of the upper left corner of the box (in pixels) 378 @return The rectangle position */ 379 wxPoint GetPosition(); 380 381 /** Returns the size of the box (in pixels) 382 @return The rectangle size */ 383 wxSize GetSize(); 384 385 /** Returns the current rectangle coordinates. 386 @return The info layer rectangle */ GetRectangle()387 const wxRect& GetRectangle() { return m_dim; }; 388 389 protected: 390 wxRect m_dim; //!< The bounding rectangle of the box. It may be resized dynamically by the Plot method. 391 wxPoint m_reference; //!< Holds the reference point for movements 392 wxBrush m_brush; //!< The brush to be used for the background 393 int m_winX, m_winY; //!< Holds the mpWindow size. Used to rescale position when window is resized. 394 395 DECLARE_DYNAMIC_CLASS(mpInfoLayer) 396 }; 397 398 /** @class mpInfoCoords 399 @brief Implements an overlay box which shows the mouse coordinates in plot units. 400 When an mpInfoCoords layer is activated, when mouse is moved over the mpWindow, its coordinates (in mpWindow units, not pixels) are continuously reported inside the layer box. */ 401 class WXDLLIMPEXP_MATHPLOT mpInfoCoords : public mpInfoLayer 402 { 403 public: 404 /** Default constructor */ 405 mpInfoCoords(); 406 /** Complete constructor, setting initial rectangle and background brush. 407 @param rect The initial bounding rectangle. 408 @param brush The wxBrush to be used for box background: default is transparent */ 409 mpInfoCoords(wxRect rect, const wxBrush* brush = wxTRANSPARENT_BRUSH); 410 411 /** Default destructor */ 412 ~mpInfoCoords(); 413 414 /** Updates the content of the info box. It is used to update coordinates. 415 @param w parent mpWindow from which to obtain information 416 @param event The event which called the update. */ 417 virtual void UpdateInfo(mpWindow& w, wxEvent& event); 418 419 /** Plot method. 420 @param dc the device content where to plot 421 @param w the window to plot 422 @sa mpLayer::Plot */ 423 virtual void Plot(wxDC & dc, mpWindow & w); 424 425 protected: 426 wxString m_content; //!< string holding the coordinates to be drawn. 427 }; 428 429 /** @class mpInfoLegend 430 @brief Implements the legend to be added to the plot 431 This layer allows you to add a legend to describe the plots in the window. The legend uses the layer name as a label, and displays only layers of type mpLAYER_PLOT. */ 432 class WXDLLIMPEXP_MATHPLOT mpInfoLegend : public mpInfoLayer 433 { 434 public: 435 /** Default constructor */ 436 mpInfoLegend(); 437 438 /** Complete constructor, setting initial rectangle and background brush. 439 @param rect The initial bounding rectangle. 440 @param brush The wxBrush to be used for box background: default is transparent 441 @sa mpInfoLayer::mpInfoLayer */ 442 mpInfoLegend(wxRect rect, const wxBrush* brush = wxTRANSPARENT_BRUSH); 443 444 /** Default destructor */ 445 ~mpInfoLegend(); 446 447 /** Updates the content of the info box. Unused in this class. 448 @param w parent mpWindow from which to obtain information 449 @param event The event which called the update. */ 450 virtual void UpdateInfo(mpWindow& w, wxEvent& event); 451 452 /** Plot method. 453 @param dc the device content where to plot 454 @param w the window to plot 455 @sa mpLayer::Plot */ 456 virtual void Plot(wxDC & dc, mpWindow & w); 457 458 protected: 459 460 }; 461 462 463 //----------------------------------------------------------------------------- 464 // mpLayer implementations - functions 465 //----------------------------------------------------------------------------- 466 467 /** @name Label alignment constants 468 @{*/ 469 470 /** @internal */ 471 #define mpALIGNMASK 0x03 472 /** Aligns label to the right. For use with mpFX. */ 473 #define mpALIGN_RIGHT 0x00 474 /** Aligns label to the center. For use with mpFX and mpFY. */ 475 #define mpALIGN_CENTER 0x01 476 /** Aligns label to the left. For use with mpFX. */ 477 #define mpALIGN_LEFT 0x02 478 /** Aligns label to the top. For use with mpFY. */ 479 #define mpALIGN_TOP mpALIGN_RIGHT 480 /** Aligns label to the bottom. For use with mpFY. */ 481 #define mpALIGN_BOTTOM mpALIGN_LEFT 482 /** Aligns X axis to bottom border. For mpScaleX */ 483 #define mpALIGN_BORDER_BOTTOM 0x04 484 /** Aligns X axis to top border. For mpScaleX */ 485 #define mpALIGN_BORDER_TOP 0x05 486 /** Set label for X axis in normal mode */ 487 #define mpX_NORMAL 0x00 488 /** Set label for X axis in time mode: the value is represented as minutes:seconds.milliseconds if time is less than 2 minutes, hours:minutes:seconds otherwise. */ 489 #define mpX_TIME 0x01 490 /** Set label for X axis in hours mode: the value is always represented as hours:minutes:seconds. */ 491 #define mpX_HOURS 0x02 492 /** Set label for X axis in date mode: the value is always represented as yyyy-mm-dd. */ 493 #define mpX_DATE 0x03 494 /** Set label for X axis in datetime mode: the value is always represented as yyyy-mm-ddThh:mm:ss. */ 495 #define mpX_DATETIME 0x04 496 /** Aligns Y axis to left border. For mpScaleY */ 497 #define mpALIGN_BORDER_LEFT mpALIGN_BORDER_BOTTOM 498 /** Aligns Y axis to right border. For mpScaleY */ 499 #define mpALIGN_BORDER_RIGHT mpALIGN_BORDER_TOP 500 /** Aligns label to north-east. For use with mpFXY. */ 501 #define mpALIGN_NE 0x00 502 /** Aligns label to north-west. For use with mpFXY. */ 503 #define mpALIGN_NW 0x01 504 /** Aligns label to south-west. For use with mpFXY. */ 505 #define mpALIGN_SW 0x02 506 /** Aligns label to south-east. For use with mpFXY. */ 507 #define mpALIGN_SE 0x03 508 509 /*@}*/ 510 511 /** @name mpLayer implementations - functions 512 @{*/ 513 514 /** Abstract base class providing plot and labeling functionality for functions F:X->Y. 515 Override mpFX::GetY to implement a function. 516 Optionally implement a constructor and pass a name (label) and a label alignment 517 to the constructor mpFX::mpFX. If the layer name is empty, no label will be plotted. 518 */ 519 class WXDLLIMPEXP_MATHPLOT mpFX : public mpLayer 520 { 521 public: 522 /** @param name Label 523 @param flags Label alignment, pass one of #mpALIGN_RIGHT, #mpALIGN_CENTER, #mpALIGN_LEFT. 524 */ 525 mpFX(wxString name = wxEmptyString, int flags = mpALIGN_RIGHT); 526 527 /** Get function value for argument. 528 Override this function in your implementation. 529 @param x Argument 530 @return Function value 531 */ 532 virtual double GetY( double x ) = 0; 533 534 /** Layer plot handler. 535 This implementation will plot the function in the visible area and 536 put a label according to the aligment specified. 537 */ 538 virtual void Plot(wxDC & dc, mpWindow & w); 539 540 protected: 541 int m_flags; //!< Holds label alignment 542 543 DECLARE_DYNAMIC_CLASS(mpFX) 544 }; 545 546 /** Abstract base class providing plot and labeling functionality for functions F:Y->X. 547 Override mpFY::GetX to implement a function. 548 Optionally implement a constructor and pass a name (label) and a label alignment 549 to the constructor mpFY::mpFY. If the layer name is empty, no label will be plotted. 550 */ 551 class WXDLLIMPEXP_MATHPLOT mpFY : public mpLayer 552 { 553 public: 554 /** @param name Label 555 @param flags Label alignment, pass one of #mpALIGN_BOTTOM, #mpALIGN_CENTER, #mpALIGN_TOP. 556 */ 557 mpFY(wxString name = wxEmptyString, int flags = mpALIGN_TOP); 558 559 /** Get function value for argument. 560 Override this function in your implementation. 561 @param y Argument 562 @return Function value 563 */ 564 virtual double GetX( double y ) = 0; 565 566 /** Layer plot handler. 567 This implementation will plot the function in the visible area and 568 put a label according to the aligment specified. 569 */ 570 virtual void Plot(wxDC & dc, mpWindow & w); 571 572 protected: 573 int m_flags; //!< Holds label alignment 574 575 DECLARE_DYNAMIC_CLASS(mpFY) 576 }; 577 578 /** Abstract base class providing plot and labeling functionality for a locus plot F:N->X,Y. 579 Locus argument N is assumed to be in range 0 .. MAX_N, and implicitly derived by enumerating 580 all locus values. Override mpFXY::Rewind and mpFXY::GetNextXY to implement a locus. 581 Optionally implement a constructor and pass a name (label) and a label alignment 582 to the constructor mpFXY::mpFXY. If the layer name is empty, no label will be plotted. 583 */ 584 class WXDLLIMPEXP_MATHPLOT mpFXY : public mpLayer 585 { 586 public: 587 /** @param name Label 588 @param flags Label alignment, pass one of #mpALIGN_NE, #mpALIGN_NW, #mpALIGN_SW, #mpALIGN_SE. 589 */ 590 mpFXY(wxString name = wxEmptyString, int flags = mpALIGN_NE); 591 592 /** Rewind value enumeration with mpFXY::GetNextXY. 593 Override this function in your implementation. 594 */ 595 virtual void Rewind() = 0; 596 597 /** Get locus value for next N. 598 Override this function in your implementation. 599 @param x Returns X value 600 @param y Returns Y value 601 */ 602 virtual bool GetNextXY(double & x, double & y) = 0; 603 604 /** Layer plot handler. 605 This implementation will plot the locus in the visible area and 606 put a label according to the alignment specified. 607 */ 608 virtual void Plot(wxDC & dc, mpWindow & w); 609 610 611 protected: 612 int m_flags; //!< Holds label alignment 613 614 // Data to calculate label positioning 615 wxCoord maxDrawX, minDrawX, maxDrawY, minDrawY; 616 //int drawnPoints; 617 618 /** Update label positioning data 619 @param xnew New x coordinate 620 @param ynew New y coordinate 621 */ 622 void UpdateViewBoundary(wxCoord xnew, wxCoord ynew); 623 624 DECLARE_DYNAMIC_CLASS(mpFXY) 625 }; 626 627 /** Abstract base class providing plot and labeling functionality for functions F:Y->X. 628 Override mpProfile::GetX to implement a function. 629 This class is similar to mpFY, but the Plot method is different. The plot is in fact represented by lines instead of points, which gives best rendering of rapidly-varying functions, and in general, data which are not so close one to another. 630 Optionally implement a constructor and pass a name (label) and a label alignment 631 to the constructor mpProfile::mpProfile. If the layer name is empty, no label will be plotted. 632 */ 633 class WXDLLIMPEXP_MATHPLOT mpProfile : public mpLayer 634 { 635 public: 636 /** @param name Label 637 @param flags Label alignment, pass one of #mpALIGN_BOTTOM, #mpALIGN_CENTER, #mpALIGN_TOP. 638 */ 639 mpProfile(wxString name = wxEmptyString, int flags = mpALIGN_TOP); 640 641 /** Get function value for argument. 642 Override this function in your implementation. 643 @param x Argument 644 @return Function value 645 */ 646 virtual double GetY( double x ) = 0; 647 648 /** Layer plot handler. 649 This implementation will plot the function in the visible area and 650 put a label according to the aligment specified. 651 */ 652 virtual void Plot(wxDC & dc, mpWindow & w); 653 654 protected: 655 int m_flags; //!< Holds label alignment 656 657 DECLARE_DYNAMIC_CLASS(mpProfile) 658 }; 659 660 /*@}*/ 661 662 //----------------------------------------------------------------------------- 663 // mpLayer implementations - furniture (scales, ...) 664 //----------------------------------------------------------------------------- 665 666 /** @name mpLayer implementations - furniture (scales, ...) 667 @{*/ 668 669 /** Plot layer implementing a x-scale ruler. 670 The ruler is fixed at Y=0 in the coordinate system. A label is plotted at 671 the bottom-right hand of the ruler. The scale numbering automatically 672 adjusts to view and zoom factor. 673 */ 674 class WXDLLIMPEXP_MATHPLOT mpScaleX : public mpLayer 675 { 676 public: 677 /** Full constructor. 678 @param name Label to plot by the ruler 679 @param flags Set the position of the scale with respect to the window. 680 @param ticks Select ticks or grid. Give TRUE (default) for drawing axis ticks, FALSE for drawing the grid. 681 @param type mpX_NORMAL for normal labels, mpX_TIME for time axis in hours, minutes, seconds. */ 682 mpScaleX(wxString name = wxT("X"), int flags = mpALIGN_CENTER, bool ticks = true, unsigned int type = mpX_NORMAL); 683 684 /** Layer plot handler. 685 This implementation will plot the ruler adjusted to the visible area. */ 686 virtual void Plot(wxDC & dc, mpWindow & w); 687 688 /** Check whether this layer has a bounding box. 689 This implementation returns \a FALSE thus making the ruler invisible 690 to the plot layer bounding box calculation by mpWindow. */ HasBBox()691 virtual bool HasBBox() { return FALSE; } 692 693 /** Set X axis alignment. 694 @param align alignment (choose between mpALIGN_BORDER_BOTTOM, mpALIGN_BOTTOM, mpALIGN_CENTER, mpALIGN_TOP, mpALIGN_BORDER_TOP */ SetAlign(int align)695 void SetAlign(int align) { m_flags = align; }; 696 697 /** Set X axis ticks or grid 698 @param ticks TRUE to plot axis ticks, FALSE to plot grid. */ SetTicks(bool ticks)699 void SetTicks(bool ticks) { m_ticks = ticks; }; 700 701 /** Get X axis ticks or grid 702 @return TRUE if plot is drawing axis ticks, FALSE if the grid is active. */ GetTicks()703 bool GetTicks() { return m_ticks; }; 704 705 /** Get X axis label view mode. 706 @return mpX_NORMAL for normal labels, mpX_TIME for time axis in hours, minutes, seconds. */ GetLabelMode()707 unsigned int GetLabelMode() { return m_labelType; }; 708 709 /** Set X axis label view mode. 710 @param mode mpX_NORMAL for normal labels, mpX_TIME for time axis in hours, minutes, seconds. */ SetLabelMode(unsigned int mode)711 void SetLabelMode(unsigned int mode) { m_labelType = mode; }; 712 713 /** Set X axis Label format (used for mpX_NORMAL draw mode). 714 @param format The format string */ SetLabelFormat(const wxString & format)715 void SetLabelFormat(const wxString& format) { m_labelFormat = format; }; 716 717 /** Get X axis Label format (used for mpX_NORMAL draw mode). 718 @return The format string */ SetLabelFormat()719 const wxString& SetLabelFormat() { return m_labelFormat; }; 720 721 protected: 722 int m_flags; //!< Flag for axis alignment 723 bool m_ticks; //!< Flag to toggle between ticks or grid 724 unsigned int m_labelType; //!< Select labels mode: mpX_NORMAL for normal labels, mpX_TIME for time axis in hours, minutes, seconds 725 wxString m_labelFormat; //!< Format string used to print labels 726 727 DECLARE_DYNAMIC_CLASS(mpScaleX) 728 }; 729 730 /** Plot layer implementing a y-scale ruler. 731 If align is set to mpALIGN_CENTER, the ruler is fixed at X=0 in the coordinate system. If the align is set to mpALIGN_TOP or mpALIGN_BOTTOM, the axis is always drawn respectively at top or bottom of the window. A label is plotted at 732 the top-right hand of the ruler. The scale numbering automatically 733 adjusts to view and zoom factor. 734 */ 735 class WXDLLIMPEXP_MATHPLOT mpScaleY : public mpLayer 736 { 737 public: 738 /** @param name Label to plot by the ruler 739 @param flags Set position of the scale respect to the window. 740 @param ticks Select ticks or grid. Give TRUE (default) for drawing axis ticks, FALSE for drawing the grid */ 741 mpScaleY(wxString name = wxT("Y"), int flags = mpALIGN_CENTER, bool ticks = true); 742 743 /** Layer plot handler. 744 This implementation will plot the ruler adjusted to the visible area. 745 */ 746 virtual void Plot(wxDC & dc, mpWindow & w); 747 748 /** Check whether this layer has a bounding box. 749 This implementation returns \a FALSE thus making the ruler invisible 750 to the plot layer bounding box calculation by mpWindow. 751 */ HasBBox()752 virtual bool HasBBox() { return FALSE; } 753 754 /** Set Y axis alignment. 755 @param align alignment (choose between mpALIGN_BORDER_LEFT, mpALIGN_LEFT, mpALIGN_CENTER, mpALIGN_RIGHT, mpALIGN_BORDER_RIGHT) */ SetAlign(int align)756 void SetAlign(int align) { m_flags = align; }; 757 758 /** Set Y axis ticks or grid 759 @param ticks TRUE to plot axis ticks, FALSE to plot grid. */ SetTicks(bool ticks)760 void SetTicks(bool ticks) { m_ticks = ticks; }; 761 762 /** Get Y axis ticks or grid 763 @return TRUE if plot is drawing axis ticks, FALSE if the grid is active. */ GetTicks()764 bool GetTicks() { return m_ticks; }; 765 766 /** Set Y axis Label format. 767 @param format The format string */ SetLabelFormat(const wxString & format)768 void SetLabelFormat(const wxString& format) { m_labelFormat = format; }; 769 770 /** Get Y axis Label format. 771 @return The format string */ SetLabelFormat()772 const wxString& SetLabelFormat() { return m_labelFormat; }; 773 774 protected: 775 int m_flags; //!< Flag for axis alignment 776 bool m_ticks; //!< Flag to toggle between ticks or grid 777 wxString m_labelFormat; //!< Format string used to print labels 778 779 DECLARE_DYNAMIC_CLASS(mpScaleY) 780 }; 781 782 //----------------------------------------------------------------------------- 783 // mpWindow 784 //----------------------------------------------------------------------------- 785 786 /** @name Constants defining mouse modes for mpWindow 787 @{*/ 788 789 /** Mouse panning drags the view. Mouse mode for mpWindow. */ 790 #define mpMOUSEMODE_DRAG 0 791 /** Mouse panning creates a zoom box. Mouse mode for mpWindow. */ 792 #define mpMOUSEMODE_ZOOMBOX 1 793 794 /*@}*/ 795 /** Define the type for the list of layers inside mpWindow */ 796 //WX_DECLARE_HASH_MAP( int, mpLayer*, wxIntegerHash, wxIntegerEqual, wxLayerList ); 797 typedef std::deque<mpLayer*> wxLayerList; 798 799 /** Canvas for plotting mpLayer implementations. 800 801 This class defines a zoomable and moveable 2D plot canvas. Any number 802 of mpLayer implementations (scale rulers, function plots, ...) can be 803 attached using mpWindow::AddLayer. 804 805 The canvas window provides a context menu with actions for navigating the view. 806 The context menu can be retrieved with mpWindow::GetPopupMenu, e.g. for extending it 807 externally. 808 809 Since wxMathPlot version 0.03, the mpWindow incorporates the following features: 810 - DoubleBuffering (Default=disabled): Can be set with EnableDoubleBuffer 811 - Mouse based pan/zoom (Default=enabled): Can be set with EnableMousePanZoom. 812 813 The mouse commands can be visualized by the user through the popup menu, and are: 814 - Mouse Move+CTRL: Pan (Move) 815 - Mouse Wheel: Vertical scroll 816 - Mouse Wheel+SHIFT: Horizontal scroll 817 - Mouse Wheel UP+CTRL: Zoom in 818 - Mouse Wheel DOWN+CTRL: Zoom out 819 820 */ 821 class WXDLLIMPEXP_MATHPLOT mpWindow : public wxWindow 822 { 823 public: mpWindow()824 mpWindow() {} 825 mpWindow( wxWindow *parent, wxWindowID id, 826 const wxPoint &pos = wxDefaultPosition, 827 const wxSize &size = wxDefaultSize, 828 long flags = 0); 829 ~mpWindow(); 830 831 /** Get reference to context menu of the plot canvas. 832 @return Pointer to menu. The menu can be modified. 833 */ GetPopupMenu()834 wxMenu* GetPopupMenu() { return &m_popmenu; } 835 836 /** Add a plot layer to the canvas. 837 @param layer Pointer to layer. The mpLayer object will get under control of mpWindow, 838 i.e. it will be delete'd on mpWindow destruction 839 @param refreshDisplay States whether to refresh the display (UpdateAll) after adding the layer. 840 @retval TRUE Success 841 @retval FALSE Failure due to out of memory. 842 */ 843 bool AddLayer( mpLayer* layer, bool refreshDisplay = true); 844 845 /** Remove a plot layer from the canvas. 846 @param layer Pointer to layer. The mpLayer object will be destructed using delete. 847 @param alsoDeleteObject If set to true, the mpLayer object will be also "deleted", not just removed from the internal list. 848 @param refreshDisplay States whether to refresh the display (UpdateAll) after removing the layer. 849 @return true if layer is deleted correctly 850 851 N.B. Only the layer reference in the mpWindow is deleted, the layer object still exists! 852 */ 853 bool DelLayer( mpLayer* layer, bool alsoDeleteObject = false, bool refreshDisplay = true); 854 855 /** Remove all layers from the plot. 856 @param alsoDeleteObject If set to true, the mpLayer objects will be also "deleted", not just removed from the internal list. 857 @param refreshDisplay States whether to refresh the display (UpdateAll) after removing the layers. 858 */ 859 void DelAllLayers( bool alsoDeleteObject, bool refreshDisplay = true); 860 861 862 /*! Get the layer in list position indicated. 863 N.B. You <i>must</i> know the index of the layer inside the list! 864 @param position position of the layer in the layers list 865 @return pointer to mpLayer 866 */ 867 mpLayer* GetLayer(int position); 868 869 /*! Get the layer by its name (case sensitive). 870 @param name The name of the layer to retrieve 871 @return A pointer to the mpLayer object, or NULL if not found. 872 */ 873 mpLayer* GetLayerByName( const wxString &name); 874 875 /** Get current view's X scale. 876 See @ref mpLayer::Plot "rules for coordinate transformation" 877 @return Scale 878 */ GetXscl()879 double GetXscl() { return m_scaleX; } GetScaleX(void)880 double GetScaleX(void) const{ return m_scaleX; }; // Schaling's method: maybe another method esists with the same name 881 882 /** Get current view's Y scale. 883 See @ref mpLayer::Plot "rules for coordinate transformation" 884 @return Scale 885 */ GetYscl()886 double GetYscl() const { return m_scaleY; } GetScaleY(void)887 double GetScaleY(void) const { return m_scaleY; } // Schaling's method: maybe another method exists with the same name 888 889 /** Get current view's X position. 890 See @ref mpLayer::Plot "rules for coordinate transformation" 891 @return X Position in layer coordinate system, that corresponds to the center point of the view. 892 */ GetXpos()893 double GetXpos() const { return m_posX; } GetPosX(void)894 double GetPosX(void) const { return m_posX; } 895 896 /** Get current view's Y position. 897 See @ref mpLayer::Plot "rules for coordinate transformation" 898 @return Y Position in layer coordinate system, that corresponds to the center point of the view. 899 */ GetYpos()900 double GetYpos() const { return m_posY; } GetPosY(void)901 double GetPosY(void) const { return m_posY; } 902 903 /** Get current view's X dimension in device context units. 904 Usually this is equal to wxDC::GetSize, but it might differ thus mpLayer 905 implementations should rely on the value returned by the function. 906 See @ref mpLayer::Plot "rules for coordinate transformation" 907 @return X dimension. 908 */ GetScrX(void)909 int GetScrX(void) const { return m_scrX; } GetXScreen(void)910 int GetXScreen(void) const { return m_scrX; } 911 912 /** Get current view's Y dimension in device context units. 913 Usually this is equal to wxDC::GetSize, but it might differ thus mpLayer 914 implementations should rely on the value returned by the function. 915 See @ref mpLayer::Plot "rules for coordinate transformation" 916 @return Y dimension. 917 */ GetScrY(void)918 int GetScrY(void) const { return m_scrY; } GetYScreen(void)919 int GetYScreen(void) const { return m_scrY; } 920 921 /** Set current view's X scale and refresh display. 922 @param scaleX New scale, must not be 0. 923 */ 924 void SetScaleX(double scaleX); 925 926 /** Set current view's Y scale and refresh display. 927 @param scaleY New scale, must not be 0. 928 */ SetScaleY(double scaleY)929 void SetScaleY(double scaleY) { if (scaleY!=0) m_scaleY=scaleY; UpdateAll(); } 930 931 /** Set current view's X position and refresh display. 932 @param posX New position that corresponds to the center point of the view. 933 */ SetPosX(double posX)934 void SetPosX(double posX) { m_posX=posX; UpdateAll(); } 935 936 /** Set current view's Y position and refresh display. 937 @param posY New position that corresponds to the center point of the view. 938 */ SetPosY(double posY)939 void SetPosY(double posY) { m_posY=posY; UpdateAll(); } 940 941 /** Set current view's X and Y position and refresh display. 942 @param posX New position that corresponds to the center point of the view. 943 @param posY New position that corresponds to the center point of the view. 944 */ SetPos(double posX,double posY)945 void SetPos( double posX, double posY) { m_posX=posX; m_posY=posY; UpdateAll(); } 946 947 /** Set current view's dimensions in device context units. 948 Needed by plotting functions. It doesn't refresh display. 949 @param scrX New position that corresponds to the center point of the view. 950 @param scrY New position that corresponds to the center point of the view. 951 */ SetScr(int scrX,int scrY)952 void SetScr( int scrX, int scrY) { m_scrX=scrX; m_scrY=scrY; } 953 954 /** Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates, using current mpWindow position and scale. 955 * @sa p2y,x2p,y2p */ 956 // double p2x(wxCoord pixelCoordX, bool drawOutside = true ); // { return m_posX + pixelCoordX/m_scaleX; } p2x(wxCoord pixelCoordX)957 inline double p2x(wxCoord pixelCoordX ) { return m_posX + pixelCoordX/m_scaleX; } 958 959 /** Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates, using current mpWindow position and scale. 960 * @sa p2x,x2p,y2p */ 961 // double p2y(wxCoord pixelCoordY, bool drawOutside = true ); //{ return m_posY - pixelCoordY/m_scaleY; } p2y(wxCoord pixelCoordY)962 inline double p2y(wxCoord pixelCoordY ) { return m_posY - pixelCoordY/m_scaleY; } 963 964 /** Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates, using current mpWindow position and scale. 965 * @sa p2x,p2y,y2p */ 966 // wxCoord x2p(double x, bool drawOutside = true); // { return (wxCoord) ( (x-m_posX) * m_scaleX); } x2p(double x)967 inline wxCoord x2p(double x) { return (wxCoord) ( (x-m_posX) * m_scaleX); } 968 969 /** Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates, using current mpWindow position and scale. 970 * @sa p2x,p2y,x2p */ 971 // wxCoord y2p(double y, bool drawOutside = true); // { return (wxCoord) ( (m_posY-y) * m_scaleY); } y2p(double y)972 inline wxCoord y2p(double y) { return (wxCoord) ( (m_posY-y) * m_scaleY); } 973 974 975 /** Enable/disable the double-buffering of the window, eliminating the flicker (default=disabled). 976 */ EnableDoubleBuffer(bool enabled)977 void EnableDoubleBuffer( bool enabled ) { m_enableDoubleBuffer = enabled; } 978 979 /** Enable/disable the feature of pan/zoom with the mouse (default=enabled) 980 */ EnableMousePanZoom(bool enabled)981 void EnableMousePanZoom( bool enabled ) { m_enableMouseNavigation = enabled; } 982 983 /** Enable or disable X/Y scale aspect locking for the view. 984 @note Explicit calls to mpWindow::SetScaleX and mpWindow::SetScaleY will set 985 an unlocked aspect, but any other action changing the view scale will 986 lock the aspect again. 987 */ 988 void LockAspect(bool enable = TRUE); 989 990 /** Checks whether the X/Y scale aspect is locked. 991 @retval TRUE Locked 992 @retval FALSE Unlocked 993 */ IsAspectLocked()994 inline bool IsAspectLocked() { return m_lockaspect; } 995 996 /** Set view to fit global bounding box of all plot layers and refresh display. 997 Scale and position will be set to show all attached mpLayers. 998 The X/Y scale aspect lock is taken into account. 999 */ 1000 void Fit(); 1001 1002 /** Set view to fit a given bounding box and refresh display. 1003 The X/Y scale aspect lock is taken into account. 1004 If provided, the parameters printSizeX and printSizeY are taken as the DC size, and the 1005 pixel scales are computed accordingly. Also, in this case the passed borders are not saved 1006 as the "desired borders", since this use will be invoked only when printing. 1007 */ 1008 void Fit(double xMin, double xMax, double yMin, double yMax,wxCoord *printSizeX=NULL,wxCoord *printSizeY=NULL); 1009 1010 /** Zoom into current view and refresh display 1011 * @param centerPoint The point (pixel coordinates) that will stay in the same position on the screen after the zoom (by default, the center of the mpWindow). 1012 */ 1013 void ZoomIn( const wxPoint& centerPoint = wxDefaultPosition ); 1014 1015 /** Zoom out current view and refresh display 1016 * @param centerPoint The point (pixel coordinates) that will stay in the same position on the screen after the zoom (by default, the center of the mpWindow). 1017 */ 1018 void ZoomOut( const wxPoint& centerPoint = wxDefaultPosition ); 1019 1020 /** Zoom in current view along X and refresh display */ 1021 void ZoomInX(); 1022 /** Zoom out current view along X and refresh display */ 1023 void ZoomOutX(); 1024 /** Zoom in current view along Y and refresh display */ 1025 void ZoomInY(); 1026 /** Zoom out current view along Y and refresh display */ 1027 void ZoomOutY(); 1028 1029 /** Zoom view fitting given coordinates to the window (p0 and p1 do not need to be in any specific order) */ 1030 void ZoomRect(wxPoint p0, wxPoint p1); 1031 1032 /** Refresh display */ 1033 void UpdateAll(); 1034 1035 // Added methods by Davide Rondini 1036 1037 /** Counts the number of plot layers, excluding axes or text: this is to count only the layers which have a bounding box. 1038 \return The number of profiles plotted. 1039 */ 1040 unsigned int CountLayers(); 1041 1042 /** Counts the number of plot layers, whether or not they have a bounding box. 1043 \return The number of layers in the mpWindow. */ CountAllLayers()1044 unsigned int CountAllLayers() { return m_layers.size(); }; 1045 1046 /** Draws the mpWindow on a page for printing 1047 \param print the mpPrintout where to print the graph */ 1048 //void PrintGraph(mpPrintout *print); 1049 1050 1051 /** Returns the left-border layer coordinate that the user wants the mpWindow to show (it may be not exactly the actual shown coordinate in the case of locked aspect ratio). 1052 * @sa Fit 1053 */ GetDesiredXmin()1054 double GetDesiredXmin() {return m_desiredXmin; } 1055 1056 /** Returns the right-border layer coordinate that the user wants the mpWindow to show (it may be not exactly the actual shown coordinate in the case of locked aspect ratio). 1057 * @sa Fit 1058 */ GetDesiredXmax()1059 double GetDesiredXmax() {return m_desiredXmax; } 1060 1061 /** Returns the bottom-border layer coordinate that the user wants the mpWindow to show (it may be not exactly the actual shown coordinate in the case of locked aspect ratio). 1062 * @sa Fit 1063 */ GetDesiredYmin()1064 double GetDesiredYmin() {return m_desiredYmin; } 1065 1066 /** Returns the top layer-border coordinate that the user wants the mpWindow to show (it may be not exactly the actual shown coordinate in the case of locked aspect ratio). 1067 * @sa Fit 1068 */ GetDesiredYmax()1069 double GetDesiredYmax() {return m_desiredYmax; } 1070 1071 /** Returns the bounding box coordinates 1072 @param bbox Pointer to a 6-element double array where to store bounding box coordinates. */ 1073 void GetBoundingBox(double* bbox); 1074 1075 /** Enable/disable scrollbars 1076 @param status Set to true to show scrollbars */ 1077 void SetMPScrollbars(bool status); 1078 1079 /** Get scrollbars status. 1080 @return true if scrollbars are visible */ GetMPScrollbars()1081 bool GetMPScrollbars() {return m_enableScrollBars; }; 1082 1083 /** Draw the window on a wxBitmap, then save it to a file. 1084 @param filename File name where to save the screenshot 1085 @param type image type to be saved: see wxImage output file types for flags 1086 @param imageSize Set a size for the output image. Default is the same as the screen size 1087 @param fit Decide whether to fit the plot into the size*/ 1088 bool SaveScreenshot(const wxString& filename, int type = wxBITMAP_TYPE_BMP, wxSize imageSize = wxDefaultSize, bool fit = false); 1089 1090 /** This value sets the zoom steps whenever the user clicks "Zoom in/out" or performs zoom with the mouse wheel. 1091 * It must be a number above unity. This number is used for zoom in, and its inverse for zoom out. Set to 1.5 by default. */ 1092 static double zoomIncrementalFactor; 1093 1094 /** Set window margins, creating a blank area where some kinds of layers cannot draw. This is useful for example to draw axes outside the area where the plots are drawn. 1095 @param top Top border 1096 @param right Right border 1097 @param bottom Bottom border 1098 @param left Left border */ 1099 void SetMargins(int top, int right, int bottom, int left); 1100 1101 /** Set the top margin. @param top Top Margin */ SetMarginTop(int top)1102 void SetMarginTop(int top) { m_marginTop = top; }; 1103 /** Set the right margin. @param right Right Margin */ SetMarginRight(int right)1104 void SetMarginRight(int right) { m_marginRight = right; }; 1105 /** Set the bottom margin. @param bottom Bottom Margin */ SetMarginBottom(int bottom)1106 void SetMarginBottom(int bottom) { m_marginBottom = bottom; }; 1107 /** Set the left margin. @param left Left Margin */ SetMarginLeft(int left)1108 void SetMarginLeft(int left) { m_marginLeft = left; }; 1109 1110 /** Get the top margin. @param top Top Margin */ GetMarginTop()1111 int GetMarginTop() { return m_marginTop; }; 1112 /** Get the right margin. @param right Right Margin */ GetMarginRight()1113 int GetMarginRight() { return m_marginRight; }; 1114 /** Get the bottom margin. @param bottom Bottom Margin */ GetMarginBottom()1115 int GetMarginBottom() { return m_marginBottom; }; 1116 /** Get the left margin. @param left Left Margin */ GetMarginLeft()1117 int GetMarginLeft() { return m_marginLeft; }; 1118 1119 /** Sets whether to show coordinate tooltip when mouse passes over the plot. \param value true for enable, false for disable */ 1120 // void EnableCoordTooltip(bool value = true); 1121 /** Gets coordinate tooltip status. \return true for enable, false for disable */ 1122 // bool GetCoordTooltip() { return m_coordTooltip; }; 1123 1124 /** Check if a given point is inside the area of a mpInfoLayer and eventually returns its pointer. 1125 @param point The position to be checked 1126 @return If an info layer is found, returns its pointer, NULL otherwise */ 1127 mpInfoLayer* IsInsideInfoLayer(wxPoint& point); 1128 1129 /** Sets the visibility of a layer by its name. 1130 @param name The layer name to set visibility 1131 @param viewable the view status to be set */ 1132 void SetLayerVisible(const wxString &name, bool viewable); 1133 1134 /** Check whether a layer with given name is visible 1135 @param name The layer name 1136 @return layer visibility status */ 1137 bool IsLayerVisible(const wxString &name ); 1138 1139 /** Sets the visibility of a layer by its position in layer list. 1140 @param position The layer position in layer list 1141 @param viewable the view status to be set */ 1142 void SetLayerVisible(const unsigned int position, bool viewable); 1143 1144 /** Check whether the layer at given position is visible 1145 @param position The layer position in layer list 1146 @return layer visibility status */ 1147 bool IsLayerVisible(const unsigned int position ); 1148 1149 /** Set Color theme. Provide colours to set a new colour theme. 1150 @param bgColour Background colour 1151 @param drawColour The colour used to draw all elements in foreground, axes excluded 1152 @param axesColour The colour used to draw axes (but not their labels) */ 1153 void SetColourTheme(const wxColour& bgColour, const wxColour& drawColour, const wxColour& axesColour); 1154 1155 /** Get axes draw colour 1156 @return reference to axis colour used in theme */ GetAxesColour()1157 const wxColour& GetAxesColour() { return m_axColour; }; 1158 1159 protected: 1160 void OnPaint (wxPaintEvent &event); //!< Paint handler, will plot all attached layers 1161 void OnSize (wxSizeEvent &event); //!< Size handler, will update scroll bar sizes 1162 // void OnScroll2 (wxScrollWinEvent &event); //!< Scroll handler, will move canvas 1163 void OnShowPopupMenu (wxMouseEvent &event); //!< Mouse handler, will show context menu 1164 void OnMouseRightDown(wxMouseEvent &event); //!< Mouse handler, for detecting when the user drags with the right button or just "clicks" for the menu 1165 void OnCenter (wxCommandEvent &event); //!< Context menu handler 1166 void OnFit (wxCommandEvent &event); //!< Context menu handler 1167 void OnZoomIn (wxCommandEvent &event); //!< Context menu handler 1168 void OnZoomOut (wxCommandEvent &event); //!< Context menu handler 1169 void OnLockAspect (wxCommandEvent &event); //!< Context menu handler 1170 void OnMouseHelp (wxCommandEvent &event); //!< Context menu handler 1171 void OnMouseWheel (wxMouseEvent &event); //!< Mouse handler for the wheel 1172 void OnMouseMove (wxMouseEvent &event); //!< Mouse handler for mouse motion (for pan) 1173 void OnMouseLeftDown (wxMouseEvent &event); //!< Mouse left click (for rect zoom) 1174 void OnMouseLeftRelease (wxMouseEvent &event); //!< Mouse left click (for rect zoom) 1175 void OnScrollThumbTrack (wxScrollWinEvent &event); //!< Scroll thumb on scroll bar moving 1176 void OnScrollPageUp (wxScrollWinEvent &event); //!< Scroll page up 1177 void OnScrollPageDown (wxScrollWinEvent &event); //!< Scroll page down 1178 void OnScrollLineUp (wxScrollWinEvent &event); //!< Scroll line up 1179 void OnScrollLineDown (wxScrollWinEvent &event); //!< Scroll line down 1180 void OnScrollTop (wxScrollWinEvent &event); //!< Scroll to top 1181 void OnScrollBottom (wxScrollWinEvent &event); //!< Scroll to bottom 1182 1183 void DoScrollCalc (const int position, const int orientation); 1184 1185 void DoZoomInXCalc (const int staticXpixel); 1186 void DoZoomInYCalc (const int staticYpixel); 1187 void DoZoomOutXCalc (const int staticXpixel); 1188 void DoZoomOutYCalc (const int staticYpixel); 1189 1190 /** Recalculate global layer bounding box, and save it in m_minX,... 1191 * \return true if there is any valid BBox information. 1192 */ 1193 virtual bool UpdateBBox(); 1194 1195 //wxList m_layers; //!< List of attached plot layers 1196 wxLayerList m_layers; //!< List of attached plot layers 1197 wxMenu m_popmenu; //!< Canvas' context menu 1198 bool m_lockaspect;//!< Scale aspect is locked or not 1199 // bool m_coordTooltip; //!< Selects whether to show coordinate tooltip 1200 wxColour m_bgColour; //!< Background Colour 1201 wxColour m_fgColour; //!< Foreground Colour 1202 wxColour m_axColour; //!< Axes Colour 1203 1204 double m_minX; //!< Global layer bounding box, left border incl. 1205 double m_maxX; //!< Global layer bounding box, right border incl. 1206 double m_minY; //!< Global layer bounding box, bottom border incl. 1207 double m_maxY; //!< Global layer bounding box, top border incl. 1208 double m_scaleX; //!< Current view's X scale 1209 double m_scaleY; //!< Current view's Y scale 1210 double m_posX; //!< Current view's X position 1211 double m_posY; //!< Current view's Y position 1212 int m_scrX; //!< Current view's X dimension 1213 int m_scrY; //!< Current view's Y dimension 1214 int m_clickedX; //!< Last mouse click X position, for centering and zooming the view 1215 int m_clickedY; //!< Last mouse click Y position, for centering and zooming the view 1216 1217 /** These are updated in Fit() only, and may be different from the real borders (layer coordinates) only if lock aspect ratio is true. 1218 */ 1219 double m_desiredXmin,m_desiredXmax,m_desiredYmin,m_desiredYmax; 1220 1221 int m_marginTop, m_marginRight, m_marginBottom, m_marginLeft; 1222 1223 int m_last_lx,m_last_ly; //!< For double buffering 1224 wxMemoryDC m_buff_dc; //!< For double buffering 1225 wxBitmap *m_buff_bmp; //!< For double buffering 1226 bool m_enableDoubleBuffer; //!< For double buffering 1227 bool m_enableMouseNavigation; //!< For pan/zoom with the mouse. 1228 bool m_mouseMovedAfterRightClick; 1229 long m_mouseRClick_X,m_mouseRClick_Y; //!< For the right button "drag" feature 1230 int m_mouseLClick_X, m_mouseLClick_Y; //!< Starting coords for rectangular zoom selection 1231 bool m_enableScrollBars; 1232 int m_scrollX, m_scrollY; 1233 mpInfoLayer* m_movingInfoLayer; //!< For moving info layers over the window area 1234 1235 DECLARE_DYNAMIC_CLASS(mpWindow) 1236 DECLARE_EVENT_TABLE() 1237 }; 1238 1239 //----------------------------------------------------------------------------- 1240 // mpFXYVector - provided by Jose Luis Blanco 1241 //----------------------------------------------------------------------------- 1242 1243 /** A class providing graphs functionality for a 2D plot (either continuous or a set of points), from vectors of data. 1244 This class can be used directly, the user does not need to derive any new class. Simply pass the data as two vectors 1245 with the same length containing the X and Y coordinates to the method SetData. 1246 1247 To generate a graph with a set of points, call 1248 \code 1249 layerVar->SetContinuity(false) 1250 \endcode 1251 1252 or 1253 1254 \code 1255 layerVar->SetContinuity(true) 1256 \endcode 1257 1258 to render the sequence of coordinates as a continuous line. 1259 1260 (Added: Jose Luis Blanco, AGO-2007) 1261 */ 1262 class WXDLLIMPEXP_MATHPLOT mpFXYVector : public mpFXY 1263 { 1264 public: 1265 /** @param name Label 1266 @param flags Label alignment, pass one of #mpALIGN_NE, #mpALIGN_NW, #mpALIGN_SW, #mpALIGN_SE. 1267 */ 1268 mpFXYVector(wxString name = wxEmptyString, int flags = mpALIGN_NE); 1269 1270 /** Changes the internal data: the set of points to draw. 1271 Both vectors MUST be of the same length. This method DOES NOT refresh the mpWindow; do it manually. 1272 * @sa Clear 1273 */ 1274 void SetData( const std::vector<double> &xs,const std::vector<double> &ys); 1275 1276 /** Clears all the data, leaving the layer empty. 1277 * @sa SetData 1278 */ 1279 void Clear(); 1280 1281 protected: 1282 /** The internal copy of the set of data to draw. 1283 */ 1284 std::vector<double> m_xs,m_ys; 1285 1286 /** The internal counter for the "GetNextXY" interface 1287 */ 1288 size_t m_index; 1289 1290 /** Loaded at SetData 1291 */ 1292 double m_minX,m_maxX,m_minY,m_maxY; 1293 1294 /** Rewind value enumeration with mpFXY::GetNextXY. 1295 Overridden in this implementation. 1296 */ 1297 void Rewind(); 1298 1299 /** Get locus value for next N. 1300 Overridden in this implementation. 1301 @param x Returns X value 1302 @param y Returns Y value 1303 */ 1304 bool GetNextXY(double & x, double & y); 1305 1306 /** Returns the actual minimum X data (loaded in SetData). 1307 */ GetMinX()1308 double GetMinX() { return m_minX; } 1309 1310 /** Returns the actual minimum Y data (loaded in SetData). 1311 */ GetMinY()1312 double GetMinY() { return m_minY; } 1313 1314 /** Returns the actual maximum X data (loaded in SetData). 1315 */ GetMaxX()1316 double GetMaxX() { return m_maxX; } 1317 1318 /** Returns the actual maximum Y data (loaded in SetData). 1319 */ GetMaxY()1320 double GetMaxY() { return m_maxY; } 1321 1322 int m_flags; //!< Holds label alignment 1323 1324 DECLARE_DYNAMIC_CLASS(mpFXYVector) 1325 }; 1326 1327 //----------------------------------------------------------------------------- 1328 // mpText - provided by Val Greene 1329 //----------------------------------------------------------------------------- 1330 1331 /** Plot layer implementing a text string. 1332 The text is plotted using a percentage system 0-100%, so the actual 1333 coordinates for the location are not required, and the text stays 1334 on the plot reguardless of the other layers location and scaling 1335 factors. 1336 */ 1337 class WXDLLIMPEXP_MATHPLOT mpText : public mpLayer 1338 { 1339 public: 1340 /** @param name text to be drawn in the plot 1341 @param offsetx holds offset for the X location in percentage (0-100) 1342 @param offsety holds offset for the Y location in percentage (0-100) */ 1343 mpText(wxString name = wxT("Title"), int offsetx = 5, int offsety = 50); 1344 1345 /** Text Layer plot handler. 1346 This implementation will plot text adjusted to the visible area. */ 1347 virtual void Plot(wxDC & dc, mpWindow & w); 1348 1349 /** mpText should not be used for scaling decisions. */ HasBBox()1350 virtual bool HasBBox() { return FALSE; } 1351 1352 protected: 1353 int m_offsetx; //!< Holds offset for X in percentage 1354 int m_offsety; //!< Holds offset for Y in percentage 1355 1356 DECLARE_DYNAMIC_CLASS(mpText) 1357 }; 1358 1359 1360 //----------------------------------------------------------------------------- 1361 // mpMarker - provided by R1kk3r 1362 //----------------------------------------------------------------------------- 1363 1364 /** Plot layer implementing a text string. 1365 The text is plotted using an absolute x,y position. 1366 */ 1367 class WXDLLIMPEXP_MATHPLOT mpMarker : public mpLayer 1368 { 1369 public: 1370 /** @param name text to be drawn in the plot 1371 @param atX absolute X location 1372 @param atY absolute Y location */ 1373 mpMarker(wxString name = wxT("[M]"), double atX = 0.0, double atY = 0.0); 1374 1375 /** Set the position of the marker. 1376 @param atX absolute X location 1377 @param atY absolute Y location */ SetPos(double atX,double atY)1378 void SetPos(double atX, double atY) {mX = atX, mY = atY; }; 1379 1380 /** Marker Layer plot handler. 1381 This implementation will plot text at the given x,y position. */ 1382 virtual void Plot(wxDC & dc, mpWindow & w); 1383 1384 /** mpMarker should not be used for scaling decisions. */ HasBBox()1385 virtual bool HasBBox() { return FALSE; } 1386 1387 protected: 1388 1389 double mX, mY; 1390 1391 DECLARE_DYNAMIC_CLASS(mpText) 1392 }; 1393 1394 1395 //----------------------------------------------------------------------------- 1396 // mpPrintout - provided by Davide Rondini 1397 //----------------------------------------------------------------------------- 1398 1399 /** Printout class used by mpWindow to draw in the objects to be printed. 1400 The object itself can then used by the default wxWidgets printing system 1401 to print mppWindow objects. 1402 */ 1403 class WXDLLIMPEXP_MATHPLOT mpPrintout : public wxPrintout 1404 { 1405 public: 1406 mpPrintout(mpWindow* drawWindow, const wxChar *title = _T("wxMathPlot print output")); ~mpPrintout()1407 virtual ~mpPrintout() {}; 1408 SetDrawState(bool drawState)1409 void SetDrawState(bool drawState) {drawn = drawState;}; 1410 bool OnPrintPage(int page); 1411 bool HasPage(int page); 1412 1413 private: 1414 bool drawn; 1415 mpWindow *plotWindow; 1416 }; 1417 1418 1419 //----------------------------------------------------------------------------- 1420 // mpMovableObject - provided by Jose Luis Blanco 1421 //----------------------------------------------------------------------------- 1422 /** This virtual class represents objects that can be moved to an arbitrary 2D location+rotation. 1423 * The current transformation is set through SetCoordinateBase. 1424 * To ease the implementation of descendent classes, mpMovableObject will 1425 * be in charge of Bounding Box computation and layer rendering, assuming that 1426 * the object updates its shape in m_shape_xs & m_shape_ys. 1427 */ 1428 class WXDLLIMPEXP_MATHPLOT mpMovableObject : public mpLayer 1429 { 1430 public: 1431 /** Default constructor (sets location and rotation to (0,0,0)) 1432 */ mpMovableObject()1433 mpMovableObject( ) : 1434 m_reference_x(0), 1435 m_reference_y(0), 1436 m_reference_phi(0), 1437 m_shape_xs(0), 1438 m_shape_ys(0) 1439 { 1440 m_type = mpLAYER_PLOT; 1441 } 1442 ~mpMovableObject()1443 virtual ~mpMovableObject() {}; 1444 1445 /** Get the current coordinate transformation. 1446 */ GetCoordinateBase(double & x,double & y,double & phi)1447 void GetCoordinateBase( double &x, double &y, double &phi ) const 1448 { 1449 x = m_reference_x; 1450 y = m_reference_y; 1451 phi = m_reference_phi; 1452 } 1453 1454 /** Set the coordinate transformation (phi in radians, 0 means no rotation). 1455 */ 1456 void SetCoordinateBase( double x, double y, double phi = 0 ) 1457 { 1458 m_reference_x = x; 1459 m_reference_y = y; 1460 m_reference_phi = phi; 1461 m_flags = mpALIGN_NE; 1462 ShapeUpdated(); 1463 } 1464 HasBBox()1465 virtual bool HasBBox() { return m_trans_shape_xs.size()!=0; } 1466 1467 /** Get inclusive left border of bounding box. 1468 */ GetMinX()1469 virtual double GetMinX() { return m_bbox_min_x; } 1470 1471 /** Get inclusive right border of bounding box. 1472 */ GetMaxX()1473 virtual double GetMaxX() { return m_bbox_max_x; } 1474 1475 /** Get inclusive bottom border of bounding box. 1476 */ GetMinY()1477 virtual double GetMinY() { return m_bbox_min_y; } 1478 1479 /** Get inclusive top border of bounding box. 1480 */ GetMaxY()1481 virtual double GetMaxY() { return m_bbox_max_y; } 1482 1483 virtual void Plot(wxDC & dc, mpWindow & w); 1484 1485 /** Set label axis alignment. 1486 * @param align alignment (choose between mpALIGN_NE, mpALIGN_NW, mpALIGN_SW, mpALIGN_SE 1487 */ SetAlign(int align)1488 void SetAlign(int align) { m_flags = align; }; 1489 1490 protected: 1491 int m_flags; //!< Holds label alignment 1492 1493 /** The coordinates of the object (orientation "phi" is in radians). 1494 */ 1495 double m_reference_x,m_reference_y,m_reference_phi; 1496 1497 /** A method for 2D translation and rotation, using the current transformation stored in m_reference_x,m_reference_y,m_reference_phi. 1498 */ 1499 void TranslatePoint( double x,double y, double &out_x, double &out_y ); 1500 1501 /** This contains the object points, in local coordinates (to be transformed by the current transformation). 1502 */ 1503 std::vector<double> m_shape_xs,m_shape_ys; 1504 1505 /** The buffer for the translated & rotated points (to avoid recomputing them with each mpWindow refresh). 1506 * 1507 */ 1508 std::vector<double> m_trans_shape_xs,m_trans_shape_ys; 1509 1510 /** The precomputed bounding box: 1511 * @sa ShapeUpdated 1512 */ 1513 double m_bbox_min_x,m_bbox_max_x,m_bbox_min_y,m_bbox_max_y; 1514 1515 /** Must be called by the descendent class after updating the shape (m_shape_xs/ys), or when the transformation changes. 1516 * This method updates the buffers m_trans_shape_xs/ys, and the precomputed bounding box. 1517 */ 1518 void ShapeUpdated(); 1519 1520 }; 1521 1522 //----------------------------------------------------------------------------- 1523 // mpCovarianceEllipse - provided by Jose Luis Blanco 1524 //----------------------------------------------------------------------------- 1525 /** A 2D ellipse, described by a 2x2 covariance matrix. 1526 * The relation between the multivariate Gaussian confidence interval and 1527 * the "quantiles" in this class is: 1528 * - 1 : 68.27% confidence interval 1529 * - 2 : 95.45% 1530 * - 3 : 99.73% 1531 * - 4 : 99.994% 1532 * For example, see http://en.wikipedia.org/wiki/Normal_distribution#Standard_deviation_and_confidence_intervals 1533 * 1534 * The ellipse will be always centered at the origin. Use mpMovableObject::SetCoordinateBase to move it. 1535 */ 1536 class WXDLLIMPEXP_MATHPLOT mpCovarianceEllipse : public mpMovableObject 1537 { 1538 public: 1539 /** Default constructor. 1540 * Initializes to a unity diagonal covariance matrix, a 95% confidence interval (2 sigmas), 32 segments, and a continuous plot (m_continuous=true). 1541 */ 1542 mpCovarianceEllipse( 1543 double cov_00 = 1, 1544 double cov_11 = 1, 1545 double cov_01 = 0, 1546 double quantiles = 2, 1547 int segments = 32, 1548 const wxString & layerName = wxT("") ) : m_cov_00(cov_00)1549 m_cov_00(cov_00), 1550 m_cov_11(cov_11), 1551 m_cov_01(cov_01), 1552 m_quantiles(quantiles), 1553 m_segments(segments) 1554 { 1555 m_continuous = true; 1556 m_name = layerName; 1557 RecalculateShape(); 1558 m_type = mpLAYER_PLOT; 1559 } 1560 ~mpCovarianceEllipse()1561 virtual ~mpCovarianceEllipse() {} 1562 GetQuantiles()1563 double GetQuantiles() const { return m_quantiles; } 1564 1565 /** Set how many "quantiles" to draw, that is, the confidence interval of the ellipse (see above). 1566 */ SetQuantiles(double q)1567 void SetQuantiles(double q) 1568 { 1569 m_quantiles=q; 1570 RecalculateShape(); 1571 } 1572 SetSegments(int segments)1573 void SetSegments( int segments ) { m_segments = segments; } GetSegments()1574 int GetSegments( ) const { return m_segments; } 1575 1576 /** Returns the elements of the current covariance matrix: 1577 */ GetCovarianceMatrix(double & cov_00,double & cov_01,double & cov_11)1578 void GetCovarianceMatrix( double &cov_00,double &cov_01,double &cov_11 ) const 1579 { 1580 cov_00 = m_cov_00; 1581 cov_01 = m_cov_01; 1582 cov_11 = m_cov_11; 1583 } 1584 1585 /** Changes the covariance matrix: 1586 */ SetCovarianceMatrix(double cov_00,double cov_01,double cov_11)1587 void SetCovarianceMatrix( double cov_00,double cov_01,double cov_11 ) 1588 { 1589 m_cov_00 = cov_00; 1590 m_cov_01 = cov_01; 1591 m_cov_11 = cov_11; 1592 RecalculateShape(); 1593 } 1594 1595 protected: 1596 /** The elements of the matrix (only 3 since cov(0,1)=cov(1,0) in any positive definite matrix). 1597 */ 1598 double m_cov_00,m_cov_11,m_cov_01; 1599 double m_quantiles; 1600 1601 /** The number of line segments that build up the ellipse. 1602 */ 1603 int m_segments; 1604 1605 /** Called to update the m_shape_xs, m_shape_ys vectors, whenever a parameter changes. 1606 */ 1607 void RecalculateShape(); 1608 }; 1609 1610 //----------------------------------------------------------------------------- 1611 // mpPolygon - provided by Jose Luis Blanco 1612 //----------------------------------------------------------------------------- 1613 /** An arbitrary polygon, descendant of mpMovableObject. 1614 * Use "setPoints" to set the list of N points. This class also can draw non-closed polygons by 1615 * passing the appropriate parameters to "setPoints". To draw a point-cloud, call "SetContinuity(false)". 1616 */ 1617 class WXDLLIMPEXP_MATHPLOT mpPolygon : public mpMovableObject 1618 { 1619 public: 1620 /** Default constructor. 1621 */ 1622 mpPolygon( const wxString & layerName = wxT("") ) 1623 { 1624 m_continuous = true; 1625 m_name = layerName; 1626 } 1627 ~mpPolygon()1628 virtual ~mpPolygon() {} 1629 1630 /** Set the points in the polygon. 1631 * @param points_xs The X coordinates of the points. 1632 * @param points_ys The Y coordinates of the points. 1633 * @param closedShape If set to true, an additional segment will be added from the last to the first point. 1634 */ 1635 void setPoints( 1636 const std::vector<double>& points_xs, 1637 const std::vector<double>& points_ys, 1638 bool closedShape=true ); 1639 1640 1641 1642 }; 1643 1644 //----------------------------------------------------------------------------- 1645 // mpBitmapLayer - provided by Jose Luis Blanco 1646 //----------------------------------------------------------------------------- 1647 /** A layer that allows you to have a bitmap image printed in the mpWindow. 1648 Use SetBitmap() to load the image in the right place. 1649 You can retrieve the image from the layer at anytime you want with getBitmapCopy() 1650 */ 1651 class WXDLLIMPEXP_MATHPLOT mpBitmapLayer : public mpLayer 1652 { 1653 public: 1654 /** Default constructor. 1655 */ mpBitmapLayer()1656 mpBitmapLayer( ) 1657 { 1658 m_min_x = m_max_x = 1659 m_min_y = m_max_y = 0; 1660 m_validImg = false; 1661 m_type = mpLAYER_BITMAP; 1662 } 1663 ~mpBitmapLayer()1664 virtual ~mpBitmapLayer() {}; 1665 1666 /** Returns a copy of the current bitmap assigned to the layer. 1667 */ 1668 void GetBitmapCopy( wxImage &outBmp ) const; 1669 1670 /** Change the bitmap associated with the layer (to update the screen, refresh the mpWindow). 1671 * @param inBmp The bitmap to associate. A copy is made, thus it can be released after calling this. 1672 * @param x The left corner X coordinate (in plot units). 1673 * @param y The top corner Y coordinate (in plot units). 1674 * @param lx The width in plot units. 1675 * @param ly The height in plot units. 1676 */ 1677 void SetBitmap( const wxImage &inBmp, double x, double y, double lx, double ly ); 1678 HasBBox()1679 virtual bool HasBBox() { return true; } 1680 1681 /** Get inclusive left border of bounding box. 1682 */ GetMinX()1683 virtual double GetMinX() { return m_min_x; } 1684 1685 /** Get inclusive right border of bounding box. 1686 */ GetMaxX()1687 virtual double GetMaxX() { return m_max_x; } 1688 1689 /** Get inclusive bottom border of bounding box. 1690 */ GetMinY()1691 virtual double GetMinY() { return m_min_y; } 1692 1693 /** Get inclusive top border of bounding box. 1694 */ GetMaxY()1695 virtual double GetMaxY() { return m_max_y; } 1696 1697 virtual void Plot(wxDC & dc, mpWindow & w); 1698 1699 /** Set label axis alignment. 1700 * @param align alignment (choose between mpALIGN_NE, mpALIGN_NW, mpALIGN_SW, mpALIGN_SE 1701 */ SetAlign(int align)1702 void SetAlign(int align) { m_flags = align; }; 1703 1704 protected: 1705 int m_flags; //!< Holds label alignment 1706 1707 /** The internal copy of the Bitmap: 1708 */ 1709 wxImage m_bitmap; 1710 wxBitmap m_scaledBitmap; 1711 wxCoord m_scaledBitmap_offset_x,m_scaledBitmap_offset_y; 1712 1713 1714 bool m_validImg; 1715 1716 1717 /** The shape of the bitmap: 1718 */ 1719 double m_min_x,m_max_x,m_min_y,m_max_y; 1720 1721 1722 }; 1723 1724 1725 1726 /*@}*/ 1727 1728 #endif // _MP_MATHPLOT_H_ 1729