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 );
 
 
  108    return m_dim.Contains( point );
 
 
  172    return m_dim.GetPosition();
 
 
  178    return m_dim.GetSize();
 
 
  243                dc.GetTextExtent( label, &tmpX, &tmpY );
 
  244                textX = ( textX > tmpX + baseWidth ) ? textX : tmpX + baseWidth + 
mpLEGEND_MARGIN;
 
  256            m_dim.height = textY;
 
  267                    dc.GetTextExtent( label, &tmpX, &tmpY );
 
 
  312        if( 
m_pen.GetWidth() <= 1 )
 
  314            for( wxCoord i = startPx; i < endPx; ++i )
 
  320                if( ( iy >= minYpx ) && ( iy <= maxYpx ) )
 
  321                    dc.DrawPoint( i, iy );
 
  326            for( wxCoord i = startPx; i < endPx; ++i )
 
  332                if( iy >= minYpx && iy <= maxYpx )
 
  333                    dc.DrawLine( i, iy, i, iy );
 
  342            dc.GetTextExtent( 
m_name, &tx, &ty );
 
 
  382        if( 
m_pen.GetWidth() <= 1 )
 
  384            for( i = minYpx; i < maxYpx; ++i )
 
  388                if( ( ix >= startPx ) && ( ix <= endPx ) )
 
  389                    dc.DrawPoint( ix, i );
 
  394            for( i = 0; i< w.
GetScrY(); ++i )
 
  398                if( ( ix >= startPx ) && ( ix <= endPx ) )
 
  399                    dc.DrawLine( ix, i, ix, i );
 
  408            dc.GetTextExtent( 
m_name, &tx, &ty );
 
 
  458    wxCHECK_RET( 
m_scaleX, wxS( 
"X scale was not set" ) );
 
  459    wxCHECK_RET( 
m_scaleY, wxS( 
"Y scale was not set" ) );
 
  470    if( endPx <= startPx || minYpx >= maxYpx )
 
  486    dc.SetClippingRegion( startPx, minYpx, endPx - startPx + 1, maxYpx - minYpx + 1 );
 
  492        std::set<wxCoord> ys;
 
  496            double px = 
m_scaleX->TransformToPlot( x );
 
  497            double py = 
m_scaleY->TransformToPlot( y );
 
  498            wxCoord newX = w.
x2p( px );
 
  509                ys.insert( w.
y2p( py ) );
 
  515                if( ( ix >= startPx ) && ( ix <= endPx ) && ( iy >= minYpx ) && ( iy <= maxYpx ) )
 
  519                    if( 
m_pen.GetWidth() <= 1 )
 
  520                        dc.DrawPoint( ix, iy );
 
  522                        dc.DrawLine( ix, iy, ix, iy );
 
  530            ys.insert( w.
y2p( py ) );
 
  545        std::vector<wxPoint>pointList;
 
  546        pointList.reserve( ( endPx - startPx ) * 2 );
 
  550        bool hasNext = 
GetNextXY( nextX, nextY );
 
  551        bool offRight = 
false;
 
  565            double px = 
m_scaleX->TransformToPlot( x );
 
  566            double py = 
m_scaleY->TransformToPlot( y );
 
  568            wxCoord x1 = w.
x2p( px );
 
  569            wxCoord y1 = w.
y2p( py );
 
  577                wxCoord nextX1 = w.
