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 );
107 m_dim = wxRect( 0, 0, 1, 1 );
108 m_brush = *wxTRANSPARENT_BRUSH;
135 return m_dim.Contains( point );
199 return m_dim.GetPosition();
205 return m_dim.GetSize();
270 dc.GetTextExtent( label, &tmpX, &tmpY );
271 textX = ( textX > tmpX + baseWidth ) ? textX : tmpX + baseWidth +
mpLEGEND_MARGIN;
283 m_dim.height = textY;
288 dc.SetTextForeground( w.GetForegroundColour() );
298 dc.GetTextExtent( label, &tmpX, &tmpY );
343 if(
m_pen.GetWidth() <= 1 )
345 for( wxCoord i = startPx; i < endPx; ++i )
351 if( ( iy >= minYpx ) && ( iy <= maxYpx ) )
352 dc.DrawPoint( i, iy );
357 for( wxCoord i = startPx; i < endPx; ++i )
363 if( iy >= minYpx && iy <= maxYpx )
364 dc.DrawLine( i, iy, i, iy );
373 dc.GetTextExtent(
m_name, &tx, &ty );
413 if(
m_pen.GetWidth() <= 1 )
415 for( i = minYpx; i < maxYpx; ++i )
419 if( ( ix >= startPx ) && ( ix <= endPx ) )
420 dc.DrawPoint( ix, i );
425 for( i = 0; i< w.
GetScrY(); ++i )
429 if( ( ix >= startPx ) && ( ix <= endPx ) )
430 dc.DrawLine( ix, i, ix, i );
439 dc.GetTextExtent(
m_name, &tx, &ty );
489 wxCHECK_RET(
m_scaleX, wxS(
"X scale was not set" ) );
490 wxCHECK_RET(
m_scaleY, wxS(
"Y scale was not set" ) );
501 if( endPx <= startPx || minYpx >= maxYpx )
510 if(
GetNextXY( x, y ) && std::isfinite( x ) && std::isfinite( y ) )
521 dc.SetClippingRegion( startPx, minYpx, endPx - startPx + 1, maxYpx - minYpx + 1 );
527 std::set<wxCoord> ys;
532 if( !std::isfinite( x ) || !std::isfinite( y ) )
535 double px =
m_scaleX->TransformToPlot( x );
536 double py =
m_scaleY->TransformToPlot( y );
537 wxCoord newX = w.
x2p( px );
548 ys.insert( w.
y2p( py ) );
554 if( ( ix >= startPx ) && ( ix <= endPx ) && ( iy >= minYpx ) && ( iy <= maxYpx ) )
558 if(
m_pen.GetWidth() <= 1 )
559 dc.DrawPoint( ix, iy );
561 dc.DrawLine( ix, iy, ix, iy );
569 ys.insert( w.
y2p( py ) );
584 std::vector<wxPoint>pointList;
585 pointList.reserve( ( endPx - startPx ) * 2 );
589 bool hasNext =
GetNextXY( nextX, nextY );
590 bool offRight =
false;
597 std::vector<wxPoint> drawPoints;
598 drawPoints.reserve( ( endPx - startPx ) * 2 );
605 if( count && dupx0 > 1 && abs( ymax0 - ymin0 ) > 2 )
606 dc.DrawLine( x0, ymin0, x0, ymax0 );
612 if( pointList.size() > 1 )
622 int chunkSize = 10000;
624 int chunkSize = 100000;
626 wxPenStyle penStyle = dc.GetPen().GetStyle();
627 bool isSolidPen = ( penStyle == wxPENSTYLE_SOLID
628 || penStyle == wxPENSTYLE_TRANSPARENT );
633 drawPoints.push_back( pointList[0] );
635 for(
size_t ii = 1; ii < pointList.size()-1; ii++ )
642 && drawPoints.back().y == pointList[ii].y
643 && drawPoints.back().y == pointList[ii+1].y )
649 drawPoints.push_back( pointList[ii] );
651 if( (
int) drawPoints.size() > chunkSize )
653 dc.DrawLines( (
int) drawPoints.size(), &drawPoints[0] );
657 drawPoints.push_back( pointList[ii] );
663 if( drawPoints.back() != pointList.back() )
664 drawPoints.push_back( pointList.back() );
666 dc.DrawLines( (
int) drawPoints.size(), &drawPoints[0] );
687 if( !std::isfinite( x ) || !std::isfinite( y ) )
694 double px =
m_scaleX->TransformToPlot( x );
695 double py =
m_scaleY->TransformToPlot( y );
697 wxCoord x1 = w.
x2p( px );
698 wxCoord y1 = w.
y2p( py );
707 if( !std::isfinite( nextX ) )
710 wxCoord nextX1 = w.
x2p(
m_scaleX->TransformToPlot( nextX ) );
712 if( nextX1 < startPx-1 )
715 else if( x1 > endPx )
723 if( !count || line_start.x != x1 )
731 pointList.emplace_back( wxPoint( x1, y1 ) );
739 ymin0 = std::min( ymin0, y1 );
740 ymax0 = std::max( ymax0, y1 );
754 dc.GetTextExtent(
m_name, &tx, &ty );
778 dc.DrawText(
m_name, tx, ty );
781 dc.DestroyClippingRegion();
789#define mpLN10 2.3025850929940456840179914546844
793 double minV, maxV, minVvis, maxVvis;
803 double minErr = 1000000000000.0;
804 double bestStep = 1.0;
807 for(
int i = 10; i <= 20; i += 2 )
809 double curr_step = fabs( maxVvis - minVvis ) / (double) i;
810 double base = pow( 10, floor( log10( curr_step ) ) );
811 double stepInt = floor( curr_step / base ) * base;
812 double err = fabs( curr_step - stepInt );
821 double numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
826 while( numberSteps - 2.0 >= m_scrX/96.0 )
829 numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
832 double v = floor( minVvis / bestStep ) * bestStep;
833 double zeroOffset = 100000000.0;
839 if( fabs( v ) < zeroOffset )
840 zeroOffset = fabs( v );
845 if( zeroOffset <= bestStep )
887 const wxString s = tickLabel.label;
889 dc.GetTextExtent( s, &tx, &ty );
908 double pymin = w.
p2y( minYpx );
909 double pymax = w.
p2y( maxYpx );
931 double y_slave0 = p0 /
m_scale;
932 double y_slave1 = p1 /
m_scale;
934 double dy_slave = ( y_slave1 - y_slave0 );
935 double exponent = floor( log10( dy_slave ) );
936 double base = dy_slave / pow( 10.0, exponent );
938 double dy_scaled = ceil( 2.0 * base ) / 2.0 * pow( 10.0, exponent );
944 minvv = floor( minvv / dy_scaled ) * dy_scaled;
947 m_scale *= dy_slave / dy_scaled;
967 double minVvis, maxVvis;
992 double minErr = 1000000000000.0;
993 double bestStep = 1.0;
996 for(
int i = 10; i <= 20; i += 2 )
998 double curr_step = fabs( maxVvis - minVvis ) / (double) i;
999 double base = pow( 10, floor( log10( curr_step ) ) );
1000 double stepInt = floor( curr_step / base ) * base;
1001 double err = fabs( curr_step - stepInt );
1010 double numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
1014 while( numberSteps >= m_scrY / 32.0 )
1017 numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
1020 double v = floor( minVvis / bestStep ) * bestStep;
1021 double zeroOffset = 100000000.0;
1022 const int iterLimit = 1000;
1025 while( v <= maxVvis && i < iterLimit )
1029 if( fabs( v ) < zeroOffset )
1030 zeroOffset = fabs( v );
1037 if( i == iterLimit )
1040 if( zeroOffset <= bestStep )
1057 double pxmin = w.
p2x( startPx );
1058 double pxmax = w.
p2x( endPx );
1067 double minV, maxV, minVvis, maxVvis;
1073 double minDecade = pow( 10, floor( log10( minV ) ) );
1074 double maxDecade = pow( 10, ceil( log10( maxV ) ) );
1075 double visibleDecades = log( maxVvis / minVvis ) / log( 10 );
1084 if( minDecade == 0.0 )
1090 while( visibleDecades - 2 >= m_scrX / 96.0 )
1093 visibleDecades = log( maxVvis / minVvis ) / log( step );
1095 if( !std::isfinite( visibleDecades ) )
1099 for( d = minDecade; d<=maxDecade; d *= step )
1103 for(
double dd = d; dd < d * step; dd += d )
1105 if( visibleDecades < 2 )
1124 SetPen( (wxPen&) *wxGREY_PEN );
1158 const int extend = w.
GetScrX();
1191 if( p >= startPx && p <= endPx )
1196 dc.DrawLine( p, orgy, p, orgy - 4 );
1198 dc.DrawLine( p, orgy, p, orgy + 4 );
1202 m_pen.SetStyle( wxPENSTYLE_DOT );
1207 m_pen.SetStyle( wxPENSTYLE_DOT );
1209 dc.DrawLine( p, orgy + 4, p, minYpx );
1210 m_pen.SetStyle( wxPENSTYLE_SOLID );
1212 dc.DrawLine( p, orgy + 4, p, orgy - 4 );
1217 dc.DrawLine( p, orgy - 4, p, maxYpx );
1219 dc.DrawLine( p, minYpx, p, maxYpx );
1222 m_pen.SetStyle( wxPENSTYLE_SOLID );
1228 m_pen.SetStyle( wxPENSTYLE_SOLID );
1230 dc.DrawLine( startPx, minYpx, endPx, minYpx );
1231 dc.DrawLine( startPx, maxYpx, endPx, maxYpx );
1237 if( !tickLabel.visible )
1243 if( ( p >= startPx ) && ( p <= endPx ) )
1246 wxString s = tickLabel.label;
1248 dc.GetTextExtent( s, &tx, &ty );
1251 dc.DrawText( s, p - tx / 2, orgy - 4 - ty );
1253 dc.DrawText( s, p - tx / 2, orgy + 4 );
1258 dc.GetTextExtent(
m_name, &tx, &ty );
1263 dc.DrawText(
m_name, extend - tx - 4, orgy - 8 - ty - labelH );
1267 dc.DrawText(
m_name, ( endPx + startPx ) / 2 - tx / 2, orgy + 6 + labelH );
1271 dc.DrawText(
m_name, extend - tx - 4, orgy - 4 - ty );
1276 dc.DrawText(
m_name, ( endPx - startPx - tx ) >> 1, orgy - 6 - ty - labelH );
1278 dc.DrawText(
m_name, extend - tx - 4, orgy + 4 );
1283 dc.DrawText(
m_name, extend - tx - 4, orgy + 6 + labelH );
1299 SetPen( (wxPen&) *wxGREY_PEN );
1345 dc.DrawLine( orgx, minYpx, orgx, maxYpx );
1354 int labelHeight = 0;
1356 dc.GetTextExtent( s, &tx, &labelHeight );
1363 if( p >= minYpx && p <= maxYpx )
1368 dc.DrawLine( orgx, p, orgx + 4, p );
1370 dc.DrawLine( orgx - 4, p, orgx, p );
1374 dc.DrawLine( orgx - 4, p, orgx + 4, p );
1376 m_pen.SetStyle( wxPENSTYLE_DOT );
1379 dc.DrawLine( orgx - 4, p, endPx, p );
1381 m_pen.SetStyle( wxPENSTYLE_SOLID );
1394 if( !tickLabel.visible )
1397 if( p >= minYpx && p <= maxYpx )
1399 s = tickLabel.label;
1400 dc.GetTextExtent( s, &tx, &ty );
1404 dc.DrawText( s, orgx + 4, p - ty / 2 );
1406 dc.DrawText( s, orgx - 4 - tx, p - ty / 2 );
1411 dc.GetTextExtent(
m_name, &tx, &ty );
1416 dc.DrawText(
m_name, labelW + 8, 4 );
1420 dc.DrawText(
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
1424 dc.DrawText(
m_name, orgx + 4, 4 );
1429 dc.DrawText(
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
1433 dc.DrawText(
m_name, orgx - 6 - tx - labelW, 4 );
1447IMPLEMENT_DYNAMIC_CLASS(
mpWindow, wxWindow )
1449BEGIN_EVENT_TABLE(
mpWindow, wxWindow )
1482 _(
"Return zoom to level prior to last zoom action" ) );
1484 _(
"Return zoom to level prior to last zoom undo" ) );
1489 _(
"Center plot view to this position" ) );
1490 m_popmenu.Append(
mpID_FIT,
_(
"Fit on Screen" ),
_(
"Set plot view to show all items" ) );
1493 SetBackgroundColour( *wxWHITE );
1497 SetSizeHints( 128, 128 );
1500 SetBackgroundStyle( wxBG_STYLE_CUSTOM );
1535 float zoom =
event.GetMagnification() + 1.0f;
1536 wxPoint pos( event.GetX(), event.GetY() );
1540 else if(
zoom < 1.0f )
1555 const wxMouseWheelAxis axis =
event.GetWheelAxis();
1556 const int modifiers =
event.GetModifiers();
1559 if( axis == wxMOUSE_WHEEL_HORIZONTAL )
1563 else if( modifiers == wxMOD_NONE )
1567 else if( modifiers == wxMOD_CONTROL )
1571 else if( modifiers == wxMOD_SHIFT )
1575 else if( modifiers == wxMOD_ALT )
1599 wxCursor
cursor = wxCURSOR_MAGNIFIER;
1601 if( event.m_middleDown )
1628 else if( event.m_leftDown )
1633 cursor = wxCURSOR_SIZING;
1635 cursor = wxCURSOR_SIZEWE;
1643 cursor = wxCURSOR_MAGNIFIER;
1645 wxClientDC dc(
this );
1648 dc.SetBrush( *wxTRANSPARENT_BRUSH );
1664 if( layer->IsInfo() && layer->IsVisible() )
1668 if( infoLayer->
Inside( event.GetPosition() ) )
1671 cursor = wxCURSOR_SIZING;
1673 cursor = wxCURSOR_SIZEWE;
1690 wxPoint pointClicked =
event.GetPosition();
1707 wxPoint pointClicked =
event.GetPosition();
1711 if( infoLayer->OnDoubleClick( pointClicked, *
this ) )
1724 wxPoint release( event.GetX(), event.GetY() );
1736 if( release != press )
1752void mpWindow::Fit(
double xMin,
double xMax,
double yMin,
double yMax,
const wxCoord* printSizeX,
1753 const wxCoord* printSizeY, wxOrientation directions )
1755 const bool isPrinting = printSizeX !=
nullptr && printSizeY !=
nullptr;
1758 double newDesiredXmin = xMin;
1759 double newDesiredXmax = xMax;
1760 double newDesiredYmin = yMin;
1761 double newDesiredYmax = yMax;
1778 newScrX = *printSizeX;
1779 newScrY = *printSizeY;
1784 GetClientSize( &newScrX, &newScrY );
1792 double desiredSpanX = xMax - xMin;
1793 double desiredSpanY = yMax - yMin;
1794 double newScaleX = ( desiredSpanX != 0 ) ?
double( plotScreenWidth ) / desiredSpanX : 1;
1795 double newScaleY = ( desiredSpanY != 0 ) ?
double( plotScreenHeight ) / desiredSpanY : 1;
1800 double newPosY = yMax + (
m_marginTop / newScaleY );
1803 if( ( ( directions & wxHORIZONTAL ) != 0 ) || isPrinting )
1817 if( ( ( directions & wxVERTICAL ) != 0 ) || isPrinting )
1839 if( ( directions & wxHORIZONTAL ) != 0 )
1853 if( ( directions & wxHORIZONTAL ) != 0 )
1872 if( ( directions & wxVERTICAL ) != 0 )
1926void mpWindow::ZoomIn(
const wxPoint& centerPoint,
double zoomFactor, wxOrientation directions )
1928 DoZoom( centerPoint, zoomFactor, directions );
1940 if( zoomFactor == 0 )
1943 DoZoom( centerPoint, 1.0 / zoomFactor, directions );
1956 p0.x = std::max( p0.x, pMinX );
1957 p0.x = std::min( p0.x, pMaxX );
1958 p0.y = std::max( p0.y, pMinY );
1959 p0.y = std::min( p0.y, pMaxY );
1960 p1.x = std::max( p1.x, pMinX );
1961 p1.x = std::min( p1.x, pMaxX );
1962 p1.y = std::max( p1.y, pMinY );
1963 p1.y = std::min( p1.y, pMaxY );
1966 double p0x =
p2x( p0.x );
1967 double p0y =
p2y( p0.y );
1968 double p1x =
p2x( p1.x );
1969 double p1y =
p2y( p1.y );
1972 double zoom_x_min = p0x<p1x ? p0x : p1x;
1973 double zoom_x_max = p0x>p1x ? p0x : p1x;
1974 double zoom_y_min = p0y<p1y ? p0y : p1y;
1975 double zoom_y_max = p0y>p1y ? p0y : p1y;
1983 Fit( zoom_x_min, zoom_x_max, zoom_y_min, zoom_y_max );
1993 if( directionsNeedingRefitting != 0 )
2045 PopupMenu( &
m_popmenu, event.GetX(), event.GetY() );
2115 if( refreshDisplay )
2127 wxLayerList::iterator layIt;
2131 if( *layIt == layer )
2134 if( alsoDeleteObject )
2139 if( refreshDisplay )
2155 if( alsoDeleteObject )
2161 if( refreshDisplay )
2168 wxPaintDC paintDC(
this );
2173 wxDC* targetDC = &paintDC;
2182 const double scale = GetDPIScaleFactor();
2183 const int physX =
static_cast<int>( std::round(
m_scrX *
scale ) );
2184 const int physY =
static_cast<int>( std::round(
m_scrY *
scale ) );
2201 if( wxGraphicsContext* ctx = targetDC->GetGraphicsContext() )
2203 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST ) )
2204 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
2205 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
2207 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
2211 targetDC->SetPen( *wxTRANSPARENT_PEN );
2212 wxBrush brush( GetBackgroundColour() );
2213 targetDC->SetBrush( brush );
2219 layer->Plot( *targetDC, *
this );
2224 targetDC->SetPen( pen );
2225 targetDC->SetBrush( *wxTRANSPARENT_BRUSH );
2235void mpWindow::DoZoom(
const wxPoint& centerPoint,
double zoomFactor, wxOrientation directions )
2239 if( directions == wxVERTICAL )
2242 directions = wxHORIZONTAL;
2245 const bool horizontally = ( directions & wxHORIZONTAL ) != 0;
2246 const bool vertically = ( directions & wxVERTICAL ) != 0;
2251 wxPoint c( centerPoint );
2252 if( c == wxDefaultPosition )
2268 const double newScaleX = horizontally ? (
m_scaleX * zoomFactor ) :
m_scaleX;
2269 const double newScaleY = vertically ? (
m_scaleY * zoomFactor ) :
m_scaleY;
2278 const double prior_layer_x =
p2x( c.x );
2282 m_posX = prior_layer_x - c.x / newScaleX;
2291 const double prior_layer_y =
p2y( c.y );
2295 m_posY = prior_layer_y + c.y / newScaleY;
2303 if( zoomFactor < 1.0 )
2311 if( directionsNeedingRefitting != 0 )
2325 const double plotSpanX = plotScreenWidth /
m_scaleX;
2336 const double plotSpanY = plotScreenHeight /
m_scaleY;
2347 return static_cast<wxOrientation
>( 0 );
2354 wxOrientation
result = {};
2356 if( ( directions & wxHORIZONTAL ) != 0 )
2359 result =
static_cast<wxOrientation
>(
result | wxHORIZONTAL );
2362 if( ( directions & wxVERTICAL ) != 0 )
2365 result =
static_cast<wxOrientation
>(
result | wxVERTICAL );
2374 const int change =
event.GetWheelRotation();
2375 const double changeUnitsX = change /
m_scaleX;
2376 const double changeUnitsY = change /
m_scaleY;
2377 const wxPoint clickPt( event.GetX(), event.GetY() );
2406 if( event.GetWheelRotation() > 0 )
2414 if( event.GetWheelRotation() > 0 )
2422 if( event.GetWheelRotation() > 0 )
2466 if( ( position >= (
int)
m_layers.size() ) || position < 0 )
2477 if( !layer->GetName().Cmp(
name ) )
2498 if( aImageSize == wxDefaultSize )
2505 sizeX = aImageSize.x;
2506 sizeY = aImageSize.y;
2510 wxBitmap screenBuffer( sizeX, sizeY );
2511 wxMemoryDC screenDC;
2512 screenDC.SelectObject( screenBuffer );
2513 screenDC.SetPen( *wxWHITE_PEN );
2515 wxBrush brush( GetBackgroundColour() );
2516 screenDC.SetBrush( brush );
2517 screenDC.DrawRectangle( 0, 0, sizeX, sizeY );
2526 layer->Plot( screenDC, *
this );
2528 if( aImageSize != wxDefaultSize )
2533 SetScr( bk_scrX, bk_scrY );
2539 aImage = screenBuffer.ConvertToImage();
2558 if( layer->IsInfo() )
2562 if( tmpLyr->
Inside( point ) )
2575 lx->SetVisible( viewable );
2594 lx->SetVisible( viewable );
2603 return lx->IsVisible();
2610 const wxColour& axesColour )
2612 SetBackgroundColour( bgColour );
2613 SetForegroundColour( drawColour );
2624 wxPen axisPen = layer->GetPen();
2625 axisPen.SetColour( axesColour );
2626 layer->SetPen( axisPen );
2632 wxPen infoPen = layer->GetPen();
2633 infoPen.SetColour( drawColour );
2634 layer->SetPen( infoPen );
2640template <
typename... Ts>
2642 wxWindow(
std::forward<Ts>( windowArgs )... ),
2680 if( wxGraphicsContext* ctx =
m_buff_dc.GetGraphicsContext() )
2682 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
2683 || !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
2685 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
2688 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
2739 double xlogmin = log10(
m_minV );
2740 double xlogmax = log10(
m_maxV );
2742 return ( log10( x ) - xlogmin ) / ( xlogmax - xlogmin );
2748 double xlogmin = log10(
m_minV );
2749 double xlogmax = log10(
m_maxV );
2751 return pow( 10.0, xplot * ( xlogmax - xlogmin ) + xlogmin );
2794 if( xs.size() != ys.size() )
2803 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,...
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.
const wxFont & GetPlotFont() const
Get the font to draw this layer with, which is the default one when none was set.
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 void OnXViewChanged()
Called whenever the visible X range changes (pan, zoom, fit, ...).
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.