Simulation: Move SIM_PLOT_TAB::m_plotWin to its own SIM_PLOT_DIAGRAM class,

while in the same file for now it only paves a way to a multiplot simtab
and maybe also to some future (soon to be named as Plotframes) non modal dialogs,
(to be used as a history view for example).
This commit is contained in:
aris-kimi 2025-06-26 00:36:32 +03:00
parent e4aa8278c5
commit 77c7cf7cc4
8 changed files with 379 additions and 317 deletions

View File

@ -193,14 +193,14 @@ void DIALOG_SIM_COMMAND::SetPlotSettings( const SIM_TAB* aSimTab )
{
if( const SIM_PLOT_TAB* plotTab = dynamic_cast<const SIM_PLOT_TAB*>( aSimTab ) )
{
if( !plotTab->GetLabelY1().IsEmpty() )
if( !plotTab->getPlotsVector()[0]->GetLabelY1().IsEmpty() )
{
m_bSizerY1->Show( true );
m_lockY1->SetLabel( wxString::Format( m_lockY1->GetLabel(), plotTab->GetLabelY1() ) );
m_y1Units->SetLabel( plotTab->GetUnitsY1() );
m_lockY1->SetLabel( wxString::Format( m_lockY1->GetLabel(), plotTab->getPlotsVector()[0]->GetLabelY1() ) );
m_y1Units->SetLabel( plotTab->getPlotsVector()[0]->GetUnitsY1() );
double min = 0.0, max = 0.0;
bool locked = plotTab->GetY1Scale( &min, &max );
bool locked = plotTab->getPlotsVector()[0]->GetY1Scale( &min, &max );
m_lockY1->SetValue( locked );
if( !std::isnan( min ) )
@ -210,14 +210,14 @@ void DIALOG_SIM_COMMAND::SetPlotSettings( const SIM_TAB* aSimTab )
m_y1Max->SetValue( SIM_VALUE::Normalize( max ) );
}
if( !plotTab->GetLabelY2().IsEmpty() )
if( !plotTab->getPlotsVector()[0]->GetLabelY2().IsEmpty() )
{
m_bSizerY2->Show( true );
m_lockY2->SetLabel( wxString::Format( m_lockY2->GetLabel(), plotTab->GetLabelY2() ) );
m_y2Units->SetLabel( plotTab->GetUnitsY2() );
m_lockY2->SetLabel( wxString::Format( m_lockY2->GetLabel(), plotTab->getPlotsVector()[0]->GetLabelY2() ) );
m_y2Units->SetLabel( plotTab->getPlotsVector()[0]->GetUnitsY2() );
double min = 0.0, max = 0.0;
bool locked = plotTab->GetY2Scale( &min, &max );
bool locked = plotTab->getPlotsVector()[0]->GetY2Scale( &min, &max );
m_lockY2->SetValue( locked );
if( !std::isnan( min ) )
@ -227,14 +227,14 @@ void DIALOG_SIM_COMMAND::SetPlotSettings( const SIM_TAB* aSimTab )
m_y2Max->SetValue( SIM_VALUE::Normalize( max ) );
}
if( !plotTab->GetLabelY3().IsEmpty() )
if( !plotTab->getPlotsVector()[0]->GetLabelY3().IsEmpty() )
{
m_bSizerY3->Show( true );
m_lockY3->SetLabel( wxString::Format( m_lockY3->GetLabel(), plotTab->GetLabelY3() ) );
m_y3Units->SetLabel( plotTab->GetUnitsY3() );
m_lockY3->SetLabel( wxString::Format( m_lockY3->GetLabel(), plotTab->getPlotsVector()[0]->GetLabelY3() ) );
m_y3Units->SetLabel( plotTab->getPlotsVector()[0]->GetUnitsY3() );
double min = 0.0, max = 0.0;
bool locked = plotTab->GetY3Scale( &min, &max );
bool locked = plotTab->getPlotsVector()[0]->GetY3Scale( &min, &max );
m_lockY3->SetValue( locked );
if( !std::isnan( min ) )
@ -244,9 +244,9 @@ void DIALOG_SIM_COMMAND::SetPlotSettings( const SIM_TAB* aSimTab )
m_y3Max->SetValue( SIM_VALUE::Normalize( max ) );
}
m_grid->SetValue( plotTab->IsGridShown() );
m_legend->SetValue( plotTab->IsLegendShown() );
m_dottedSecondary->SetValue( plotTab->GetDottedSecondary() );
m_grid->SetValue( plotTab->getPlotsVector()[0]->IsGridShown() );
m_legend->SetValue( plotTab->getPlotsVector()[0]->IsLegendShown() );
m_dottedSecondary->SetValue( plotTab->getPlotsVector()[0]->GetDottedSecondary() );
#define GET_STR( val ) EDA_UNIT_UTILS::UI::MessageTextFromValue( unityScale, EDA_UNITS::UNSCALED, \
val, false /* no units */ )
@ -526,34 +526,34 @@ void DIALOG_SIM_COMMAND::ApplySettings( SIM_TAB* aTab )
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( aTab ) )
{
if( !plotTab->GetLabelY1().IsEmpty() )
if( !plotTab->getPlotsVector()[0]->GetLabelY1().IsEmpty() )
{
plotTab->SetY1Scale( m_lockY1->GetValue(),
SIM_VALUE::ToDouble( m_y1Min->GetValue().ToStdString() ),
SIM_VALUE::ToDouble( m_y1Max->GetValue().ToStdString() ) );
plotTab->getPlotsVector()[0]->SetY1Scale( m_lockY1->GetValue(),
SIM_VALUE::ToDouble( m_y1Min->GetValue().ToStdString() ),
SIM_VALUE::ToDouble( m_y1Max->GetValue().ToStdString() ) );
}
if( !plotTab->GetLabelY2().IsEmpty() )
if( !plotTab->getPlotsVector()[0]->GetLabelY2().IsEmpty() )
{
plotTab->SetY2Scale( m_lockY2->GetValue(),
SIM_VALUE::ToDouble( m_y2Min->GetValue().ToStdString() ),
SIM_VALUE::ToDouble( m_y2Max->GetValue().ToStdString() ) );
plotTab->getPlotsVector()[0]->SetY2Scale( m_lockY2->GetValue(),
SIM_VALUE::ToDouble( m_y2Min->GetValue().ToStdString() ),
SIM_VALUE::ToDouble( m_y2Max->GetValue().ToStdString() ) );
}
if( !plotTab->GetLabelY3().IsEmpty() )
if( !plotTab->getPlotsVector()[0]->GetLabelY3().IsEmpty() )
{
plotTab->SetY3Scale( m_lockY3->GetValue(),
SIM_VALUE::ToDouble( m_y3Min->GetValue().ToStdString() ),
SIM_VALUE::ToDouble( m_y3Max->GetValue().ToStdString() ) );
plotTab->getPlotsVector()[0]->SetY3Scale( m_lockY3->GetValue(),
SIM_VALUE::ToDouble( m_y3Min->GetValue().ToStdString() ),
SIM_VALUE::ToDouble( m_y3Max->GetValue().ToStdString() ) );
}
plotTab->GetPlotWin()->LockY( m_lockY1->GetValue()
|| m_lockY2->GetValue()
|| m_lockY3->GetValue() );
plotTab->ShowGrid( m_grid->GetValue() );
plotTab->ShowLegend( m_legend->GetValue() );
plotTab->SetDottedSecondary( m_dottedSecondary->GetValue() );
plotTab->getPlotsVector()[0]->ShowGrid( m_grid->GetValue() );
plotTab->getPlotsVector()[0]->ShowLegend( m_legend->GetValue() );
plotTab->getPlotsVector()[0]->SetDottedSecondary( m_dottedSecondary->GetValue() );
plotTab->GetPlotWin()->SetMarginLeft( TO_INT( m_marginLeft ) );
plotTab->GetPlotWin()->SetMarginRight( TO_INT( m_marginRight ) );
@ -1015,5 +1015,3 @@ void DIALOG_SIM_COMMAND::OnFilterMouseMoved( wxMouseEvent& aEvent )
else
SetCursor( wxCURSOR_IBEAM );
}