x2p( 
m_scaleX->TransformToPlot( nextX ) );
 
  579                if( nextX1 < startPx-1 )
 
  582            else if( x1 > endPx )
 
  590            if( !count || line_start.x != x1 )
 
  596                if( count && dupx0 > 1 && abs( ymax0 - ymin0 ) > 2 )
 
  597                    dc.DrawLine( x0, ymin0, x0, ymax0 );
 
  603                pointList.emplace_back( wxPoint( x1, y1 ) );
 
  611                ymin0 = std::min( ymin0, y1 );
 
  612                ymax0 = std::max( ymax0, y1 );
 
  618        if( pointList.size() > 1 )
 
  625            std::vector<wxPoint> drawPoints;
 
  626            drawPoints.reserve( ( endPx - startPx ) * 2 );
 
  629            int chunkSize = 10000;
 
  631            int chunkSize = 100000;
 
  633            if( dc.GetPen().GetStyle() == wxPENSTYLE_DOT )
 
  636            drawPoints.push_back( pointList[0] );   
 
  638            for( 
size_t ii = 1; ii < pointList.size()-1; ii++ )
 
  642                if( 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] );
 
  675        dc.GetTextExtent( 
m_name, &tx, &ty );
 
  699        dc.DrawText( 
m_name, tx, ty );
 
  702    dc.DestroyClippingRegion();
 
 
  710#define mpLN10 2.3025850929940456840179914546844 
  714    double minV, maxV, minVvis, maxVvis;
 
  724    double  minErr = 1000000000000.0;
 
  725    double  bestStep = 1.0;
 
  728    for( 
int i = 10; i <= 20; i += 2 )
 
  730        double  curr_step    = fabs( maxVvis - minVvis ) / (double) i;
 
  731        double  base    = pow( 10, floor( log10( curr_step ) ) );
 
  732        double  stepInt = floor( curr_step / base ) * base;
 
  733        double  err = fabs( curr_step - stepInt );
 
  742    double numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
 
  747    while( numberSteps - 2.0 >= m_scrX/96.0 )
 
  750        numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
 
  753    double v = floor( minVvis / bestStep ) * bestStep;
 
  754    double zeroOffset = 100000000.0;
 
  760        if( fabs( v ) < zeroOffset )
 
  761            zeroOffset = fabs( v );
 
  766    if( zeroOffset <= bestStep )
 
 
  808        const wxString s = tickLabel.label;
 
  810        dc.GetTextExtent( s, &tx, &ty );
 
 
  829    double  pymin   = w.
p2y( minYpx );
 
  830    double  pymax   = w.
p2y( maxYpx );
 
 
  852    double y_slave0 = p0 / 
m_scale;
 
  853    double y_slave1 = p1 / 
m_scale;
 
  855    double  dy_slave = ( y_slave1 - y_slave0 );
 
  856    double  exponent = floor( log10( dy_slave ) );
 
  857    double  base = dy_slave / pow( 10.0, exponent );
 
  859    double dy_scaled = ceil( 2.0 * base ) / 2.0 * pow( 10.0, exponent );
 
  865    minvv = floor( minvv / dy_scaled ) * dy_scaled;
 
  868    m_scale *= dy_slave / dy_scaled;
 
 
  888    double minVvis, maxVvis;
 
  913    double  minErr = 1000000000000.0;
 
  914    double  bestStep = 1.0;
 
  917    for( 
int i = 10; i <= 20; i += 2 )
 
  919        double  curr_step = fabs( maxVvis - minVvis ) / (double) i;
 
  920        double  base = pow( 10, floor( log10( curr_step ) ) );
 
  921        double  stepInt = floor( curr_step / base ) * base;
 
  922        double  err = fabs( curr_step - stepInt );
 
  931    double numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
 
  935    while( numberSteps >= m_scrY / 32.0 )
 
  938        numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
 
  941    double v = floor( minVvis / bestStep ) * bestStep;
 
  942    double zeroOffset = 100000000.0;
 
  943    const  int iterLimit = 1000;
 
  946    while( v <= maxVvis && i < iterLimit )
 
  950        if( fabs( v ) < zeroOffset )
 
  951            zeroOffset = fabs( v );
 
  961    if( zeroOffset <= bestStep )
 
 
  978    double  pxmin   = w.
p2x( startPx );
 
  979    double  pxmax   = w.
p2x( endPx );
 
 
  988    double minV, maxV, minVvis, maxVvis;
 
  994    double  minDecade   = pow( 10, floor( log10( minV ) ) );
 
  995    double  maxDecade   = pow( 10, ceil( log10( maxV ) ) );
 
  996    double visibleDecades = log( maxVvis / minVvis ) / log( 10 );
 
 1005    if( minDecade == 0.0 )
 
 1011    while( visibleDecades - 2 >= m_scrX / 96.0 )
 
 1014        visibleDecades = log( maxVvis / minVvis ) / log( step );
 
 1016        if( !std::isfinite( visibleDecades ) )
 
 1020    for( d = minDecade; d<=maxDecade; d *= step )
 
 1024        for( 
double dd = d; dd < d * step; dd += d )
 
 1026            if( visibleDecades < 2 )
 
 
 1045    SetFont( (wxFont&) *wxSMALL_FONT );
 
 1046    SetPen( (wxPen&) *wxGREY_PEN );
 
 
 1080        const int extend = w.
