30#include "wx/dcclient.h"
36#include <wx/graphics.h>
51#define mpLEGEND_MARGIN 5
52#define mpLEGEND_LINEWIDTH 10
58bool mpFiniteRange(
const std::vector<double>& aValues,
double& aMin,
double& aMax )
62 for(
const double value : aValues )
64 if( !std::isfinite( value ) )
69 aMin = std::min( aMin, value );
70 aMax = std::max( aMax, value );
88IMPLEMENT_ABSTRACT_CLASS(
mpLayer, wxObject )
93 SetPen( (wxPen&) *wxBLACK_PEN );
94 SetFont( (wxFont&) *wxNORMAL_FONT );
108 m_dim = wxRect( 0, 0, 1, 1 );
109 m_brush = *wxTRANSPARENT_BRUSH;
136 return m_dim.Contains( point );
200 return m_dim.GetPosition();
206 return m_dim.GetSize();
271 dc.GetTextExtent( label, &tmpX, &tmpY );
272 textX = ( textX > tmpX + baseWidth ) ? textX : tmpX + baseWidth +
mpLEGEND_MARGIN;
284 m_dim.height = textY;
295 dc.GetTextExtent( label, &tmpX, &tmpY );
340 if(
m_pen.GetWidth() <= 1 )
342 for( wxCoord i = startPx; i < endPx; ++i )
348 if( ( iy >= minYpx ) && ( iy <= maxYpx ) )
349 dc.DrawPoint( i, iy );
354 for( wxCoord i = startPx; i < endPx; ++i )
360 if( iy >= minYpx && iy <= maxYpx )
361 dc.DrawLine( i, iy, i, iy );
370 dc.GetTextExtent(
m_name, &tx, &ty );
410 if(
m_pen.GetWidth() <= 1 )
412 for( i = minYpx; i < maxYpx; ++i )
416 if( ( ix >= startPx ) && ( ix <= endPx ) )
417 dc.DrawPoint( ix, i );
422 for( i = 0; i< w.
GetScrY(); ++i )
426 if( ( ix >= startPx ) && ( ix <= endPx ) )
427 dc.DrawLine( ix, i, ix, i );
436 dc.GetTextExtent(
m_name, &tx, &ty );
486 wxCHECK_RET(
m_scaleX, wxS(
"X scale was not set" ) );
487 wxCHECK_RET(
m_scaleY, wxS(
"Y scale was not set" ) );
498 if( endPx <= startPx || minYpx >= maxYpx )
507 if(
GetNextXY( x, y ) && std::isfinite( x ) && std::isfinite( y ) )
518 dc.SetClippingRegion( startPx, minYpx, endPx - startPx + 1, maxYpx - minYpx + 1 );
524 std::set<wxCoord> ys;
529 if( !std::isfinite( x ) || !std::isfinite( y ) )
532 double px =
m_scaleX->TransformToPlot( x );
533 double py =
m_scaleY->TransformToPlot( y );
534 wxCoord newX = w.
x2p( px );
545 ys.insert( w.
y2p( py ) );
551 if( ( ix >= startPx ) && ( ix <= endPx ) && ( iy >= minYpx ) && ( iy <= maxYpx ) )
555 if(
m_pen.GetWidth() <= 1 )
556 dc.DrawPoint( ix, iy );
558 dc.DrawLine( ix, iy, ix, iy );
566 ys.insert( w.
y2p( py ) );
581 std::vector<wxPoint>pointList;
582 pointList.reserve( ( endPx - startPx ) * 2 );
586 bool hasNext =
GetNextXY( nextX, nextY );
587 bool offRight =
false;
594 std::vector<wxPoint> drawPoints;
595 drawPoints.reserve( ( endPx - startPx ) * 2 );
602 if( count && dupx0 > 1 && abs( ymax0 - ymin0 ) > 2 )
603 dc.DrawLine( x0, ymin0, x0, ymax0 );
609 if( pointList.size() > 1 )
619 int chunkSize = 10000;
621 int chunkSize = 100000;
623 wxPenStyle penStyle = dc.GetPen().GetStyle();
624 bool isSolidPen = ( penStyle == wxPENSTYLE_SOLID
625 || penStyle == wxPENSTYLE_TRANSPARENT );
630 drawPoints.push_back( pointList[0] );
632 for(
size_t ii = 1; ii < pointList.size()-1; ii++ )
639 && drawPoints.back().y == pointList[ii].y
640 && drawPoints.back().y == pointList[ii+1].y )
646 drawPoints.push_back( pointList[ii] );
648 if( (
int) drawPoints.size() > chunkSize )
650 dc.DrawLines( (
int) drawPoints.size(), &drawPoints[0] );
654 drawPoints.push_back( pointList[ii] );
660 if( drawPoints.back() != pointList.back() )
661 drawPoints.push_back( pointList.back() );
663 dc.DrawLines( (
int) drawPoints.size(), &drawPoints[0] );
684 if( !std::isfinite( x ) || !std::isfinite( y ) )
691 double px =
m_scaleX->TransformToPlot( x );
692 double py =
m_scaleY->TransformToPlot( y );
694 wxCoord x1 = w.
x2p( px );
695 wxCoord y1 = w.
y2p( py );
704 if( !std::isfinite( nextX ) )
707 wxCoord nextX1 = w.
x2p(
m_scaleX->TransformToPlot( nextX ) );
709 if( nextX1 < startPx-1 )
712 else if( x1 > endPx )
720 if( !count || line_start.x != x1 )
728 pointList.emplace_back( wxPoint( x1, y1 ) );
736 ymin0 = std::min( ymin0, y1 );
737 ymax0 = std::max( ymax0, y1 );
751 dc.GetTextExtent(
m_name, &tx, &ty );
775 dc.DrawText(
m_name, tx, ty );
778 dc.DestroyClippingRegion();
786#define mpLN10 2.3025850929940456840179914546844
790 double minV, maxV, minVvis, maxVvis;
800 double minErr = 1000000000000.0;
801 double bestStep = 1.0;
804 for(
int i = 10; i <= 20; i += 2 )
806 double curr_step = fabs( maxVvis - minVvis ) / (double) i;
807 double base = pow( 10, floor( log10( curr_step ) ) );
808 double stepInt = floor( curr_step / base ) * base;
809 double err = fabs( curr_step - stepInt );
818 double numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
823 while( numberSteps - 2.0 >= m_scrX/96.0 )
826 numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
829 double v = floor( minVvis / bestStep ) * bestStep;
830 double zeroOffset = 100000000.0;
836 if( fabs( v ) < zeroOffset )
837 zeroOffset = fabs( v );
842 if( zeroOffset <= bestStep )
884 const wxString s = tickLabel.label;
886 dc.GetTextExtent( s, &tx, &ty );
905 double pymin = w.
p2y( minYpx );
906 double pymax = w.
p2y( maxYpx );
928 double y_slave0 = p0 /
m_scale;
929 double y_slave1 = p1 /
m_scale;
931 double dy_slave = ( y_slave1 - y_slave0 );
932 double exponent = floor( log10( dy_slave ) );
933 double base = dy_slave / pow( 10.0, exponent );
935 double dy_scaled = ceil( 2.0 * base ) / 2.0 * pow( 10.0, exponent );
941 minvv = floor( minvv / dy_scaled ) * dy_scaled;
944 m_scale *= dy_slave / dy_scaled;
964 double minVvis, maxVvis;
989 double minErr = 1000000000000.0;
990 double bestStep = 1.0;
993 for(
int i = 10; i <= 20; i += 2 )
995 double curr_step = fabs( maxVvis - minVvis ) / (double) i;
996 double base = pow( 10, floor( log10( curr_step ) ) );
997 double stepInt = floor( curr_step / base ) * base;
998 double err = fabs( curr_step - stepInt );
1007 double numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
1011 while( numberSteps >= m_scrY / 32.0 )
1014 numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
1017 double v = floor( minVvis / bestStep ) * bestStep;
1018 double zeroOffset = 100000000.0;
1019 const int iterLimit = 1000;
1022 while( v <= maxVvis && i < iterLimit )
1026 if( fabs( v ) < zeroOffset )
1027 zeroOffset = fabs( v );
1034 if( i == iterLimit )
1037 if( zeroOffset <= bestStep )
1054 double pxmin = w.
p2x( startPx );
1055 double pxmax = w.
p2x( endPx );
1064 double minV, maxV, minVvis, maxVvis;
1070 double minDecade = pow( 10, floor( log10( minV ) ) );
1071 double maxDecade = pow( 10, ceil( log10( maxV ) ) );
1072 double visibleDecades = log( maxVvis / minVvis ) / log( 10 );
1081 if( minDecade == 0.0 )
1087 while( visibleDecades - 2 >= m_scrX / 96.0 )
1090 visibleDecades = log( maxVvis / minVvis ) / log( step );
1092 if( !std::isfinite( visibleDecades ) )
1096 for( d = minDecade; d<=maxDecade; d *= step )
1100 for(
double dd = d; dd < d * step; dd += d )
1102 if( visibleDecades < 2 )
1121 SetFont( (wxFont&) *wxSMALL_FONT );
1122 SetPen( (wxPen&) *wxGREY_PEN );
1156 const int extend = w.
GetScrX();
1189 if( p >= startPx && p <= endPx )
1194 dc.DrawLine( p, orgy, p, orgy - 4 );
1196 dc.DrawLine( p, orgy, p, orgy + 4 );
1200 m_pen.SetStyle( wxPENSTYLE_DOT );
1205 m_pen.SetStyle( wxPENSTYLE_DOT );
1207 dc.DrawLine( p, orgy + 4, p, minYpx );
1208 m_pen.SetStyle( wxPENSTYLE_SOLID );
1210 dc.DrawLine( p, orgy + 4, p, orgy - 4 );
1215 dc.DrawLine( p, orgy - 4, p, maxYpx );
1217 dc.DrawLine( p, minYpx, p, maxYpx );
1220 m_pen.SetStyle( wxPENSTYLE_SOLID );
1226 m_pen.SetStyle( wxPENSTYLE_SOLID );
1228 dc.DrawLine( startPx, minYpx, endPx, minYpx );
1229 dc.DrawLine( startPx, maxYpx, endPx, maxYpx );
1235 if( !tickLabel.visible )
1241 if( ( p >= startPx ) && ( p <= endPx ) )
1244 wxString s = tickLabel.label;
1246 dc.GetTextExtent( s, &tx, &ty );
1249 dc.DrawText( s, p - tx / 2, orgy - 4 - ty );
1251 dc.DrawText( s, p - tx / 2, orgy + 4 );
1256 dc.GetTextExtent(
m_name, &tx, &ty );
1261 dc.DrawText(
m_name, extend - tx - 4, orgy - 8 - ty - labelH );
1265 dc.DrawText(
m_name, ( endPx + startPx ) / 2 - tx / 2, orgy + 6 + labelH );
1269 dc.DrawText(
m_name, extend - tx - 4, orgy - 4 - ty );
1274 dc.DrawText(
m_name, ( endPx - startPx - tx ) >> 1, orgy - 6 - ty - labelH );
1276 dc.DrawText(
m_name, extend - tx - 4, orgy + 4 );
1281 dc.DrawText(
m_name, extend - tx - 4, orgy + 6 + labelH );
1297 SetFont( (wxFont&) *wxSMALL_FONT );
1298 SetPen( (wxPen&) *wxGREY_PEN );
1344 dc.DrawLine( orgx, minYpx, orgx, maxYpx );
1353 int labelHeight = 0;
1355 dc.GetTextExtent( s, &tx, &labelHeight );
1362 if( p >= minYpx && p <= maxYpx )
1367 dc.DrawLine( orgx, p, orgx + 4, p );
1369 dc.DrawLine( orgx - 4, p, orgx, p );
1373 dc.DrawLine( orgx - 4, p, orgx + 4, p );
1375 m_pen.SetStyle( wxPENSTYLE_DOT );
1378 dc.DrawLine( orgx - 4, p, endPx, p );
1380 m_pen.SetStyle( wxPENSTYLE_SOLID );
1393 if( !tickLabel.visible )
1396 if( p >= minYpx && p <= maxYpx )
1398 s = tickLabel.label;
1399 dc.GetTextExtent( s, &tx, &ty );
1403 dc.DrawText( s, orgx + 4, p - ty / 2 );
1405 dc.DrawText( s, orgx - 4 - tx, p - ty / 2 );
1410 dc.GetTextExtent(
m_name, &tx, &ty );
1415 dc.DrawText(
m_name, labelW + 8, 4 );
1419 dc.DrawText(
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
1423 dc.DrawText(
m_name, orgx + 4, 4 );
1428 dc.DrawText(
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
1432 dc.DrawText(
m_name, orgx - 6 - tx - labelW, 4 );
1446IMPLEMENT_DYNAMIC_CLASS(
mpWindow, wxWindow )
1448BEGIN_EVENT_TABLE(
mpWindow, wxWindow )
1481 _(
"Return zoom to level prior to last zoom action" ) );
1483 _(
"Return zoom to level prior to last zoom undo" ) );
1488 _(
"Center plot view to this position" ) );
1489 m_popmenu.Append(
mpID_FIT,
_(
"Fit on Screen" ),
_(
"Set plot view to show all items" ) );
1492 SetBackgroundColour( *wxWHITE );
1496 SetSizeHints( 128, 128 );
1499 SetBackgroundStyle( wxBG_STYLE_CUSTOM );
1534 float zoom =
event.GetMagnification() + 1.0f;
1535 wxPoint pos( event.GetX(), event.GetY() );
1539 else if(
zoom < 1.0f )
1554 const wxMouseWheelAxis axis =
event.GetWheelAxis();
1555 const int modifiers =
event.GetModifiers();
1558 if( axis == wxMOUSE_WHEEL_HORIZONTAL )
1562 else if( modifiers == wxMOD_NONE )
1566 else if( modifiers == wxMOD_CONTROL )
1570 else if( modifiers == wxMOD_SHIFT )
1574 else if( modifiers == wxMOD_ALT )
1598 wxCursor
cursor = wxCURSOR_MAGNIFIER;
1600 if( event.m_middleDown )
1627 else if( event.m_leftDown )
1632 cursor = wxCURSOR_SIZING;
1634 cursor = wxCURSOR_SIZEWE;
1642 cursor = wxCURSOR_MAGNIFIER;
1644 wxClientDC dc(
this );
1647 dc.SetBrush( *wxTRANSPARENT_BRUSH );
1663 if( layer->IsInfo() && layer->IsVisible() )
1667 if( infoLayer->
Inside( event.GetPosition() ) )
1670 cursor = wxCURSOR_SIZING;
1672 cursor = wxCURSOR_SIZEWE;
1689 wxPoint pointClicked =
event.GetPosition();
1698 wxPoint pointClicked =
event.GetPosition();
1702 if( infoLayer->OnDoubleClick( pointClicked, *
this ) )
1715 wxPoint release( event.GetX(), event.GetY() );
1727 if( release != press )
1743void mpWindow::Fit(
double xMin,
double xMax,
double yMin,
double yMax,
const wxCoord* printSizeX,
1744 const wxCoord* printSizeY, wxOrientation directions )
1746 const bool isPrinting = printSizeX !=
nullptr && printSizeY !=
nullptr;
1749 double newDesiredXmin = xMin;
1750 double newDesiredXmax = xMax;
1751 double newDesiredYmin = yMin;
1752 double newDesiredYmax = yMax;
1769 newScrX = *printSizeX;
1770 newScrY = *printSizeY;
1775 GetClientSize( &newScrX, &newScrY );
1783 double desiredSpanX = xMax - xMin;
1784 double desiredSpanY = yMax - yMin;
1785 double newScaleX = ( desiredSpanX != 0 ) ?
double( plotScreenWidth ) / desiredSpanX : 1;
1786 double newScaleY = ( desiredSpanY != 0 ) ?
double( plotScreenHeight ) / desiredSpanY : 1;
1791 double newPosY = yMax + (
m_marginTop / newScaleY );
1794 if( ( ( directions & wxHORIZONTAL ) != 0 ) || isPrinting )
1808 if( ( ( directions & wxVERTICAL ) != 0 ) || isPrinting )
1839 if( ( directions & wxHORIZONTAL ) != 0 )
1858 if( ( directions & wxVERTICAL ) != 0 )
1910void mpWindow::ZoomIn(
const wxPoint& centerPoint,
double zoomFactor, wxOrientation directions )
1912 DoZoom( centerPoint, zoomFactor, directions );
1924 if( zoomFactor == 0 )
1927 DoZoom( centerPoint, 1.0 / zoomFactor, directions );
1940 p0.x = std::max( p0.x, pMinX );
1941 p0.x = std::min( p0.x, pMaxX );
1942 p0.y = std::max( p0.y, pMinY );
1943 p0.y = std::min( p0.y, pMaxY );
1944 p1.x = std::max( p1.x, pMinX );
1945 p1.x = std::min( p1.x, pMaxX );
1946 p1.y = std::max( p1.y, pMinY );
1947 p1.y = std::min( p1.y, pMaxY );
1950 double p0x =
p2x( p0.x );
1951 double p0y =
p2y( p0.y );
1952 double p1x =
p2x( p1.x );
1953 double p1y =
p2y( p1.y );
1956 double zoom_x_min = p0x<p1x ? p0x : p1x;
1957 double zoom_x_max = p0x>p1x ? p0x : p1x;
1958 double zoom_y_min = p0y<p1y ? p0y : p1y;
1959 double zoom_y_max = p0y>p1y ? p0y : p1y;
1967 Fit( zoom_x_min, zoom_x_max, zoom_y_min, zoom_y_max );
1977 if( directionsNeedingRefitting != 0 )
2029 PopupMenu( &
m_popmenu, event.GetX(), event.GetY() );
2099 if( refreshDisplay )
2111 wxLayerList::iterator layIt;
2115 if( *layIt == layer )
2118 if( alsoDeleteObject )
2123 if( refreshDisplay )
2139 if( alsoDeleteObject )
2145 if( refreshDisplay )
2152 wxPaintDC paintDC(
this );
2157 wxDC* targetDC = &paintDC;
2166 const double scale = GetDPIScaleFactor();
2167 const int physX =
static_cast<int>( std::round(
m_scrX *
scale ) );
2168 const int physY =
static_cast<int>( std::round(
m_scrY *
scale ) );
2185 if( wxGraphicsContext* ctx = targetDC->GetGraphicsContext() )
2187 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST ) )
2188 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
2189 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
2191 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
2195 targetDC->SetPen( *wxTRANSPARENT_PEN );
2196 wxBrush brush( GetBackgroundColour() );
2197 targetDC->SetBrush( brush );
2203 layer->Plot( *targetDC, *
this );
2208 targetDC->SetPen( pen );
2209 targetDC->SetBrush( *wxTRANSPARENT_BRUSH );
2219void mpWindow::DoZoom(
const wxPoint& centerPoint,
double zoomFactor, wxOrientation directions )
2223 if( directions == wxVERTICAL )
2226 directions = wxHORIZONTAL;
2229 const bool horizontally = ( directions & wxHORIZONTAL ) != 0;
2230 const bool vertically = ( directions & wxVERTICAL ) != 0;
2235 wxPoint c( centerPoint );
2236 if( c == wxDefaultPosition )
2252 const double newScaleX = horizontally ? (
m_scaleX * zoomFactor ) :
m_scaleX;
2253 const double newScaleY = vertically ? (
m_scaleY * zoomFactor ) :
m_scaleY;
2262 const double prior_layer_x =
p2x( c.x );
2266 m_posX = prior_layer_x - c.x / newScaleX;
2275 const double prior_layer_y =
p2y( c.y );
2279 m_posY = prior_layer_y + c.y / newScaleY;
2287 if( zoomFactor < 1.0 )
2295 if( directionsNeedingRefitting != 0 )
2306 const double plotSpanX = plotScreenWidth /
m_scaleX;
2317 const double plotSpanY = plotScreenHeight /
m_scaleY;
2328 return static_cast<wxOrientation
>( 0 );
2335 wxOrientation
result = {};
2337 if( ( directions & wxHORIZONTAL ) != 0 )
2340 result =
static_cast<wxOrientation
>(
result | wxHORIZONTAL );
2343 if( ( directions & wxVERTICAL ) != 0 )
2346 result =
static_cast<wxOrientation
>(
result | wxVERTICAL );
2355 const int change =
event.GetWheelRotation();
2356 const double changeUnitsX = change /
m_scaleX;
2357 const double changeUnitsY = change /
m_scaleY;
2358 const wxPoint clickPt( event.GetX(), event.GetY() );
2387 if( event.GetWheelRotation() > 0 )
2395 if( event.GetWheelRotation() > 0 )
2403 if( event.GetWheelRotation() > 0 )
2447 if( ( position >= (
int)
m_layers.size() ) || position < 0 )
2458 if( !layer->GetName().Cmp(
name ) )
2479 if( aImageSize == wxDefaultSize )
2486 sizeX = aImageSize.x;
2487 sizeY = aImageSize.y;
2491 wxBitmap screenBuffer( sizeX, sizeY );
2492 wxMemoryDC screenDC;
2493 screenDC.SelectObject( screenBuffer );
2494 screenDC.SetPen( *wxWHITE_PEN );
2496 wxBrush brush( GetBackgroundColour() );
2497 screenDC.SetBrush( brush );
2498 screenDC.DrawRectangle( 0, 0, sizeX, sizeY );
2507 layer->Plot( screenDC, *
this );
2509 if( aImageSize != wxDefaultSize )
2514 SetScr( bk_scrX, bk_scrY );
2520 aImage = screenBuffer.ConvertToImage();
2539 if( layer->IsInfo() )
2543 if( tmpLyr->
Inside( point ) )
2556 lx->SetVisible( viewable );
2575 lx->SetVisible( viewable );
2584 return lx->IsVisible();
2591 const wxColour& axesColour )
2593 SetBackgroundColour( bgColour );
2594 SetForegroundColour( drawColour );
2605 wxPen axisPen = layer->GetPen();
2606 axisPen.SetColour( axesColour );
2607 layer->SetPen( axisPen );
2613 wxPen infoPen = layer->GetPen();
2614 infoPen.SetColour( drawColour );
2615 layer->SetPen( infoPen );
2621template <
typename... Ts>
2623 wxWindow(
std::forward<Ts>( windowArgs )... ),
2661 if( wxGraphicsContext* ctx =
m_buff_dc.GetGraphicsContext() )
2663 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
2664 || !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
2666 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
2669 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
2720 double xlogmin = log10(
m_minV );
2721 double xlogmax = log10(
m_maxV );
2723 return ( log10( x ) - xlogmin ) / ( xlogmax - xlogmin );
2729 double xlogmin = log10(
m_minV );
2730 double xlogmax = log10(
m_maxV );
2732 return pow( 10.0, xplot * ( xlogmax - xlogmin ) + xlogmin );
2775 if( xs.size() != ys.size() )
2784 const double unbounded = std::numeric_limits<double>::quiet_NaN();
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.
mpFXYVector(const wxString &name=wxEmptyString, int flags=mpALIGN_NE)
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
mpFXY(const wxString &name=wxEmptyString, int flags=mpALIGN_NE)
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.
mpFX(const wxString &name=wxEmptyString, int flags=mpALIGN_RIGHT)
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.
mpFY(const wxString &name=wxEmptyString, int flags=mpALIGN_TOP)
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 bool OnDoubleClick(const wxPoint &point, mpWindow &w)
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,...
void SetFont(const wxFont &font)
Set layer font.
bool IsVisible() const
Checks whether the layer is visible or not.
virtual double GetMinY() const
Get inclusive bottom border of bounding box.
virtual void SetName(const wxString &name)
Set layer name.
const wxPen & GetPen() const
Get pen set for this layer.
void SetPen(const wxPen &pen)
Set layer pen.
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)
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.
mpScaleXBase(const wxString &name=wxT("X"), int flags=mpALIGN_CENTER, bool ticks=true, unsigned int type=mpX_NORMAL)
Full constructor.
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
mpScaleY(const wxString &name=wxT("Y"), int flags=mpALIGN_CENTER, bool ticks=true)
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...
void onMouseLeftDClick(wxMouseEvent &event)
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.
EVT_MENU(ID_COMPARE_PROJECT_BRANCHES, KICAD_MANAGER_FRAME::OnCompareProjectBranches) KICAD_MANAGER_FRAME
#define mpLEGEND_LINEWIDTH
bool mpFiniteRange(const std::vector< double > &aValues, double &aMin, double &aMax)
Find the smallest and largest finite value in aValues.
#define mpALIGN_BORDER_RIGHT
Aligns Y axis to right border.
bool WXDLLIMPEXP_MATHPLOT mpFiniteRange(const std::vector< double > &aValues, double &aMin, double &aMax)
Find the smallest and largest finite value in aValues.
#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)
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
KIBIS top(path, &reporter)
wxString result
Test unit parsing edge cases and error handling.