2016-08-11 12:41:21 +00:00
/////////////////////////////////////////////////////////////////////////////
// Name: mathplot.cpp
// Purpose: Framework for plotting in wxWindows
// Original Author: David Schalig
// Maintainer: Davide Rondini
2016-08-11 12:42:18 +00:00
// Contributors: Jose Luis Blanco, Val Greene, Maciej Suminski, Tomasz Wlostowski
2016-08-11 12:41:21 +00:00
// Created: 21/07/2003
2016-08-11 12:42:18 +00:00
// Last edit: 05/08/2016
2016-08-11 12:41:21 +00:00
// Copyright: (c) David Schalig, Davide Rondini
2024-01-23 01:02:50 +00:00
// Copyright (c) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors.
2016-08-11 12:41:21 +00:00
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
# ifndef _MP_MATHPLOT_H_
# define _MP_MATHPLOT_H_
2016-08-16 07:49:39 +00:00
/**
2016-11-28 13:18:22 +00:00
* wxMathPlot is a framework for mathematical graph plotting in wxWindows .
*
* The framework is designed for convenience and ease of use .
*
* @ section screenshots Screenshots
* < a href = " http://wxmathplot.sourceforge.net/screenshot.shtml " > Go to the screenshots page . < / a >
*
* @ section overview Overview
* The heart of wxMathPlot is mpWindow , which is a 2 D canvas for plot layers .
* mpWindow can be embedded as subwindow in a wxPane , a wxFrame , or any other wxWindow .
* mpWindow provides a zoomable and moveable view of the layers . The current view can
* be controlled with the mouse , the scrollbars , and a context menu .
*
* Plot layers are implementations of the abstract base class mpLayer . Those can
* 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 .
* 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 .
*
* 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 .
*
* @ section coding Coding conventions
* wxMathPlot sticks to wxWindow ' s coding conventions .
* All entities defined by wxMathPlot have the prefix < i > mp < / i > .
*
* @ section author Author and license
* wxMathPlot is published under the terms of the wxWindow license . < br >
* The original author is David Schalig < mrhill @ users . sourceforge . net > . < br >
* From June 2007 the project is maintained by Davide Rondini < cdron77 @ users . sourceforge . net > . < br >
* Authors can be contacted via the wxMathPlot ' s homepage at
* https : //sourceforge.net/projects/wxmathplot<br>
* Contributors : < br >
* Jose Luis Blanco , Val Greene . < br >
*/
2016-08-11 12:41:21 +00:00
2023-04-19 11:51:26 +00:00
2016-11-28 13:18:22 +00:00
// this definition uses windows dll to export function.
// WXDLLIMPEXP_MATHPLOT definition definition changed to WXDLLIMPEXP_MATHPLOT
// mathplot_EXPORTS will be defined by cmake
2016-08-11 12:41:25 +00:00
# ifdef mathplot_EXPORTS
# define WXDLLIMPEXP_MATHPLOT WXEXPORT
2016-11-28 13:18:22 +00:00
# define WXDLLIMPEXP_DATA_MATHPLOT( type ) WXEXPORT type
# else // not making DLL
2016-08-11 12:41:25 +00:00
# define WXDLLIMPEXP_MATHPLOT
2016-11-28 13:18:22 +00:00
# define WXDLLIMPEXP_DATA_MATHPLOT( type ) type
2016-08-11 12:41:21 +00:00
# endif
# include <wx/defs.h>
# include <wx/menu.h>
# include <wx/scrolwin.h>
# include <wx/event.h>
# include <wx/dynarray.h>
# include <wx/pen.h>
# include <wx/dcmemory.h>
# include <wx/string.h>
# include <wx/print.h>
# include <wx/image.h>
2023-09-26 12:18:28 +00:00
# include <vector>
2016-08-11 12:41:21 +00:00
# include <deque>
2023-09-26 12:18:28 +00:00
# include <stack>
# include <array>
2020-05-08 14:34:28 +00:00
# include <algorithm>
2016-08-11 12:41:21 +00:00
// For memory leak debug
# ifdef _WINDOWS
# ifdef _DEBUG
# include <crtdbg.h>
2016-11-28 13:18:22 +00:00
# define DEBUG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__)
2016-08-11 12:41:21 +00:00
# else
2016-11-28 13:18:22 +00:00
# define DEBUG_NEW new
# endif // _DEBUG
# endif // _WINDOWS
2016-08-11 12:41:21 +00:00
// Separation for axes when set close to border
# define X_BORDER_SEPARATION 40
# define Y_BORDER_SEPARATION 60
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
// classes
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
class WXDLLIMPEXP_MATHPLOT mpLayer ;
class WXDLLIMPEXP_MATHPLOT mpFX ;
class WXDLLIMPEXP_MATHPLOT mpFY ;
class WXDLLIMPEXP_MATHPLOT mpFXY ;
class WXDLLIMPEXP_MATHPLOT mpFXYVector ;
class WXDLLIMPEXP_MATHPLOT mpScaleX ;
class WXDLLIMPEXP_MATHPLOT mpScaleY ;
class WXDLLIMPEXP_MATHPLOT mpWindow ;
class WXDLLIMPEXP_MATHPLOT mpPrintout ;
/** Command IDs used by mpWindow */
enum
{
2016-11-28 13:18:22 +00:00
mpID_FIT = 2000 , // !< Fit view to match bounding box of all layers
2023-09-26 12:18:28 +00:00
mpID_ZOOM_UNDO ,
mpID_ZOOM_REDO ,
2016-11-28 13:18:22 +00:00
mpID_ZOOM_IN , // !< Zoom into view at clickposition / window center
mpID_ZOOM_OUT , // !< Zoom out
mpID_CENTER , // !< Center view on click position
2016-08-11 12:41:21 +00:00
} ;
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
// mpLayer
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
typedef enum __mp_Layer_Type
{
mpLAYER_UNDEF , // !< Layer type undefined
mpLAYER_AXIS , // !< Axis type layer
mpLAYER_PLOT , // !< Plot type layer
mpLAYER_INFO , // !< Info box type layer
mpLAYER_BITMAP // !< Bitmap type layer
2016-08-11 12:41:21 +00:00
} mpLayerType ;
/** Plot layer, abstract base class.
2016-11-28 13:18:22 +00:00
* Any number of mpLayer implementations can be attached to mpWindow .
* Examples for mpLayer implementations are function graphs , or scale rulers .
*
* For convenience mpLayer defines a name , a font ( wxFont ) , a pen ( wxPen ) ,
* and a continuity property ( bool ) as class members .
* The default values at constructor are the default font , a black pen , and
* continuity set to false ( draw separate points ) .
* These may or may not be used by implementations .
*/
2016-08-11 12:41:48 +00:00
class mpScaleBase ;
2016-08-11 12:41:21 +00:00
class WXDLLIMPEXP_MATHPLOT mpLayer : public wxObject
{
2016-11-28 13:18:22 +00:00
public :
mpLayer ( ) ;
virtual ~ mpLayer ( ) { } ;
/** Check whether this layer has a bounding box.
2021-03-06 09:27:41 +00:00
* The default implementation returns \ a true . Override and return
* false if your mpLayer implementation should be ignored by the calculation
2016-11-28 13:18:22 +00:00
* of the global bounding box for all layers in a mpWindow .
2021-03-06 09:27:41 +00:00
* @ retval true Has bounding box
* @ retval false Has not bounding box
2016-11-28 13:18:22 +00:00
*/
2021-03-06 09:27:41 +00:00
virtual bool HasBBox ( ) const { return true ; }
2016-11-28 13:18:22 +00:00
/** Check whether the layer is an info box.
2021-06-09 19:32:58 +00:00
* The default implementation returns \ a false . It is overridden to \ a true for mpInfoLayer
2016-11-28 13:18:22 +00:00
* class and its derivative . It is necessary to define mouse actions behaviour over
* info boxes .
* @ return whether the layer is an info boxes
* @ sa mpInfoLayer : : IsInfo
*/
2021-03-06 09:27:41 +00:00
virtual bool IsInfo ( ) const { return false ; } ;
2016-11-28 13:18:22 +00:00
/** Get inclusive left border of bounding box.
* @ return Value
*/
2021-03-06 09:27:41 +00:00
virtual double GetMinX ( ) const { return - 1.0 ; }
2016-11-28 13:18:22 +00:00
/** Get inclusive right border of bounding box.
* @ return Value
*/
2021-03-06 09:27:41 +00:00
virtual double GetMaxX ( ) const { return 1.0 ; }
2016-11-28 13:18:22 +00:00
/** Get inclusive bottom border of bounding box.
* @ return Value
*/
2021-03-06 09:27:41 +00:00
virtual double GetMinY ( ) const { return - 1.0 ; }
2016-11-28 13:18:22 +00:00
/** Get inclusive top border of bounding box.
* @ return Value
*/
2021-03-06 09:27:41 +00:00
virtual double GetMaxY ( ) const { return 1.0 ; }
2016-11-28 13:18:22 +00:00
/** Plot given view of layer to the given device context.
* An implementation of this function has to transform layer coordinates to
* wxDC coordinates based on the view parameters retrievable from the mpWindow
* passed in \ a w .
* Note that the public methods of mpWindow : x2p , y2p and p2x , p2y are already provided
* which transform layer coordinates to DC pixel coordinates , and < b > user code should rely
* on them < / b > for portability and future changes to be applied transparently , instead of
* implementing the following formulas manually .
*
* The passed device context \ a dc has its coordinate origin set to the top - left corner
* of the visible area ( the default ) . The coordinate orientation is as shown in the
* following picture :
* < pre >
* ( wxDC origin 0 , 0 )
* x - - - - - - - - - - - - - > ascending X - - - - - - - - - - - - - - - - +
* | |
* | |
* | V ascending Y |
* | |
* | |
* | |
* | + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + < - - right - bottom corner of the mpWindow visible area .
* < / pre >
* Note that Y ascends in downward direction , whereas the usual vertical orientation
* for mathematical plots is vice versa . Thus Y - orientation will be swapped usually ,
* when transforming between wxDC and mpLayer coordinates . This change of coordinates
* is taken into account in the methods p2x , p2y , x2p , y2p .
*
* < b > Rules for transformation between mpLayer and wxDC coordinates < / b >
* @ code
* dc_X = ( layer_X - mpWindow : : GetPosX ( ) ) * mpWindow : : GetScaleX ( )
* dc_Y = ( mpWindow : : GetPosY ( ) - layer_Y ) * mpWindow : : GetScaleY ( ) // swapping Y-orientation
*
* layer_X = ( dc_X / mpWindow : : GetScaleX ( ) ) + mpWindow : : GetPosX ( ) // scale guaranteed to be not 0
* layer_Y = mpWindow : : GetPosY ( ) - ( dc_Y / mpWindow : : GetScaleY ( ) ) // swapping Y-orientation
* @ endcode
*
* @ param dc Device context to plot to .
* @ param w View to plot . The visible area can be retrieved from this object .
* @ sa mpWindow : : p2x , mpWindow : : p2y , mpWindow : : x2p , mpWindow : : y2p
*/
virtual void Plot ( wxDC & dc , mpWindow & w ) = 0 ;
/** Get layer name.
* @ return Name
*/
const wxString & GetName ( ) const { return m_name ; }
2023-03-19 23:02:23 +00:00
const wxString & GetDisplayName ( ) const
{
return m_displayName . IsEmpty ( ) ? m_name : m_displayName ;
}
2016-11-28 13:18:22 +00:00
/** Get font set for this layer.
* @ return Font
*/
const wxFont & GetFont ( ) const { return m_font ; }
/** Get pen set for this layer.
* @ return Pen
*/
2021-03-06 09:27:41 +00:00
const wxPen & GetPen ( ) const { return m_pen ; }
2016-11-28 13:18:22 +00:00
/** Set the 'continuity' property of the layer (true:draws a continuous line, false:draws separate points).
* @ sa GetContinuity
*/
void SetContinuity ( bool continuity ) { m_continuous = continuity ; }
/** Gets the 'continuity' property of the layer.
* @ sa SetContinuity
*/
bool GetContinuity ( ) const { return m_continuous ; }
/** Shows or hides the text label with the name of the layer (default is visible).
*/
void ShowName ( bool show ) { m_showName = show ; } ;
/** Set layer name
* @ param name Name , will be copied to internal class member
*/
2023-03-19 23:02:23 +00:00
virtual void SetName ( const wxString & name ) { m_name = name ; }
2016-11-28 13:18:22 +00:00
/** Set layer font
* @ param font Font , will be copied to internal class member
*/
2023-06-19 21:52:13 +00:00
void SetFont ( const wxFont & font ) { m_font = font ; }
2016-11-28 13:18:22 +00:00
/** Set layer pen
* @ param pen Pen , will be copied to internal class member
*/
2023-06-19 21:52:13 +00:00
void SetPen ( const wxPen & pen ) { m_pen = pen ; }
2016-11-28 13:18:22 +00:00
/** Get layer type: a Layer can be of different types: plot lines, axis, info boxes, etc, this method returns the right value.
* @ return An integer indicating layer type */
2021-03-06 09:27:41 +00:00
mpLayerType GetLayerType ( ) const { return m_type ; } ;
2016-11-28 13:18:22 +00:00
/** Checks whether the layer is visible or not.
* @ return \ a true if visible */
2021-03-06 09:27:41 +00:00
bool IsVisible ( ) const { return m_visible ; } ;
2016-11-28 13:18:22 +00:00
/** Sets layer visibility.
* @ param show visibility bool . */
void SetVisible ( bool show ) { m_visible = show ; } ;
/** Get brush set for this layer.
* @ return brush . */
const wxBrush & GetBrush ( ) const { return m_brush ; } ;
/** Set layer brush
2021-04-04 06:48:02 +00:00
* @ param brush brush , will be copied to internal class member */
2023-08-02 15:26:17 +00:00
void SetBrush ( const wxBrush & brush ) { m_brush = brush ; } ;
2016-11-28 13:18:22 +00:00
protected :
2023-03-19 23:02:23 +00:00
wxFont m_font ; // !< Layer's font
wxPen m_pen ; // !< Layer's pen
wxBrush m_brush ; // !< Layer's brush
wxString m_name ; // !< Layer's name
wxString m_displayName ;
bool m_continuous ; // !< Specify if the layer will be plotted as a continuous line or a set of points.
bool m_showName ; // !< States whether the name of the layer must be shown (default is true).
mpLayerType m_type ; // !< Define layer type, which is assigned by constructor
bool m_visible ; // !< Toggles layer visibility
2016-11-28 13:18:22 +00:00
DECLARE_DYNAMIC_CLASS ( mpLayer )
2016-08-11 12:41:21 +00:00
} ;
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
// mpInfoLayer
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
/** @class mpInfoLayer
2016-11-28 13:18:22 +00:00
* @ brief Base class to create small rectangular info boxes
* 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 .
*/
2016-08-11 12:41:21 +00:00
class WXDLLIMPEXP_MATHPLOT mpInfoLayer : public mpLayer
{
2016-11-28 13:18:22 +00:00
public :
/** Default constructor. */
mpInfoLayer ( ) ;
/** Complete constructor.
* @ param rect Sets the initial size rectangle of the layer .
* @ param brush pointer to a fill brush . Default is transparent */
mpInfoLayer ( wxRect rect , const wxBrush * brush = wxTRANSPARENT_BRUSH ) ;
/** Destructor */
virtual ~ mpInfoLayer ( ) ;
/** mpInfoLayer has not bounding box. @sa mpLayer::HasBBox
2021-03-06 09:27:41 +00:00
* @ return always \ a false */
virtual bool HasBBox ( ) const override { return false ; }
2016-11-28 13:18:22 +00:00
2021-06-09 19:32:58 +00:00
/** Plot method. Can be overridden by derived classes.
2016-11-28 13:18:22 +00:00
* @ param dc the device content where to plot
* @ param w the window to plot
* @ sa mpLayer : : Plot */
virtual void Plot ( wxDC & dc , mpWindow & w ) override ;
/** Specifies that this is an Info box layer.
2021-03-06 09:27:41 +00:00
* @ return always \ a true
2016-11-28 13:18:22 +00:00
* @ sa mpLayer : : IsInfo */
2021-03-06 09:27:41 +00:00
virtual bool IsInfo ( ) const override { return true ; }
2016-11-28 13:18:22 +00:00
/** Checks whether a point is inside the info box rectangle.
* @ param point The point to be checked
* @ return \ a true if the point is inside the bounding box */
2023-01-31 17:29:46 +00:00
virtual bool Inside ( const wxPoint & point ) const ;
2016-11-28 13:18:22 +00:00
/** Moves the layer rectangle of given pixel deltas.
* @ param delta The wxPoint container for delta coordinates along x and y . Units are in pixels . */
virtual void Move ( wxPoint delta ) ;
/** Updates the rectangle reference point. Used by internal methods of mpWindow to correctly move mpInfoLayers. */
virtual void UpdateReference ( ) ;
/** Returns the position of the upper left corner of the box (in pixels)
* @ return The rectangle position */
2021-03-06 09:27:41 +00:00
wxPoint GetPosition ( ) const ;
2016-11-28 13:18:22 +00:00
/** Returns the size of the box (in pixels)
* @ return The rectangle size */
2021-03-06 09:27:41 +00:00
wxSize GetSize ( ) const ;
2016-11-28 13:18:22 +00:00
protected :
2023-08-02 15:26:17 +00:00
wxRect m_dim ; // !< The bounding rectangle of the box. It may be resized dynamically
// by the Plot method.
wxPoint m_reference ; // !< Holds the reference point for movements
wxBrush m_brush ; // !< The brush to be used for the background
int m_winX ; // !< Holds the mpWindow size. Used to rescale position when window is
int m_winY ; // resized.
2016-11-28 13:18:22 +00:00
DECLARE_DYNAMIC_CLASS ( mpInfoLayer )
2016-08-11 12:41:21 +00:00
} ;
/** @class mpInfoLegend
2016-11-28 13:18:22 +00:00
* @ brief Implements the legend to be added to the plot
* 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 . */
2016-08-11 12:41:21 +00:00
class WXDLLIMPEXP_MATHPLOT mpInfoLegend : public mpInfoLayer
{
2016-11-28 13:18:22 +00:00
public :
/** Default constructor */
mpInfoLegend ( ) ;
/** Complete constructor, setting initial rectangle and background brush.
* @ param rect The initial bounding rectangle .
* @ param brush The wxBrush to be used for box background : default is transparent
* @ sa mpInfoLayer : : mpInfoLayer */
mpInfoLegend ( wxRect rect , const wxBrush * brush = wxTRANSPARENT_BRUSH ) ;
/** Default destructor */
~ mpInfoLegend ( ) ;
/** Plot method.
* @ param dc the device content where to plot
* @ param w the window to plot
2023-08-02 15:26:17 +00:00
*/
2016-11-28 13:18:22 +00:00
virtual void Plot ( wxDC & dc , mpWindow & w ) override ;
protected :
2016-08-11 12:41:21 +00:00
} ;
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
// mpLayer implementations - functions
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
/** @name Label alignment constants
2016-11-28 13:18:22 +00:00
* @ { */
2016-08-11 12:41:21 +00:00
/** @internal */
2016-11-28 13:18:22 +00:00
# define mpALIGNMASK 0x03
2016-08-11 12:41:21 +00:00
/** Aligns label to the right. For use with mpFX. */
2016-11-28 13:18:22 +00:00
# define mpALIGN_RIGHT 0x00
2016-08-11 12:41:21 +00:00
/** Aligns label to the center. For use with mpFX and mpFY. */
2016-11-28 13:18:22 +00:00
# define mpALIGN_CENTER 0x01
2016-08-11 12:41:21 +00:00
/** Aligns label to the left. For use with mpFX. */
2016-11-28 13:18:22 +00:00
# define mpALIGN_LEFT 0x02
2016-08-11 12:41:21 +00:00
/** Aligns label to the top. For use with mpFY. */
2016-11-28 13:18:22 +00:00
# define mpALIGN_TOP mpALIGN_RIGHT
2016-08-11 12:41:21 +00:00
/** Aligns label to the bottom. For use with mpFY. */
2016-11-28 13:18:22 +00:00
# define mpALIGN_BOTTOM mpALIGN_LEFT
2016-08-11 12:41:21 +00:00
/** Aligns X axis to bottom border. For mpScaleX */
2016-11-28 13:18:22 +00:00
# define mpALIGN_BORDER_BOTTOM 0x04
2016-08-11 12:41:21 +00:00
/** Aligns X axis to top border. For mpScaleX */
2016-11-28 13:18:22 +00:00
# define mpALIGN_BORDER_TOP 0x05
2023-02-10 20:52:52 +00:00
/** Aligns label to the right of mpALIGN_RIGHT */
# define mpALIGN_FAR_RIGHT 0x06
2016-08-11 12:41:21 +00:00
/** Set label for X axis in normal mode */
2016-11-28 13:18:22 +00:00
# define mpX_NORMAL 0x00
2016-08-11 12:41:21 +00:00
/** 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. */
2016-11-28 13:18:22 +00:00
# define mpX_TIME 0x01
2016-08-11 12:41:21 +00:00
/** Set label for X axis in hours mode: the value is always represented as hours:minutes:seconds. */
2016-11-28 13:18:22 +00:00
# define mpX_HOURS 0x02
2016-08-11 12:41:21 +00:00
/** Set label for X axis in date mode: the value is always represented as yyyy-mm-dd. */
2016-11-28 13:18:22 +00:00
# define mpX_DATE 0x03
2016-08-11 12:41:21 +00:00
/** Set label for X axis in datetime mode: the value is always represented as yyyy-mm-ddThh:mm:ss. */
2016-11-28 13:18:22 +00:00
# define mpX_DATETIME 0x04
2016-08-11 12:41:21 +00:00
/** Aligns Y axis to left border. For mpScaleY */
2016-11-28 13:18:22 +00:00
# define mpALIGN_BORDER_LEFT mpALIGN_BORDER_BOTTOM
2016-08-11 12:41:21 +00:00
/** Aligns Y axis to right border. For mpScaleY */
2016-11-28 13:18:22 +00:00
# define mpALIGN_BORDER_RIGHT mpALIGN_BORDER_TOP
2016-08-11 12:41:21 +00:00
/** Aligns label to north-east. For use with mpFXY. */
2016-11-28 13:18:22 +00:00
# define mpALIGN_NE 0x00
2016-08-11 12:41:21 +00:00
/** Aligns label to north-west. For use with mpFXY. */
2016-11-28 13:18:22 +00:00
# define mpALIGN_NW 0x01
2016-08-11 12:41:21 +00:00
/** Aligns label to south-west. For use with mpFXY. */
2016-11-28 13:18:22 +00:00
# define mpALIGN_SW 0x02
2016-08-11 12:41:21 +00:00
/** Aligns label to south-east. For use with mpFXY. */
2016-11-28 13:18:22 +00:00
# define mpALIGN_SE 0x03
2016-08-11 12:41:21 +00:00
/*@}*/
/** @name mpLayer implementations - functions
2016-11-28 13:18:22 +00:00
* @ { */
2016-08-11 12:41:21 +00:00
/** Abstract base class providing plot and labeling functionality for functions F:X->Y.
2016-11-28 13:18:22 +00:00
* Override mpFX : : GetY to implement a function .
* Optionally implement a constructor and pass a name ( label ) and a label alignment
* to the constructor mpFX : : mpFX . If the layer name is empty , no label will be plotted .
*/
2016-08-11 12:41:21 +00:00
class WXDLLIMPEXP_MATHPLOT mpFX : public mpLayer
{
2016-11-28 13:18:22 +00:00
public :
/** @param name Label
* @ param flags Label alignment , pass one of # mpALIGN_RIGHT , # mpALIGN_CENTER , # mpALIGN_LEFT .
*/
2017-09-23 09:20:10 +00:00
mpFX ( const wxString & name = wxEmptyString , int flags = mpALIGN_RIGHT ) ;
2016-11-28 13:18:22 +00:00
/** Get function value for argument.
* Override this function in your implementation .
* @ param x Argument
* @ return Function value
*/
2021-03-06 09:27:41 +00:00
virtual double GetY ( double x ) const = 0 ;
2016-11-28 13:18:22 +00:00
/** Layer plot handler.
2023-08-02 15:26:17 +00:00
* This implementation will plot the function in the visible area and put a label according
* to the alignment specified .
2016-11-28 13:18:22 +00:00
*/
virtual void Plot ( wxDC & dc , mpWindow & w ) override ;
protected :
int m_flags ; // !< Holds label alignment
DECLARE_DYNAMIC_CLASS ( mpFX )
2016-08-11 12:41:21 +00:00
} ;
/** Abstract base class providing plot and labeling functionality for functions F:Y->X.
2016-11-28 13:18:22 +00:00
* Override mpFY : : GetX to implement a function .
2023-08-02 15:26:17 +00:00
* Optionally implement a constructor and pass a name ( label ) and a label alignment to the
* constructor mpFY : : mpFY . If the layer name is empty , no label will be plotted .
2016-11-28 13:18:22 +00:00
*/
2016-08-11 12:41:21 +00:00
class WXDLLIMPEXP_MATHPLOT mpFY : public mpLayer
{
2016-11-28 13:18:22 +00:00
public :
/** @param name Label
* @ param flags Label alignment , pass one of # mpALIGN_BOTTOM , # mpALIGN_CENTER , # mpALIGN_TOP .
*/
2017-09-23 09:20:10 +00:00
mpFY ( const wxString & name = wxEmptyString , int flags = mpALIGN_TOP ) ;
2016-11-28 13:18:22 +00:00
/** Get function value for argument.
* Override this function in your implementation .
* @ param y Argument
* @ return Function value
*/
2021-03-06 09:27:41 +00:00
virtual double GetX ( double y ) const = 0 ;
2016-11-28 13:18:22 +00:00
/** Layer plot handler.
2023-08-02 15:26:17 +00:00
* This implementation will plot the function in the visible area and put a label according
* to the alignment specified .
2016-11-28 13:18:22 +00:00
*/
virtual void Plot ( wxDC & dc , mpWindow & w ) override ;
protected :
int m_flags ; // !< Holds label alignment
DECLARE_DYNAMIC_CLASS ( mpFY )
2016-08-11 12:41:21 +00:00
} ;
/** Abstract base class providing plot and labeling functionality for a locus plot F:N->X,Y.
2016-11-28 13:18:22 +00:00
* Locus argument N is assumed to be in range 0 . . MAX_N , and implicitly derived by enumerating
* all locus values . Override mpFXY : : Rewind and mpFXY : : GetNextXY to implement a locus .
* Optionally implement a constructor and pass a name ( label ) and a label alignment
* to the constructor mpFXY : : mpFXY . If the layer name is empty , no label will be plotted .
*/
2016-08-11 12:41:48 +00:00
2016-08-11 12:41:21 +00:00
class WXDLLIMPEXP_MATHPLOT mpFXY : public mpLayer
{
2016-11-28 13:18:22 +00:00
public :
/** @param name Label
* @ param flags Label alignment , pass one of # mpALIGN_NE , # mpALIGN_NW , # mpALIGN_SW , # mpALIGN_SE .
*/
2017-09-23 09:20:10 +00:00
mpFXY ( const wxString & name = wxEmptyString , int flags = mpALIGN_NE ) ;
2016-11-28 13:18:22 +00:00
/** Rewind value enumeration with mpFXY::GetNextXY.
* Override this function in your implementation .
*/
virtual void Rewind ( ) = 0 ;
2024-05-23 11:24:13 +00:00
virtual void SetSweepWindow ( int aSweepIdx ) { Rewind ( ) ; }
2016-11-28 13:18:22 +00:00
/** Get locus value for next N.
* Override this function in your implementation .
* @ param x Returns X value
* @ param y Returns Y value
*/
virtual bool GetNextXY ( double & x , double & y ) = 0 ;
2021-03-06 09:27:41 +00:00
virtual size_t GetCount ( ) const = 0 ;
2024-05-23 11:24:13 +00:00
virtual int GetSweepCount ( ) const { return 1 ; }
2019-11-19 16:17:37 +00:00
2016-11-28 13:18:22 +00:00
/** Layer plot handler.
2023-08-02 15:26:17 +00:00
* This implementation will plot the locus in the visible area and put a label according to
* the alignment specified .
2016-11-28 13:18:22 +00:00
*/
virtual void Plot ( wxDC & dc , mpWindow & w ) override ;
virtual void SetScale ( mpScaleBase * scaleX , mpScaleBase * scaleY ) ;
void UpdateScales ( ) ;
double s2x ( double plotCoordX ) const ;
double s2y ( double plotCoordY ) const ;
double x2s ( double x ) const ;
double y2s ( double y ) const ;
protected :
int m_flags ; // !< Holds label alignment
// Data to calculate label positioning
wxCoord maxDrawX , minDrawX , maxDrawY , minDrawY ;
// int drawnPoints;
mpScaleBase * m_scaleX , * m_scaleY ;
/** Update label positioning data
* @ param xnew New x coordinate
* @ param ynew New y coordinate
*/
void UpdateViewBoundary ( wxCoord xnew , wxCoord ynew ) ;
DECLARE_DYNAMIC_CLASS ( mpFXY )
2016-08-11 12:41:21 +00:00
} ;
/*@}*/
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
// mpLayer implementations - furniture (scales, ...)
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
/** @name mpLayer implementations - furniture (scales, ...)
2016-11-28 13:18:22 +00:00
* @ { */
2016-08-11 12:41:21 +00:00
/** Plot layer implementing a x-scale ruler.
2023-08-02 15:26:17 +00:00
* The ruler is fixed at Y = 0 in the coordinate system . A label is plotted at the bottom - right
* hand of the ruler . The scale numbering automatically adjusts to view and zoom factor .
2016-11-28 13:18:22 +00:00
*/
2016-08-11 12:41:48 +00:00
class WXDLLIMPEXP_MATHPLOT mpScaleBase : public mpLayer
{
2016-11-28 13:18:22 +00:00
public :
2016-12-30 11:39:41 +00:00
mpScaleBase ( ) ;
2016-11-28 13:18:22 +00:00
virtual ~ mpScaleBase ( ) { } ;
2016-08-11 12:41:48 +00:00
2021-03-06 09:27:41 +00:00
virtual bool IsHorizontal ( ) const = 0 ;
2016-08-11 12:41:48 +00:00
2021-03-06 09:27:41 +00:00
bool HasBBox ( ) const override { return false ; }
2016-08-11 12:42:04 +00:00
2016-11-28 13:18:22 +00:00
/** Set X axis alignment.
2017-06-16 07:14:28 +00:00
* @ param align alignment ( choose between mpALIGN_BORDER_BOTTOM , mpALIGN_BOTTOM , mpALIGN_CENTER ,
* mpALIGN_TOP , mpALIGN_BORDER_TOP
*/
2016-11-28 13:18:22 +00:00
void SetAlign ( int align ) { m_flags = align ; } ;
2016-08-11 12:41:48 +00:00
2016-11-28 13:18:22 +00:00
void SetNameAlign ( int align ) { m_nameFlags = align ; }
2016-08-11 12:41:48 +00:00
2016-11-28 13:18:22 +00:00
/** Set X axis ticks or grid
2017-06-16 07:14:28 +00:00
* @ param enable = true to plot axis ticks , false to plot grid .
*/
2016-11-28 13:18:22 +00:00
void SetTicks ( bool enable ) { m_ticks = enable ; } ;
2016-08-11 12:41:48 +00:00
2016-11-28 13:18:22 +00:00
/** Get X axis ticks or grid
2021-03-06 09:27:41 +00:00
* @ return true if plot is drawing axis ticks , false if the grid is active .
2017-06-16 07:14:28 +00:00
*/
2021-03-06 09:27:41 +00:00
bool GetTicks ( ) const { return m_ticks ; } ;
2016-08-11 12:41:48 +00:00
2021-03-06 09:27:41 +00:00
void GetDataRange ( double & minV , double & maxV ) const
2016-11-28 13:18:22 +00:00
{
minV = m_minV ;
maxV = m_maxV ;
}
2016-08-11 12:41:49 +00:00
2023-06-18 15:23:38 +00:00
virtual void ExtendDataRange ( double minV , double maxV )
2016-11-28 13:18:22 +00:00
{
if ( ! m_rangeSet )
2016-08-11 12:42:18 +00:00
{
2016-11-28 13:18:22 +00:00
m_minV = minV ;
m_maxV = maxV ;
m_rangeSet = true ;
2016-08-11 12:42:18 +00:00
}
2016-11-28 13:18:22 +00:00
else
2016-08-11 12:42:18 +00:00
{
2016-11-28 13:18:22 +00:00
m_minV = std : : min ( minV , m_minV ) ;
m_maxV = std : : max ( maxV , m_maxV ) ;
2016-08-11 12:42:18 +00:00
}
2016-11-28 13:18:22 +00:00
if ( m_minV = = m_maxV )
2016-08-11 12:42:18 +00:00
{
2018-05-28 14:41:12 +00:00
m_minV = m_minV - 1.0 ;
m_maxV = m_maxV + 1.0 ;
2016-08-11 12:42:18 +00:00
}
2016-11-28 13:18:22 +00:00
}
2016-08-11 12:41:49 +00:00
2023-09-20 16:23:08 +00:00
virtual void ResetDataRange ( )
2016-11-28 13:18:22 +00:00
{
2023-06-18 15:23:38 +00:00
m_rangeSet = false ;
2016-11-28 13:18:22 +00:00
}
2016-08-11 12:42:04 +00:00
2016-11-28 13:18:22 +00:00
double AbsMaxValue ( ) const
{
return std : : max ( std : : abs ( m_maxV ) , std : : abs ( m_minV ) ) ;
}
2016-08-11 12:42:04 +00:00
2016-11-28 13:18:22 +00:00
double AbsVisibleMaxValue ( ) const
{
return m_absVisibleMaxV ;
}
2016-08-11 12:41:48 +00:00
2023-07-19 15:25:57 +00:00
void SetAxisMinMax ( bool lock , double minV , double maxV )
{
m_axisLocked = lock ;
m_axisMin = minV ;
m_axisMax = maxV ;
}
bool GetAxisMinMax ( double * minV , double * maxV )
{
if ( m_axisLocked )
{
* minV = m_axisMin ;
* maxV = m_axisMax ;
}
else if ( ! m_tickValues . empty ( ) )
{
* minV = m_tickValues . front ( ) ;
* maxV = m_tickValues . back ( ) ;
}
return m_axisLocked ;
}
2021-03-06 09:27:41 +00:00
virtual double TransformToPlot ( double x ) const { return 0.0 ; } ;
virtual double TransformFromPlot ( double xplot ) const { return 0.0 ; } ;
2016-08-11 12:41:49 +00:00
2023-08-02 15:26:17 +00:00
struct TICK_LABEL
2016-11-28 13:18:22 +00:00
{
2023-08-02 15:26:17 +00:00
TICK_LABEL ( double pos_ = 0.0 , const wxString & label_ = wxT ( " " ) ) :
2023-08-02 14:43:53 +00:00
pos ( pos_ ) ,
label ( label_ ) ,
visible ( true )
2016-12-30 13:36:23 +00:00
{ }
2023-08-02 14:43:53 +00:00
double pos ;
2016-11-28 13:18:22 +00:00
wxString label ;
2023-08-02 14:43:53 +00:00
bool visible ;
2016-11-28 13:18:22 +00:00
} ;
2016-08-11 12:42:04 +00:00
2016-11-28 13:18:22 +00:00
protected :
2016-08-11 12:42:04 +00:00
2023-08-02 15:26:17 +00:00
void updateTickLabels ( wxDC & dc , mpWindow & w ) ;
void computeLabelExtents ( wxDC & dc , mpWindow & w ) ;
2016-08-11 12:42:04 +00:00
2021-03-06 09:27:41 +00:00
// virtual int getLabelDecimalDigits(int maxDigits) const;
2016-11-28 13:18:22 +00:00
virtual void getVisibleDataRange ( mpWindow & w , double & minV , double & maxV ) { } ;
virtual void recalculateTicks ( wxDC & dc , mpWindow & w ) { } ;
2016-08-11 12:42:04 +00:00
2016-11-28 13:18:22 +00:00
virtual void formatLabels ( ) { } ;
2016-08-11 12:42:04 +00:00
2023-07-19 15:25:57 +00:00
protected :
2023-08-02 15:26:17 +00:00
std : : vector < double > m_tickValues ;
std : : vector < TICK_LABEL > m_tickLabels ;
double m_offset , m_scale ;
double m_absVisibleMaxV ;
int m_flags ; // !< Flag for axis alignment
int m_nameFlags ;
bool m_ticks ; // !< Flag to toggle between ticks or grid
double m_minV , m_maxV ;
bool m_rangeSet ;
bool m_axisLocked ;
double m_axisMin ;
double m_axisMax ;
int m_maxLabelHeight ;
int m_maxLabelWidth ;
2016-08-11 12:41:48 +00:00
} ;
class WXDLLIMPEXP_MATHPLOT mpScaleXBase : public mpScaleBase
2016-08-11 12:41:21 +00:00
{
2016-11-28 13:18:22 +00:00
public :
/** Full constructor.
* @ param name Label to plot by the ruler
* @ param flags Set the position of the scale with respect to the window .
2023-08-02 15:26:17 +00:00
* @ param ticks Select ticks or grid . Give true ( default ) for drawing axis ticks , false for
* drawing the grid .
2016-11-28 13:18:22 +00:00
* @ param type mpX_NORMAL for normal labels , mpX_TIME for time axis in hours , minutes , seconds .
*/
2023-08-02 15:26:17 +00:00
mpScaleXBase ( const wxString & name = wxT ( " X " ) , int flags = mpALIGN_CENTER , bool ticks = true ,
unsigned int type = mpX_NORMAL ) ;
2016-11-28 13:18:22 +00:00
virtual ~ mpScaleXBase ( ) { } ;
2021-03-06 09:27:41 +00:00
virtual bool IsHorizontal ( ) const override { return true ; }
2016-11-28 13:18:22 +00:00
virtual void Plot ( wxDC & dc , mpWindow & w ) override ;
virtual void getVisibleDataRange ( mpWindow & w , double & minV , double & maxV ) override ;
DECLARE_DYNAMIC_CLASS ( mpScaleXBase )
2016-08-11 12:41:48 +00:00
} ;
2016-08-11 12:41:25 +00:00
2016-08-11 12:41:48 +00:00
class WXDLLIMPEXP_MATHPLOT mpScaleX : public mpScaleXBase
{
2016-11-28 13:18:22 +00:00
public :
/** Full constructor.
* @ param name Label to plot by the ruler
* @ param flags Set the position of the scale with respect to the window .
2023-08-02 15:26:17 +00:00
* @ param ticks Select ticks or grid . Give true ( default ) for drawing axis ticks , false for
* drawing the grid .
* @ param type mpX_NORMAL for normal labels , mpX_TIME for time axis in hours , minutes , seconds .
*/
mpScaleX ( const wxString & name = wxT ( " X " ) , int flags = mpALIGN_CENTER , bool ticks = true ,
unsigned int type = mpX_NORMAL ) ;
2016-08-11 12:41:25 +00:00
2021-03-06 09:27:41 +00:00
virtual double TransformToPlot ( double x ) const override ;
virtual double TransformFromPlot ( double xplot ) const override ;
2016-08-11 12:41:25 +00:00
2016-11-28 13:18:22 +00:00
protected :
virtual void recalculateTicks ( wxDC & dc , mpWindow & w ) override ;
2016-08-11 12:41:48 +00:00
2016-11-28 13:18:22 +00:00
DECLARE_DYNAMIC_CLASS ( mpScaleX )
2016-08-11 12:41:21 +00:00
} ;
2016-08-11 12:41:48 +00:00
class WXDLLIMPEXP_MATHPLOT mpScaleXLog : public mpScaleXBase
{
2016-11-28 13:18:22 +00:00
public :
/** Full constructor.
* @ param name Label to plot by the ruler
* @ param flags Set the position of the scale with respect to the window .
2023-08-02 15:26:17 +00:00
* @ param ticks Select ticks or grid . Give true ( default ) for drawing axis ticks , false for
* drawing the grid .
2016-11-28 13:18:22 +00:00
* @ param type mpX_NORMAL for normal labels , mpX_TIME for time axis in hours , minutes , seconds .
*/
2023-08-02 15:26:17 +00:00
mpScaleXLog ( const wxString & name = wxT ( " log(X) " ) , int flags = mpALIGN_CENTER ,
2016-11-28 13:18:22 +00:00
bool ticks = true , unsigned int type = mpX_NORMAL ) ;
2021-03-06 09:27:41 +00:00
virtual double TransformToPlot ( double x ) const override ;
virtual double TransformFromPlot ( double xplot ) const override ;
2016-11-28 13:18:22 +00:00
protected :
void recalculateTicks ( wxDC & dc , mpWindow & w ) override ;
DECLARE_DYNAMIC_CLASS ( mpScaleXLog )
} ;
2016-08-11 12:41:48 +00:00
2016-11-28 13:18:22 +00:00
/** Plot layer implementing a y-scale ruler.
* 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
* the top - right hand of the ruler .
* The scale numbering automatically adjusts to view and zoom factor .
*/
class WXDLLIMPEXP_MATHPLOT mpScaleY : public mpScaleBase
{
public :
/** @param name Label to plot by the ruler
* @ param flags Set position of the scale respect to the window .
2023-08-02 15:26:17 +00:00
* @ param ticks Select ticks or grid . Give true ( default ) for drawing axis ticks , false for
* drawing the grid
2016-11-28 13:18:22 +00:00
*/
2021-03-06 09:27:41 +00:00
mpScaleY ( const wxString & name = wxT ( " Y " ) , int flags = mpALIGN_CENTER , bool ticks = true ) ;
2016-08-11 12:41:48 +00:00
2021-03-06 09:27:41 +00:00
virtual bool IsHorizontal ( ) const override { return false ; }
2016-08-11 12:41:48 +00:00
2016-11-28 13:18:22 +00:00
/** Layer plot handler.
* This implementation will plot the ruler adjusted to the visible area .
*/
virtual void Plot ( wxDC & dc , mpWindow & w ) override ;
2016-08-11 12:41:48 +00:00
2016-11-28 13:18:22 +00:00
/** Check whether this layer has a bounding box.
2021-03-06 09:27:41 +00:00
* This implementation returns \ a false thus making the ruler invisible
2016-11-28 13:18:22 +00:00
* to the plot layer bounding box calculation by mpWindow .
*/
2021-03-06 09:27:41 +00:00
virtual bool HasBBox ( ) const override { return false ; }
2016-08-11 12:41:48 +00:00
2021-03-06 09:27:41 +00:00
virtual double TransformToPlot ( double x ) const override ;
virtual double TransformFromPlot ( double xplot ) const override ;
2016-08-11 12:41:25 +00:00
2023-08-02 15:26:17 +00:00
void SetMasterScale ( mpScaleY * masterScale ) { m_masterScale = masterScale ; }
2016-08-11 12:41:25 +00:00
2016-11-28 13:18:22 +00:00
protected :
virtual void getVisibleDataRange ( mpWindow & w , double & minV , double & maxV ) override ;
virtual void recalculateTicks ( wxDC & dc , mpWindow & w ) override ;
2016-08-11 12:41:25 +00:00
2016-11-28 13:18:22 +00:00
void computeSlaveTicks ( mpWindow & w ) ;
2016-08-11 12:41:25 +00:00
2016-11-28 13:18:22 +00:00
mpScaleY * m_masterScale ;
2023-08-02 15:26:17 +00:00
int m_flags ; // !< Flag for axis alignment
bool m_ticks ; // !< Flag to toggle between ticks or grid
2016-08-11 12:41:48 +00:00
2016-11-28 13:18:22 +00:00
DECLARE_DYNAMIC_CLASS ( mpScaleY )
2016-08-11 12:41:21 +00:00
} ;
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
// mpWindow
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
/** @name Constants defining mouse modes for mpWindow
2016-11-28 13:18:22 +00:00
* @ { */
2016-08-11 12:41:21 +00:00
/** Mouse panning drags the view. Mouse mode for mpWindow. */
# define mpMOUSEMODE_DRAG 0
/** Mouse panning creates a zoom box. Mouse mode for mpWindow. */
# define mpMOUSEMODE_ZOOMBOX 1
/*@}*/
/** Define the type for the list of layers inside mpWindow */
2016-11-28 13:18:22 +00:00
// WX_DECLARE_HASH_MAP( int, mpLayer*, wxIntegerHash, wxIntegerEqual, wxLayerList );
2016-08-11 12:41:21 +00:00
typedef std : : deque < mpLayer * > wxLayerList ;
/** Canvas for plotting mpLayer implementations.
2016-11-28 13:18:22 +00:00
*
* This class defines a zoomable and moveable 2 D plot canvas . Any number
* of mpLayer implementations ( scale rulers , function plots , . . . ) can be
* attached using mpWindow : : AddLayer .
*
* The canvas window provides a context menu with actions for navigating the view .
* The context menu can be retrieved with mpWindow : : GetPopupMenu , e . g . for extending it
* externally .
*
* Since wxMathPlot version 0.03 , the mpWindow incorporates the following features :
* - DoubleBuffering ( Default = disabled ) : Can be set with EnableDoubleBuffer
* - Mouse based pan / zoom ( Default = enabled ) : Can be set with EnableMousePanZoom .
*
* The mouse commands can be visualized by the user through the popup menu , and are :
* - Mouse Move + CTRL : Pan ( Move )
* - Mouse Wheel : Vertical scroll
* - Mouse Wheel + SHIFT : Horizontal scroll
* - Mouse Wheel UP + CTRL : Zoom in
* - Mouse Wheel DOWN + CTRL : Zoom out
*
*/
2016-08-11 12:41:21 +00:00
class WXDLLIMPEXP_MATHPLOT mpWindow : public wxWindow
{
2016-11-28 13:18:22 +00:00
public :
2024-01-23 01:02:50 +00:00
/**
* Enumerates the possible mouse wheel actions that can be performed on the plot .
*/
enum class MouseWheelAction
{
NONE ,
PAN_LEFT_RIGHT ,
PAN_RIGHT_LEFT ,
PAN_UP_DOWN ,
ZOOM ,
ZOOM_HORIZONTALLY ,
ZOOM_VERTICALLY ,
COUNT // Internal use only
} ;
/**
* Contains the set of modified mouse wheel actions that can be performed on the plot .
*/
struct MouseWheelActionSet
{
/* If this bundled wxMathPlot implementation is to remain single-header and not dependent
* on any part of KiCad , then the SIM_MOUSE_WHEEL_ACTION_SET struct must be duplicated
* here . SIM_PLOT_TAB : : convertMouseWheelActions is used to convert from
* SIM_MOUSE_WHEEL_ACTION_SET to mpWindow : : MouseWheelActionSet . */
MouseWheelAction verticalUnmodified ;
MouseWheelAction verticalWithCtrl ;
MouseWheelAction verticalWithShift ;
MouseWheelAction verticalWithAlt ;
MouseWheelAction horizontal ;
} ;
2020-09-22 11:29:13 +00:00
mpWindow ( ) ;
2023-07-05 17:25:52 +00:00
mpWindow ( wxWindow * parent , wxWindowID id ) ;
2016-11-28 13:18:22 +00:00
~ mpWindow ( ) ;
/** Get reference to context menu of the plot canvas.
* @ return Pointer to menu . The menu can be modified .
*/
wxMenu * GetPopupMenu ( ) { return & m_popmenu ; }
/** Add a plot layer to the canvas.
* @ param layer Pointer to layer . The mpLayer object will get under control of mpWindow ,
* i . e . it will be delete ' d on mpWindow destruction
2023-08-02 15:26:17 +00:00
* @ param refreshDisplay States whether to refresh the display ( UpdateAll ) after adding the
* layer .
2021-03-06 09:27:41 +00:00
* @ retval true Success
* @ retval false Failure due to out of memory .
2016-11-28 13:18:22 +00:00
*/
bool AddLayer ( mpLayer * layer , bool refreshDisplay = true ) ;
/** Remove a plot layer from the canvas.
* @ param layer Pointer to layer . The mpLayer object will be destructed using delete .
2023-08-02 15:26:17 +00:00
* @ param alsoDeleteObject If set to true , the mpLayer object will be also " deleted " , not just
* removed from the internal list .
* @ param refreshDisplay States whether to refresh the display ( UpdateAll ) after removing the
* layer .
2016-11-28 13:18:22 +00:00
* @ return true if layer is deleted correctly
*
* N . B . Only the layer reference in the mpWindow is deleted , the layer object still exists !
*/
bool DelLayer ( mpLayer * layer , bool alsoDeleteObject = false , bool refreshDisplay = true ) ;
/** Remove all layers from the plot.
2023-08-02 15:26:17 +00:00
* @ param alsoDeleteObject If set to true , the mpLayer objects will be also " deleted " , not
* just removed from the internal list .
* @ param refreshDisplay States whether to refresh the display ( UpdateAll ) after removing the
* layers .
2016-11-28 13:18:22 +00:00
*/
void DelAllLayers ( bool alsoDeleteObject , bool refreshDisplay = true ) ;
/*! Get the layer in list position indicated.
* N . B . You < i > must < / i > know the index of the layer inside the list !
* @ param position position of the layer in the layers list
* @ return pointer to mpLayer
*/
2021-03-06 09:27:41 +00:00
mpLayer * GetLayer ( int position ) const ;
2016-11-28 13:18:22 +00:00
/*! Get the layer by its name (case sensitive).
* @ param name The name of the layer to retrieve
* @ return A pointer to the mpLayer object , or NULL if not found .
*/
2021-03-06 09:27:41 +00:00
const mpLayer * GetLayerByName ( const wxString & name ) const ;
mpLayer * GetLayerByName ( const wxString & name )
{
return const_cast < mpLayer * > ( static_cast < const mpWindow * > ( this ) - > GetLayerByName ( name ) ) ;
}
2016-11-28 13:18:22 +00:00
/** Get current view's X scale.
* See @ ref mpLayer : : Plot " rules for coordinate transformation "
* @ return Scale
*/
2023-07-19 15:25:57 +00:00
double GetScaleX ( ) const { return m_scaleX ; } ;
2016-11-28 13:18:22 +00:00
/** Get current view's Y scale.
* See @ ref mpLayer : : Plot " rules for coordinate transformation "
* @ return Scale
*/
2023-07-19 15:25:57 +00:00
double GetScaleY ( ) const { return m_scaleY ; }
2016-11-28 13:18:22 +00:00
/** Get current view's X position.
* See @ ref mpLayer : : Plot " rules for coordinate transformation "
* @ return X Position in layer coordinate system , that corresponds to the center point of the view .
*/
2023-07-19 15:25:57 +00:00
double GetPosX ( ) const { return m_posX ; }
2016-11-28 13:18:22 +00:00
/** Get current view's Y position.
* See @ ref mpLayer : : Plot " rules for coordinate transformation "
* @ return Y Position in layer coordinate system , that corresponds to the center point of the view .
*/
2023-07-19 15:25:57 +00:00
double GetPosY ( ) const { return m_posY ; }
2016-11-28 13:18:22 +00:00
/** Get current view's X dimension in device context units.
* Usually this is equal to wxDC : : GetSize , but it might differ thus mpLayer
* implementations should rely on the value returned by the function .
* See @ ref mpLayer : : Plot " rules for coordinate transformation "
* @ return X dimension .
*/
2023-07-19 15:25:57 +00:00
int GetScrX ( ) const { return m_scrX ; }
int GetXScreen ( ) const { return m_scrX ; }
2016-11-28 13:18:22 +00:00
/** Get current view's Y dimension in device context units.
* Usually this is equal to wxDC : : GetSize , but it might differ thus mpLayer
* implementations should rely on the value returned by the function .
* See @ ref mpLayer : : Plot " rules for coordinate transformation "
* @ return Y dimension .
*/
2023-07-19 15:25:57 +00:00
int GetScrY ( ) const { return m_scrY ; }
int GetYScreen ( ) const { return m_scrY ; }
2016-11-28 13:18:22 +00:00
/** Set current view's X scale and refresh display.
* @ param scaleX New scale , must not be 0.
*/
void SetScaleX ( double scaleX ) ;
/** Set current view's Y scale and refresh display.
* @ param scaleY New scale , must not be 0.
*/
void SetScaleY ( double scaleY )
{
2021-03-06 09:27:41 +00:00
if ( scaleY ! = 0 )
2016-11-28 13:18:22 +00:00
m_scaleY = scaleY ;
2016-08-11 12:41:37 +00:00
2016-11-28 13:18:22 +00:00
UpdateAll ( ) ;
}
2016-08-11 12:42:08 +00:00
2016-11-28 13:18:22 +00:00
/** Set current view's X position and refresh display.
* @ param posX New position that corresponds to the center point of the view .
*/
void SetPosX ( double posX ) { m_posX = posX ; UpdateAll ( ) ; }
/** Set current view's Y position and refresh display.
* @ param posY New position that corresponds to the center point of the view .
*/
void SetPosY ( double posY ) { m_posY = posY ; UpdateAll ( ) ; }
/** Set current view's X and Y position and refresh display.
* @ param posX New position that corresponds to the center point of the view .
* @ param posY New position that corresponds to the center point of the view .
*/
void SetPos ( double posX , double posY ) { m_posX = posX ; m_posY = posY ; UpdateAll ( ) ; }
/** Set current view's dimensions in device context units.
* Needed by plotting functions . It doesn ' t refresh display .
* @ param scrX New position that corresponds to the center point of the view .
* @ param scrY New position that corresponds to the center point of the view .
*/
void SetScr ( int scrX , int scrY ) { m_scrX = scrX ; m_scrY = scrY ; }
/** Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates, using current mpWindow position and scale.
* @ sa p2y , x2p , y2p */
inline double p2x ( wxCoord pixelCoordX ) { return m_posX + pixelCoordX / m_scaleX ; }
/** Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates, using current mpWindow position and scale.
* @ sa p2x , x2p , y2p */
inline double p2y ( wxCoord pixelCoordY ) { return m_posY - pixelCoordY / m_scaleY ; }
/** Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates, using current mpWindow position and scale.
* @ sa p2x , p2y , y2p */
inline wxCoord x2p ( double x ) { return ( wxCoord ) ( ( x - m_posX ) * m_scaleX ) ; }
/** Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates, using current mpWindow position and scale.
* @ sa p2x , p2y , x2p */
inline wxCoord y2p ( double y ) { return ( wxCoord ) ( ( m_posY - y ) * m_scaleY ) ; }
/** Enable/disable the double-buffering of the window, eliminating the flicker (default=disabled).
*/
void EnableDoubleBuffer ( bool enabled ) { m_enableDoubleBuffer = enabled ; }
/** Enable/disable the feature of pan/zoom with the mouse (default=enabled)
*/
void EnableMousePanZoom ( bool enabled ) { m_enableMouseNavigation = enabled ; }
2024-01-23 01:02:50 +00:00
/** Set the pan/zoom actions corresponding to mousewheel/trackpad events. */
2024-01-30 03:59:12 +00:00
void SetMouseWheelActions ( const MouseWheelActionSet & s ) { m_mouseWheelActions = s ; }
2019-11-19 14:58:32 +00:00
2016-11-28 13:18:22 +00:00
/** Set view to fit global bounding box of all plot layers and refresh display.
* Scale and position will be set to show all attached mpLayers .
* The X / Y scale aspect lock is taken into account .
*/
void Fit ( ) override ;
/** Set view to fit a given bounding box and refresh display.
* The X / Y scale aspect lock is taken into account .
* If provided , the parameters printSizeX and printSizeY are taken as the DC size , and the
* pixel scales are computed accordingly . Also , in this case the passed borders are not saved
* as the " desired borders " , since this use will be invoked only when printing .
*/
void Fit ( double xMin , double xMax , double yMin , double yMax ,
2024-01-23 01:02:50 +00:00
const wxCoord * printSizeX = nullptr , const wxCoord * printSizeY = nullptr ,
wxOrientation directions = wxBOTH ) ;
2016-11-28 13:18:22 +00:00
/** Zoom into current view and refresh display
2019-09-26 14:29:52 +00:00
* @ 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 ) .
2016-11-28 13:18:22 +00:00
*/
void ZoomIn ( const wxPoint & centerPoint = wxDefaultPosition ) ;
2024-01-30 03:59:12 +00:00
void ZoomIn ( const wxPoint & centerPoint , double zoomFactor , wxOrientation directions = wxBOTH ) ;
2016-11-28 13:18:22 +00:00
/** Zoom out current view and refresh display
2019-09-26 14:29:52 +00:00
* @ 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 ) .
2016-11-28 13:18:22 +00:00
*/
void ZoomOut ( const wxPoint & centerPoint = wxDefaultPosition ) ;
2024-01-23 01:02:50 +00:00
void ZoomOut ( const wxPoint & centerPoint , double zoomFactor ,
wxOrientation directions = wxBOTH ) ;
2016-11-28 13:18:22 +00:00
2019-09-26 14:29:52 +00:00
/** Zoom view fitting given coordinates to the window (p0 and p1 do not need to be in any specific order)
*/
2016-11-28 13:18:22 +00:00
void ZoomRect ( wxPoint p0 , wxPoint p1 ) ;
/** Refresh display */
void UpdateAll ( ) ;
// Added methods by Davide Rondini
/** Counts the number of plot layers, whether or not they have a bounding box.
* \ return The number of layers in the mpWindow . */
2021-03-06 09:27:41 +00:00
unsigned int CountAllLayers ( ) const { return m_layers . size ( ) ; } ;
2016-11-28 13:18:22 +00:00
2019-09-26 14:29:52 +00:00
/** 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 ) .
2016-11-28 13:18:22 +00:00
* @ sa Fit
*/
2021-03-06 09:27:41 +00:00
double GetDesiredXmin ( ) const { return m_desiredXmin ; }
2016-11-28 13:18:22 +00:00
2019-09-26 14:29:52 +00:00
/** 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 ) .
2016-11-28 13:18:22 +00:00
* @ sa Fit
*/
2021-03-06 09:27:41 +00:00
double GetDesiredXmax ( ) const { return m_desiredXmax ; }
2016-11-28 13:18:22 +00:00
2019-09-26 14:29:52 +00:00
/** 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 ) .
2016-11-28 13:18:22 +00:00
* @ sa Fit
*/
2021-03-06 09:27:41 +00:00
double GetDesiredYmin ( ) const { return m_desiredYmin ; }
2016-11-28 13:18:22 +00:00
2019-09-26 14:29:52 +00:00
/** 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 ) .
2016-11-28 13:18:22 +00:00
* @ sa Fit
*/
2021-03-06 09:27:41 +00:00
double GetDesiredYmax ( ) const { return m_desiredYmax ; }
2016-11-28 13:18:22 +00:00
/** Returns the bounding box coordinates
2019-09-26 14:29:52 +00:00
* @ param bbox Pointer to a 6 - element double array where to store bounding box coordinates .
*/
2021-03-06 09:27:41 +00:00
void GetBoundingBox ( double * bbox ) const ;
2016-11-28 13:18:22 +00:00
/** Draw the window on a wxBitmap, then save it to a file.
2024-03-19 16:04:42 +00:00
* @ param aImage a wxImage where to save the screenshot
* @ param aImageSize Set a size for the output image . Default is the same as the screen size
* @ param aFit Decide whether to fit the plot into the size
*/
bool SaveScreenshot ( wxImage & aImage ,
wxSize aImageSize = wxDefaultSize , bool aFit = false ) ;
2016-11-28 13:18:22 +00:00
/** This value sets the zoom steps whenever the user clicks "Zoom in/out" or performs zoom with the mouse wheel.
2019-09-26 14:29:52 +00:00
* 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 .
*/
2016-11-28 13:18:22 +00:00
static double zoomIncrementalFactor ;
2019-09-26 14:29:52 +00:00
/** 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 .
2016-11-28 13:18:22 +00:00
* @ param top Top border
* @ param right Right border
* @ param bottom Bottom border
* @ param left Left border */
void SetMargins ( int top , int right , int bottom , int left ) ;
/** Set the top margin. @param top Top Margin */
void SetMarginTop ( int top ) { m_marginTop = top ; } ;
/** Set the right margin. @param right Right Margin */
void SetMarginRight ( int right ) { m_marginRight = right ; } ;
/** Set the bottom margin. @param bottom Bottom Margin */
void SetMarginBottom ( int bottom ) { m_marginBottom = bottom ; } ;
/** Set the left margin. @param left Left Margin */
void SetMarginLeft ( int left ) { m_marginLeft = left ; } ;
2017-06-16 07:14:28 +00:00
/** @return the top margin. */
2021-03-06 09:27:41 +00:00
int GetMarginTop ( ) const { return m_marginTop ; } ;
2017-06-16 07:14:28 +00:00
/** @return the right margin. */
2021-03-06 09:27:41 +00:00
int GetMarginRight ( ) const { return m_marginRight ; } ;
2017-06-16 07:14:28 +00:00
/** @return the bottom margin. */
2021-03-06 09:27:41 +00:00
int GetMarginBottom ( ) const { return m_marginBottom ; } ;
2017-06-16 07:14:28 +00:00
/** @return the left margin. */
2021-03-06 09:27:41 +00:00
int GetMarginLeft ( ) const { return m_marginLeft ; } ;
2016-11-28 13:18:22 +00:00
/** Check if a given point is inside the area of a mpInfoLayer and eventually returns its pointer.
* @ param point The position to be checked
* @ return If an info layer is found , returns its pointer , NULL otherwise */
mpInfoLayer * IsInsideInfoLayer ( wxPoint & point ) ;
/** Sets the visibility of a layer by its name.
* @ param name The layer name to set visibility
* @ param viewable the view status to be set */
void SetLayerVisible ( const wxString & name , bool viewable ) ;
/** Check whether a layer with given name is visible
* @ param name The layer name
* @ return layer visibility status */
2021-03-06 09:27:41 +00:00
bool IsLayerVisible ( const wxString & name ) const ;
2016-11-28 13:18:22 +00:00
/** Sets the visibility of a layer by its position in layer list.
* @ param position The layer position in layer list
* @ param viewable the view status to be set */
void SetLayerVisible ( const unsigned int position , bool viewable ) ;
/** Check whether the layer at given position is visible
* @ param position The layer position in layer list
* @ return layer visibility status */
2021-03-06 09:27:41 +00:00
bool IsLayerVisible ( unsigned int position ) const ;
2016-11-28 13:18:22 +00:00
/** Set Color theme. Provide colours to set a new colour theme.
* @ param bgColour Background colour
* @ param drawColour The colour used to draw all elements in foreground , axes excluded
* @ param axesColour The colour used to draw axes ( but not their labels ) */
2023-08-02 15:26:17 +00:00
void SetColourTheme ( const wxColour & bgColour , const wxColour & drawColour ,
2016-11-28 13:18:22 +00:00
const wxColour & axesColour ) ;
/** Get axes draw colour
* @ return reference to axis colour used in theme */
const wxColour & GetAxesColour ( ) { return m_axColour ; } ;
2024-01-23 01:02:50 +00:00
/** Enable limiting of zooming & panning to the area used by the plots */
2016-11-28 13:18:22 +00:00
void LimitView ( bool aEnable )
{
m_enableLimitedView = aEnable ;
}
2023-07-19 15:25:57 +00:00
void LockY ( bool aLock ) { m_yLocked = aLock ; }
2023-07-20 16:20:57 +00:00
bool GetYLocked ( ) const { return m_yLocked ; }
2023-07-19 15:25:57 +00:00
2023-09-26 12:18:28 +00:00
void ZoomUndo ( ) ;
void ZoomRedo ( ) ;
int UndoZoomStackSize ( ) const { return m_undoZoomStack . size ( ) ; }
int RedoZoomStackSize ( ) const { return m_redoZoomStack . size ( ) ; }
2024-01-23 01:02:50 +00:00
/** Limits the zoomed or panned view to the area used by the plots. */
void AdjustLimitedView ( wxOrientation directions = wxBOTH ) ;
2023-07-19 15:25:57 +00:00
2023-09-26 12:18:28 +00:00
void OnFit ( wxCommandEvent & event ) ;
void OnCenter ( wxCommandEvent & event ) ;
2016-11-28 13:18:22 +00:00
protected :
2024-01-23 01:02:50 +00:00
static MouseWheelActionSet defaultMouseWheelActions ( ) ;
2023-09-26 12:18:28 +00:00
void pushZoomUndo ( const std : : array < double , 4 > & aZoom ) ;
2016-11-28 13:18:22 +00:00
2023-09-26 12:18:28 +00:00
void OnPaint ( wxPaintEvent & event ) ; // !< Paint handler, will plot all attached layers
void OnSize ( wxSizeEvent & event ) ; // !< Size handler, will update scroll bar sizes
void OnShowPopupMenu ( wxMouseEvent & event ) ; // !< Mouse handler, will show context menu
void OnMouseMiddleDown ( wxMouseEvent & event ) ; // !< Mouse handler, for detecting when the user
2016-11-28 13:18:22 +00:00
// !< drags with the middle button or just "clicks" for the menu
2023-09-26 12:18:28 +00:00
void onZoomIn ( wxCommandEvent & event ) ; // !< Context menu handler
void onZoomOut ( wxCommandEvent & event ) ; // !< Context menu handler
void onZoomUndo ( wxCommandEvent & event ) ; // !< Context menu handler
void onZoomRedo ( wxCommandEvent & event ) ; // !< Context menu handler
void onMouseWheel ( wxMouseEvent & event ) ; // !< Mouse handler for the wheel
void onMagnify ( wxMouseEvent & event ) ; // !< Pinch zoom handler
void onMouseMove ( wxMouseEvent & event ) ; // !< Mouse handler for mouse motion (for pan)
void onMouseLeftDown ( wxMouseEvent & event ) ; // !< Mouse left click (for rect zoom)
void onMouseLeftRelease ( wxMouseEvent & event ) ; // !< Mouse left click (for rect zoom)
2016-11-28 13:18:22 +00:00
2024-01-23 01:02:50 +00:00
void DoZoom ( const wxPoint & centerPoint , double zoomFactor , wxOrientation directions ) ;
void RecomputeDesiredX ( double & min , double & max ) ;
void RecomputeDesiredY ( double & min , double & max ) ;
wxOrientation ViewNeedsRefitting ( wxOrientation directions ) const ;
2016-08-11 12:42:08 +00:00
2024-01-23 01:02:50 +00:00
void PerformMouseWheelAction ( wxMouseEvent & event , MouseWheelAction action ) ;
2016-11-28 13:18:22 +00:00
/** Recalculate global layer bounding box, and save it in m_minX,...
* \ return true if there is any valid BBox information .
*/
virtual bool UpdateBBox ( ) ;
/** Applies new X view coordinates depending on the settings
* \ return true if the changes were applied
*/
virtual bool SetXView ( double pos , double desiredMax , double desiredMin ) ;
/** Applies new Y view coordinates depending on the settings
* \ return true if the changes were applied
*/
virtual bool SetYView ( double pos , double desiredMax , double desiredMin ) ;
// wxList m_layers; //!< List of attached plot layers
wxLayerList m_layers ; // !< List of attached plot layers
wxMenu m_popmenu ; // !< Canvas' context menu
wxColour m_bgColour ; // !< Background Colour
wxColour m_fgColour ; // !< Foreground Colour
wxColour m_axColour ; // !< Axes Colour
double m_minX ; // !< Global layer bounding box, left border incl.
double m_maxX ; // !< Global layer bounding box, right border incl.
double m_minY ; // !< Global layer bounding box, bottom border incl.
double m_maxY ; // !< Global layer bounding box, top border incl.
double m_scaleX ; // !< Current view's X scale
double m_scaleY ; // !< Current view's Y scale
double m_posX ; // !< Current view's X position
double m_posY ; // !< Current view's Y position
int m_scrX ; // !< Current view's X dimension
int m_scrY ; // !< Current view's Y dimension
int m_clickedX ; // !< Last mouse click X position, for centering and zooming the view
int m_clickedY ; // !< Last mouse click Y position, for centering and zooming the view
2023-07-19 15:25:57 +00:00
bool m_yLocked ;
2024-01-23 01:02:50 +00:00
/** These are updated in Fit, ZoomIn, ZoomOut, ZoomRect, SetXView, SetYView and may be different
* from the real borders ( layer coordinates ) only if lock aspect ratio is true .
*
* @ note They use the plot area as their coordinate system , and not the layer coordinate
* system used by m_posX / Y .
2016-11-28 13:18:22 +00:00
*/
double m_desiredXmin , m_desiredXmax , m_desiredYmin , m_desiredYmax ;
2024-01-23 01:02:50 +00:00
// These are gaps between the curve extrema and the edges of the plot area, expressed as
// a factor of global layer bounding box width/height.
double m_topBottomPlotGapFactor ;
double m_leftRightPlotGapFactor ;
2016-11-28 13:18:22 +00:00
int m_marginTop , m_marginRight , m_marginBottom , m_marginLeft ;
int m_last_lx , m_last_ly ; // !< For double buffering
wxMemoryDC m_buff_dc ; // !< For double buffering
wxBitmap * m_buff_bmp ; // !< For double buffering
bool m_enableDoubleBuffer ; // !< For double buffering
bool m_enableMouseNavigation ; // !< For pan/zoom with the mouse.
bool m_enableLimitedView ;
2024-01-23 01:02:50 +00:00
MouseWheelActionSet m_mouseWheelActions ;
2016-11-28 13:18:22 +00:00
wxPoint m_mouseMClick ; // !< For the middle button "drag" feature
wxPoint m_mouseLClick ; // !< Starting coords for rectangular zoom selection
2024-01-23 01:02:50 +00:00
mpInfoLayer * m_movingInfoLayer ; // !< For moving info layers over the window area
2016-11-28 13:18:22 +00:00
bool m_zooming ;
wxRect m_zoomRect ;
2023-09-26 12:18:28 +00:00
std : : stack < std : : array < double , 4 > > m_undoZoomStack ;
std : : stack < std : : array < double , 4 > > m_redoZoomStack ;
2016-11-28 13:18:22 +00:00
DECLARE_DYNAMIC_CLASS ( mpWindow )
DECLARE_EVENT_TABLE ( )
2024-01-23 01:02:50 +00:00
private :
struct DelegatingContructorTag { } ;
template < typename . . . Ts >
mpWindow ( DelegatingContructorTag , Ts & & . . . windowArgs ) ;
void initializeGraphicsContext ( ) ;
2016-08-11 12:41:21 +00:00
} ;
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
// mpFXYVector - provided by Jose Luis Blanco
2016-11-28 13:18:22 +00:00
// -----------------------------------------------------------------------------
2016-08-11 12:41:21 +00:00
/** A class providing graphs functionality for a 2D plot (either continuous or a set of points), from vectors of data.
2016-11-28 13:18:22 +00:00
* This class can be used directly , the user does not need to derive any new class . Simply pass the data as two vectors
* with the same length containing the X and Y coordinates to the method SetData .
*
* To generate a graph with a set of points , call
* \ code
* layerVar - > SetContinuity ( false )
* \ endcode
*
* or
*
* \ code
* layerVar - > SetContinuity ( true )
* \ endcode
*
* to render the sequence of coordinates as a continuous line .
*
* ( Added : Jose Luis Blanco , AGO - 2007 )
*/
2016-08-11 12:41:21 +00:00
class WXDLLIMPEXP_MATHPLOT mpFXYVector : public mpFXY
{
2016-11-28 13:18:22 +00:00
public :
/** @param name Label
* @ param flags Label alignment , pass one of # mpALIGN_NE , # mpALIGN_NW , # mpALIGN_SW , # mpALIGN_SE .
*/
2017-09-23 09:20:10 +00:00
mpFXYVector ( const wxString & name = wxEmptyString , int flags = mpALIGN_NE ) ;
2016-11-28 13:18:22 +00:00
virtual ~ mpFXYVector ( ) { }
/** Changes the internal data: the set of points to draw.
* Both vectors MUST be of the same length . This method DOES NOT refresh the mpWindow ; do it manually .
* @ sa Clear
*/
virtual void SetData ( const std : : vector < double > & xs , const std : : vector < double > & ys ) ;
2024-05-23 11:24:13 +00:00
void SetSweepCount ( int aSweepCount ) { m_sweepCount = aSweepCount ; }
void SetSweepSize ( size_t aSweepSize ) { m_sweepSize = aSweepSize ; }
2016-11-28 13:18:22 +00:00
/** Clears all the data, leaving the layer empty.
* @ sa SetData
*/
void Clear ( ) ;
protected :
/** The internal copy of the set of data to draw.
*/
std : : vector < double > m_xs , m_ys ;
2024-05-23 11:24:13 +00:00
size_t m_index ; // internal counter for the "GetNextXY" interface
size_t m_sweepWindow ; // last m_index of the current sweep
2016-11-28 13:18:22 +00:00
/** Loaded at SetData
*/
double m_minX , m_maxX , m_minY , m_maxY ;
2024-05-23 11:24:13 +00:00
int m_sweepCount = 1 ; // sweeps to split data into
size_t m_sweepSize = std : : numeric_limits < size_t > : : max ( ) ; // data-points in each sweep
2016-11-28 13:18:22 +00:00
/** Rewind value enumeration with mpFXY::GetNextXY.
* Overridden in this implementation .
*/
void Rewind ( ) override ;
2024-05-23 11:24:13 +00:00
void SetSweepWindow ( int aSweepIdx ) override ;
2016-11-28 13:18:22 +00:00
/** Get locus value for next N.
* Overridden in this implementation .
* @ param x Returns X value
* @ param y Returns Y value
*/
bool GetNextXY ( double & x , double & y ) override ;
2024-05-23 11:24:13 +00:00
size_t GetCount ( ) const override { return m_xs . size ( ) ; }
int GetSweepCount ( ) const override { return m_sweepCount ; }
2019-11-19 16:17:37 +00:00
2016-11-28 13:18:22 +00:00
public :
/** Returns the actual minimum X data (loaded in SetData).
*/
2021-03-06 09:27:41 +00:00
double GetMinX ( ) const override { return m_minX ; }
2016-11-28 13:18:22 +00:00
/** Returns the actual minimum Y data (loaded in SetData).
*/
2021-03-06 09:27:41 +00:00
double GetMinY ( ) const override { return m_minY ; }
2016-11-28 13:18:22 +00:00
/** Returns the actual maximum X data (loaded in SetData).
*/
2021-03-06 09:27:41 +00:00
double GetMaxX ( ) const override { return m_maxX ; }
2016-11-28 13:18:22 +00:00
/** Returns the actual maximum Y data (loaded in SetData).
*/
2021-03-06 09:27:41 +00:00
double GetMaxY ( ) const override { return m_maxY ; }
2016-11-28 13:18:22 +00:00
protected :
DECLARE_DYNAMIC_CLASS ( mpFXYVector )
2016-08-11 12:41:21 +00:00
} ;
2016-08-11 12:41:48 +00:00
2016-11-28 13:18:22 +00:00
# endif // _MP_MATHPLOT_H_