GetScrX();    
 
 1113            if( p >= startPx && p <= endPx )
 
 1118                        dc.DrawLine( p, orgy, p, orgy - 4 );
 
 1120                        dc.DrawLine( p, orgy, p, orgy + 4 );
 
 1124                    m_pen.SetStyle( wxPENSTYLE_DOT );
 
 1129                        m_pen.SetStyle( wxPENSTYLE_DOT );
 
 1131                        dc.DrawLine( p, orgy + 4, p, minYpx );
 
 1132                        m_pen.SetStyle( wxPENSTYLE_SOLID );
 
 1134                        dc.DrawLine( p, orgy + 4, p, orgy - 4 );
 
 1139                            dc.DrawLine( p, orgy - 4, p, maxYpx );
 
 1141                            dc.DrawLine( p, minYpx, p, maxYpx );
 
 1144                    m_pen.SetStyle( wxPENSTYLE_SOLID );
 
 1150        m_pen.SetStyle( wxPENSTYLE_SOLID );
 
 1152        dc.DrawLine( startPx, minYpx, endPx, minYpx );
 
 1153        dc.DrawLine( startPx, maxYpx, endPx, maxYpx );
 
 1159            if( !tickLabel.visible )
 
 1165            if( ( p >= startPx ) && ( p <= endPx ) )
 
 1168                wxString s = tickLabel.label;
 
 1170                dc.GetTextExtent( s, &tx, &ty );
 
 1173                    dc.DrawText( s, p - tx / 2, orgy - 4 - ty );
 
 1175                    dc.DrawText( s, p - tx / 2, orgy + 4 );
 
 1180        dc.GetTextExtent( 
m_name, &tx, &ty );
 
 1185            dc.DrawText( 
m_name, extend - tx - 4, orgy - 8 - ty - labelH );
 
 1189            dc.DrawText( 
m_name, ( endPx + startPx ) / 2 - tx / 2, orgy + 6 + labelH );
 
 1193            dc.DrawText( 
m_name, extend - tx - 4, orgy - 4 - ty );
 
 1198                dc.DrawText( 
m_name, ( endPx - startPx - tx ) >> 1, orgy - 6 - ty - labelH );
 
 1200                dc.DrawText( 
m_name, extend - tx - 4, orgy + 4 );
 
 1205            dc.DrawText( 
m_name, extend - tx - 4, orgy + 6 + labelH );
 
 
 1221    SetFont( (wxFont&) *wxSMALL_FONT );
 
 1222    SetPen( (wxPen&) *wxGREY_PEN );
 
 
 1268        dc.DrawLine( orgx, minYpx, orgx, maxYpx );
 
 1277        int labelHeight = 0;
 
 1279        dc.GetTextExtent( s, &tx, &labelHeight );
 
 1286            if( p >= minYpx && p <= maxYpx )
 
 1291                        dc.DrawLine( orgx, p, orgx + 4, p );
 
 1293                        dc.DrawLine( orgx - 4, p, orgx, p );
 
 1297                    dc.DrawLine( orgx - 4, p, orgx + 4, p );
 
 1299                    m_pen.SetStyle( wxPENSTYLE_DOT );
 
 1302                    dc.DrawLine( orgx - 4, p, endPx, p );
 
 1304                    m_pen.SetStyle( wxPENSTYLE_SOLID );
 
 1317            if( !tickLabel.visible )
 
 1320            if( p >= minYpx && p <= maxYpx )
 
 1322                s = tickLabel.label;
 
 1323                dc.GetTextExtent( s, &tx, &ty );
 
 1327                    dc.DrawText( s, orgx + 4, p - ty / 2 );
 
 1329                    dc.DrawText( s, orgx - 4 - tx, p - ty / 2 );    
 
 1334        dc.GetTextExtent( 
m_name, &tx, &ty );
 
 1339            dc.DrawText( 
m_name, labelW + 8, 4 );
 
 1343            dc.DrawText( 
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
 
 1347            dc.DrawText( 
m_name, orgx + 4, 4 );
 
 1352            dc.DrawText( 
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
 
 1356            dc.DrawText( 
m_name, orgx - 6 - tx - labelW, 4 );
 
 
 1370IMPLEMENT_DYNAMIC_CLASS( 
mpWindow, wxWindow )
 
 1372BEGIN_EVENT_TABLE( 
mpWindow, wxWindow )
 
 1405                      _( 
"Return zoom to level prior to last zoom action" ) );
 
 1407                      _( 
"Return zoom to level prior to last zoom undo" ) );
 
 1412                      _( 
"Center plot view to this position" ) );
 
 1413    m_popmenu.Append( 
mpID_FIT, 
_( 
"Fit on Screen" ), 
_( 
"Set plot view to show all items" ) );
 
 1416    SetBackgroundColour( *wxWHITE );
 
 1420    SetSizeHints( 128, 128 );
 
 1423    SetBackgroundStyle( wxBG_STYLE_CUSTOM );
 
 
 1458    float   zoom = 
