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 );
500 return wxEmptyString;
511 return wxEmptyString;
522 return wxEmptyString;
533 return wxEmptyString;
696 if( sim_cmd.StartsWith(
".dc", &rem ) )
704 ch = rem.GetChar( 0 );
839 bool hasVoltageTraces =
false;
841 for(
const auto& [
id, candidate ] :
m_traces )
845 hasVoltageTraces =
true;
850 if( !hasVoltageTraces )
882 if( aX.size() > 0 && aX[0] == 0 )
884 aX.erase( aX.begin() );
885 aY.erase( aY.begin() );
893 for(
double& pt : aY )
894 pt = pt * 180.0 / M_PI;
898 for(
double& pt : aY )
902 pt = 20 * log( pt ) / log( 10.0 );
928 if( trace == aTrace )
959 bool aEnable,
const wxString& aSignalName )
963 if( t ==
nullptr || t->
HasCursor( aCursorId ) == aEnable )
973 cursor->SetName( aSignalName );
987 wxQueueEvent( GetParent(),
new wxCommandEvent( EVT_SIM_CURSOR_UPDATE ) );
999 wxStringTokenizer tokenizer(
GetSimCommand(), wxS(
" \t\n\r" ), wxTOKEN_STRTOK );
1000 wxString cmd = tokenizer.GetNextToken().Lower();
1002 wxASSERT( cmd == wxS(
".tran" ) );
1008 if( tokenizer.HasMoreTokens() )
1011 if( tokenizer.HasMoreTokens() )
1014 if( tokenizer.HasMoreTokens() )
1031 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.
void EnsureThirdYAxisExists()
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)
Enable limiting of 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.
KICOMMON_API 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".