95 lines
3.4 KiB
C++
95 lines
3.4 KiB
C++
#pragma once
|
|
#include "SweepFrequent.h"
|
|
#include "../Axis/Axis.h"
|
|
#include "../base/PerformanceShower_p.h"
|
|
#include "../base/Plot.h"
|
|
#include "../base/Plot_p.h"
|
|
|
|
|
|
namespace YSG {
|
|
|
|
struct SweepFrequentRenderState : YSG::RenderState, SweepFrequent_Prop {
|
|
|
|
};
|
|
|
|
struct SweepFrequentTempData : YSG::TempData {
|
|
std::list<QVector<double>> mData;
|
|
};
|
|
|
|
struct SweepFrequentPrivate : YSG::RenderData {
|
|
D_Ptr(SweepFrequent)
|
|
QVector<QPointF> mFrequents;
|
|
int mOffset;
|
|
int mBlockFrquentPointSize{};
|
|
int mBlockNum;
|
|
Range mFrequentRange;
|
|
bool mFristLoop = true;
|
|
void setUpFrequents(int blockFrquentPointSize, int blockNum, Range frequentRange) {
|
|
mBlockFrquentPointSize = blockFrquentPointSize;
|
|
mBlockNum = blockNum;
|
|
mFrequentRange = frequentRange;
|
|
SweepFrequentRenderState *s = renderState();
|
|
int pointSize = blockNum * blockFrquentPointSize;
|
|
mFrequents.resize(pointSize);
|
|
int spaceSize = pointSize - 1;
|
|
double step = frequentRange.length() / spaceSize;
|
|
double cur = frequentRange.lower;
|
|
for(int i = 0; i < spaceSize; ++i) {
|
|
mFrequents[i].setX(cur);
|
|
cur += step;
|
|
}
|
|
mFrequents.last().setX(frequentRange.upper);
|
|
mFristLoop = true;
|
|
}
|
|
protected:
|
|
void prepareData() override {
|
|
SpinLockGuard guard(&mBufferLock);
|
|
syncStatePipeline();
|
|
SweepFrequentRenderState *s = renderState();
|
|
SweepFrequentTempData *d = renderTempData();
|
|
if(
|
|
mBlockFrquentPointSize != s->blockFrequentPointSize ||
|
|
mBlockNum != s->blockNum ||
|
|
mFrequentRange != s->frequentRange
|
|
) {
|
|
setUpFrequents(s->blockFrequentPointSize, s->blockNum, s->frequentRange);
|
|
mOffset = 0;
|
|
}
|
|
for(const QVector<double>& data : d->mData) {
|
|
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;
|
|
}
|
|
}
|
|
d->mData.clear();
|
|
}
|
|
|
|
void draw(QPainter* painter) override {
|
|
SweepFrequentRenderState *s = renderState();
|
|
int n = mFrequents.size();
|
|
QVector<QPointF> data(n);
|
|
{
|
|
Cacl prepareData("轴映射数据耗时: %1 avg: %2", q()->mPlot->d->mShower);
|
|
for(int i = 0; i < n; ++i) {
|
|
const QPointF& p = mFrequents[i];
|
|
data[i].rx() = s->frequentAxis->coordToPixel(p.x(), SRC::Render);
|
|
data[i].ry() = s->powerAxis->coordToPixel(p.y(), SRC::Render);
|
|
}
|
|
}
|
|
|
|
painter->setPen(s->pen);
|
|
painter->drawPolyline(data.data(), !mFristLoop ? data.size() : mOffset * mBlockFrquentPointSize);
|
|
|
|
painter->setPen(s->curFrequentPen);
|
|
double f = mOffset * mFrequentRange.length()/(mBlockNum-1.0);
|
|
double ff = s->frequentAxis->coordToPixel(f, SRC::Render);
|
|
painter->drawLine(QPointF(ff, 0), QPointF(ff, q()->mPlot->height()));
|
|
}
|
|
};
|
|
}
|