event.GetMagnification() + 1.0f;
 
 1459    wxPoint pos( event.GetX(), event.GetY() );
 
 1463    else if( 
zoom < 1.0f )
 
 
 1478    const wxMouseWheelAxis axis = 
event.GetWheelAxis();
 
 1479    const int              modifiers = 
event.GetModifiers();
 
 1482    if( axis == wxMOUSE_WHEEL_HORIZONTAL )
 
 1486    else if( modifiers == wxMOD_NONE )
 
 1490    else if( modifiers == wxMOD_CONTROL )
 
 1494    else if( modifiers == wxMOD_SHIFT )
 
 1498    else if( modifiers == wxMOD_ALT )
 
 
 1522    wxCursor 
cursor = wxCURSOR_MAGNIFIER;
 
 1524    if( event.m_middleDown )
 
 1551    else if( event.m_leftDown )
 
 1556                cursor = wxCURSOR_SIZING;
 
 1558                cursor = wxCURSOR_SIZEWE;
 
 1566            cursor = wxCURSOR_MAGNIFIER;
 
 1568            wxClientDC dc( 
this );
 
 1571            dc.SetBrush( *wxTRANSPARENT_BRUSH );
 
 1587            if( layer->IsInfo() && layer->IsVisible() )
 
 1591                if( infoLayer->
Inside( event.GetPosition() ) )
 
 1594                        cursor = wxCURSOR_SIZING;
 
 1596                        cursor = wxCURSOR_SIZEWE;
 
 
 1613    wxPoint pointClicked = 
event.GetPosition();
 
 
 1622    wxPoint pointClicked = 
event.GetPosition();
 
 1626        if( infoLayer->OnDoubleClick( pointClicked, *
this ) )
 
 
 1639    wxPoint release( event.GetX(), event.GetY() );
 
 1651        if( release != press )
 
 
 1667void mpWindow::Fit( 
double xMin, 
double xMax, 
double yMin, 
double yMax, 
const wxCoord* printSizeX,
 
 1668                    const wxCoord* printSizeY, wxOrientation directions )
 
 1670    const bool isPrinting = printSizeX != 
nullptr && printSizeY != 
nullptr;
 
 1673    double newDesiredXmin = xMin;
 
 1674    double newDesiredXmax = xMax;
 
 1675    double newDesiredYmin = yMin;
 
 1676    double newDesiredYmax = yMax;
 
 1693        newScrX = *printSizeX;
 
 1694        newScrY = *printSizeY;
 
 1699        GetClientSize( &newScrX, &newScrY );
 
 1707    double desiredSpanX = xMax - xMin;
 
 1708    double desiredSpanY = yMax - yMin;
 
 1709    double newScaleX = ( desiredSpanX != 0 ) ? 
double( plotScreenWidth )  / desiredSpanX : 1;
 
 1710    double newScaleY = ( desiredSpanY != 0 ) ? 
