399 lines
16 KiB
C++
399 lines
16 KiB
C++
#include "Spectrum_p.h"
|
|
|
|
|
|
|
|
namespace YSG {
|
|
using Spectrum_Binding = RenderAble_Binding<Spectrum, SpectrumPrivate, SpectrumRenderState, SpectrumInputData>;
|
|
Spectrum::Spectrum() {
|
|
Spectrum_Binding::init(this, "Spectrum");
|
|
}
|
|
SpectrumPrivate* Spectrum::d() {
|
|
return Spectrum_Binding::d(this);
|
|
}
|
|
RenderData* Spectrum::create_render_data() {
|
|
return Spectrum_Binding::create_render_data();
|
|
}
|
|
RenderState* Spectrum::create_render_state() {
|
|
return Spectrum_Binding::create_render_state();
|
|
}
|
|
InputData* Spectrum::create_input_data() {
|
|
return Spectrum_Binding::create_input_data();
|
|
}
|
|
FrequentAxis* Spectrum::frequent_axis(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::frequent_axis, src);
|
|
}
|
|
void Spectrum::set_frequent_axis(FrequentAxis* value) {
|
|
d()->set_state_value(&SpectrumRenderState::frequent_axis, value);
|
|
}
|
|
Axis* Spectrum::power_axis(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::power_axis, src);
|
|
}
|
|
void Spectrum::set_power_axis(Axis* value) {
|
|
d()->set_state_value(&SpectrumRenderState::power_axis, value);
|
|
}
|
|
int Spectrum::frequent_point_size(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::frequent_point_size, src);
|
|
}
|
|
Range Spectrum::frequent_range(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::frequent_range, src);
|
|
}
|
|
double Spectrum::middle_sweep_frequent(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::middle_sweep_frequent, src);
|
|
}
|
|
void Spectrum::set_middle_sweep_frequent(double value) {
|
|
d()->set_state_value(&SpectrumRenderState::middle_sweep_frequent, value);
|
|
}
|
|
Range Spectrum::sweep_frequent_range(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::sweep_frequent_range, src);
|
|
}
|
|
void Spectrum::set_sweep_frequent_range(Range value) {
|
|
d()->set_state_value(&SpectrumRenderState::sweep_frequent_range, std::move(value));
|
|
}
|
|
bool Spectrum::use_max_line(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::use_max_line, src);
|
|
}
|
|
void Spectrum::set_use_max_line(bool value) {
|
|
d()->set_state_value(&SpectrumRenderState::use_max_line, value);
|
|
}
|
|
bool Spectrum::use_min_line(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::use_min_line, src);
|
|
}
|
|
void Spectrum::set_use_min_line(bool value) {
|
|
d()->set_state_value(&SpectrumRenderState::use_min_line, value);
|
|
}
|
|
bool Spectrum::use_max_marker(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::use_max_marker, src);
|
|
}
|
|
void Spectrum::set_use_max_marker(bool value) {
|
|
d()->set_state_value(&SpectrumRenderState::use_max_marker, value);
|
|
}
|
|
bool Spectrum::use_min_marker(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::use_min_marker, src);
|
|
}
|
|
void Spectrum::set_use_min_marker(bool value) {
|
|
d()->set_state_value(&SpectrumRenderState::use_min_marker, value);
|
|
}
|
|
bool Spectrum::use_sweep_frequent_rect(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::use_sweep_frequent_rect, src);
|
|
}
|
|
void Spectrum::set_use_sweep_frequent_rect(bool value) {
|
|
d()->set_state_value(&SpectrumRenderState::use_sweep_frequent_rect, value);
|
|
}
|
|
QBrush Spectrum::max_brush(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::max_brush, src);
|
|
}
|
|
void Spectrum::set_max_brush(QBrush value) {
|
|
d()->set_state_value(&SpectrumRenderState::max_brush, std::move(value));
|
|
}
|
|
QBrush Spectrum::cur_brush(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::cur_brush, src);
|
|
}
|
|
void Spectrum::set_cur_brush(QBrush value) {
|
|
d()->set_state_value(&SpectrumRenderState::cur_brush, std::move(value));
|
|
}
|
|
QBrush Spectrum::min_brush(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::min_brush, src);
|
|
}
|
|
void Spectrum::set_min_brush(QBrush value) {
|
|
d()->set_state_value(&SpectrumRenderState::min_brush, std::move(value));
|
|
}
|
|
QPen Spectrum::max_pen(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::max_pen, src);
|
|
}
|
|
void Spectrum::set_max_pen(QPen value) {
|
|
d()->set_state_value(&SpectrumRenderState::max_pen, std::move(value));
|
|
}
|
|
QPen Spectrum::cur_pen(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::cur_pen, src);
|
|
}
|
|
void Spectrum::set_cur_pen(QPen value) {
|
|
d()->set_state_value(&SpectrumRenderState::cur_pen, std::move(value));
|
|
}
|
|
QPen Spectrum::min_pen(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::min_pen, src);
|
|
}
|
|
void Spectrum::set_min_pen(QPen value) {
|
|
d()->set_state_value(&SpectrumRenderState::min_pen, std::move(value));
|
|
}
|
|
QPen Spectrum::select_marker_pen(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::select_marker_pen, src);
|
|
}
|
|
void Spectrum::set_select_marker_pen(QPen value) {
|
|
d()->set_state_value(&SpectrumRenderState::select_marker_pen, std::move(value));
|
|
}
|
|
QPen Spectrum::marker_pen(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::marker_pen, src);
|
|
}
|
|
void Spectrum::set_marker_pen(QPen value) {
|
|
d()->set_state_value(&SpectrumRenderState::marker_pen, std::move(value));
|
|
}
|
|
QPen Spectrum::middle_frequent_pen(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::middle_frequent_pen, src);
|
|
}
|
|
void Spectrum::set_middle_frequent_pen(QPen value) {
|
|
d()->set_state_value(&SpectrumRenderState::middle_frequent_pen, std::move(value));
|
|
}
|
|
QBrush Spectrum::sweep_rect_brush(SRC src) {
|
|
return d()->state_value(&SpectrumRenderState::sweep_rect_brush, src);
|
|
}
|
|
void Spectrum::set_sweep_rect_brush(QBrush value) {
|
|
d()->set_state_value(&SpectrumRenderState::sweep_rect_brush, std::move(value));
|
|
}
|
|
void Spectrum::set_frequent_point_size(int frequent_point_size) {
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->frequent_point_size = frequent_point_size;
|
|
}
|
|
|
|
void Spectrum::set_frequent_range(Range frequent_range){
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->frequent_range = frequent_range;
|
|
}
|
|
|
|
|
|
Spectrum::Builder::Builder(FrequentAxis* frequent_axis, Axis* power_axis) {
|
|
ASSERT(frequent_axis->mPlot != nullptr, "Afterglow build error! frequent_axis->mPlot == nullptr");
|
|
ASSERT(frequent_axis->mPlot == power_axis->mPlot, "Afterglow build error! frequent_axis->mPlot != power_axis->mPlot");
|
|
plot = frequent_axis->mPlot;
|
|
this->frequent_axis = frequent_axis;
|
|
this->power_axis = power_axis;
|
|
}
|
|
Spectrum* Spectrum::Builder::build() {
|
|
auto ret = new Spectrum;
|
|
ret->init(plot, layerName);
|
|
SpectrumPrivate* pd = ret->d();
|
|
SpectrumRenderState* sc = reinterpret_cast<SpectrumRenderState*>(pd->state(State_Edit));
|
|
PROP_R(FrequentAxis*, frequent_axis)
|
|
PROP_R(Axis*, power_axis);
|
|
PROP_R(int, frequent_point_size);
|
|
PROP_R(Range, frequent_range);
|
|
PROP_R(double, middle_sweep_frequent);
|
|
PROP_R(Range, sweep_frequent_range);
|
|
PROP_R(bool, use_max_line);
|
|
PROP_R(bool, use_min_line);
|
|
PROP_R(bool, use_max_marker);
|
|
PROP_R(bool, use_min_marker);
|
|
PROP_R(bool, use_sweep_frequent_rect);
|
|
PROP_R(QBrush, max_brush);
|
|
PROP_R(QBrush, cur_brush);
|
|
PROP_R(QBrush, min_brush);
|
|
PROP_R(QPen, max_pen);
|
|
PROP_R(QPen, cur_pen);
|
|
PROP_R(QPen, min_pen);
|
|
PROP_R(QPen, select_marker_pen);
|
|
PROP_R(QPen, marker_pen);
|
|
PROP_R(QPen, middle_frequent_pen);
|
|
PROP_R(QBrush, sweep_rect_brush);
|
|
return ret;
|
|
}
|
|
|
|
void SpectrumPrivate::update_frequent_point_size(int frequent_point_size, Range frequent_range) {
|
|
if(frequent_point_size == 0) return;
|
|
cacheFrequentPointSize = frequent_point_size;
|
|
cacheFrequentRange = frequent_range;
|
|
maxPowers.resize(frequent_point_size);
|
|
curPowers.resize(frequent_point_size);
|
|
minPowers.resize(frequent_point_size);
|
|
frequents.resize(frequent_point_size);
|
|
double cur = frequent_range.lower;
|
|
double step = frequent_range.length() / (frequent_point_size - 1);
|
|
frequents[0] = frequent_range.lower;
|
|
for(int i = 1; i < frequent_point_size; ++i) {
|
|
cur += step;
|
|
frequents[i] = cur;
|
|
}
|
|
maxPowers.fill(frequent_range.lower);
|
|
minPowers.fill(frequent_range.upper);
|
|
}
|
|
void SpectrumPrivate::set_frequent_data(const QVector<double>& lineData, const SpectrumRenderState* s) {
|
|
if(lineData.size() != s->frequent_point_size) {
|
|
qDebug() << "setFrenquentData 数据大小不对 " << lineData.size() << " mFrequentPointSize == " << s->frequent_point_size;
|
|
return;
|
|
}
|
|
curPowers = lineData;
|
|
curPowers.detach();
|
|
double min = std::numeric_limits<double>::max();
|
|
double max = std::numeric_limits<double>::min();
|
|
int minIndex = 0, maxIndex = 0;
|
|
for(int i = 0; i < s->frequent_point_size; ++i) {
|
|
double& curData = curPowers[i];
|
|
if(s->use_max_line && curData > maxPowers.at(i)) {
|
|
maxPowers[i] = curData;
|
|
}
|
|
if(s->use_min_line && curData < minPowers.at(i)) {
|
|
minPowers[i] = curData;
|
|
}
|
|
if(s->use_max_marker && curData > max) {
|
|
max = curData;
|
|
maxIndex = i;
|
|
}
|
|
if(s->use_min_marker && curData < min) {
|
|
min = curData;
|
|
minIndex = i;
|
|
}
|
|
}
|
|
maxMarkerKey = frequents[maxIndex];
|
|
maxMarkerValue = curPowers[maxIndex];
|
|
minMarkerKey = frequents[minIndex];
|
|
minMarkerValue = curPowers[minIndex];
|
|
}
|
|
double SpectrumPrivate::get_y(const double& x, bool& ok) {
|
|
int i = binary_search(x, frequents, ok);
|
|
if(!ok) return -1;
|
|
const double& x1 = frequents.at(i);
|
|
const double& x2 = frequents.at(i + 1);
|
|
const double& y1 = curPowers.at(i);
|
|
const double& y2 = curPowers.at(i + 1);
|
|
double k = (y2 - y1) / (x2 - x1);
|
|
double b = y1 - k * x1;
|
|
return (int)(k * x + b);
|
|
}
|
|
void SpectrumPrivate::draw_line(QPainter* painter, const SpectrumRenderState* s, const QVector<double>& ys, const QPen& pen, const QBrush& brush) {
|
|
if(frequents.empty()) return;
|
|
int n = frequents.size();
|
|
QVector<QPointF> points(n+2);
|
|
double upperBoundPixel = s->power_axis->coord_to_pixel(s->power_axis->coord_range().upper, SRC::Render);
|
|
points.first() = QPointF(s->frequent_axis->coord_to_pixel(frequents.first(), SRC::Render), upperBoundPixel);
|
|
points.last() = QPointF(s->frequent_axis->coord_to_pixel(frequents.last(), SRC::Render), upperBoundPixel);
|
|
for(int i = 0; i < n; ++i) {
|
|
double x = s->frequent_axis->coord_to_pixel(frequents.at(i), SRC::Render);
|
|
double y = s->power_axis->coord_to_pixel(ys.at(i), SRC::Render);
|
|
points[i + 1] = QPointF(x, y);
|
|
}
|
|
painter->setPen(pen);
|
|
if(pen.style() != Qt::NoPen) painter->drawPolyline(points.data() + 1, n);
|
|
painter->setBrush(brush);
|
|
if(brush.style() != Qt::NoBrush) painter->drawPolygon(points.data(), n + 2);
|
|
}
|
|
void SpectrumPrivate::draw_spectrum(QPainter* painter, SpectrumRenderState* s) {
|
|
if(s->use_max_line) draw_line(painter, s, maxPowers, s->max_pen, s->max_brush);
|
|
draw_line(painter, s, curPowers, s->cur_pen, s->cur_brush);
|
|
if(s->use_min_line) draw_line(painter, s, minPowers, s->min_pen, s->min_brush);
|
|
if(s->use_max_marker) s->draw_marker(painter, maxMarkerKey, maxMarkerValue, false, false);
|
|
if(s->use_min_marker) s->draw_marker(painter, minMarkerKey, minMarkerValue, false, false);
|
|
for(Marker& customMarker : s->markerList) {
|
|
bool ok;
|
|
double value = get_y(customMarker.frequent, ok);
|
|
if(ok) s->draw_marker(painter, customMarker.frequent, value, customMarker.drawLine, s->markerList.indexOf(customMarker) == s->curSelectIndex);
|
|
}
|
|
if(s->use_sweep_frequent_rect) {
|
|
s->draw_axis_rect(painter, s->sweep_frequent_range, s->middle_sweep_frequent);
|
|
}
|
|
}
|
|
void SpectrumPrivate::draw(QPainter* painter) {
|
|
auto s = render_state();
|
|
PerformanceShower *shower = q()->mPlot->d->mShower;
|
|
if(shower) {
|
|
shower->set_performance_line("mFrequentPointSize", PerformanceLine(QString("mFrequentPointSize:%1").arg(s->frequent_point_size)));
|
|
}
|
|
draw_spectrum(painter, s);
|
|
if(q()->hover_ok(q())) {
|
|
q()->draw_hover(painter, s->frequent_axis, s->power_axis);
|
|
}
|
|
}
|
|
|
|
|
|
void Spectrum::give_data(const QVector<double> &lineData){
|
|
if(!ok()) return;
|
|
SpectrumPrivate* pd = d();
|
|
Render_State_Lease<SpectrumPrivate, SpectrumRenderState> state(pd);
|
|
int frequent_point_size = state->frequent_point_size;
|
|
if(lineData.size() != frequent_point_size) {
|
|
qDebug() << "setFrenquentData 数据大小不对 " << lineData.size() << " mFrequentPointSize == " << frequent_point_size;
|
|
return;
|
|
}
|
|
Render_Input_Lease<SpectrumPrivate, SpectrumInputData> input(pd);
|
|
input->mDataList.push_back(lineData);
|
|
}
|
|
|
|
void Spectrum::add_custom_marker(double frequent){
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->markerList.append(Marker{frequent, false});
|
|
}
|
|
|
|
void Spectrum::add_custom_line_marker(double frequent){
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->markerList.append(Marker{frequent, true});
|
|
}
|
|
|
|
void Spectrum::remove_custom_marker(double frequent){
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
for (Marker &marker: edit->markerList) {
|
|
if (qFuzzyCompare(marker.frequent, frequent)) {
|
|
edit->markerList.removeOne(marker);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Spectrum::remove_current_marker(SRC src) {
|
|
Q_UNUSED(src)
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->markerList.removeAt(edit->curSelectIndex);
|
|
}
|
|
|
|
void Spectrum::clear_all_custom_marker(SRC src) {
|
|
Q_UNUSED(src)
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->markerList.clear();
|
|
}
|
|
|
|
double Spectrum::get_mark_frequent(int markIndex, SRC src) {
|
|
auto render_state = d()->state_data(src);
|
|
if (markIndex < 0 || markIndex >= render_state->markerList.size())
|
|
return -1;
|
|
return render_state->markerList[markIndex].frequent;
|
|
}
|
|
|
|
void Spectrum::set_marker_frequent(int markerIndex, double frequent) {
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
QVector<Marker> &markers = edit->markerList;
|
|
if (markerIndex < 0 || markerIndex >= markers.size())
|
|
return;
|
|
markers[markerIndex].frequent = frequent;
|
|
}
|
|
|
|
void Spectrum::set_current_marker_frequent(double frequent) {
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->set_cur_frequent(frequent);
|
|
}
|
|
|
|
int Spectrum::select_line_marker_size(SRC src) {
|
|
auto render_state = d()->state_data(src);
|
|
return render_state->markerList.size();
|
|
}
|
|
|
|
int Spectrum::cur_select_marker_index(SRC src) {
|
|
auto render_state = d()->state_data(src);
|
|
return render_state->curSelectIndex;
|
|
}
|
|
|
|
void Spectrum::set_selected_line_marker(int markerIndex){
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->set_select_index(markerIndex);
|
|
}
|
|
|
|
void Spectrum::select_next(SRC src) {
|
|
Q_UNUSED(src)
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->select_next_marker();
|
|
}
|
|
|
|
void Spectrum::select_previous(SRC src) {
|
|
Q_UNUSED(src)
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->select_prev_marker();
|
|
}
|
|
|
|
void Spectrum::un_select_marker(SRC src) {
|
|
Q_UNUSED(src)
|
|
Render_Edit_Lease<SpectrumPrivate, SpectrumRenderState> edit(d());
|
|
edit->un_select();
|
|
}
|
|
|
|
double Spectrum::get_power(double frequent, bool& ok, SRC src) {
|
|
Q_UNUSED(src)
|
|
return d()->get_y(frequent, ok);
|
|
}
|
|
|
|
}
|