42 fmt.Printf(
"%%.0%df", nDigits );
52static void getSISuffix(
double x,
const wxString& unit,
int& power, wxString& suffix )
54 const int n_powers = 11;
82 for(
int i = 0; i < n_powers - 1; i++ )
84 double r_cur = pow( 10, powers[i].exponent );
86 if( fabs( x ) >= r_cur && fabs( x ) < r_cur * 1000.0 )
88 power = powers[i].exponent;
90 if( powers[i].suffix )
91 suffix = wxString( powers[i].suffix ) + unit;
103 if( std::isnan( x ) )
106 auto countSignificantDigits =
109 while( k && ( k % 10LL ) == 0LL )
123 int64_t k = (int)( ( x - floor( x ) ) * pow( 10.0, (
double) maxDigits ) );
124 int n = countSignificantDigits( k );
127 n = std::min( n, countSignificantDigits( k + 1 ) );
133template <
typename T_PARENT>
138 T_PARENT(
name, flags, false ),
147 double maxVis = T_PARENT::AbsVisibleMaxValue();
152 int constexpr MAX_DIGITS = 3;
153 int constexpr MAX_DISAMBIGUATION_DIGITS = 6;
154 bool duplicateLabels =
false;
158 double sf = pow( 10.0, power );
165 for(
size_t ii = 0; ii < T_PARENT::m_tickLabels.size(); ++ii )
172 if( ii > 0 && l.
label == T_PARENT::m_tickLabels[ii-1].label )
173 duplicateLabels =
true;
176 while( duplicateLabels && ++digits <= MAX_DISAMBIGUATION_DIGITS );
201 LIN_SCALE::ExtendDataRange( minV, maxV );
231template <
typename T_PARENT>
236 T_PARENT(
name, flags, false ),
247 int constexpr MAX_DIGITS = 3;
252 double sf = pow( 10.0, power );
291 if( dataX.size() <= 1 )
295 auto maxXIt = std::upper_bound( dataX.begin(), dataX.end(),
m_coords.x );
296 int maxIdx = maxXIt - dataX.begin();
297 int minIdx = maxIdx - 1;
300 if( minIdx < 0 || maxIdx >= (
int) dataX.size() )
309 const double leftX = dataX[minIdx];
310 const double rightX = dataX[maxIdx];
311 const double leftY = dataY[minIdx];
312 const double rightY = dataY[maxIdx];
315 m_coords.y = leftY + ( rightY - leftY ) / ( rightX - leftX ) * (
m_coords.x - leftX );
324 return wxString::Format(
_(
"%d" ),
id );
327 return wxEmptyString;
345 wxQueueEvent( aWindow.GetParent(),
new wxCommandEvent( EVT_SIM_CURSOR_UPDATE ) );
368 wxColour fg =
GetPen().GetColour();
371 pen.SetStyle(
m_continuous ? wxPENSTYLE_SOLID : wxPENSTYLE_LONG_DASH );
374 if( topPx < cursorPos.y && cursorPos.y < bottomPx )
375 aDC.DrawLine( leftPx, cursorPos.y, rightPx, cursorPos.y );
377 if( leftPx < cursorPos.x && cursorPos.x < rightPx )
379 aDC.DrawLine( cursorPos.x, topPx, cursorPos.x, bottomPx );
381 wxString
id =
getID();
382 wxSize size = aDC.GetTextExtent( wxS(
"M" ) );
383 wxRect textRect( wxPoint( cursorPos.x + 1 - size.x / 2, topPx - 4 - size.y ), size );
394 size.y = ( size.y / 2 ) * 2;
395 poly[0] = { cursorPos.x - 1 - size.y / 2, topPx - size.y };
396 poly[1] = { cursorPos.x + 1 + size.y / 2, topPx - size.y };
397 poly[2] = { cursorPos.x, topPx };
399 brush.SetStyle( wxBRUSHSTYLE_SOLID );
401 aDC.SetBrush( brush );
402 aDC.DrawPolygon( 3, poly );
404 aDC.SetTextForeground( fg );
405 aDC.DrawLabel(
id, textRect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL );
415 return (
std::abs( (
double) aPoint.x -
433 SIM_TAB( aSimCommand, parent ),
435 m_axis_y1( nullptr ),
436 m_axis_y2( nullptr ),
437 m_axis_y3( nullptr ),
440 m_sizer =
new wxBoxSizer( wxVERTICAL );
498 return wxEmptyString;
509 return wxEmptyString;
520 return wxEmptyString;
531 return wxEmptyString;
694 if( sim_cmd.StartsWith(
".dc", &rem ) )
702 ch = rem.GetChar( 0 );
831 bool hasVoltageTraces =
false;
833 for(
const auto& [
id, candidate ] :
m_traces )
837 hasVoltageTraces =
true;
842 if( !hasVoltageTraces )
874 if( aX.size() > 0 && aX[0] == 0 )
876 aX.erase( aX.begin() );
877 aY.erase( aY.begin() );
885 for(
double& pt : aY )
886 pt = pt * 180.0 / M_PI;
890 for(
double& pt : aY )
894 pt = 20 * log( pt ) / log( 10.0 );
920 if( trace == aTrace )
951 bool aEnable,
const wxString& aSignalName )
955 if( t ==
nullptr || t->
HasCursor( aCursorId ) == aEnable )
965 cursor->SetName( aSignalName );
979 wxQueueEvent( GetParent(),
new wxCommandEvent( EVT_SIM_CURSOR_UPDATE ) );
991 wxStringTokenizer tokenizer(
GetSimCommand(), wxS(
" \t\n\r" ), wxTOKEN_STRTOK );
992 wxString cmd = tokenizer.GetNextToken().Lower();
994 wxASSERT( cmd == wxS(
".tran" ) );
1000 if( tokenizer.HasMoreTokens() )
1003 if( tokenizer.HasMoreTokens() )
1006 if( tokenizer.HasMoreTokens() )
1023 trace->UpdateScales();
The SIMULATOR_FRAME holds the main user-interface for running simulations.
static constexpr int DRAG_MARGIN
bool Inside(const wxPoint &aPoint) const override
Checks whether a point is inside the info box rectangle.
void doSetCoordX(double aValue)
void SetCoordX(double aValue)
void UpdateReference() override
Updates the rectangle reference point.
void Plot(wxDC &aDC, mpWindow &aWindow) override
Plot method.
A color representation with 4 components: red, green, blue, alpha.
wxColour ToColour() const
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
void formatLabels() override
wxString GetUnits() const
LIN_SCALE(const wxString &name, const wxString &unit, int flags)
wxString m_base_axis_label
wxString GetUnits() const
LOG_SCALE(const wxString &name, const wxString &unit, int flags)
void formatLabels() override
wxColour GetPlotColor(enum COLOR_SET aColorId)
wxColour GenerateColor(std::map< wxString, wxColour > aTraceColors)
bool DeleteTrace(const wxString &aVectorName, int aTraceType)
void EnableCursor(const wxString &aVectorName, int aType, int aCursorId, bool aEnable, const wxString &aSignalName)
Reset scale ranges to fit the current traces.
mpWindow * GetPlotWin() const
void prepareDCAxes(int aNewTraceType)
Create/Ensure axes are available for plotting.
wxString GetUnitsY2() const
void SetTraceData(TRACE *aTrace, std::vector< double > &aX, std::vector< double > &aY)
void SetY2Scale(bool aLock, double aMin, double aMax)
TRACE * GetTrace(const wxString &aVecName, int aType) const
void SetY1Scale(bool aLock, double aMin, double aMax)
void SetY3Scale(bool aLock, double aMin, double aMax)
std::map< wxString, TRACE * > m_traces
void UpdateTraceStyle(TRACE *trace)
Update plot colors.
void ResetScales(bool aIncludeX)
Update trace line style.
SIM_PLOT_TAB(const wxString &aSimCommand, wxWindow *parent)
wxString GetUnitsX() const
void OnLanguageChanged() override
Getter for math plot window.
wxString getTraceId(const wxString &aVectorName, int aType) const
Construct the plot axes for DC simulation plot.
TRACE * GetOrAddTrace(const wxString &aVectorName, int aType)
wxPoint m_LastLegendPosition
wxString GetUnitsY1() const
std::map< wxString, wxColour > m_sessionTraceColors
void updateAxes(int aNewTraceType=SIM_TRACE_TYPE::SPT_UNKNOWN)
wxString GetUnitsY3() const
SIM_TYPE GetSimType() const
const wxString & GetSimCommand() const
Helper class to recognize Spice formatted values.
void ResetDataRange() override
void ExtendDataRange(double minV, double maxV) override
void SetStartAndEnd(double aStartTime, double aEndTime)
TIME_SCALE(const wxString &name, const wxString &unit, int flags)
void SetTraceColour(const wxColour &aColour)
std::map< int, CURSOR * > & GetCursors()
SIM_TRACE_TYPE GetType() const
bool HasCursor(int aCursorId)
void SetData(const std::vector< double > &aX, const std::vector< double > &aY) override
Assigns new data set for the trace.
void SetCursor(int aCursorId, CURSOR *aCursor)
const std::vector< double > & GetDataY() const
wxColour GetTraceColour() const
const std::vector< double > & GetDataX() const
CURSOR * GetCursor(int aCursorId)
virtual void SetScale(mpScaleBase *scaleX, mpScaleBase *scaleY)
double y2s(double y) const
double x2s(double x) const
double s2x(double plotCoordX) const
wxPoint GetPosition() const
Returns the position of the upper left corner of the box (in pixels)
virtual void Move(wxPoint delta)
Moves the layer rectangle of given pixel deltas.
Implements the legend to be added to the plot This layer allows you to add a legend to describe the p...
void SetFont(const wxFont &font)
Set layer font.
const wxString & GetName() const
Get layer name.
virtual void SetName(const wxString &name)
Set layer name.
const wxPen & GetPen() const
Get pen set for this layer.
void SetVisible(bool show)
Sets layer visibility.
void SetPen(const wxPen &pen)
Set layer pen.
void SetAxisMinMax(bool lock, double minV, double maxV)
void SetNameAlign(int align)
virtual void ResetDataRange()
void SetMasterScale(mpScaleY *masterScale)
Canvas for plotting mpLayer implementations.
void SetColourTheme(const wxColour &bgColour, const wxColour &drawColour, const wxColour &axesColour)
Set Color theme.
int GetMarginLeft() const
void SetMargins(int top, int right, int bottom, int left)
Set window margins, creating a blank area where some kinds of layers cannot draw.
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,...
void LimitView(bool aEnable)
Limit zooming & panning to the area used by the plots.
wxCoord x2p(double x)
Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates,...
bool DelLayer(mpLayer *layer, bool alsoDeleteObject=false, bool refreshDisplay=true)
Remove a plot layer from the canvas.
void UpdateAll()
Refresh display.
wxCoord y2p(double y)
Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates,...
int GetMarginRight() const
int GetMarginBottom() const
void EnableDoubleBuffer(bool enabled)
Enable/disable the double-buffering of the window, eliminating the flicker (default=disabled).
bool AddLayer(mpLayer *layer, bool refreshDisplay=true)
Add a plot layer to the canvas.
#define mpALIGN_RIGHT
Aligns label to the right.
#define mpALIGN_FAR_RIGHT
Aligns label to the right of mpALIGN_RIGHT.
#define mpALIGN_LEFT
Aligns label to the left.
#define mpALIGN_BOTTOM
Aligns label to the bottom.
wxFont GetStatusFont(wxWindow *aWindow)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Class is responsible for providing colors for traces on simulation plot.
wxDEFINE_EVENT(EVT_SIM_CURSOR_UPDATE, wxCommandEvent)
static void getSISuffix(double x, const wxString &unit, int &power, wxString &suffix)
static int countDecimalDigits(double x, int maxDigits)
static wxString formatFloat(double x, int nDigits)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".