#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> mData; }; struct SweepFrequentPrivate : YSG::RenderData { D_Ptr(SweepFrequent) QVector 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& 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 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())); } }; }