double( plotScreenHeight ) / desiredSpanY : 1;
 
 1715    double newPosY = yMax + ( 
m_marginTop  / newScaleY );
 
 1718    if( ( ( directions & wxHORIZONTAL ) != 0 ) || isPrinting )
 
 1732    if( ( ( directions & wxVERTICAL ) != 0 ) || isPrinting )
 
 
 1763    if( ( directions & wxHORIZONTAL ) != 0 )
 
 1782    if( ( directions & wxVERTICAL ) != 0 )
 
 
 1834void mpWindow::ZoomIn( 
const wxPoint& centerPoint, 
double zoomFactor, wxOrientation directions )
 
 1836    DoZoom( centerPoint, zoomFactor, directions );
 
 
 1848    if( zoomFactor == 0 )
 
 1851    DoZoom( centerPoint, 1.0 / zoomFactor, directions );
 
 
 1864    p0.x = std::max( p0.x, pMinX );
 
 1865    p0.x = std::min( p0.x, pMaxX );
 
 1866    p0.y = std::max( p0.y, pMinY );
 
 1867    p0.y = std::min( p0.y, pMaxY );
 
 1868    p1.x = std::max( p1.x, pMinX );
 
 1869    p1.x = std::min( p1.x, pMaxX );
 
 1870    p1.y = std::max( p1.y, pMinY );
 
 1871    p1.y = std::min( p1.y, pMaxY );
 
 1874    double  p0x = 
p2x( p0.x );
 
 1875    double  p0y = 
p2y( p0.y );
 
 1876    double  p1x = 
p2x( p1.x );
 
 1877    double  p1y = 