View File

@ -59,7 +59,7 @@ void SIMULATOR_FRAME_UI::parseTraceParams( SIM_PLOT_TAB* aPlotTab, TRACE* aTrace
wxColour color;
color.Set( item );
aTrace->SetTraceColour( color );
aPlotTab->UpdateTraceStyle( aTrace );
aPlotTab->getPlotsVector()[0]->UpdateTraceStyle( aTrace );
}
else if( item.StartsWith( wxS( "cursor1" ) ) )
{
@ -99,11 +99,11 @@ void SIMULATOR_FRAME_UI::parseTraceParams( SIM_PLOT_TAB* aPlotTab, TRACE* aTrace
}
else if( item == wxS( "dottedSecondary" ) )
{
aPlotTab->SetDottedSecondary( true );
aPlotTab->getPlotsVector()[0]->SetDottedSecondary( true );
}
else if( item == wxS( "hideGrid" ) )
{
aPlotTab->ShowGrid( false );
aPlotTab->getPlotsVector()[0]->ShowGrid( false );
}
}
}
@ -315,10 +315,10 @@ bool SIMULATOR_FRAME_UI::loadLegacyWorkbook( const wxString& aPath )
coords[0].ToLong( &x );
coords[1].ToLong( &y );
plotTab->SetLegendPosition( wxPoint( (int) x, (int) y ) );
plotTab->getPlotsVector()[0]->SetLegendPosition( wxPoint( (int) x, (int) y ) );
}
plotTab->ShowLegend( true );
plotTab->getPlotsVector()[0]->ShowLegend( true );
}
else
{
@ -349,5 +349,3 @@ bool SIMULATOR_FRAME_UI::loadLegacyWorkbook( const wxString& aPath )
file.Close();
return true;
}

View File

