30#include "wx/dcclient.h"
36#include <wx/graphics.h>
50#define mpLEGEND_MARGIN 5
51#define mpLEGEND_LINEWIDTH 10
60IMPLEMENT_ABSTRACT_CLASS(
mpLayer, wxObject )
65 SetPen( (wxPen&) *wxBLACK_PEN );
66 SetFont( (wxFont&) *wxNORMAL_FONT );
80 m_dim = wxRect( 0, 0, 1, 1 );
81 m_brush = *wxTRANSPARENT_BRUSH;
82 m_reference.x = 0; m_reference.y = 0;
108 return m_dim.Contains( point );
166 return m_dim.GetPosition();
172 return m_dim.GetSize();
237 dc.GetTextExtent( label, &tmpX, &tmpY );
238 textX = ( textX > tmpX + baseWidth ) ? textX : tmpX + baseWidth +
mpLEGEND_MARGIN;
250 m_dim.height = textY;
261 dc.GetTextExtent( label, &tmpX, &tmpY );
306 if(
m_pen.GetWidth() <= 1 )
308 for( wxCoord i = startPx; i < endPx; ++i )
314 if( ( iy >= minYpx ) && ( iy <= maxYpx ) )
315 dc.DrawPoint( i, iy );
320 for( wxCoord i = startPx; i < endPx; ++i )
326 if( iy >= minYpx && iy <= maxYpx )
327 dc.DrawLine( i, iy, i, iy );
336 dc.GetTextExtent(
m_name, &tx, &ty );
376 if(
m_pen.GetWidth() <= 1 )
378 for( i = minYpx; i < maxYpx; ++i )
382 if( ( ix >= startPx ) && ( ix <= endPx ) )
383 dc.DrawPoint( ix, i );
388 for( i = 0; i< w.
GetScrY(); ++i )
392 if( ( ix >= startPx ) && ( ix <= endPx ) )
393 dc.DrawLine( ix, i, ix, i );
402 dc.GetTextExtent(
m_name, &tx, &ty );
430 maxDrawX = minDrawX = maxDrawY = minDrawY = 0;
452 wxCHECK_RET(
m_scaleX, wxS(
"X scale was not set" ) );
453 wxCHECK_RET(
m_scaleY, wxS(
"Y scale was not set" ) );
464 if( endPx <= startPx || minYpx >= maxYpx )
480 dc.SetClippingRegion( startPx, minYpx, endPx - startPx + 1, maxYpx - minYpx + 1 );
486 std::set<wxCoord> ys;
492 wxCoord newX = w.
x2p( px );
503 ys.insert( w.
y2p( py ) );
509 if( ( ix >= startPx ) && ( ix <= endPx ) && ( iy >= minYpx ) && ( iy <= maxYpx ) )
513 if(
m_pen.GetWidth() <= 1 )
514 dc.DrawPoint( ix, iy );
516 dc.DrawLine( ix, iy, ix, iy );
524 ys.insert( w.
y2p( py ) );
539 std::vector<wxPoint>pointList;
540 pointList.reserve( ( endPx - startPx ) * 2 );
544 bool hasNext =
GetNextXY( nextX, nextY );
545 bool offRight =
false;
562 wxCoord x1 = w.
x2p( px );
563 wxCoord y1 = w.
y2p( py );
573 if( nextX1 < startPx-1 )
576 else if( x1 > endPx )
584 if( !count || line_start.x != x1 )
590 if( count && dupx0 > 1 && abs( ymax0 - ymin0 ) > 2 )
591 dc.DrawLine( x0, ymin0, x0, ymax0 );
597 pointList.emplace_back( wxPoint( x1, y1 ) );
605 ymin0 = std::min( ymin0, y1 );
606 ymax0 = std::max( ymax0, y1 );
612 if( pointList.size() > 1 )
619 std::vector<wxPoint> drawPoints;
620 drawPoints.reserve( ( endPx - startPx ) * 2 );
623 int chunkSize = 10000;
625 int chunkSize = 100000;
627 if( dc.GetPen().GetStyle() == wxPENSTYLE_DOT )
630 drawPoints.push_back( pointList[0] );
632 for(
size_t ii = 1; ii < pointList.size()-1; ii++ )
636 if( drawPoints.back().y == pointList[ii].y &&
637 drawPoints.back().y == pointList[ii+1].y )
643 drawPoints.push_back( pointList[ii] );
645 if( (
int) drawPoints.size() > chunkSize )
647 dc.DrawLines( (
int) drawPoints.size(), &drawPoints[0] );
651 drawPoints.push_back( pointList[ii] );
657 if( drawPoints.back() != pointList.back() )
658 drawPoints.push_back( pointList.back() );
660 dc.DrawLines( (
int) drawPoints.size(), &drawPoints[0] );
669 dc.GetTextExtent(
m_name, &tx, &ty );
693 dc.DrawText(
m_name, tx, ty );
696 dc.DestroyClippingRegion();
704#define mpLN10 2.3025850929940456840179914546844
708 double minV, maxV, minVvis, maxVvis;
718 double minErr = 1000000000000.0;
719 double bestStep = 1.0;
722 for(
int i = 10; i <= 20; i += 2 )
724 double curr_step = fabs( maxVvis - minVvis ) / (double) i;
725 double base = pow( 10, floor( log10( curr_step ) ) );
726 double stepInt = floor( curr_step / base ) * base;
727 double err = fabs( curr_step - stepInt );
736 double numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
741 while( numberSteps - 2.0 >= m_scrX/96.0 )
744 numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
747 double v = floor( minVvis / bestStep ) * bestStep;
748 double zeroOffset = 100000000.0;
754 if( fabs( v ) < zeroOffset )
755 zeroOffset = fabs( v );
760 if( zeroOffset <= bestStep )
802 const wxString s = tickLabel.label;
804 dc.GetTextExtent( s, &tx, &ty );
823 double pymin = w.
p2y( minYpx );
824 double pymax = w.
p2y( maxYpx );
846 double y_slave0 = p0 /
m_scale;
847 double y_slave1 = p1 /
m_scale;
849 double dy_slave = ( y_slave1 - y_slave0 );
850 double exponent = floor( log10( dy_slave ) );
851 double base = dy_slave / pow( 10.0, exponent );
853 double dy_scaled = ceil( 2.0 * base ) / 2.0 * pow( 10.0, exponent );
859 minvv = floor( minvv / dy_scaled ) * dy_scaled;
862 m_scale *= dy_slave / dy_scaled;
882 double minVvis, maxVvis;
907 double minErr = 1000000000000.0;
908 double bestStep = 1.0;
911 for(
int i = 10; i <= 20; i += 2 )
913 double curr_step = fabs( maxVvis - minVvis ) / (double) i;
914 double base = pow( 10, floor( log10( curr_step ) ) );
915 double stepInt = floor( curr_step / base ) * base;
916 double err = fabs( curr_step - stepInt );
925 double numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
929 while( numberSteps >= m_scrY / 32.0 )
932 numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
935 double v = floor( minVvis / bestStep ) * bestStep;
936 double zeroOffset = 100000000.0;
937 const int iterLimit = 1000;
940 while( v <= maxVvis && i < iterLimit )
944 if( fabs( v ) < zeroOffset )
945 zeroOffset = fabs( v );
955 if( zeroOffset <= bestStep )
972 double pxmin = w.
p2x( startPx );
973 double pxmax = w.
p2x( endPx );
982 double minV, maxV, minVvis, maxVvis;
988 double minDecade = pow( 10, floor( log10( minV ) ) );
989 double maxDecade = pow( 10, ceil( log10( maxV ) ) );
990 double visibleDecades = log( maxVvis / minVvis ) / log( 10 );
999 if( minDecade == 0.0 )
1005 while( visibleDecades - 2 >= m_scrX / 96.0 )
1008 visibleDecades = log( maxVvis / minVvis ) / log( step );
1010 if( !std::isfinite( visibleDecades ) )
1014 for( d = minDecade; d<=maxDecade; d *= step )
1018 for(
double dd = d; dd < d * step; dd += d )
1020 if( visibleDecades < 2 )
1039 SetFont( (wxFont&) *wxSMALL_FONT );
1040 SetPen( (wxPen&) *wxGREY_PEN );
1074 const int extend = w.
GetScrX();
1107 if( p >= startPx && p <= endPx )
1112 dc.DrawLine( p, orgy, p, orgy - 4 );
1114 dc.DrawLine( p, orgy, p, orgy + 4 );
1118 m_pen.SetStyle( wxPENSTYLE_DOT );
1123 m_pen.SetStyle( wxPENSTYLE_DOT );
1125 dc.DrawLine( p, orgy + 4, p, minYpx );
1126 m_pen.SetStyle( wxPENSTYLE_SOLID );
1128 dc.DrawLine( p, orgy + 4, p, orgy - 4 );
1133 dc.DrawLine( p, orgy - 4, p, maxYpx );
1135 dc.DrawLine( p, minYpx, p, maxYpx );
1138 m_pen.SetStyle( wxPENSTYLE_SOLID );
1144 m_pen.SetStyle( wxPENSTYLE_SOLID );
1146 dc.DrawLine( startPx, minYpx, endPx, minYpx );
1147 dc.DrawLine( startPx, maxYpx, endPx, maxYpx );
1153 if( !tickLabel.visible )
1159 if( ( p >= startPx ) && ( p <= endPx ) )
1162 wxString s = tickLabel.label;
1164 dc.GetTextExtent( s, &tx, &ty );
1167 dc.DrawText( s, p - tx / 2, orgy - 4 - ty );
1169 dc.DrawText( s, p - tx / 2, orgy + 4 );
1174 dc.GetTextExtent(
m_name, &tx, &ty );
1179 dc.DrawText(
m_name, extend - tx - 4, orgy - 8 - ty - labelH );
1183 dc.DrawText(
m_name, ( endPx + startPx ) / 2 - tx / 2, orgy + 6 + labelH );
1187 dc.DrawText(
m_name, extend - tx - 4, orgy - 4 - ty );
1192 dc.DrawText(
m_name, ( endPx - startPx - tx ) >> 1, orgy - 6 - ty - labelH );
1194 dc.DrawText(
m_name, extend - tx - 4, orgy + 4 );
1199 dc.DrawText(
m_name, extend - tx - 4, orgy + 6 + labelH );
1215 SetFont( (wxFont&) *wxSMALL_FONT );
1216 SetPen( (wxPen&) *wxGREY_PEN );
1220 m_masterScale =
nullptr;
1262 dc.DrawLine( orgx, minYpx, orgx, maxYpx );
1271 int labelHeight = 0;
1273 dc.GetTextExtent( s, &tx, &labelHeight );
1280 if( p >= minYpx && p <= maxYpx )
1285 dc.DrawLine( orgx, p, orgx + 4, p );
1287 dc.DrawLine( orgx - 4, p, orgx, p );
1291 dc.DrawLine( orgx - 4, p, orgx + 4, p );
1293 m_pen.SetStyle( wxPENSTYLE_DOT );
1296 dc.DrawLine( orgx - 4, p, endPx, p );
1298 m_pen.SetStyle( wxPENSTYLE_SOLID );
1311 if( !tickLabel.visible )
1314 if( p >= minYpx && p <= maxYpx )
1316 s = tickLabel.label;
1317 dc.GetTextExtent( s, &tx, &ty );
1321 dc.DrawText( s, orgx + 4, p - ty / 2 );
1323 dc.DrawText( s, orgx - 4 - tx, p - ty / 2 );
1328 dc.GetTextExtent(
m_name, &tx, &ty );
1333 dc.DrawText(
m_name, labelW + 8, 4 );
1337 dc.DrawText(
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
1341 dc.DrawText(
m_name, orgx + 4, 4 );
1346 dc.DrawText(
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
1350 dc.DrawText(
m_name, orgx - 6 - tx - labelW, 4 );
1364IMPLEMENT_DYNAMIC_CLASS(
mpWindow, wxWindow )
1366BEGIN_EVENT_TABLE(
mpWindow, wxWindow )
1389 initializeGraphicsContext();
1398 _(
"Return zoom to level prior to last zoom action" ) );
1400 _(
"Return zoom to level prior to last zoom undo" ) );
1405 _(
"Center plot view to this position" ) );
1406 m_popmenu.Append(
mpID_FIT,
_(
"Fit on Screen" ),
_(
"Set plot view to show all items" ) );
1409 SetBackgroundColour( *wxWHITE );
1413 SetSizeHints( 128, 128 );
1416 SetBackgroundStyle( wxBG_STYLE_CUSTOM );
1451 float zoom =
event.GetMagnification() + 1.0f;
1452 wxPoint pos( event.GetX(), event.GetY() );
1456 else if(
zoom < 1.0f )
1471 const wxMouseWheelAxis axis =
event.GetWheelAxis();
1472 const int modifiers =
event.GetModifiers();
1475 if( axis == wxMOUSE_WHEEL_HORIZONTAL )
1479 else if( modifiers == wxMOD_NONE )
1483 else if( modifiers == wxMOD_CONTROL )
1487 else if( modifiers == wxMOD_SHIFT )
1491 else if( modifiers == wxMOD_ALT )
1515 wxCursor
cursor = wxCURSOR_MAGNIFIER;
1517 if( event.m_middleDown )
1544 else if( event.m_leftDown )
1549 cursor = wxCURSOR_SIZING;
1551 cursor = wxCURSOR_SIZEWE;
1559 cursor = wxCURSOR_MAGNIFIER;
1561 wxClientDC dc(
this );
1564 dc.SetBrush( *wxTRANSPARENT_BRUSH );
1580 if( layer->IsInfo() && layer->IsVisible() )
1584 if( infoLayer->
Inside( event.GetPosition() ) )
1587 cursor = wxCURSOR_SIZING;
1589 cursor = wxCURSOR_SIZEWE;
1606 wxPoint pointClicked =
event.GetPosition();
1615 wxPoint release( event.GetX(), event.GetY() );
1627 if( release != press )
1643void mpWindow::Fit(
double xMin,
double xMax,
double yMin,
double yMax,
const wxCoord* printSizeX,
1644 const wxCoord* printSizeY, wxOrientation directions )
1646 const bool isPrinting = printSizeX !=
nullptr && printSizeY !=
nullptr;
1649 double newDesiredXmin = xMin;
1650 double newDesiredXmax = xMax;
1651 double newDesiredYmin = yMin;
1652 double newDesiredYmax = yMax;
1669 newScrX = *printSizeX;
1670 newScrY = *printSizeY;
1675 GetClientSize( &newScrX, &newScrY );
1683 double desiredSpanX = xMax - xMin;
1684 double desiredSpanY = yMax - yMin;
1685 double newScaleX = ( desiredSpanX != 0 ) ?
double( plotScreenWidth ) / desiredSpanX : 1;
1686 double newScaleY = ( desiredSpanY != 0 ) ?
double( plotScreenHeight ) / desiredSpanY : 1;
1691 double newPosY = yMax + (
m_marginTop / newScaleY );
1694 if( ( ( directions & wxHORIZONTAL ) != 0 ) || isPrinting )
1708 if( ( ( directions & wxVERTICAL ) != 0 ) || isPrinting )
1739 if( ( directions & wxHORIZONTAL ) != 0 )
1758 if( ( directions & wxVERTICAL ) != 0 )
1810void mpWindow::ZoomIn(
const wxPoint& centerPoint,
double zoomFactor, wxOrientation directions )
1812 DoZoom( centerPoint, zoomFactor, directions );
1824 if( zoomFactor == 0 )
1827 DoZoom( centerPoint, 1.0 / zoomFactor, directions );
1840 p0.x = std::max( p0.x, pMinX );
1841 p0.x = std::min( p0.x, pMaxX );
1842 p0.y = std::max( p0.y, pMinY );
1843 p0.y = std::min( p0.y, pMaxY );
1844 p1.x = std::max( p1.x, pMinX );
1845 p1.x = std::min( p1.x, pMaxX );
1846 p1.y = std::max( p1.y, pMinY );
1847 p1.y = std::min( p1.y, pMaxY );
1850 double p0x =
p2x( p0.x );
1851 double p0y =
p2y( p0.y );
1852 double p1x =
p2x( p1.x );
1853 double p1y =
p2y( p1.y );
1856 double zoom_x_min = p0x<p1x ? p0x : p1x;
1857 double zoom_x_max = p0x>p1x ? p0x : p1x;
1858 double zoom_y_min = p0y<p1y ? p0y : p1y;
1859 double zoom_y_max = p0y>p1y ? p0y : p1y;
1867 Fit( zoom_x_min, zoom_x_max, zoom_y_min, zoom_y_max );
1877 if( directionsNeedingRefitting != 0 )
1929 PopupMenu( &
m_popmenu, event.GetX(), event.GetY() );
1999 if( refreshDisplay )
2011 wxLayerList::iterator layIt;
2015 if( *layIt == layer )
2018 if( alsoDeleteObject )
2023 if( refreshDisplay )
2039 if( alsoDeleteObject )
2045 if( refreshDisplay )
2052 wxPaintDC paintDC(
this );
2057 wxDC* targetDC = &paintDC;
2074 if( wxGraphicsContext* ctx = targetDC->GetGraphicsContext() )
2076 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST ) )
2077 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
2078 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
2080 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
2084 targetDC->SetPen( *wxTRANSPARENT_PEN );
2085 wxBrush brush( GetBackgroundColour() );
2086 targetDC->SetBrush( brush );
2092 layer->Plot( *targetDC, *
this );
2097 targetDC->SetPen( pen );
2098 targetDC->SetBrush( *wxTRANSPARENT_BRUSH );
2108void mpWindow::DoZoom(
const wxPoint& centerPoint,
double zoomFactor, wxOrientation directions )
2112 if( directions == wxVERTICAL )
2115 directions = wxHORIZONTAL;
2118 const bool horizontally = ( directions & wxHORIZONTAL ) != 0;
2119 const bool vertically = ( directions & wxVERTICAL ) != 0;
2124 wxPoint c( centerPoint );
2125 if( c == wxDefaultPosition )
2141 const double newScaleX = horizontally ? (
m_scaleX * zoomFactor ) :
m_scaleX;
2142 const double newScaleY = vertically ? (
m_scaleY * zoomFactor ) :
m_scaleY;
2151 const double prior_layer_x =
p2x( c.x );
2155 m_posX = prior_layer_x - c.x / newScaleX;
2164 const double prior_layer_y =
p2y( c.y );
2168 m_posY = prior_layer_y + c.y / newScaleY;
2176 if( zoomFactor < 1.0 )
2184 if( directionsNeedingRefitting != 0 )
2195 const double plotSpanX = plotScreenWidth /
m_scaleX;
2206 const double plotSpanY = plotScreenHeight /
m_scaleY;
2217 return static_cast<wxOrientation
>( 0 );
2224 wxOrientation result = {};
2226 if( ( directions & wxHORIZONTAL ) != 0 )
2229 result =
static_cast<wxOrientation
>( result | wxHORIZONTAL );
2232 if( ( directions & wxVERTICAL ) != 0 )
2235 result =
static_cast<wxOrientation
>( result | wxVERTICAL );
2244 const int change =
event.GetWheelRotation();
2245 const double changeUnitsX = change /
m_scaleX;
2246 const double changeUnitsY = change /
m_scaleY;
2247 const wxPoint clickPt( event.GetX(), event.GetY() );
2276 if( event.GetWheelRotation() > 0 )
2284 if( event.GetWheelRotation() > 0 )
2292 if( event.GetWheelRotation() > 0 )
2336 if( ( position >= (
int)
m_layers.size() ) || position < 0 )
2347 if( !layer->GetName().Cmp(
name ) )
2368 if( aImageSize == wxDefaultSize )
2375 sizeX = aImageSize.x;
2376 sizeY = aImageSize.y;
2380 wxBitmap screenBuffer( sizeX, sizeY );
2381 wxMemoryDC screenDC;
2382 screenDC.SelectObject( screenBuffer );
2383 screenDC.SetPen( *wxWHITE_PEN );
2385 wxBrush brush( GetBackgroundColour() );
2386 screenDC.SetBrush( brush );
2387 screenDC.DrawRectangle( 0, 0, sizeX, sizeY );
2396 layer->Plot( screenDC, *
this );
2398 if( aImageSize != wxDefaultSize )
2403 SetScr( bk_scrX, bk_scrY );
2409 aImage = screenBuffer.ConvertToImage();
2428 if( layer->IsInfo() )
2432 if( tmpLyr->
Inside( point ) )
2445 lx->SetVisible( viewable );
2454 return lx->IsVisible();
2464 lx->SetVisible( viewable );
2473 return lx->IsVisible();
2480 const wxColour& axesColour )
2482 SetBackgroundColour( bgColour );
2483 SetForegroundColour( drawColour );
2494 wxPen axisPen = layer->GetPen();
2495 axisPen.SetColour( axesColour );
2496 layer->SetPen( axisPen );
2502 wxPen infoPen = layer->GetPen();
2503 infoPen.SetColour( drawColour );
2504 layer->SetPen( infoPen );
2510template <
typename... Ts>
2512 wxWindow(
std::forward<Ts>( windowArgs )... ),
2526 m_desiredXmin( 0.0 ),
2527 m_desiredXmax( 1.0 ),
2528 m_desiredYmin( 0.0 ),
2529 m_desiredYmax( 1.0 ),
2530 m_topBottomPlotGapFactor( 0.03 ),
2531 m_leftRightPlotGapFactor( 0.0 ),
2534 m_marginBottom( 0 ),
2538 m_buff_bmp( nullptr ),
2539 m_enableDoubleBuffer( false ),
2540 m_enableMouseNavigation( true ),
2541 m_enableLimitedView( false ),
2542 m_mouseWheelActions( defaultMouseWheelActions() ),
2543 m_movingInfoLayer( nullptr ),
2550 if( wxGraphicsContext* ctx =
m_buff_dc.GetGraphicsContext() )
2552 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
2553 || !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
2555 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
2558 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
2609 double xlogmin = log10(
m_minV );
2610 double xlogmax = log10(
m_maxV );
2612 return ( log10( x ) - xlogmin ) / ( xlogmax - xlogmin );
2618 double xlogmin = log10(
m_minV );
2619 double xlogmax = log10(
m_maxV );
2621 return pow( 10.0, xplot * ( xlogmax - xlogmin ) + xlogmin );
2664 if( xs.size() != ys.size() )
2679 for(
const double x : xs )
2688 for(
const double y : ys )
A class providing graphs functionality for a 2D plot (either continuous or a set of points),...
void SetSweepWindow(int aSweepIdx) override
bool GetNextXY(double &x, double &y) override
Get locus value for next N.
std::vector< double > m_ys
double m_minX
Loaded at SetData.
std::vector< double > m_xs
The internal copy of the set of data to draw.
virtual void SetData(const std::vector< double > &xs, const std::vector< double > &ys)
Changes the internal data: the set of points to draw.
void Clear()
Clears all the data, leaving the layer empty.
void Rewind() override
Rewind value enumeration with mpFXY::GetNextXY.
Abstract base class providing plot and labeling functionality for a locus plot F:N->X,...
double s2y(double plotCoordY) const
virtual void SetScale(mpScaleBase *scaleX, mpScaleBase *scaleY)
virtual void Rewind()=0
Rewind value enumeration with mpFXY::GetNextXY.
virtual void SetSweepWindow(int aSweepIdx)
virtual size_t GetCount() const =0
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
double y2s(double y) const
void UpdateViewBoundary(wxCoord xnew, wxCoord ynew)
Update label positioning data.
double x2s(double x) const
virtual int GetSweepCount() const
double s2x(double plotCoordX) const
virtual bool GetNextXY(double &x, double &y)=0
Get locus value for next N.
Abstract base class providing plot and labeling functionality for functions F:X->Y.
virtual double GetY(double x) const =0
Get function value for argument.
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
Abstract base class providing plot and labeling functionality for functions F:Y->X.
virtual double GetX(double y) const =0
Get function value for argument.
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
Base class to create small rectangular info boxes mpInfoLayer is the base class to create a small rec...
virtual ~mpInfoLayer()
Destructor.
mpInfoLayer()
Default constructor.
wxPoint GetPosition() const
Returns the position of the upper left corner of the box (in pixels)
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot method.
virtual void UpdateReference()
Updates the rectangle reference point.
virtual bool Inside(const wxPoint &point) const
Checks whether a point is inside the info box rectangle.
virtual void Move(wxPoint delta)
Moves the layer rectangle of given pixel deltas.
wxSize GetSize() const
Returns the size of the box (in pixels)
Implements the legend to be added to the plot This layer allows you to add a legend to describe the p...
mpInfoLegend()
Default constructor.
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot method.
~mpInfoLegend()
Default destructor.
const wxString & GetDisplayName() const
mpLayerType GetLayerType() const
Get layer type: a Layer can be of different types: plot lines, axis, info boxes, etc,...
bool IsVisible() const
Checks whether the layer is visible or not.
virtual double GetMinY() const
Get inclusive bottom border of bounding box.
const wxPen & GetPen() const
Get pen set for this layer.
virtual double GetMaxX() const
Get inclusive right border of bounding box.
virtual double GetMinX() const
Get inclusive left border of bounding box.
virtual double GetMaxY() const
Get inclusive top border of bounding box.
Plot layer implementing a x-scale ruler.
virtual void recalculateTicks(wxDC &dc, mpWindow &w)
void GetDataRange(double &minV, double &maxV) const
std::vector< double > m_tickValues
virtual double TransformToPlot(double x) const
virtual void formatLabels()
void computeLabelExtents(wxDC &dc, mpWindow &w)
virtual void ExtendDataRange(double minV, double maxV)
std::vector< TICK_LABEL > m_tickLabels
void updateTickLabels(wxDC &dc, mpWindow &w)
virtual double TransformFromPlot(double xplot) const
virtual void getVisibleDataRange(mpWindow &w, double &minV, double &maxV) override
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot given view of layer to the given device context.
mpScaleXLog(const wxString &name=wxT("log(X)"), int flags=mpALIGN_CENTER, bool ticks=true, unsigned int type=mpX_NORMAL)
Full constructor.
virtual double TransformFromPlot(double xplot) const override
virtual double TransformToPlot(double x) const override
void recalculateTicks(wxDC &dc, mpWindow &w) override
virtual double TransformToPlot(double x) const override
virtual double TransformFromPlot(double xplot) const override
virtual void recalculateTicks(wxDC &dc, mpWindow &w) override
mpScaleX(const wxString &name=wxT("X"), int flags=mpALIGN_CENTER, bool ticks=true, unsigned int type=mpX_NORMAL)
Full constructor.
Plot layer implementing a y-scale ruler.
virtual void getVisibleDataRange(mpWindow &w, double &minV, double &maxV) override
virtual double TransformFromPlot(double xplot) const override
void computeSlaveTicks(mpWindow &w)
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
virtual void recalculateTicks(wxDC &dc, mpWindow &w) override
virtual double TransformToPlot(double x) const override
Canvas for plotting mpLayer implementations.
bool SaveScreenshot(wxImage &aImage, wxSize aImageSize=wxDefaultSize, bool aFit=false)
Draw the window on a wxBitmap, then save it to a file.
mpInfoLayer * m_movingInfoLayer
void DelAllLayers(bool alsoDeleteObject, bool refreshDisplay=true)
Remove all layers from the plot.
void SetColourTheme(const wxColour &bgColour, const wxColour &drawColour, const wxColour &axesColour)
Set Color theme.
virtual bool SetYView(double pos, double desiredMax, double desiredMin)
Applies new Y view coordinates depending on the settings.
void ZoomRect(wxPoint p0, wxPoint p1)
Zoom view fitting given coordinates to the window (p0 and p1 do not need to be in any specific order)
void onMouseLeftRelease(wxMouseEvent &event)
int GetMarginLeft() const
bool m_enableMouseNavigation
void RecomputeDesiredY(double &min, double &max)
wxOrientation ViewNeedsRefitting(wxOrientation directions) const
void OnPaint(wxPaintEvent &event)
void OnShowPopupMenu(wxMouseEvent &event)
void onMouseLeftDown(wxMouseEvent &event)
void onMouseWheel(wxMouseEvent &event)
static MouseWheelActionSet defaultMouseWheelActions()
void SetMargins(int top, int right, int bottom, int left)
Set window margins, creating a blank area where some kinds of layers cannot draw.
MouseWheelActionSet m_mouseWheelActions
int GetScrX() const
Get current view's X dimension in device context units.
int GetScrY() const
Get current view's Y dimension in device context units.
double p2x(wxCoord pixelCoordX)
Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates,...
double p2y(wxCoord pixelCoordY)
Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates,...
void initializeGraphicsContext()
void RecomputeDesiredX(double &min, double &max)
wxCoord x2p(double x)
Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates,...
MouseWheelAction
Enumerates the possible mouse wheel actions that can be performed on the plot.
double m_leftRightPlotGapFactor
mpInfoLayer * IsInsideInfoLayer(wxPoint &point)
Check if a given point is inside the area of a mpInfoLayer and eventually returns its pointer.
void OnMouseMiddleDown(wxMouseEvent &event)
std::stack< std::array< double, 4 > > m_redoZoomStack
void SetLayerVisible(const wxString &name, bool viewable)
Sets the visibility of a layer by its name.
void DoZoom(const wxPoint ¢erPoint, double zoomFactor, wxOrientation directions)
mpLayer * GetLayer(int position) const
void onZoomRedo(wxCommandEvent &event)
void ZoomIn(const wxPoint ¢erPoint=wxDefaultPosition)
Zoom into current view and refresh display.
void ZoomOut(const wxPoint ¢erPoint=wxDefaultPosition)
Zoom out current view and refresh display.
virtual bool UpdateBBox()
Recalculate global layer bounding box, and save it in m_minX,...
bool DelLayer(mpLayer *layer, bool alsoDeleteObject=false, bool refreshDisplay=true)
Remove a plot layer from the canvas.
void UpdateAll()
Refresh display.
void AdjustLimitedView(wxOrientation directions=wxBOTH)
Limits the zoomed or panned view to the area used by the plots.
wxCoord y2p(double y)
Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates,...
void OnCenter(wxCommandEvent &event)
virtual bool SetXView(double pos, double desiredMax, double desiredMin)
Applies new X view coordinates depending on the settings.
void SetScaleX(double scaleX)
Set current view's X scale and refresh display.
void onMagnify(wxMouseEvent &event)
double m_topBottomPlotGapFactor
void onZoomOut(wxCommandEvent &event)
void pushZoomUndo(const std::array< double, 4 > &aZoom)
std::stack< std::array< double, 4 > > m_undoZoomStack
int GetMarginRight() const
void GetBoundingBox(double *bbox) const
Returns the bounding box coordinates.
void SetScr(int scrX, int scrY)
Set current view's dimensions in device context units.
int GetMarginBottom() const
void PerformMouseWheelAction(wxMouseEvent &event, MouseWheelAction action)
static double zoomIncrementalFactor
This value sets the zoom steps whenever the user clicks "Zoom in/out" or performs zoom with the mouse...
double m_desiredXmin
These are updated in Fit, ZoomIn, ZoomOut, ZoomRect, SetXView, SetYView and may be different from the...
bool m_enableDoubleBuffer
void OnFit(wxCommandEvent &event)
void OnSize(wxSizeEvent &event)
const mpLayer * GetLayerByName(const wxString &name) const
unsigned int CountAllLayers() const
Counts the number of plot layers, whether or not they have a bounding box.
void SetPos(double posX, double posY)
Set current view's X and Y position and refresh display.
void onZoomIn(wxCommandEvent &event)
double GetScaleY() const
Get current view's Y scale.
double GetScaleX() const
Get current view's X scale.
bool AddLayer(mpLayer *layer, bool refreshDisplay=true)
Add a plot layer to the canvas.
void Fit() override
Set view to fit global bounding box of all plot layers and refresh display.
void onZoomUndo(wxCommandEvent &event)
double GetPosY() const
Get current view's Y position.
void onMouseMove(wxMouseEvent &event)
double GetPosX() const
Get current view's X position.
bool IsLayerVisible(const wxString &name) const
Check whether a layer with given name is visible.
#define mpLEGEND_LINEWIDTH
#define mpALIGN_BORDER_RIGHT
Aligns Y axis to right border.
#define mpALIGN_RIGHT
Aligns label to the right.
#define mpALIGN_NW
Aligns label to north-west.
#define mpALIGN_FAR_RIGHT
Aligns label to the right of mpALIGN_RIGHT.
#define mpALIGN_BORDER_TOP
Aligns X axis to top border.
#define mpALIGN_CENTER
Aligns label to the center.
#define mpALIGN_LEFT
Aligns label to the left.
#define mpALIGN_TOP
Aligns label to the top.
#define mpALIGN_BORDER_LEFT
Aligns Y axis to left border.
#define mpALIGN_SE
Aligns label to south-east.
#define mpALIGN_NE
Aligns label to north-east.
#define mpALIGN_BOTTOM
Aligns label to the bottom.
#define mpALIGN_BORDER_BOTTOM
Aligns X axis to bottom border.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
Contains the set of modified mouse wheel actions that can be performed on the plot.
MouseWheelAction horizontal
MouseWheelAction verticalWithShift
MouseWheelAction verticalWithCtrl
MouseWheelAction verticalWithAlt
MouseWheelAction verticalUnmodified