p2y( p1.y );
 
 1880    double  zoom_x_min = p0x<p1x ? p0x : p1x;
 
 1881    double  zoom_x_max = p0x>p1x ? p0x : p1x;
 
 1882    double  zoom_y_min = p0y<p1y ? p0y : p1y;
 
 1883    double  zoom_y_max = p0y>p1y ? p0y : p1y;
 
 1891    Fit( zoom_x_min, zoom_x_max, zoom_y_min, zoom_y_max );
 
 1901    if( directionsNeedingRefitting != 0 )
 
 
 1953    PopupMenu( &
m_popmenu, event.GetX(), event.GetY() );
 
 
 2023        if( refreshDisplay )
 
 
 2035    wxLayerList::iterator layIt;
 
 2039        if( *layIt == layer )
 
 2042            if( alsoDeleteObject )
 
 2047            if( refreshDisplay )
 
 
 2063        if( alsoDeleteObject )
 
 2069    if( refreshDisplay )
 
 
 2076    wxPaintDC paintDC( 
this );
 
 2081    wxDC* targetDC = &paintDC;
 
 2098    if( wxGraphicsContext* ctx = targetDC->GetGraphicsContext() )
 
 2100        if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST ) )
 
 2101            if( !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
 
 2102                ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
 
 2104        ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
 
 2108    targetDC->SetPen( *wxTRANSPARENT_PEN );
 
 2109    wxBrush brush( GetBackgroundColour() );
 
 2110    targetDC->SetBrush( brush );
 
 2116        layer->Plot( *targetDC, *
this );
 
 2121        targetDC->SetPen( pen );
 
 2122        targetDC->SetBrush( *wxTRANSPARENT_BRUSH );
 
 
 2132void mpWindow::DoZoom( 
const wxPoint& centerPoint, 
double zoomFactor, wxOrientation directions )
 
 2136        if( directions == wxVERTICAL )
 
 2139        directions = wxHORIZONTAL;
 
 2142    const bool horizontally = ( directions & wxHORIZONTAL ) != 0;
 
 2143    const bool vertically   = ( directions & wxVERTICAL )   != 0;
 
 2148    wxPoint c( centerPoint );
 
 2149    if( c == wxDefaultPosition )
 
 2165    const double newScaleX = horizontally ? ( 
m_scaleX * zoomFactor ) : 
m_scaleX;
 
 2166    const double newScaleY = vertically   ? ( 
m_scaleY * zoomFactor ) : 
m_scaleY;
 
 2175        const double prior_layer_x = 
p2x( c.x );
 
 2179        m_posX = prior_layer_x - c.x / newScaleX;
 
 2188        const double prior_layer_y = 
p2y( c.y );
 
 2192        m_posY = prior_layer_y + c.y / newScaleY;
 
 2200    if( zoomFactor < 1.0 )
 
 2208        if( directionsNeedingRefitting != 0 )
 
 
 2219    const double plotSpanX = plotScreenWidth / 
m_scaleX;
 
 
 2230    const double plotSpanY = plotScreenHeight / 
m_scaleY;
 
 
 2241        return static_cast<wxOrientation
>( 0 );
 
 2248    wxOrientation 
result = {};
 
 2250    if( ( directions & wxHORIZONTAL ) != 0 )
 
 2253            result = 
static_cast<wxOrientation
>( 
result | wxHORIZONTAL );
 
 2256    if( ( directions & wxVERTICAL ) != 0 )
 
 2259            result = 
static_cast<wxOrientation
>( 
result | wxVERTICAL );
 
 
 2268    const int     change = 
event.GetWheelRotation();
 
 2269    const double  changeUnitsX = change / 
m_scaleX;
 
 2270    const double  changeUnitsY = change / 
m_scaleY;
 
 2271    const wxPoint clickPt( event.GetX(), event.GetY() );
 
 2300        if( event.GetWheelRotation() > 0 )
 
 2308        if( event.GetWheelRotation() > 0 )
 
 2316        if( event.GetWheelRotation() > 0 )
 
 
 2360    if( ( position >= (
int) 
m_layers.size() ) || position < 0 )
 
 
 2371        if( !layer->GetName().Cmp( 
name ) )
 
 
 2392    if( aImageSize == wxDefaultSize )
 
 2399        sizeX = aImageSize.x;
 
 2400        sizeY = aImageSize.y;
 
 2404    wxBitmap screenBuffer( sizeX, sizeY );
 
 2405    wxMemoryDC screenDC;
 
 2406    screenDC.SelectObject( screenBuffer );
 
 2407    screenDC.SetPen( *wxWHITE_PEN );
 
 2409    wxBrush brush( GetBackgroundColour() );
 
 2410    screenDC.SetBrush( brush );
 
 2411    screenDC.DrawRectangle( 0, 0, sizeX, sizeY );
 
 2420        layer->Plot( screenDC, *
this );
 
 2422    if( aImageSize != wxDefaultSize )
 
 2427        SetScr( bk_scrX, bk_scrY );
 
 2433    aImage = screenBuffer.ConvertToImage();
 
 
 2452        if( layer->IsInfo() )
 
 2456            if( tmpLyr->
Inside( point ) )
 
 
 2469        lx->SetVisible( viewable );
 
 
 2488        lx->SetVisible( viewable );
 
 
 2497        return lx->IsVisible();
 
 
 2504                               const wxColour& axesColour )
 
 2506    SetBackgroundColour( bgColour );
 
 2507    SetForegroundColour( drawColour );
 
 2518            wxPen axisPen = layer->GetPen();
 
 2519            axisPen.SetColour( axesColour );
 
 2520            layer->SetPen( axisPen );
 
 2526            wxPen infoPen = layer->GetPen();
 
 2527            infoPen.SetColour( drawColour );
 
 2528            layer->SetPen( infoPen );
 
 
 2534template <
typename... Ts>
 
 2536        wxWindow( 
std::forward<Ts>( windowArgs )... ),
 
 
 2574    if( wxGraphicsContext* ctx = 
m_buff_dc.GetGraphicsContext() )
 
 2576        if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
 
 2577            || !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
 
 2579            ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
 
 2582        ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
 
 
 2633    double  xlogmin = log10( 
m_minV );
 
 2634    double  xlogmax = log10( 
m_maxV );
 
 2636    return ( log10( x ) - xlogmin ) / ( xlogmax - xlogmin );
 
 
 2642    double  xlogmin = log10( 
m_minV );
 
 2643    double  xlogmax = log10( 
m_maxV );
 
 2645    return pow( 10.0, xplot * ( xlogmax - xlogmin ) + xlogmin );
 
 
 2688    if( xs.size() != ys.size() )
 
 2703        for( 
const double x : xs )
 
 2712        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.
 
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.
 
#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
 
wxString result
Test unit parsing edge cases and error handling.