@ -434,34 +434,56 @@ void CURSOR::UpdateReference()
}
SIM_PLOT_TAB::SIM_PLOT_TAB( const wxString& aSimCommand, wxWindow* parent ) :
SIM_TAB( aSimCommand, parent ),
SIM_PLOT_DIAGRAM::SIM_PLOT_DIAGRAM( wxWindow* aParent ) :
m_parent( aParent ),
m_sizerBox( nullptr ),
m_axis_x( nullptr ),
m_axis_y1( nullptr ),
m_axis_y2( nullptr ),
m_axis_y3( nullptr ),
m_dotted_cp( false )
{
m_sizer = new wxBoxSizer( wxVERTICAL );
m_plotWin = new mpWindow( this, wxID_ANY );
/*
wxString sizerLabel = _( "Main Plot:" );
m_sizerBox = new wxStaticBoxSizer( wxVERTICAL, m_parent , sizerLabel );
*/
m_sizerBox = new wxBoxSizer( wxVERTICAL );
}
m_plotWin->LimitView( true );
m_plotWin->SetMargins( 30, 70, 45, 70 );
SIM_PLOT_DIAGRAM::~SIM_PLOT_DIAGRAM()
{
// ~mpWindow destroys all the added layers, so there is no need to destroy m_traces contents
}
SIM_PLOT_TAB::SIM_PLOT_TAB( const wxString& aSimCommand, wxWindow* parent ) :
SIM_TAB( aSimCommand, parent )
{
m_plotsVector.clear();
m_plotsVector.emplace_back( new SIM_PLOT_DIAGRAM( this ) ); // Keep one entry as the main plot for now.
m_sizerTop = new wxBoxSizer( wxVERTICAL );
m_sizerTop = m_plotsVector[0]->m_sizerBox;
m_plotsVector[0]->m_plotWin = new mpWindow( this, wxID_ANY );
m_plotsVector[0]->m_plotWin->LimitView( true );
m_plotsVector[0]->m_plotWin->SetMargins( 30, 70, 45, 70 );
UpdatePlotColors();
updateAxes();
// a mpInfoLegend displays le name of traces on the left top panel corner:
m_legend = new mpInfoLegend( wxRect( 0, 0, 200, 40 ), wxTRANSPARENT_BRUSH );
m_legend->SetVisible( false );
m_plotWin->AddLayer( m_legend );
m_LastLegendPosition = m_legend->GetPosition();
m_plotsVector[0]->m_legend = new mpInfoLegend( wxRect( 0, 0, 200, 40 ), wxTRANSPARENT_BRUSH );
m_plotsVector[0]->m_legend->SetVisible( false );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_legend );
m_plotsVector[0]->m_LastLegendPosition = m_plotsVector[0]->m_legend->GetPosition();
m_plotWin->EnableDoubleBuffer( true );
m_plotWin->UpdateAll();
m_plotsVector[0]->m_plotWin->EnableDoubleBuffer( true );
m_plotsVector[0]->m_plotWin->UpdateAll();
m_sizer->Add( m_plotWin, 1, wxALL | wxEXPAND, 1 );
SetSizer( m_sizer );
m_plotsVector[0]->m_sizerBox->Add( m_plotsVector[0]->m_plotWin, 1, wxALL | wxEXPAND, 1 );
SetSizer( m_sizerTop );
}
@ -471,28 +493,28 @@ SIM_PLOT_TAB::~SIM_PLOT_TAB()
}
void SIM_PLOT_TAB::SetY1Scale( bool aLock, double aMin, double aMax )
void SIM_PLOT_DIAGRAM::SetY1Scale( bool aLock, double aMin, double aMax )
{
wxCHECK( m_axis_y1, /* void */ );
m_axis_y1->SetAxisMinMax( aLock, aMin, aMax );
}
void SIM_PLOT_TAB::SetY2Scale( bool aLock, double aMin, double aMax )
void SIM_PLOT_DIAGRAM::SetY2Scale( bool aLock, double aMin, double aMax )
{
wxCHECK( m_axis_y2, /* void */ );
m_axis_y2->SetAxisMinMax( aLock, aMin, aMax );
}
void SIM_PLOT_TAB::SetY3Scale( bool aLock, double aMin, double aMax )
void SIM_PLOT_DIAGRAM::SetY3Scale( bool aLock, double aMin, double aMax )
{
wxCHECK( m_axis_y3, /* void */ );
m_axis_y3->SetAxisMinMax( aLock, aMin, aMax );
}
wxString SIM_PLOT_TAB::GetUnitsX() const
wxString SIM_PLOT_DIAGRAM::GetUnitsX() const
{
LOG_SCALE<mpScaleXLog>* logScale = dynamic_cast<LOG_SCALE<mpScaleXLog>*>( m_axis_x );
LIN_SCALE<mpScaleX>* linScale = dynamic_cast<LIN_SCALE<mpScaleX>*>( m_axis_x );
@ -506,7 +528,7 @@ wxString SIM_PLOT_TAB::GetUnitsX() const
}
wxString SIM_PLOT_TAB::GetUnitsY1() const
wxString SIM_PLOT_DIAGRAM::GetUnitsY1() const
{
LIN_SCALE<mpScaleY>* linScale = dynamic_cast<LIN_SCALE<mpScaleY>*>( m_axis_y1 );
@ -517,7 +539,7 @@ wxString SIM_PLOT_TAB::GetUnitsY1() const
}
wxString SIM_PLOT_TAB::GetUnitsY2() const
wxString SIM_PLOT_DIAGRAM::GetUnitsY2() const
{
LIN_SCALE<mpScaleY>* linScale = dynamic_cast<LIN_SCALE<mpScaleY>*>( m_axis_y2 );
@ -528,7 +550,7 @@ wxString SIM_PLOT_TAB::GetUnitsY2() const
}
wxString SIM_PLOT_TAB::GetUnitsY3() const
wxString SIM_PLOT_DIAGRAM::GetUnitsY3() const
{
LIN_SCALE<mpScaleY>* linScale = dynamic_cast<LIN_SCALE<mpScaleY>*>( m_axis_y3 );
@ -544,47 +566,47 @@ void SIM_PLOT_TAB::updateAxes( int aNewTraceType )
switch( GetSimType() )
{
case ST_AC:
if( !m_axis_x )
if( !m_plotsVector[0]->m_axis_x )
{
m_axis_x = new LOG_SCALE<mpScaleXLog>( wxEmptyString, wxT( "Hz" ), mpALIGN_BOTTOM );
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotWin->AddLayer( m_axis_x );
m_plotsVector[0]->SetAxisX( new LOG_SCALE<mpScaleXLog>( wxEmptyString, wxT( "Hz" ), mpALIGN_BOTTOM ) );
m_plotsVector[0]->m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_x );
m_axis_y1 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "dB" ), mpALIGN_LEFT );
m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotWin->AddLayer( m_axis_y1 );
m_plotsVector[0]->SetAxisY1( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "dB" ), mpALIGN_LEFT ) );
m_plotsVector[0]->m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y1 );
m_axis_y2 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "°" ), mpALIGN_RIGHT );
m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
m_axis_y2->SetMasterScale( m_axis_y1 );
m_plotWin->AddLayer( m_axis_y2 );
m_plotsVector[0]->SetAxisY2( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "°" ), mpALIGN_RIGHT ) );
m_plotsVector[0]->m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
m_plotsVector[0]->m_axis_y2->SetMasterScale( m_plotsVector[0]->m_axis_y1 );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y2 );
}
m_axis_x->SetName( _( "Frequency" ) );
m_axis_y1->SetName( _( "Gain" ) );
m_axis_y2->SetName( _( "Phase" ) );
m_plotsVector[0]->m_axis_x->SetName( _( "Frequency" ) );
m_plotsVector[0]->m_axis_y1->SetName( _( "Gain" ) );
m_plotsVector[0]->m_axis_y2->SetName( _( "Phase" ) );
break;
case ST_SP:
if( !m_axis_x )
if( !m_plotsVector[0]->m_axis_x )
{
m_axis_x = new LOG_SCALE<mpScaleXLog>( wxEmptyString, wxT( "Hz" ), mpALIGN_BOTTOM );
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotWin->AddLayer( m_axis_x );
m_plotsVector[0]->SetAxisX( new LOG_SCALE<mpScaleXLog>( wxEmptyString, wxT( "Hz" ), mpALIGN_BOTTOM ) );
m_plotsVector[0]->m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_x );
m_axis_y1 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "" ), mpALIGN_LEFT );
m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotWin->AddLayer( m_axis_y1 );
m_plotsVector[0]->SetAxisY1( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "" ), mpALIGN_LEFT ) );
m_plotsVector[0]->m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y1 );
m_axis_y2 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "°" ), mpALIGN_RIGHT );
m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
m_axis_y2->SetMasterScale( m_axis_y1 );
m_plotWin->AddLayer( m_axis_y2 );
m_plotsVector[0]->SetAxisY2( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "°" ), mpALIGN_RIGHT ) );
m_plotsVector[0]->m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
m_plotsVector[0]->m_axis_y2->SetMasterScale( m_plotsVector[0]->m_axis_y1 );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y2 );
}
m_axis_x->SetName( _( "Frequency" ) );
m_axis_y1->SetName( _( "Amplitude" ) );
m_axis_y2->SetName( _( "Phase" ) );
m_plotsVector[0]->m_axis_x->SetName( _( "Frequency" ) );
m_plotsVector[0]->m_axis_y1->SetName( _( "Amplitude" ) );
m_plotsVector[0]->m_axis_y2->SetName( _( "Phase" ) );
break;
case ST_DC:
@ -592,85 +614,85 @@ void SIM_PLOT_TAB::updateAxes( int aNewTraceType )
break;
case ST_NOISE:
if( !m_axis_x )
if( !m_plotsVector[0]->m_axis_x )
{
m_axis_x = new LOG_SCALE<mpScaleXLog>( wxEmptyString, wxT( "Hz" ), mpALIGN_BOTTOM );
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotWin->AddLayer( m_axis_x );
m_plotsVector[0]->SetAxisX( new LOG_SCALE<mpScaleXLog>( wxEmptyString, wxT( "Hz" ), mpALIGN_BOTTOM ) );
m_plotsVector[0]->m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_x );
if( ( aNewTraceType & SPT_CURRENT ) == 0 )
{
m_axis_y1 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "" ), mpALIGN_LEFT );
m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotWin->AddLayer( m_axis_y1 );
m_plotsVector[0]->SetAxisY1( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "" ), mpALIGN_LEFT ) );
m_plotsVector[0]->m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y1 );
}
else
{
m_axis_y2 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "" ), mpALIGN_RIGHT );
m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
m_plotWin->AddLayer( m_axis_y2 );
m_plotsVector[0]->SetAxisY2( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "" ), mpALIGN_RIGHT ) );
m_plotsVector[0]->m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y2 );
}
}
m_axis_x->SetName( _( "Frequency" ) );
m_plotsVector[0]->m_axis_x->SetName( _( "Frequency" ) );
if( m_axis_y1 )
m_axis_y1->SetName( _( "Noise (V/√Hz)" ) );
if( m_plotsVector[0]->m_axis_y1 )
m_plotsVector[0]->m_axis_y1->SetName( _( "Noise (V/√Hz)" ) );
if( m_axis_y2 )
m_axis_y2->SetName( _( "Noise (A/√Hz)" ) );
if( m_plotsVector[0]->m_axis_y2 )
m_plotsVector[0]->m_axis_y2->SetName( _( "Noise (A/√Hz)" ) );
break;
case ST_FFT:
if( !m_axis_x )
if( !m_plotsVector[0]->m_axis_x )
{
m_axis_x = new LOG_SCALE<mpScaleXLog>( wxEmptyString, wxT( "Hz" ), mpALIGN_BOTTOM );
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotWin->AddLayer( m_axis_x );
m_plotsVector[0]->SetAxisX( new LOG_SCALE<mpScaleXLog>( wxEmptyString, wxT( "Hz" ), mpALIGN_BOTTOM ) );
m_plotsVector[0]->m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_x );
m_axis_y1 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "dB" ), mpALIGN_LEFT );
m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotWin->AddLayer( m_axis_y1 );
m_plotsVector[0]->SetAxisY1( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "dB" ), mpALIGN_LEFT ) );
m_plotsVector[0]->m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y1 );
}
m_axis_x->SetName( _( "Frequency" ) );
m_axis_y1->SetName( _( "Intensity" ) );
m_plotsVector[0]->m_axis_x->SetName( _( "Frequency" ) );
m_plotsVector[0]->m_axis_y1->SetName( _( "Intensity" ) );
break;
case ST_TRAN:
if( !m_axis_x )
if( !m_plotsVector[0]->m_axis_x )
{
m_axis_x = new TIME_SCALE( wxEmptyString, wxT( "s" ), mpALIGN_BOTTOM );
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotWin->AddLayer( m_axis_x );
m_plotsVector[0]->SetAxisX( new TIME_SCALE( wxEmptyString, wxT( "s" ), mpALIGN_BOTTOM ) );
m_plotsVector[0]->m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_x );
m_axis_y1 = new LIN_SCALE<mpScaleY>(wxEmptyString, wxT( "V" ), mpALIGN_LEFT );
m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotWin->AddLayer( m_axis_y1 );
m_plotsVector[0]->SetAxisY1( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "V" ), mpALIGN_LEFT ) );
m_plotsVector[0]->m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y1 );
m_axis_y2 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "A" ), mpALIGN_RIGHT );
m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
m_axis_y2->SetMasterScale( m_axis_y1 );
m_plotWin->AddLayer( m_axis_y2 );
m_plotsVector[0]->SetAxisY2( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "A" ), mpALIGN_RIGHT ) );
m_plotsVector[0]->m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
m_plotsVector[0]->m_axis_y2->SetMasterScale( m_plotsVector[0]->m_axis_y1 );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y2 );
}
m_axis_x->SetName( _( "Time" ) );
m_axis_y1->SetName( _( "Voltage" ) );
m_axis_y2->SetName( _( "Current" ) );
m_plotsVector[0]->m_axis_x->SetName( _( "Time" ) );
m_plotsVector[0]->m_axis_y1->SetName( _( "Voltage" ) );
m_plotsVector[0]->m_axis_y2->SetName( _( "Current" ) );
if( ( aNewTraceType & SPT_POWER ) && !m_axis_y3 )
if( ( aNewTraceType & SPT_POWER ) && !m_plotsVector[0]->m_axis_y3 )
{
m_plotWin->SetMargins( 30, 140, 45, 70 );
m_plotsVector[0]->m_plotWin->SetMargins( 30, 140, 45, 70 );
m_axis_y3 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "W" ), mpALIGN_FAR_RIGHT );
m_axis_y3->SetNameAlign( mpALIGN_FAR_RIGHT );
m_axis_y3->SetMasterScale( m_axis_y1 );
m_plotWin->AddLayer( m_axis_y3 );
m_plotsVector[0]->SetAxisY3( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "W" ), mpALIGN_FAR_RIGHT ) );
m_plotsVector[0]->m_axis_y3->SetNameAlign( mpALIGN_FAR_RIGHT );
m_plotsVector[0]->m_axis_y3->SetMasterScale( m_plotsVector[0]->m_axis_y1 );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y3 );
}
if( m_axis_y3 )
m_axis_y3->SetName( _( "Power" ) );
if( m_plotsVector[0]->m_axis_y3 )
m_plotsVector[0]->m_axis_y3->SetName( _( "Power" ) );
break;
@ -679,17 +701,17 @@ void SIM_PLOT_TAB::updateAxes( int aNewTraceType )
break;
}
if( m_axis_x )
m_axis_x->SetFont( KIUI::GetStatusFont( m_plotWin ) );
if( m_plotsVector[0]->m_axis_x )
m_plotsVector[0]->m_axis_x->SetFont( KIUI::GetStatusFont( m_plotsVector[0]->m_plotWin ) );
if( m_axis_y1 )
m_axis_y1->SetFont( KIUI::GetStatusFont( m_plotWin ) );
if( m_plotsVector[0]->m_axis_y1 )
m_plotsVector[0]->m_axis_y1->SetFont( KIUI::GetStatusFont( m_plotsVector[0]->m_plotWin ) );
if( m_axis_y2 )
m_axis_y2->SetFont( KIUI::GetStatusFont( m_plotWin ) );
if( m_plotsVector[0]->m_axis_y2 )
m_plotsVector[0]->m_axis_y2->SetFont( KIUI::GetStatusFont( m_plotsVector[0]->m_plotWin ) );
if( m_axis_y3 )
m_axis_y3->SetFont( KIUI::GetStatusFont( m_plotWin ) );
if( m_plotsVector[0]->m_axis_y3 )
m_plotsVector[0]->m_axis_y3->SetFont( KIUI::GetStatusFont( m_plotsVector[0]->m_plotWin ) );
}
@ -718,85 +740,85 @@ void SIM_PLOT_TAB::prepareDCAxes( int aNewTraceType )
// Make sure that we have a reliable default (even if incorrectly labeled)
default:
case 'v':
if( !m_axis_x )
if( !m_plotsVector[0]->m_axis_x )
{
m_axis_x = new LIN_SCALE<mpScaleX>( wxEmptyString, wxT( "V" ), mpALIGN_BOTTOM );
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotWin->AddLayer( m_axis_x );
m_plotsVector[0]->SetAxisX( new LIN_SCALE<mpScaleX>( wxEmptyString, wxT( "V" ), mpALIGN_BOTTOM ) );
m_plotsVector[0]->m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_x );
}
m_axis_x->SetName( _( "Voltage (swept)" ) );
m_plotsVector[0]->m_axis_x->SetName( _( "Voltage (swept)" ) );
break;
case 'i':
if( !m_axis_x )
if( !m_plotsVector[0]->m_axis_x )
{
m_axis_x = new LIN_SCALE<mpScaleX>( wxEmptyString, wxT( "A" ), mpALIGN_BOTTOM );
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotWin->AddLayer( m_axis_x );
m_plotsVector[0]->SetAxisX( new LIN_SCALE<mpScaleX>( wxEmptyString, wxT( "A" ), mpALIGN_BOTTOM ) );
m_plotsVector[0]->m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_x );
}
m_axis_x->SetName( _( "Current (swept)" ) );
m_plotsVector[0]->m_axis_x->SetName( _( "Current (swept)" ) );
break;
case 'r':
if( !m_axis_x )
if( !m_plotsVector[0]->m_axis_x )
{
m_axis_x = new LIN_SCALE<mpScaleX>( wxEmptyString, wxT( "" ), mpALIGN_BOTTOM );
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotWin->AddLayer( m_axis_x );
m_plotsVector[0]->SetAxisX( new LIN_SCALE<mpScaleX>( wxEmptyString, wxT( "" ), mpALIGN_BOTTOM ) );
m_plotsVector[0]->m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_x );
}
m_axis_x->SetName( _( "Resistance (swept)" ) );
m_plotsVector[0]->m_axis_x->SetName( _( "Resistance (swept)" ) );
break;
case 't':
if( !m_axis_x )
if( !m_plotsVector[0]->m_axis_x )
{
m_axis_x = new LIN_SCALE<mpScaleX>( wxEmptyString, wxT( "°C" ), mpALIGN_BOTTOM );
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotWin->AddLayer( m_axis_x );
m_plotsVector[0]->SetAxisX( new LIN_SCALE<mpScaleX>( wxEmptyString, wxT( "°C" ), mpALIGN_BOTTOM ) );
m_plotsVector[0]->m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_x );
}
m_axis_x->SetName( _( "Temperature (swept)" ) );
m_plotsVector[0]->m_axis_x->SetName( _( "Temperature (swept)" ) );
break;
}
if( !m_axis_y1 )
if( !m_plotsVector[0]->m_axis_y1 )
{
m_axis_y1 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "V" ), mpALIGN_LEFT );
m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotWin->AddLayer( m_axis_y1 );
m_plotsVector[0]->SetAxisY1( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "V" ), mpALIGN_LEFT ) );
m_plotsVector[0]->m_axis_y1->SetNameAlign( mpALIGN_LEFT );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y1 );
}
if( !m_axis_y2 )
if( !m_plotsVector[0]->m_axis_y2 )
{
m_axis_y2 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "A" ), mpALIGN_RIGHT );
m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
m_plotWin->AddLayer( m_axis_y2 );
m_plotsVector[0]->SetAxisY2( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "A" ), mpALIGN_RIGHT ) );
m_plotsVector[0]->m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y2 );
}
m_axis_y1->SetName( _( "Voltage (measured)" ) );
m_axis_y2->SetName( _( "Current" ) );
m_plotsVector[0]->m_axis_y1->SetName( _( "Voltage (measured)" ) );
m_plotsVector[0]->m_axis_y2->SetName( _( "Current" ) );
if( ( aNewTraceType & SPT_POWER ) )
EnsureThirdYAxisExists();
if( m_axis_y3 )
m_axis_y3->SetName( _( "Power" ) );
if( m_plotsVector[0]->m_axis_y3 )
m_plotsVector[0]->m_axis_y3->SetName( _( "Power" ) );
}
}
void SIM_PLOT_TAB::EnsureThirdYAxisExists()
{
if( !m_axis_y3 )
if( !m_plotsVector[0]->m_axis_y3 )
{
m_plotWin->SetMargins( 30, 140, 45, 70 );
m_axis_y3 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "W" ), mpALIGN_FAR_RIGHT );
m_axis_y3->SetNameAlign( mpALIGN_FAR_RIGHT );
m_axis_y3->SetMasterScale( m_axis_y1 );
m_plotWin->AddLayer( m_axis_y3 );
m_plotsVector[0]->m_plotWin->SetMargins( 30, 140, 45, 70 );
m_plotsVector[0]->SetAxisY3( new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "W" ), mpALIGN_FAR_RIGHT ) );
m_plotsVector[0]->m_axis_y3->SetNameAlign( mpALIGN_FAR_RIGHT );
m_plotsVector[0]->m_axis_y3->SetMasterScale( m_plotsVector[0]->m_axis_y1 );
m_plotsVector[0]->m_plotWin->AddLayer( m_plotsVector[0]->m_axis_y3 );
}
}
@ -804,22 +826,22 @@ void SIM_PLOT_TAB::EnsureThirdYAxisExists()
void SIM_PLOT_TAB::UpdatePlotColors()
{
// Update bg and fg colors:
m_plotWin->SetColourTheme( m_colors.GetPlotColor( SIM_PLOT_COLORS::COLOR_SET::BACKGROUND ),
m_colors.GetPlotColor( SIM_PLOT_COLORS::COLOR_SET::FOREGROUND ),
m_colors.GetPlotColor( SIM_PLOT_COLORS::COLOR_SET::AXIS ) );
m_plotsVector[0]->m_plotWin->SetColourTheme( m_colors.GetPlotColor( SIM_PLOT_COLORS::COLOR_SET::BACKGROUND ),
m_colors.GetPlotColor( SIM_PLOT_COLORS::COLOR_SET::FOREGROUND ),
m_colors.GetPlotColor( SIM_PLOT_COLORS::COLOR_SET::AXIS ) );
m_plotWin->UpdateAll();
m_plotsVector[0]->m_plotWin->UpdateAll();
}
void SIM_PLOT_TAB::OnLanguageChanged()
{
updateAxes();
m_plotWin->UpdateAll();
m_plotsVector[0]->m_plotWin->UpdateAll();
}
void SIM_PLOT_TAB::UpdateTraceStyle( TRACE* trace )
void SIM_PLOT_DIAGRAM::UpdateTraceStyle( TRACE* trace )
{
int type = trace->GetType();
wxPenStyle penStyle;
@ -834,7 +856,9 @@ void SIM_PLOT_TAB::UpdateTraceStyle( TRACE* trace )
penStyle = wxPENSTYLE_SOLID;
trace->SetPen( wxPen( trace->GetTraceColour(), 2, penStyle ) );
m_sessionTraceColors[ trace->GetName() ] = trace->GetTraceColour();
SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( m_parent );
plotTab->SetSessionColors( trace->GetName(), trace->GetTraceColour() );
}
@ -850,7 +874,7 @@ TRACE* SIM_PLOT_TAB::GetOrAddTrace( const wxString& aVectorName, int aType )
{
bool hasVoltageTraces = false;
for( const auto& [ id, candidate ] : m_traces )
for( const auto& [id, candidate] : m_plotsVector[0]->m_traces )
{
if( candidate->GetType() & SPT_VOLTAGE )
{
@ -861,11 +885,11 @@ TRACE* SIM_PLOT_TAB::GetOrAddTrace( const wxString& aVectorName, int aType )
if( !hasVoltageTraces )
{
if( m_axis_y2 )
m_axis_y2->SetMasterScale( nullptr );
if( m_plotsVector[0]->m_axis_y2 )
m_plotsVector[0]->m_axis_y2->SetMasterScale( nullptr );
if( m_axis_y3 )
m_axis_y3->SetMasterScale( nullptr );
if( m_plotsVector[0]->m_axis_y3 )
m_plotsVector[0]->m_axis_y3->SetMasterScale( nullptr );
}
}
@ -876,10 +900,10 @@ TRACE* SIM_PLOT_TAB::GetOrAddTrace( const wxString& aVectorName, int aType )
else
trace->SetTraceColour( m_colors.GenerateColor( m_sessionTraceColors ) );
UpdateTraceStyle( trace );
m_traces[ getTraceId( aVectorName, aType ) ] = trace;
m_plotsVector[0]->UpdateTraceStyle( trace );
m_plotsVector[0]->m_traces[getTraceId( aVectorName, aType )] = trace;
m_plotWin->AddLayer( (mpLayer*) trace );
m_plotsVector[0]->m_plotWin->AddLayer( (mpLayer*) trace );
}
return trace;
@ -889,7 +913,7 @@ TRACE* SIM_PLOT_TAB::GetOrAddTrace( const wxString& aVectorName, int aType )
void SIM_PLOT_TAB::SetTraceData( TRACE* trace, std::vector<double>& aX, std::vector<double>& aY,
int aSweepCount, size_t aSweepSize )
{
if( dynamic_cast<LOG_SCALE<mpScaleXLog>*>( m_axis_x ) )
if( dynamic_cast<LOG_SCALE<mpScaleXLog>*>( m_plotsVector[0]->m_axis_x ) )
{
// log( 0 ) is not valid.
if( aX.size() > 0 && aX[0] == 0 )
@ -925,15 +949,15 @@ void SIM_PLOT_TAB::SetTraceData( TRACE* trace, std::vector<double>& aX, std::vec
if( ( trace->GetType() & SPT_AC_PHASE )
|| ( ( GetSimType() != ST_AC ) && ( trace->GetType() & SPT_CURRENT ) ) )
{
trace->SetScale( m_axis_x, m_axis_y2 );
trace->SetScale( m_plotsVector[0]->m_axis_x, m_plotsVector[0]->m_axis_y2 );
}
else if( trace->GetType() & SPT_POWER )
{
trace->SetScale( m_axis_x, m_axis_y3 );
trace->SetScale( m_plotsVector[0]->m_axis_x, m_plotsVector[0]->m_axis_y3 );
}
else
{
trace->SetScale( m_axis_x, m_axis_y1 );
trace->SetScale( m_plotsVector[0]->m_axis_x, m_plotsVector[0]->m_axis_y1 );
}
for( auto& [ cursorId, cursor ] : trace->GetCursors() )
@ -946,22 +970,22 @@ void SIM_PLOT_TAB::SetTraceData( TRACE* trace, std::vector<double>& aX, std::vec
void SIM_PLOT_TAB::DeleteTrace( TRACE* aTrace )
{
for( const auto& [ name, trace ] : m_traces )
for( const auto& [name, trace] : m_plotsVector[0]->m_traces )
{
if( trace == aTrace )
{
m_traces.erase( name );
m_plotsVector[0]->m_traces.erase( name );
break;
}
}
for( const auto& [ id, cursor ] : aTrace->GetCursors() )
for( const auto& [id, cursor] : aTrace->GetCursors() )
{
if( cursor )
m_plotWin->DelLayer( cursor, true );
m_plotsVector[0]->m_plotWin->DelLayer( cursor, true );
}
m_plotWin->DelLayer( aTrace, true, true );
m_plotsVector[0]->m_plotWin->DelLayer( aTrace, true, true );
ResetScales( false );
}
@ -989,7 +1013,7 @@ void SIM_PLOT_TAB::EnableCursor( TRACE* aTrace, int aCursorId, const wxString& a
cursor->SetX( center );
aTrace->SetCursor( aCursorId, cursor );
m_plotWin->AddLayer( cursor );
m_plotsVector[0]->m_plotWin->AddLayer( cursor );
// Notify the parent window about the changes
wxQueueEvent( this, new wxCommandEvent( EVT_SIM_CURSOR_UPDATE ) );
@ -1011,9 +1035,9 @@ void SIM_PLOT_TAB::DisableCursor( TRACE* aTrace, int aCursorId )
void SIM_PLOT_TAB::ResetScales( bool aIncludeX )
{
if( m_axis_x && aIncludeX )
if( m_plotsVector[0]->m_axis_x && aIncludeX )
{
m_axis_x->ResetDataRange();
m_plotsVector[0]->m_axis_x->ResetDataRange();
if( GetSimType() == ST_TRAN )
{
@ -1035,20 +1059,20 @@ void SIM_PLOT_TAB::ResetScales( bool aIncludeX )
if( tokenizer.HasMoreTokens() )
start = SPICE_VALUE( tokenizer.GetNextToken() );
static_cast<TIME_SCALE*>( m_axis_x )->SetStartAndEnd( start.ToDouble(), end.ToDouble() );
static_cast<TIME_SCALE*>( m_plotsVector[0]->m_axis_x )->SetStartAndEnd( start.ToDouble(), end.ToDouble() );
}
}
if( m_axis_y1 )
m_axis_y1->ResetDataRange();
if( m_plotsVector[0]->m_axis_y1 )
m_plotsVector[0]->m_axis_y1->ResetDataRange();
if( m_axis_y2 )
m_axis_y2->ResetDataRange();
if( m_plotsVector[0]->m_axis_y2 )
m_plotsVector[0]->m_axis_y2->ResetDataRange();
if( m_axis_y3 )
m_axis_y3->ResetDataRange();
if( m_plotsVector[0]->m_axis_y3 )
m_plotsVector[0]->m_axis_y3->ResetDataRange();
for( auto& [ name, trace ] : m_traces )
for( auto& [name, trace] : m_plotsVector[0]->m_traces )
trace->UpdateScales();
}

View File

@ -188,23 +188,42 @@ protected:
};
class SIM_PLOT_TAB : public SIM_TAB
class SIM_PLOT_DIAGRAM
{
friend class SIM_PLOT_TAB;
friend class SIMULATOR_FRAME_UI;
friend class SIMULATOR_CONTROL;
public:
SIM_PLOT_TAB( const wxString& aSimCommand, wxWindow* parent );
SIM_PLOT_DIAGRAM( wxWindow* aParent );
~SIM_PLOT_DIAGRAM();
virtual ~SIM_PLOT_TAB();
void ApplyPreferences( const SIM_PREFERENCES& aPrefs ) override
{
m_plotWin->SetMouseWheelActions( convertMouseWheelActions( aPrefs.mouse_wheel_actions ) );
}
wxString GetUnitsX() const;
wxString GetLabelX() const
{
return m_axis_x ? m_axis_x->GetName() : wxString( wxS( "" ) );
}
mpScaleXBase* GetAxisX() const { return m_axis_x; }
void SetAxisX( mpScaleXBase* aAxisX ) { m_axis_x = aAxisX; }
void SetAxisY1( mpScaleY* aAxisY1 ) { m_axis_y1 = aAxisY1; }
void SetAxisY2( mpScaleY* aAxisY2 ) { m_axis_y2 = aAxisY2; }
void SetAxisY3( mpScaleY* aAxisY3 ) { m_axis_y3 = aAxisY3; }
void SetY1Scale( bool aLock, double aMin, double aMax );
void SetY2Scale( bool aLock, double aMin, double aMax );
void SetY3Scale( bool aLock, double aMin, double aMax );
wxString GetUnitsY1() const;
wxString GetUnitsY2() const;
wxString GetUnitsY3() const;
wxString GetLabelY1() const
{
return m_axis_y1 ? m_axis_y1->GetName() : wxString( wxS( "" ) );
@ -244,25 +263,12 @@ public:
return false;
}
void SetY1Scale( bool aLock, double aMin, double aMax );
void SetY2Scale( bool aLock, double aMin, double aMax );
void SetY3Scale( bool aLock, double aMin, double aMax );
wxString GetUnitsX() const;
wxString GetUnitsY1() const;
wxString GetUnitsY2() const;
wxString GetUnitsY3() const;
const std::map<wxString, TRACE*>& GetTraces() const
bool IsGridShown() const
{
return m_traces;
}
if( !m_axis_x || !m_axis_y1 )
return false;
TRACE* GetTrace( const wxString& aVecName, int aType ) const
{
auto trace = m_traces.find( getTraceId( aVecName, aType ) );
return trace == m_traces.end() ? nullptr : trace->second;
return !m_axis_x->GetTicks();
}
void ShowGrid( bool aEnable )
@ -282,14 +288,22 @@ public:
m_plotWin->UpdateAll();
}
bool IsGridShown() const
{
if( !m_axis_x || !m_axis_y1 )
return false;
return !m_axis_x->GetTicks();
/**
* Draw secondary signal traces (current or phase) with dotted lines
*/
void SetDottedSecondary( bool aEnable )
{
m_dotted_cp = aEnable;
for( const auto& [name, trace] : m_traces )
UpdateTraceStyle( trace );
m_plotWin->UpdateAll();
}
bool GetDottedSecondary() const { return m_dotted_cp; }
void ShowLegend( bool aEnable )
{
m_legend->SetVisible( aEnable );
@ -313,22 +327,58 @@ public:
m_LastLegendPosition = aPosition;
}
/**
* Draw secondary signal traces (current or phase) with dotted lines
*/
void SetDottedSecondary( bool aEnable )
///< Update trace line style
void UpdateTraceStyle( TRACE* trace );
public:
wxPoint m_LastLegendPosition;
private:
wxWindow* m_parent;
// The plot window
mpWindow* m_plotWin;
/*
// A to be used plot's sizer
wxStaticBoxSizer* m_sizerBox;
*/
// A temp plot sizer for now
wxBoxSizer* m_sizerBox;
// Traces to be plotted
std::map<wxString, TRACE*> m_traces;
mpScaleXBase* m_axis_x;
mpScaleY* m_axis_y1;
mpScaleY* m_axis_y2;
mpScaleY* m_axis_y3;
bool m_dotted_cp;
mpInfoLegend* m_legend;
//wxString m_description;
};
class SIM_PLOT_TAB : public SIM_TAB
{
public:
SIM_PLOT_TAB( const wxString& aSimCommand, wxWindow* parent );
virtual ~SIM_PLOT_TAB();
void ApplyPreferences( const SIM_PREFERENCES& aPrefs ) override
{
m_dotted_cp = aEnable;
for( const auto& [ name, trace ] : m_traces )
UpdateTraceStyle( trace );
m_plotWin->UpdateAll();
m_plotsVector[0]->m_plotWin->SetMouseWheelActions( convertMouseWheelActions( aPrefs.mouse_wheel_actions ) );
}
bool GetDottedSecondary() const
const std::map<wxString, TRACE*>& GetTraces() const { return m_plotsVector[0]->m_traces; }
TRACE* GetTrace( const wxString& aVecName, int aType ) const
{
return m_dotted_cp;
auto trace = m_plotsVector[0]->m_traces.find( getTraceId( aVecName, aType ) );
return trace == m_plotsVector[0]->m_traces.end() ? nullptr : trace->second;
}
///< Turn on/off the cursor for a particular trace.
@ -338,16 +388,13 @@ public:
///< Reset scale ranges to fit the current traces.
void ResetScales( bool aIncludeX );
///< Update trace line style
void UpdateTraceStyle( TRACE* trace );
///< Update plot colors
void UpdatePlotColors();
void OnLanguageChanged() override;
///< Getter for math plot window
mpWindow* GetPlotWin() const { return m_plotWin; }
mpWindow* GetPlotWin() const { return m_plotsVector[0]->m_plotWin; }
TRACE* GetOrAddTrace( const wxString& aVectorName, int aType );
@ -361,8 +408,9 @@ public:
void EnsureThirdYAxisExists();
public:
wxPoint m_LastLegendPosition;
std::vector<SIM_PLOT_DIAGRAM*> getPlotsVector() const { return m_plotsVector; }
void SetSessionColors( const wxString& aString, const wxColour& aColor ) { m_sessionTraceColors[aString] = aColor; }
private:
static mpWindow::MouseWheelActionSet
@ -398,20 +446,10 @@ private:
SIM_PLOT_COLORS m_colors;
std::map<wxString, wxColour> m_sessionTraceColors;
// Top-level plot window
mpWindow* m_plotWin;
wxBoxSizer* m_sizer;
// Top-level sizer
wxBoxSizer* m_sizerTop;
// Traces to be plotted
std::map<wxString, TRACE*> m_traces;
mpScaleXBase* m_axis_x;
mpScaleY* m_axis_y1;
mpScaleY* m_axis_y2;
mpScaleY* m_axis_y3;
mpInfoLegend* m_legend;
bool m_dotted_cp;
std::vector<SIM_PLOT_DIAGRAM*> m_plotsVector;
// Measurements (and their format strings)
std::vector<std::pair<wxString, wxString>> m_measurements;

View File

@ -678,21 +678,21 @@ void SIMULATOR_FRAME::setupUIConditions()
[this]( const SELECTION& aSel )
{
SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentSimTab() );
return plotTab && plotTab->IsGridShown();
return plotTab && plotTab->getPlotsVector()[0]->IsGridShown();
};
auto showLegendCondition =
[this]( const SELECTION& aSel )
{
SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentSimTab() );
return plotTab && plotTab->IsLegendShown();
return plotTab && plotTab->getPlotsVector()[0]->IsLegendShown();
};
auto showDottedCondition =
[this]( const SELECTION& aSel )
{
SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentSimTab() );
return plotTab && plotTab->GetDottedSecondary();
return plotTab && plotTab->getPlotsVector()[0]->GetDottedSecondary();
};
auto darkModePlotCondition =

View File

@ -1284,7 +1284,7 @@ void SIMULATOR_FRAME_UI::onSignalsGridCellChanged( wxGridEvent& aEvent )
if( trace )
{
trace->SetTraceColour( color.ToColour() );
plotTab->UpdateTraceStyle( trace );
plotTab->getPlotsVector()[0]->UpdateTraceStyle( trace );
plotTab->UpdatePlotColors();
OnModify();
}
@ -1472,9 +1472,9 @@ void SIMULATOR_FRAME_UI::OnUpdateUI( wxUpdateUIEvent& event )
{
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentSimTab() ) )
{
if( plotTab->GetLegendPosition() != plotTab->m_LastLegendPosition )
if( plotTab->getPlotsVector()[0]->GetLegendPosition() != plotTab->getPlotsVector()[0]->m_LastLegendPosition )
{
plotTab->m_LastLegendPosition = plotTab->GetLegendPosition();
plotTab->getPlotsVector()[0]->m_LastLegendPosition = plotTab->getPlotsVector()[0]->GetLegendPosition();
OnModify();
}
}
@ -2274,20 +2274,20 @@ bool SIMULATOR_FRAME_UI::loadJsonWorkbook( const wxString& aPath )
plotTab->Measurements().emplace_back( m_js[ "expr" ], m_js[ "format" ] );
}
plotTab->SetDottedSecondary( tab_js[ "dottedSecondary" ] );
plotTab->ShowGrid( tab_js[ "showGrid" ] );
plotTab->getPlotsVector()[0]->SetDottedSecondary( tab_js["dottedSecondary"] );
plotTab->getPlotsVector()[0]->ShowGrid( tab_js["showGrid"] );
if( tab_js.contains( "fixedY1scale" ) )
{
const nlohmann::json& scale_js = tab_js[ "fixedY1scale" ];
plotTab->SetY1Scale( true, scale_js[ "min" ], scale_js[ "max" ] );
plotTab->getPlotsVector()[0]->SetY1Scale( true, scale_js["min"], scale_js["max"] );
plotTab->GetPlotWin()->LockY( true );
}
if( tab_js.contains( "fixedY2scale" ) )
{
const nlohmann::json& scale_js = tab_js[ "fixedY2scale" ];
plotTab->SetY2Scale( true, scale_js[ "min" ], scale_js[ "max" ] );
plotTab->getPlotsVector()[0]->SetY2Scale( true, scale_js["min"], scale_js["max"] );
plotTab->GetPlotWin()->LockY( true );
}
@ -2295,15 +2295,15 @@ bool SIMULATOR_FRAME_UI::loadJsonWorkbook( const wxString& aPath )
{
plotTab->EnsureThirdYAxisExists();
const nlohmann::json& scale_js = tab_js[ "fixedY3scale" ];
plotTab->SetY3Scale( true, scale_js[ "min" ], scale_js[ "max" ] );
plotTab->getPlotsVector()[0]->SetY3Scale( true, scale_js["min"], scale_js["max"] );
plotTab->GetPlotWin()->LockY( true );
}
if( tab_js.contains( "legend" ) )
{
const nlohmann::json& legend_js = tab_js[ "legend" ];
plotTab->SetLegendPosition( wxPoint( legend_js[ "x" ], legend_js[ "y" ] ) );
plotTab->ShowLegend( true );
plotTab->getPlotsVector()[0]->SetLegendPosition( wxPoint( legend_js["x"], legend_js["y"] ) );
plotTab->getPlotsVector()[0]->ShowLegend( true );
}
if( tab_js.contains( "margins" ) )
@ -2414,7 +2414,7 @@ bool SIMULATOR_FRAME_UI::loadJsonWorkbook( const wxString& aPath )
wxColour color;
color.Set( wxString( trace_js["color"].get<wxString>() ) );
trace->SetTraceColour( color );
plotTab->UpdateTraceStyle( trace );
plotTab->getPlotsVector()[0]->UpdateTraceStyle( trace );
}
}
}
@ -2584,27 +2584,31 @@ bool SIMULATOR_FRAME_UI::SaveWorkbook( const wxString& aPath )
{ "format", format } } ) );
}
// clang-format off
tab_js[ "traces" ] = traces_js;
tab_js[ "measurements" ] = measurements_js;
tab_js[ "dottedSecondary" ] = plotTab->GetDottedSecondary();
tab_js[ "showGrid" ] = plotTab->IsGridShown();
tab_js[ "dottedSecondary" ] = plotTab->getPlotsVector()[0]->GetDottedSecondary();
tab_js[ "showGrid" ] = plotTab->getPlotsVector()[0]->IsGridShown();
// clang-format on
double min, max;
if( plotTab->GetY1Scale( &min, &max ) )
if( plotTab->getPlotsVector()[0]->GetY1Scale( &min, &max ) )
tab_js[ "fixedY1scale" ] = nlohmann::json( { { "min", min }, { "max", max } } );
if( plotTab->GetY2Scale( &min, &max ) )
if( plotTab->getPlotsVector()[0]->GetY2Scale( &min, &max ) )
tab_js[ "fixedY2scale" ] = nlohmann::json( { { "min", min }, { "max", max } } );
if( plotTab->GetY3Scale( &min, &max ) )
if( plotTab->getPlotsVector()[0]->GetY3Scale( &min, &max ) )
tab_js[ "fixedY3scale" ] = nlohmann::json( { { "min", min }, { "max", max } } );
if( plotTab->IsLegendShown() )
// clang-format off
if( plotTab->getPlotsVector()[0]->IsLegendShown() )
{
tab_js[ "legend" ] = nlohmann::json( { { "x", plotTab->GetLegendPosition().x },
{ "y", plotTab->GetLegendPosition().y } } );
tab_js[ "legend" ] = nlohmann::json( { { "x", plotTab->getPlotsVector()[0]->GetLegendPosition().x },
{ "y", plotTab->getPlotsVector()[0]->GetLegendPosition().y } } );
}
// clang-format on
mpWindow* plotWin = plotTab->GetPlotWin();
@ -2904,18 +2908,18 @@ void SIMULATOR_FRAME_UI::updatePlotCursors()
if( plotTab->GetSimType() == ST_AC )
{
if( aTrace->GetType() & SPT_AC_PHASE )
return plotTab->GetUnitsY2();
return plotTab->getPlotsVector()[0]->GetUnitsY2();
else
return plotTab->GetUnitsY1();
return plotTab->getPlotsVector()[0]->GetUnitsY1();
}
else
{
if( aTrace->GetType() & SPT_POWER )
return plotTab->GetUnitsY3();
return plotTab->getPlotsVector()[0]->GetUnitsY3();
else if( aTrace->GetType() & SPT_CURRENT )
return plotTab->GetUnitsY2();
return plotTab->getPlotsVector()[0]->GetUnitsY2();
else
return plotTab->GetUnitsY1();
return plotTab->getPlotsVector()[0]->GetUnitsY1();
}
};
@ -2925,18 +2929,18 @@ void SIMULATOR_FRAME_UI::updatePlotCursors()
if( plotTab->GetSimType() == ST_AC )
{
if( aTrace->GetType() & SPT_AC_PHASE )
return plotTab->GetLabelY2();
return plotTab->getPlotsVector()[0]->GetLabelY2();
else
return plotTab->GetLabelY1();
return plotTab->getPlotsVector()[0]->GetLabelY1();
}
else
{
if( aTrace->GetType() & SPT_POWER )
return plotTab->GetLabelY3();
return plotTab->getPlotsVector()[0]->GetLabelY3();
else if( aTrace->GetType() & SPT_CURRENT )
return plotTab->GetLabelY2();
return plotTab->getPlotsVector()[0]->GetLabelY2();
else
return plotTab->GetLabelY1();
return plotTab->getPlotsVector()[0]->GetLabelY1();
}
};
@ -2960,7 +2964,7 @@ void SIMULATOR_FRAME_UI::updatePlotCursors()
wxRealPoint coords = cursor->GetCoords();
int row = m_cursorsGrid->GetNumberRows();
m_cursorFormatsDyn[0][0].UpdateUnits( plotTab->GetUnitsX() );
m_cursorFormatsDyn[0][0].UpdateUnits( plotTab->getPlotsVector()[0]->GetUnitsX() );
m_cursorFormatsDyn[0][1].UpdateUnits( cursor1Units );
m_cursorsGrid->AppendRows( 1 );
@ -2983,7 +2987,7 @@ void SIMULATOR_FRAME_UI::updatePlotCursors()
wxRealPoint coords = cursor->GetCoords();
int row = m_cursorsGrid->GetNumberRows();
m_cursorFormatsDyn[1][0].UpdateUnits( plotTab->GetUnitsX() );
m_cursorFormatsDyn[1][0].UpdateUnits( plotTab->getPlotsVector()[0]->GetUnitsX() );
m_cursorFormatsDyn[1][1].UpdateUnits( cursor2Units );
m_cursorsGrid->AppendRows( 1 );
@ -3000,7 +3004,7 @@ void SIMULATOR_FRAME_UI::updatePlotCursors()
wxRealPoint coords = cursor2->GetCoords() - cursor1->GetCoords();
wxString signal;
m_cursorFormatsDyn[2][0].UpdateUnits( plotTab->GetUnitsX() );
m_cursorFormatsDyn[2][0].UpdateUnits( plotTab->getPlotsVector()[0]->GetUnitsX() );
m_cursorFormatsDyn[2][1].UpdateUnits( cursor1Units );
if( cursor1->GetName() == cursor2->GetName() )
@ -3015,7 +3019,7 @@ void SIMULATOR_FRAME_UI::updatePlotCursors()
m_cursorsGrid->SetCellValue( 2, COL_CURSOR_Y, formatValue( coords.y, 2, 1 ) );
}
// Set up the labels
m_cursorsGrid->SetColLabelValue( COL_CURSOR_X, plotTab->GetLabelX() );
m_cursorsGrid->SetColLabelValue( COL_CURSOR_X, plotTab->getPlotsVector()[0]->GetLabelX() );
wxString valColName = _( "Value" );
@ -3046,7 +3050,7 @@ void SIMULATOR_FRAME_UI::updatePlotCursors()
wxRealPoint coords = cursor->GetCoords();
int row = m_cursorsGrid->GetNumberRows();
m_cursorFormatsDyn[i][0].UpdateUnits( plotTab->GetUnitsX() );
m_cursorFormatsDyn[i][0].UpdateUnits( plotTab->getPlotsVector()[0]->GetUnitsX() );
m_cursorFormatsDyn[i][1].UpdateUnits( cursUnits );
m_cursorsGrid->AppendRows( 1 );
@ -3056,7 +3060,7 @@ void SIMULATOR_FRAME_UI::updatePlotCursors()
m_cursorsGrid->SetCellValue( row, COL_CURSOR_Y, formatValue( coords.y, i, 1 ) );
// Set up the labels
m_cursorsGrid->SetColLabelValue( COL_CURSOR_X, plotTab->GetLabelX() );
m_cursorsGrid->SetColLabelValue( COL_CURSOR_X, plotTab->getPlotsVector()[0]->GetLabelX() );
valColName = _( "Value" );

