diff --git a/eeschema/sim/sim_plot_frame.cpp b/eeschema/sim/sim_plot_frame.cpp index 3f54ecdf09..7f92555bff 100644 --- a/eeschema/sim/sim_plot_frame.cpp +++ b/eeschema/sim/sim_plot_frame.cpp @@ -157,7 +157,7 @@ bool SIM_PLOT_FRAME::isSimulationRunning() } -void SIM_PLOT_FRAME::updatePlot( const wxString& aSpiceName, const wxString& aTitle, SIM_PLOT_PANEL* aPanel ) +void SIM_PLOT_FRAME::updatePlot( const wxString& aSpiceName, const wxString& aName, SIM_PLOT_PANEL* aPanel ) { auto data_y = m_simulator->GetPlot( (const char*) aSpiceName.c_str() ); auto data_t = m_simulator->GetPlot( "time" ); @@ -165,7 +165,7 @@ void SIM_PLOT_FRAME::updatePlot( const wxString& aSpiceName, const wxString& aTi if( data_y.empty() || data_t.empty() ) return; - aPanel->AddTrace( aSpiceName, aTitle, data_t.size(), data_t.data(), data_y.data(), 0 ); + aPanel->AddTrace( aSpiceName, aName, data_t.size(), data_t.data(), data_y.data(), 0 ); } @@ -219,11 +219,18 @@ void SIM_PLOT_FRAME::menuShowGridState( wxUpdateUIEvent& event ) void SIM_PLOT_FRAME::onSignalDblClick( wxCommandEvent& event ) { int idx = m_signals->GetSelection(); + SIM_PLOT_PANEL* plot = currentPlot(); if( idx != wxNOT_FOUND ) { - AddVoltagePlot( m_signals->GetString( idx ) ); - currentPlot()->Fit(); + const wxString& netName = m_signals->GetString( idx ); + + if( plot->IsShown( netName ) ) + plot->DeleteTrace( netName ); + else + AddVoltagePlot( netName ); + + plot->Fit(); } } @@ -283,7 +290,7 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent ) SIM_PLOT_PANEL* plotPanel = static_cast( m_plotNotebook->GetPage( i ) ); for( const auto& trace : plotPanel->GetTraces() ) - updatePlot( trace->GetSpiceName(), trace->GetName(), plotPanel ); + updatePlot( trace.second->GetSpiceName(), trace.second->GetName(), plotPanel ); } } diff --git a/eeschema/sim/sim_plot_frame.h b/eeschema/sim/sim_plot_frame.h index b3c4197c43..f70fdb32a8 100644 --- a/eeschema/sim/sim_plot_frame.h +++ b/eeschema/sim/sim_plot_frame.h @@ -68,10 +68,10 @@ class SIM_PLOT_FRAME : public SIM_PLOT_FRAME_BASE * the plot, it will be added. * @param aSpiceName is the plot name in the format accepted by the current simulator instance * (for NGSPICE it is e.g. "V(1)"). - * @param aTitle is the name used in the legend. + * @param aName is the name used in the legend. * @param aPanel is the panel that should receive the update. */ - void updatePlot( const wxString& aSpiceName, const wxString& aTitle, SIM_PLOT_PANEL* aPanel ); + void updatePlot( const wxString& aSpiceName, const wxString& aName, SIM_PLOT_PANEL* aPanel ); /** * @brief Returns node number for a given net. diff --git a/eeschema/sim/sim_plot_panel.cpp b/eeschema/sim/sim_plot_panel.cpp index e353730353..180cf043fc 100644 --- a/eeschema/sim/sim_plot_panel.cpp +++ b/eeschema/sim/sim_plot_panel.cpp @@ -118,21 +118,21 @@ SIM_PLOT_PANEL::~SIM_PLOT_PANEL() } -void SIM_PLOT_PANEL::AddTrace( const wxString& aSpiceName, const wxString& aTitle, int aPoints, +bool SIM_PLOT_PANEL::AddTrace( const wxString& aSpiceName, const wxString& aName, int aPoints, const double* aT, const double* aY, int aFlags ) { TRACE* t = NULL; // Find previous entry, if there is one - auto it = std::find_if( m_traces.begin(), m_traces.end(), - [&](const TRACE* t) { return t->GetName() == aTitle; }); + auto prev = m_traces.find( aName ); + bool addedNewEntry = ( prev == m_traces.end() ); - if( it == m_traces.end() ) + if( addedNewEntry ) { // New entry - t = new TRACE( aTitle, aSpiceName ); + t = new TRACE( aName, aSpiceName ); t->SetPen( wxPen( generateColor(), 1, wxSOLID ) ); - m_traces.push_back( t ); + m_traces[aName] = t; // It is a trick to keep legend always on the top DelLayer( m_legend ); @@ -141,19 +141,37 @@ void SIM_PLOT_PANEL::AddTrace( const wxString& aSpiceName, const wxString& aTitl } else { - t = *it; + t = prev->second; } t->SetData( std::vector( aT, aT + aPoints ), std::vector( aY, aY + aPoints ) ); UpdateAll(); + + return addedNewEntry; } -void SIM_PLOT_PANEL::DeleteTraces() +bool SIM_PLOT_PANEL::DeleteTrace( const wxString& aName ) { - for( TRACE* t : m_traces ) + auto trace = m_traces.find( aName ); + + if( trace != m_traces.end() ) { - DelLayer( t, true ); + m_traces.erase( trace ); + DelLayer( trace->second, true, true ); + + return true; + } + + return false; +} + + +void SIM_PLOT_PANEL::DeleteAllTraces() +{ + for( auto& t : m_traces ) + { + DelLayer( t.second, true ); } m_traces.clear(); diff --git a/eeschema/sim/sim_plot_panel.h b/eeschema/sim/sim_plot_panel.h index 0b73f44168..2e55336792 100644 --- a/eeschema/sim/sim_plot_panel.h +++ b/eeschema/sim/sim_plot_panel.h @@ -27,12 +27,13 @@ #define __SIM_PLOT_PANEL_H #include +#include class TRACE : public mpFXYVector { public: - TRACE( const wxString& aTitle, const wxString& aSpiceName ) - : mpFXYVector( aTitle ), m_spiceName( aSpiceName ) + TRACE( const wxString& aName, const wxString& aSpiceName ) + : mpFXYVector( aName ), m_spiceName( aSpiceName ) { SetContinuity( true ); ShowName( false ); @@ -108,12 +109,19 @@ public: ~SIM_PLOT_PANEL(); - void AddTrace( const wxString& aSpiceName, const wxString& aTitle, int aPoints, + bool AddTrace( const wxString& aSpiceName, const wxString& aName, int aPoints, const double* aT, const double* aY, int aFlags ); - void DeleteTraces(); + bool DeleteTrace( const wxString& aName ); - const std::vector& GetTraces() const + bool IsShown( const wxString& aName ) const + { + return ( m_traces.count( aName ) != 0 ); + } + + void DeleteAllTraces(); + + const std::map& GetTraces() const { return m_traces; } @@ -128,7 +136,7 @@ private: unsigned int m_colorIdx; // Traces to be plotted - std::vector m_traces; + std::map m_traces; mpScaleX* m_axis_x; mpScaleY* m_axis_y;