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 = aWindow.GetForegroundColour();
372 if( cursorColor.
Distance( textColor ) < 0.66 )
375 pen.SetColour( cursorColor.
ToColour() );
376 pen.SetStyle(
m_continuous ? wxPENSTYLE_SOLID : wxPENSTYLE_LONG_DASH );
379 if( topPx < cursorPos.y && cursorPos.y < bottomPx )
380 aDC.DrawLine( leftPx, cursorPos.y, rightPx, cursorPos.y );
382 if( leftPx < cursorPos.x && cursorPos.x < rightPx )
384 aDC.DrawLine( cursorPos.x, topPx, cursorPos.x, bottomPx );
386 wxString
id =
getID();
387 wxSize size = aDC.GetTextExtent( wxS(
"M" ) );
388 wxRect textRect( wxPoint( cursorPos.x + 1 - size.x / 2, topPx - 4 - size.y ), size );
399 size.y = ( size.y / 2 ) * 2;
400 poly[0] = { cursorPos.x - 1 - size.y / 2, topPx - size.y };
401 poly[1] = { cursorPos.x + 1 + size.y / 2, topPx - size.y };
402 poly[2] = { cursorPos.x, topPx };
404 brush.SetStyle( wxBRUSHSTYLE_SOLID );
406 aDC.SetBrush( brush );
407 aDC.DrawPolygon( 3, poly );
409 aDC.SetTextForeground( textColor.
ToColour() );
410 aDC.DrawLabel(
id, textRect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL );
420 return (
std::abs( (
double) aPoint.x -
438 SIM_TAB( aSimCommand, parent ),
440 m_axis_y1( nullptr ),
441 m_axis_y2( nullptr ),
442 m_axis_y3( nullptr ),
445 m_sizer =
new wxBoxSizer( wxVERTICAL );
505 return wxEmptyString;
516 return wxEmptyString;
527 return wxEmptyString;
538 return wxEmptyString;
701 if( sim_cmd.StartsWith(
".dc", &rem ) )
709 ch = rem.GetChar( 0 );
828 penStyle = wxPENSTYLE_SOLID;
830 penStyle =
m_dotted_cp ? wxPENSTYLE_DOT : wxPENSTYLE_SOLID;
832 penStyle =
m_dotted_cp ? wxPENSTYLE_DOT : wxPENSTYLE_SOLID;
834 penStyle = wxPENSTYLE_SOLID;
851 bool hasVoltageTraces =
false;
853 for(
const auto& [
id, candidate ] :
m_traces )
857 hasVoltageTraces =
true;
862 if( !hasVoltageTraces )
890 int aSweepCount,
size_t aSweepSize )
895 if( aX.size() > 0 && aX[0] == 0 )
897 aX.erase( aX.begin() );
898 aY.erase( aY.begin() );
906 for(
double& pt : aY )
907 pt = pt * 180.0 / M_PI;
911 for(
double& pt : aY )
915 pt = 20 * log( pt ) / log( 10.0 );
951 if( trace == aTrace )
982 bool aEnable,
const wxString& aSignalName )
986 if( t ==
nullptr || t->
HasCursor( aCursorId ) == aEnable )
996 cursor->SetName( aSignalName );
1010 wxQueueEvent( GetParent(),
new wxCommandEvent( EVT_SIM_CURSOR_UPDATE ) );
1022 wxStringTokenizer tokenizer(
GetSimCommand(), wxS(
" \t\n\r" ), wxTOKEN_STRTOK );
1023 wxString cmd = tokenizer.GetNextToken().Lower();
1025 wxASSERT( cmd == wxS(
".tran" ) );
1031 if( tokenizer.HasMoreTokens() )
1034 if( tokenizer.HasMoreTokens() )
1037 if( tokenizer.HasMoreTokens() )
1054 trace->UpdateScales();
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
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.
COLOR4D & Invert()
Makes the color inverted, alpha remains the same.
wxColour ToColour() const
double Distance(const COLOR4D &other) const
Returns the distance (in RGB space) between two colors.
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 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)
void SetTraceData(TRACE *aTrace, std::vector< double > &aX, std::vector< double > &aY, int aSweepCount, size_t aSweepSize)
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)
void SetSweepSize(size_t aSweepSize)
void SetSweepCount(int aSweepCount)
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)