Axis autorange

This commit is contained in:
Maciej Suminski 2016-08-11 14:41:14 +02:00
parent 91d1f7135b
commit 0261a0e59c
2 changed files with 88 additions and 20 deletions

View File

@ -24,11 +24,14 @@
#include "sim_plot_panel.h"
#include <limits>
SIM_PLOT_PANEL::SIM_PLOT_PANEL( wxWindow* parent, wxWindowID id, const wxPoint& pos,
const wxSize& size, long style, const wxString& name )
: wxMathGL( parent, id, pos, size, style, name ), m_painter( this )
{
AutoResize = true;
resetRanges();
SetDraw( &m_painter );
}
@ -38,16 +41,46 @@ SIM_PLOT_PANEL::~SIM_PLOT_PANEL()
}
template<typename T>
static std::pair<T, T> find_minmax( const T* aArray, unsigned int aSize )
{
std::pair<T, T> result( std::numeric_limits<T>::max(), std::numeric_limits<T>::min() );
const T* ptr = aArray;
for( unsigned int i = 0; i < aSize; ++i )
{
if( *ptr < result.first )
result.first = *ptr;
if( *ptr > result.second )
result.second = *ptr;
++ptr;
}
return result;
}
void SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
double* aT, double* aX, int aFlags )
double* aT, double* aY, int aFlags )
{
TRACE trace;
trace.name = aName;
trace.x.Set( aT, aPoints );
trace.y.Set( aX, aPoints );
trace.y.Set( aY, aPoints );
m_traces.push_back( trace );
// Update axis ranges
std::pair<double, double> traceRangeT = find_minmax( aT, aPoints );
m_axisRangeX.first = std::min( traceRangeT.first, m_axisRangeX.first );
m_axisRangeX.second = std::max( traceRangeT.second, m_axisRangeX.second );
std::pair<double, double> traceRangeY = find_minmax( aY, aPoints );
m_axisRangeY.first = std::min( traceRangeY.first, m_axisRangeY.first );
m_axisRangeY.second = std::max( traceRangeY.second, m_axisRangeY.second );
Update();
}
@ -55,38 +88,65 @@ void SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
void SIM_PLOT_PANEL::DeleteTraces()
{
m_traces.clear();
resetRanges();
Update();
}
void SIM_PLOT_PANEL::resetRanges()
{
// Set ranges to inverted values, so when there is a new plot added, it will
// overridden with correct values
m_axisRangeX.first = std::numeric_limits<double>::max();
m_axisRangeX.second = std::numeric_limits<double>::min();
m_axisRangeY.first = std::numeric_limits<double>::max();
m_axisRangeY.second = std::numeric_limits<double>::min();
}
int SIM_PLOT_PAINTER::Draw( mglGraph* aGraph )
{
const std::vector<SIM_PLOT_PANEL::TRACE>& traces = m_parent->m_traces;
const std::pair<double, double>& axisRangeX = m_parent->m_axisRangeX;
std::pair<double, double> axisRangeY = m_parent->m_axisRangeY;
aGraph->Clf();
//aGraph->SetRanges(-10e-3,10e-3,-2,2);
aGraph->Axis( "x" );
aGraph->Label( 'x', "Time", 0 );
//aGraph->SetRange( 'x', 0, 10e-3 );
// Axis settings
// Use autorange values if possible
if( axisRangeX.first < axisRangeX.second )
aGraph->SetRange( 'x', axisRangeX.first, axisRangeX.second );
else
aGraph->SetRange( 'x', 0, 1 );
aGraph->Axis( "y" );
aGraph->Label( 'y', "Voltage", 0 );
//aGraph->SetRange( 'y', -1.5, 1.5 );
for( auto t : traces )
if( axisRangeY.first < axisRangeY.second )
{
aGraph->AddLegend( (const char*) t.name.c_str(), "" );
aGraph->Plot( t.y );
// Increase the Y axis range, so it is easy to read the extreme values
axisRangeY.first -= axisRangeY.second * 0.1;
axisRangeY.second += axisRangeY.second * 0.1;
aGraph->SetRange( 'y', axisRangeY.first, axisRangeY.second );
}
else
{
aGraph->SetRange( 'y', 0, 1 );
}
aGraph->Axis( "xy" );
aGraph->Label( 'x', "Time [s]", 0 );
aGraph->Label( 'y', "Voltage [V]", 0 );
aGraph->Box();
aGraph->Grid();
// Draw traces
for( auto t : traces )
{
aGraph->AddLegend( (const char*) t.name.c_str(), "" );
aGraph->Plot( t.y, "-" );
}
if( traces.size() )
aGraph->Legend( 1, "-#" );
aGraph->SetAutoRanges( 0, 0, 0, 0 );
return 0;
}

View File

@ -32,7 +32,7 @@ class SIM_PLOT_PANEL;
class SIM_PLOT_PAINTER : public mglDraw
{
public:
SIM_PLOT_PAINTER( SIM_PLOT_PANEL* aParent )
SIM_PLOT_PAINTER( const SIM_PLOT_PANEL* aParent )
: m_parent( aParent )
{
}
@ -46,7 +46,7 @@ public:
int Draw( mglGraph* aGraph ) override;
private:
SIM_PLOT_PANEL* m_parent;
const SIM_PLOT_PANEL* m_parent;
};
@ -63,13 +63,21 @@ public:
mglData x, y;
};
std::vector<TRACE> m_traces;
void AddTrace( const wxString& name, int n_points, double *t, double *x, int flags = 0 );
void DeleteTraces();
private:
SIM_PLOT_PAINTER m_painter;
// Traces to be plotted
std::vector<TRACE> m_traces;
// Axis ranges determined by the added traces data
std::pair<double, double> m_axisRangeX, m_axisRangeY;
void resetRanges();
friend class SIM_PLOT_PAINTER;
};
#endif