test_sdk/gui/gtl_gui_spec_chart.cpp

399 lines
14 KiB
C++

#include "gtl_gui_spec_chart.h"
#include "math/gtl_math_spec_meas.h"
#include "gui/spec/gtl_gui_spec_band_marker.h"
#include "gui/spec/gtl_gui_spec_harm_marker.h"
namespace gtl
{
namespace gui
{
spec_chart::spec_chart(gtl::math::spec::types type, QWidget* parent)
: chart(parent)
, _type(type)
, _frequency(100000)
, _resolution(100)
, _window(5)
, _lines(_frequency/_resolution)
, _average(1)
, _overlap(0)
, _unit(0)
, _meas_model(nullptr)
, _meas_cnt(0)
, _band_markers{new spec::band_markers(this)}
, _harm_markers{new spec::harm_markers(this)}
{
_band_marker_action_add = new QAction(tr("Add band marker"), this);
_markers_menu->insertAction(_marker_action_remove, _band_marker_action_add);
connect(_band_marker_action_add, &QAction::triggered, this, &spec_chart::add_band_marker);
_harm_marker_action_add = new QAction(tr("Add harmonic marker"), this);
_markers_menu->insertAction(_marker_action_remove, _harm_marker_action_add);
connect(_harm_marker_action_add, &QAction::triggered, this, &spec_chart::add_harm_marker);
}
spec_chart::~spec_chart()
{
remove();
}
qreal spec_chart::frequency()
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
_frequency = static_cast<spec_series*>(*iter_series)->frequency();
}
return _frequency;
}
qreal spec_chart::resolution()
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
_resolution = static_cast<spec_series*>(*iter_series)->resolution();
}
return _resolution;
}
int spec_chart::window()
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
_window = static_cast<int>(static_cast<spec_series*>(*iter_series)->window());
}
return _window;
}
int spec_chart::lines()
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
_lines = static_cast<spec_series*>(*iter_series)->lines();
}
return _lines;
}
int spec_chart::average()
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
_average = static_cast<spec_series*>(*iter_series)->average();
}
return _average;
}
qreal spec_chart::overlap()
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
_overlap = static_cast<spec_series*>(*iter_series)->overlap();
}
return _overlap;
}
int spec_chart::unit()
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
_unit = static_cast<int>(static_cast<spec_series*>(*iter_series)->unit());
}
return _unit;
}
void spec_chart::save(QDomElement &root_element)
{
chart::save(root_element);
root_element.setAttribute("type", _type);
root_element.setAttribute("freq", _frequency);
root_element.setAttribute("resolution", _resolution);
root_element.setAttribute("window", _window);
root_element.setAttribute("lines", _lines);
root_element.setAttribute("avg", _average);
root_element.setAttribute("overlap", _overlap);
root_element.setAttribute("unit", _unit);
}
void spec_chart::load(const QDomElement &root_element)
{
chart::load(root_element);
_type = (gtl::math::spec::types)root_element.attribute("type", "0").toInt();
_frequency = root_element.attribute("freq", "100000").toDouble();
_resolution = root_element.attribute("resolution", "100").toDouble();
_window = root_element.attribute("window", "5").toInt();
_lines = root_element.attribute("lines", QString::number(qRound(_frequency/_resolution))).toUInt();
_average = root_element.attribute("avg", "1").toUInt();
_overlap = root_element.attribute("overlap", "0").toDouble();
_unit = root_element.attribute("unit", "0").toInt();
}
spec::band_markers *spec_chart::band_markers() const
{
return _band_markers;
}
spec::harm_markers *spec_chart::harm_markers() const
{
return _harm_markers;
}
void spec_chart::set_type(int value)
{
_type = (gtl::math::spec::types)value;
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
static_cast<spec_series*>(*iter_series)->set_type(_type);
}
math::spec::types spec_chart::type() const
{
return _type;
}
void spec_chart::add_instrument(const QPointF &pos)
{
_instruments.back()->add(pos);
if (_instruments.back()->is_complete())
{
_mouse_action = ::chart::edit_instruments;
}
}
void spec_chart::draw_instrument(const QPointF &pos)
{
_instruments.back()->draw(QPointF(_axis_x->map_from_widget(pos.x()), _axis_y->map_from_widget(pos.y())));
}
void spec_chart::set_frequency(qreal value)
{
if(value != _frequency)
{
if(_series.empty())
{
_frequency = value;
}
else
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
static_cast<spec_series*>(*iter_series)->set_frequency(value);
_frequency = static_cast<spec_series*>(*iter_series)->frequency();
}
}
emit frequency_changed();
}
}
void spec_chart::set_resolution(qreal value)
{
if(value != _resolution)
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
static_cast<spec_series*>(*iter_series)->set_resolution(value);
_resolution = static_cast<spec_series*>(*iter_series)->resolution();
}
emit resolution_changed();
}
}
void spec_chart::set_window(int value)
{
if(value != _window)
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
static_cast<spec_series*>(*iter_series)->set_window(value);
_window = static_cast<int>(static_cast<spec_series*>(*iter_series)->window() - 1);
}
emit window_changed();
}
}
void spec_chart::set_lines(int value)
{
if(value != _lines)
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
static_cast<spec_series*>(*iter_series)->set_lines(value);
_lines = static_cast<spec_series*>(*iter_series)->lines();
}
emit lines_changed();
}
}
void spec_chart::set_average(int value)
{
if(value != _average)
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
static_cast<spec_series*>(*iter_series)->set_average(value);
_average = static_cast<spec_series*>(*iter_series)->average();
}
emit average_changed();
}
}
void spec_chart::set_overlap(qreal value)
{
if(value != _overlap)
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
static_cast<spec_series*>(*iter_series)->set_overlap(value);
_overlap = static_cast<spec_series*>(*iter_series)->overlap();
}
emit overlap_changed();
}
}
void spec_chart::set_unit(int value)
{
if(value != _unit)
{
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
static_cast<spec_series*>(*iter_series)->set_unit(value);
_unit = static_cast<int>(static_cast<spec_series*>(*iter_series)->unit());
}
emit unit_changed();
}
}
void spec_chart::set_measures(spec_meas_model* model)
{
_meas_model = model;
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
static_cast<spec_series*>(*iter_series)->set_measures(_meas_model);
}
void spec_chart::set_x_log(bool value)
{
if(value)
{
qreal min = .001;
for(auto series: _series)
{
if(_series.size() < 2)
continue;
if(static_cast<::chart::series::xy::xy*>(series)->at_x(1) < min)
min = static_cast<::chart::series::xy::xy*>(series)->at_x(1);
}
_axis_x->set_boundaries(min, _axis_x->max_boundary());
}
else
_axis_x->set_boundaries(0, _axis_x->max_boundary());
_axis_x->set_scale(value ? ::chart::axis::logarithmic : ::chart::axis::linear);
}
void spec_chart::handle_measures(SpecMeasParamsListPtr meas)
{
for(int i = 0; i < meas->count(); i++)
for(int j = 0; j < _meas_model->measures()->count(); j++)
{
if(meas->at(i).id == _meas_model->measures()->at(j).id)
{
gtl::math::spec_meas::params *p = const_cast<gtl::math::spec_meas::params *>(&_meas_model->measures()->at(j));
p->value = meas->at(i).value;
_meas_cnt++;
}
}
if(_meas_cnt >= _meas_model->measures()->count())
{
_meas_model->all_done();
_meas_cnt = 0;
}
}
gtl::gui::spgr::widget* spec_chart::create_spgr(QWidget *parent, data_model_node *node)
{
if(node)
for(std::vector<::chart::series::series*>::iterator iter_series = _series.begin(); iter_series != _series.end(); iter_series++)
{
spec_series* ser = static_cast<spec_series*>(*iter_series);
if(ser->ad()->name() == node->name())
return ser->create_spgr(parent);
}
return nullptr;
}
void spec_chart::add_band_marker()
{
spec::band_marker* marker = new spec::band_marker(_marker_series, _set_theme_action->isChecked());
add(marker);
connect(marker, &chart_marker::get_nearest_x, this, &spec_chart::get_neares_series_x);
connect(marker, &chart_marker::get_series_data, this, &spec_chart::get_series_data);
connect(marker, &chart_marker::get_series_values, this, &spec_chart::get_series_values);
connect(marker, &chart_marker::deleting, this, &spec_chart::remove_marker);
// marker->set_pos(_mouse_pos_release);
_markers->add_marker(marker);
_mouse_action = ::chart::add_instruments;
draw_instrument(_mouse_pos_release);
_band_markers->add(marker);
}
void spec_chart::add_harm_marker()
{
chart_marker* marker = new spec::harm_marker(_marker_series, _set_theme_action->isChecked());
add(marker);
connect(marker, &chart_marker::get_nearest_x, this, &spec_chart::get_neares_series_x);
connect(marker, &chart_marker::get_series_data, this, &spec_chart::get_series_data);
connect(marker, &chart_marker::get_series_values, this, &spec_chart::get_series_values);
connect(marker, &chart_marker::deleting, this, &spec_chart::remove_marker);
marker->set_pos(_mouse_pos_release);
_markers->add_marker(marker);
_harm_markers->add(marker);
}
chart_series *spec_chart::create_series(analog_data *ai)
{
spec_series *series = new spec_series(is_updating(), _type, ai, _axis_x, _axis_y);
connect(series, &spec_series::initialized, this, &spec_chart::set_bounds_x);
connect(series, &spec_series::measures_changed, this, &spec_chart::handle_measures);
series->set_frequency(_frequency);
set_frequency(series->frequency());
series->set_resolution(_resolution);
series->set_window(_window);
series->set_lines(_lines);
series->set_average(_average);
series->set_overlap(_overlap);
series->set_unit(_unit);
series->set_measures(_meas_model);
series->update();
return series;
}
}
}