View File

@ -29,7 +29,7 @@
#define SIMULATOR_FRAME_UI_H
#include <sim/simulator_frame_ui_base.h>
#include "sim/simulator_frame_ui_base.h"
#include <sim/sim_types.h>
#include <sim/sim_plot_tab.h>
#include <sim/sim_preferences.h>

View File

@ -421,7 +421,7 @@ int SIMULATOR_CONTROL::ToggleGrid( const TOOL_EVENT& aEvent )
{
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) )
{
plotTab->ShowGrid( !plotTab->IsGridShown() );
plotTab->getPlotsVector()[0]->ShowGrid( !plotTab->getPlotsVector()[0]->IsGridShown() );
m_simulatorFrame->OnModify();
}
@ -433,7 +433,7 @@ int SIMULATOR_CONTROL::ToggleLegend( const TOOL_EVENT& aEvent )
{
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) )
{
plotTab->ShowLegend( !plotTab->IsLegendShown() );
plotTab->getPlotsVector()[0]->ShowLegend( !plotTab->getPlotsVector()[0]->IsLegendShown() );
m_simulatorFrame->OnModify();
}
@ -445,7 +445,7 @@ int SIMULATOR_CONTROL::ToggleDottedSecondary( const TOOL_EVENT& aEvent )
{
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) )
{
plotTab->SetDottedSecondary( !plotTab->GetDottedSecondary() );
plotTab->getPlotsVector()[0]->SetDottedSecondary( !plotTab->getPlotsVector()[0]->GetDottedSecondary() );
m_simulatorFrame->OnModify();
}