399 lines
14 KiB
C++
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|