96 lines
3.7 KiB
C++
96 lines
3.7 KiB
C++
#pragma once
|
|
#include "../Axis/Axis.h"
|
|
#include "../architecture/Bounded_Input_Buffer.h"
|
|
#include "../architecture/Plot_p.h"
|
|
#include "Interpolation_p.h"
|
|
#include "Performance_Shower_p.h"
|
|
#include "Sweep_Frequent.h"
|
|
namespace YSG {
|
|
struct Sweep_Frequent_Render_State : YSG::Render_State, Sweep_Frequent_Prop {};
|
|
struct Sweep_Frequent_Input_Data : YSG::Input_Data {
|
|
Bounded_Vector_Double_Input_Buffer mData;
|
|
void clear() override {
|
|
mData.clear();
|
|
}
|
|
std::uint64_t pending_count() const override {
|
|
return mData.pending_count();
|
|
}
|
|
std::uint64_t dropped_count() const override {
|
|
return mData.dropped_count();
|
|
}
|
|
std::uint64_t pushed_count() const override {
|
|
return mData.pushed_count();
|
|
}
|
|
};
|
|
struct Sweep_Frequent_Private : YSG::Typed_Render_Data<Sweep_Frequent, Sweep_Frequent_Render_State, Sweep_Frequent_Input_Data> {
|
|
friend class Sweep_Frequent;
|
|
QVector<QPointF> mFrequents;
|
|
int mOffset;
|
|
int mBlockFrquentPointSize{};
|
|
int mBlockNum;
|
|
Range mFrequentRange;
|
|
bool mFristLoop = true;
|
|
void set_up_frequents(int blockFrquentPointSize, int block_num, Range frequent_range) {
|
|
mBlockFrquentPointSize = blockFrquentPointSize;
|
|
mBlockNum = block_num;
|
|
mFrequentRange = frequent_range;
|
|
Sweep_Frequent_Render_State* s = render_state();
|
|
int pointSize = block_num * blockFrquentPointSize;
|
|
mFrequents.resize(pointSize);
|
|
int spaceSize = pointSize - 1;
|
|
double step = frequent_range.length() / spaceSize;
|
|
double cur = frequent_range.lower;
|
|
for (int i = 0; i < spaceSize; ++i) {
|
|
mFrequents[i].setX(cur);
|
|
cur += step;
|
|
}
|
|
mFrequents.last().setX(frequent_range.upper);
|
|
mFristLoop = true;
|
|
}
|
|
protected:
|
|
void prepare_data() override {
|
|
sync_state_pipeline();
|
|
Sweep_Frequent_Render_State* s = render_state();
|
|
Sweep_Frequent_Input_Data* d = render_input_data();
|
|
if (
|
|
mBlockFrquentPointSize != s->block_frequent_point_size ||
|
|
mBlockNum != s->block_num ||
|
|
mFrequentRange != s->frequent_range) {
|
|
set_up_frequents(s->block_frequent_point_size, s->block_num, s->frequent_range);
|
|
mOffset = 0;
|
|
}
|
|
d->mData.read_all_reverse([this](const QVector<double>& data) {
|
|
QPointF* start = &mFrequents[mOffset * mBlockFrquentPointSize];
|
|
for (int i = 0; i < mBlockFrquentPointSize; ++i) {
|
|
start[i].setY(data[i]);
|
|
}
|
|
mOffset++;
|
|
if (mOffset == mBlockNum) {
|
|
mOffset = 0;
|
|
mFristLoop = false;
|
|
}
|
|
});
|
|
clear_render_input();
|
|
}
|
|
void draw(QPainter* painter) override {
|
|
Sweep_Frequent_Render_State* s = render_state();
|
|
int n = mFrequents.size();
|
|
int available_count = !mFristLoop ? n : mOffset * mBlockFrquentPointSize;
|
|
QVector<QPointF> data;
|
|
{
|
|
Cacl prepare_data("轴映射数据耗时:%1 SRTT:%2 RTTVAR:%3", q()->mPlot->d->mShower);
|
|
data = create_line_points(s->frequent_axis, s->power_axis, s->frequent_range, n, available_count, s->visible_range_only, s->interpolation_mode, [this](int i) {
|
|
return mFrequents.at(i).y();
|
|
});
|
|
}
|
|
painter->setPen(s->pen);
|
|
if (!data.empty())
|
|
painter->drawPolyline(data.data(), data.size());
|
|
painter->setPen(s->cur_frequent_pen);
|
|
double f = mOffset * mFrequentRange.length() / (mBlockNum - 1.0);
|
|
double ff = s->frequent_axis->coord_to_pixel(f, SRC::Render);
|
|
painter->drawLine(QPointF(ff, 0), QPointF(ff, q()->mPlot->height()));
|
|
}
|
|
};
|
|
} // namespace YSG
|