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 ) )
109 int64_t k = (int)( ( x - floor( x ) ) * pow( 10.0, (
double) maxDigits ) );
112 while( k && ( ( k % 10LL ) == 0LL || ( k % 10LL ) == 9LL ) )
129template <
typename parent>
134 parent(
name, flags, false ),
143 double maxVis = parent::AbsVisibleMaxValue();
148 int constexpr DIGITS = 3;
152 double sf = pow( 10.0, power );
158 digits = std::max( digits, k );
163 l.label =
formatFloat( l.pos / sf, digits ) + suffix;
173template <
typename parent>
178 parent(
name, flags, false ),
193 double sf = pow( 10.0, power );
232 if( dataX.size() <= 1 )
236 auto maxXIt = std::upper_bound( dataX.begin(), dataX.end(),
m_coords.x );
237 int maxIdx = maxXIt - dataX.begin();
238 int minIdx = maxIdx - 1;
247 else if( maxIdx >= (
int) dataX.size() )
249 maxIdx = dataX.size() - 1;
254 const double leftX = dataX[minIdx];
255 const double rightX = dataX[maxIdx];
256 const double leftY = dataY[minIdx];
257 const double rightY = dataY[maxIdx];
260 m_coords.y = leftY + ( rightY - leftY ) / ( rightX - leftX ) * (
m_coords.x - leftX );
269 return wxString::Format(
_(
"%d" ),
id );
272 return wxEmptyString;
290 wxQueueEvent( aWindow.GetParent(),
new wxCommandEvent( EVT_SIM_CURSOR_UPDATE ) );
315 wxColour fg =
GetPen().GetColour();
318 pen.SetStyle(
m_continuous ? wxPENSTYLE_SOLID : wxPENSTYLE_LONG_DASH );
321 if( topPx < cursorPos.y && cursorPos.y < bottomPx )
322 aDC.DrawLine( leftPx, cursorPos.y, rightPx, cursorPos.y );
324 if( leftPx < cursorPos.x && cursorPos.x < rightPx )
326 aDC.DrawLine( cursorPos.x, topPx, cursorPos.x, bottomPx );
328 wxString
id =
getID();
329 wxSize size = aDC.GetTextExtent( wxS(
"M" ) );
330 wxRect textRect( wxPoint( cursorPos.x + 1 - size.x / 2, topPx - 4 - size.y ), size );
341 size.y = ( size.y / 2 ) * 2;
342 poly[0] = { cursorPos.x - 1 - size.y / 2, topPx - size.y };
343 poly[1] = { cursorPos.x + 1 + size.y / 2, topPx - size.y };
344 poly[2] = { cursorPos.x, topPx };
346 brush.SetStyle( wxBRUSHSTYLE_SOLID );
348 aDC.SetBrush( brush );
349 aDC.DrawPolygon( 3, poly );
351 aDC.SetTextForeground( fg );
352 aDC.DrawLabel(
id, textRect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL );
362 return (
std::abs( (
double) aPoint.x -
380 wxWindowID
id,
const wxPoint& pos,
const wxSize& size,
long style,
381 const wxString&
name ) :
384 m_axis_y1( nullptr ),
385 m_axis_y2( nullptr ),
386 m_axis_y3( nullptr ),
389 m_sizer =
new wxBoxSizer( wxVERTICAL );
428 return wxEmptyString;
439 return wxEmptyString;
450 return wxEmptyString;
461 return wxEmptyString;
558 if( sim_cmd.StartsWith(
".dc", &rem ) )
566 ch = rem.GetChar( 0 );
665 for(
const auto& [
id,
cursor ] : trace->GetCursors() )
703 bool hasVoltageTraces =
false;
705 for(
const auto& [
id, candidate ] :
m_traces )
709 hasVoltageTraces =
true;
714 if( !hasVoltageTraces )
739 std::vector<double> tmp( aY, aY + aPoints );
745 for(
unsigned int i = 0; i < aPoints; i++ )
746 tmp[i] = tmp[i] * 180.0 / M_PI;
750 for(
unsigned int i = 0; i < aPoints; i++ )
754 tmp[i] = 20 * log( tmp[i] ) / log( 10.0 );
759 trace->
SetData( std::vector<double>( aX, aX + aPoints ), tmp );
782 if( trace == aTrace )
813 bool aEnable,
const wxString& aSignalName )
817 if( t ==
nullptr || t->
HasCursor( aCursorId ) == aEnable )
827 cursor->SetName( aSignalName );
842 wxQueueEvent( GetParent(),
new wxCommandEvent( EVT_SIM_CURSOR_UPDATE ) );
861 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.
wxString GetUnits() const
LIN_SCALE(const wxString &name, const wxString &unit, int flags)
void formatLabels() override
LOG_SCALE(const wxString &name, const wxString &unit, int flags)
void formatLabels() override
wxString GetUnits() const
const wxString & GetSimCommand() const
wxColour GenerateColor(std::map< wxString, TRACE * > aTraces)
wxColour GetPlotColor(enum COLOR_SET aColorId)
void UpdateTraceStyle(TRACE *trace)
Update plot colors.
void ResetScales()
Update trace line style.
wxString GetUnitsX() const
void updateAxes(int aNewTraceType=SIM_TRACE_TYPE::SPT_UNKNOWN)
TRACE * AddTrace(const wxString &aVectorName, int aType)
bool DeleteTrace(const wxString &aVectorName, int aTraceType)
TRACE * GetTrace(const wxString &aVecName, int aType) const
virtual ~SIM_PLOT_PANEL()
wxString GetUnitsY3() const
wxString getTraceId(const wxString &aVectorName, int aType) const
Construct the plot axes for DC simulation plot.
void OnLanguageChanged() override
Getter for math plot window.
void EnableCursor(const wxString &aVectorName, int aType, int aCursorId, bool aEnable, const wxString &aSignalName)
Reset scale ranges to fit the current traces.
std::map< wxString, TRACE * > m_traces
void prepareDCAxes(int aNewTraceType)
Create/Ensure axes are available for plotting.
void SetTraceData(TRACE *aTrace, unsigned int aPoints, const double *aX, const double *aY)
wxString GetUnitsY2() const
SIM_PLOT_PANEL(const wxString &aCommand, int aOptions, wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0, const wxString &name=wxPanelNameStr)
mpWindow * GetPlotWin() const
wxString GetUnitsY1() const
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
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...
bool m_drawOutsideMargins
void SetPen(wxPen pen)
Set layer pen.
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 SetNameAlign(int align)
Plot layer implementing a y-scale ruler.
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
int GetScrX(void) const
Get current view's X dimension in device context units.
void SetMargins(int top, int right, int bottom, int left)
Set window margins, creating a blank area where some kinds of layers cannot draw.
double p2x(wxCoord pixelCoordX)
Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates,...
int GetXScreen(void) const
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).
int GetScrY(void) const
Get current view's Y dimension in device context units.
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.
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".