test_sdk/gui/orbit/gtl_gui_orbit_series.cpp

391 lines
11 KiB
C++
Raw Normal View History

#include "orbit/gtl_gui_orbit_series.h"
#include <QDebug>
namespace gtl {
namespace gui {
namespace orbit {
series::series(QWidget* parent, ::chart::axis_horz* axis_x, ::chart::axis_vert* axis_y)
: ::chart::series::series(axis_x, axis_y),
_x(nullptr),
_y(nullptr),
_time(0.1),
_start(0.),
_stop(_time),
_turns(1),
_is_updating(true),
_max(1.5),
_device(nullptr),
_freq(nullptr),
_samples_x(0),
_samples_y(0),
_size(0)
{
_axis_horz->set_range(-_max, _max, 0);
_axis_vert->set_range(-_max, _max, 0);
init();
}
series::~series()
{
_data_x.clear();
_data_y.clear();
_points.clear();
if(_freq)
delete _freq;
}
void series::save(QDomElement &root_element)
{
root_element.setAttribute("time", _time);
root_element.setAttribute("start", _start);
root_element.setAttribute("stop", _stop);
root_element.setAttribute("turns", _turns);
root_element.setAttribute("max", _max);
}
void series::load(const QDomElement &root_element)
{
_time = root_element.attribute("time", "1").toDouble();
_start = root_element.attribute("start", "0").toDouble();
_stop = root_element.attribute("stop", "1").toDouble();
_turns = root_element.attribute("turns", "1").toDouble();
_max = root_element.attribute("max", "1").toDouble();
}
void series::set_updating(bool value)
{
_is_updating = value;
}
void series::autoscale()
{
if(_x && _y)
{
prepareGeometryChange();
qreal x_max = *std::max_element(_x->begin(), _x->end());
qreal y_max = *std::max_element(_y->begin(), _y->end());
_max = std::max(x_max, y_max);
_max *= 1.5;
_axis_horz->set_range(-_max, _max, 0);
_axis_vert->set_range(-_max, _max, 0);
}
}
void series::set_pos(QPointF pos)
{
// _pos = pos;
}
QString series::name() const
{
if(_x)
return _x->name();
return "";
}
void series::set_tool_tip(QPoint pos)
{
}
void series::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
if(!_x || !_y)
return;
if(_samples_x != _samples_y)
return;
QRectF boundary = boundingRect();
painter->setClipRect(_axis_vert->boundingRect());
painter->setTransform(QTransform().translate(
boundary.left(),
boundary.top()
)
.scale(
boundary.width() / _axis_horz->range_scaled(),
-boundary.height() / _axis_vert->range_scaled()
)
.translate(
-_axis_horz->min_scaled(),
- _axis_vert->max_scaled()
)
);
painter->setPen(QPen(QColor(_x->color()), 0));
int start = _start * _x->get_rate();
int size = (_stop - _start) * _x->get_rate();
if( (start + size) <= _points.size())
painter->drawPolyline(_points.data() + start, size);
else
painter->drawPolyline(_points.data(), _points.size());
}
gtl::analog_data *series::x() const
{
return _x;
}
void series::set_x(gtl::analog_data *value)
{
if (_x == value)
return;
if(_x)
disconnect(_x, &gtl::analog_data::data_changed, this, &series::handle_x_changed);
_x = value;
if(_freq)
{
delete _freq;
_freq = nullptr;
}
if(_x)
{
_freq = new gtl::math::freq(_x);
_freq->set_time(_time);
connect(_freq, &gtl::math::freq::value_changed, [=]{emit freq_changed();});
init();
connect(_x, &gtl::analog_data::data_changed, this, &series::handle_x_changed);
}
emit x_changed();
}
gtl::analog_data *series::y() const
{
return _y;
}
void series::set_y(gtl::analog_data *value)
{
if (_y == value)
return;
if(_y)
disconnect(_y, &gtl::analog_data::data_changed, this, &series::handle_y_changed);
_y = value;
if(_y)
{
if(_device)
disconnect(_device, &gtl::device::recieved_data, this, &series::update_series);
_device = static_cast<gtl::device*>(_y->root());
init();
connect(_y, &gtl::analog_data::data_changed, this, &series::handle_y_changed);
if(_device)
connect(_device, &gtl::device::recieved_data, this, &series::update_series);
}
emit y_changed();
}
qreal series::time() const
{
return _time;
}
void series::set_time(qreal value)
{
if (qFuzzyCompare(_time, value))
return;
_time = value;
if(_freq)
_turns = _time*_freq->value();
if(_stop > _time)
_stop = _time;
if(_start > _time)
_start = 0;
init();
emit time_changed();
}
qreal series::start() const
{
return _start;
}
void series::set_start(qreal value)
{
if (qFuzzyCompare(_start, value))
return;
_start = value;
if(_start >= _time)
_start = 0;
emit start_changed();
}
qreal series::stop() const
{
return _stop;
}
void series::set_stop(qreal value)
{
if (qFuzzyCompare(_stop, value))
return;
_stop = value;
if(_stop >= _time)
_stop = _time;
emit stop_changed();
}
qreal series::turns() const
{
return _turns;
}
void series::set_turns(qreal value)
{
if (qFuzzyCompare(_turns, value))
return;
_turns = value;
if(_freq)
{
if(_freq->value() > 0)
_time = _turns/_freq->value();
init();
}
emit turns_changed();
}
qreal series::freq() const
{
if(_freq)
return _freq->value();
return 0;
}
QColor series::color()
{
if(_x)
return _x->color();
return QColor(Qt::black);
}
void series::update_series()
{
if(_samples_x != _samples_y)
{
_data_x.clear();
_data_y.clear();
_points.clear();
_samples_x = 0;
_samples_y = 0;
return;
}
int size = std::min(_data_x.size(), _data_y.size());
if((_points.size() + size) > _size)
{
int psize = size + _points.size() - _size;
if(psize > 0 && _points.size() >= psize)
_points.erase(_points.begin(), _points.begin() + psize);
}
for(int i = 0; i < size; i++)
{
QPointF point(_data_x.at(i), _data_y.at(i));
_points.push_back(point);
}
if(size)
{
_data_x.erase(_data_x.begin(), _data_x.begin() + size);
_data_y.erase(_data_y.begin(), _data_y.begin() + size);
}
prepareGeometryChange();
}
void series::set_icolor()
{
}
void series::handle_x_changed()
{
_x->lock_device();
_samples_x += _x->size();
std::copy(_x->begin(), _x->end(), std::back_inserter(_data_x));
_x->unlock_device();
}
void series::handle_y_changed()
{
_y->lock_device();
_samples_y += _y->size();
std::copy(_y->begin(), _y->end(), std::back_inserter(_data_y));
_y->unlock_device();
}
void series::init()
{
if(_x && _y)
{
_x->lock_device();
_y->lock_device();
_samples_x = 0;
_samples_y = 0;
_data_x.clear();
_data_y.clear();
_points.clear();
if(_freq)
{
if(_freq->value() > 0)
_turns = _time*_freq->value();
if(_time > 0)
_freq->set_time(_time);
}
_size = _x->get_rate()*_time;
_points.reserve(_size);
_x->unlock_device();
_y->unlock_device();
}
}
}
} // namespace gui
} // namespace gtl