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