概述
qcustomplot 提供了显示 时间的坐标轴挺方便的,不过分配的tick 通过它的优化算法,会被自动设置tick的数量。在某些业务场景下就不适用。代码如下 可固定tick数量
为从x轴的数据中筛选出等分tick坐标点 提供如下算法:
double intiger;
double v = modf(range.size() / double(mTickCount + 1e-10), &intiger);
double ext = range.size() - intiger * mTickCount;
double forward = floor(ext/ double(2 + 1e-10));
QVector<double> result;
result.push_back(range.lower);
result.push_back(range.lower + forward + intiger);
for (int i = 2; i < mTickCount; ++i)
result.push_back(result.back() + intiger);
class QCP_LIB_DECL QCPAxisTickerMsecTime : public QCPAxisTicker
{
Q_GADGET
public:
QCPAxisTickerMsecTime();
// getters:
QString timeFormat() const { return mTimeFormat; }
// setters:
void setTimeFormat(const QString& format);
protected:
// property members:
QString mTimeFormat;
// reimplemented virtual methods:
virtual QVector<double> createTickVector(double tickStep, const QCPRange& range);
virtual double getTickStep(const QCPRange& range) Q_DECL_OVERRIDE;
virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
virtual QString getTickLabel(double tick, const QLocale& locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
};
QCPAxisTickerMsecTime::QCPAxisTickerMsecTime() :
mTimeFormat(QLatin1String("hh:mm:ss"))
{
setTickCount(4);
}
void QCPAxisTickerMsecTime::setTimeFormat(const QString& format)
{
mTimeFormat = format;
}
QVector<double> QCPAxisTickerMsecTime::createTickVector(double tickStep, const QCPRange& range)
{
double intiger;
double v = modf(range.size() / double(mTickCount + 1e-10), &intiger);
double ext = range.size() - intiger * mTickCount;
double forward = floor(ext/ double(2 + 1e-10));
QVector<double> result;
result.push_back(range.lower);
result.push_back(range.lower + forward + intiger);
for (int i = 2; i < mTickCount; ++i)
result.push_back(result.back() + intiger);
// Generate tick positions according to tickStep:
//qint64 firstStep = qint64(floor((range.lower - mTickOrigin) / tickStep)); // do not use qFloor here, or we'll lose 64 bit precision
//qint64 lastStep = qint64(ceil((range.upper - mTickOrigin) / tickStep)); // do not use qCeil here, or we'll lose 64 bit precision
//int tickcount = int(lastStep - firstStep + 1);
//if (tickcount < 0) tickcount = 0;
//result.resize(tickcount);
//for (int i = 0; i < tickcount; ++i)
//
result[i] = mTickOrigin + (firstStep + i) * tickStep;
return result;
}
double QCPAxisTickerMsecTime::getTickStep(const QCPRange& range)
{
double result = range.size() / double(mTickCount + 1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers
if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds
{
//if (mSmallestUnit == tuMilliseconds)
//
result = qMax(cleanMantissa(result), 0.001); // smallest tick step is 1 millisecond
//else // have no milliseconds available in format, so stick with 1 second tickstep
result = 1.0;
}
else if (result < 3600 * 24) // below a day
{
// the filling of availableSteps seems a bit contorted but it fills in a sorted fashion and thus saves a post-fill sorting run
QVector<double> availableSteps;
// seconds range:
availableSteps << 1 << 2 << 2.5 << 5 << 10 << 15 << 30
<< 1 * 60 << 2.5 * 60 << 2 * 60 << 5 * 60 << 10 * 60 << 15 * 60 << 30 * 60
<< 1 * 3600 << 2 * 3600 << 3 * 3600 << 6 * 3600 << 12 * 3600 << 24 * 3600;
// pick available step that is most appropriate to approximate ideal step:
result = pickClosest(result, availableSteps);
}
else // more than a day, go back to normal clean mantissa algorithm but in units of days
{
const double secondsPerDay = 3600 * 24;
result = cleanMantissa(result / secondsPerDay) * secondsPerDay;
}
return result;
}
int QCPAxisTickerMsecTime::getSubTickCount(double tickStep)
{
int result = QCPAxisTicker::getSubTickCount(tickStep);
switch (qRound(tickStep)) // hand chosen subticks for specific minute/hour/day range (as specified in getTickStep)
{
case 5 * 60: result = 4; break;
case 10 * 60: result = 1; break;
case 15 * 60: result = 2; break;
case 30 * 60: result = 1; break;
case 60 * 60: result = 3; break;
case 3600 * 2: result = 3; break;
case 3600 * 3: result = 2; break;
case 3600 * 6: result = 1; break;
case 3600 * 12: result = 3; break;
case 3600 * 24: result = 3; break;
}
return result;
}
QString QCPAxisTickerMsecTime::getTickLabel(double tick, const QLocale& locale, QChar formatChar, int precision)
{
Q_UNUSED(precision)
Q_UNUSED(formatChar)
Q_UNUSED(locale)
bool negative = tick < 0;
if (negative) tick *= -1;
QString result = QDateTime::fromMSecsSinceEpoch(tick).toString(mTimeFormat);
if (negative)
result.prepend(QLatin1Char('-'));
return result;
}
最后
以上就是凶狠草莓为你收集整理的qcustomplot 自定义毫秒时间轴的全部内容,希望文章能够帮你解决qcustomplot 自定义毫秒时间轴所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复