qcustomplot 自定义毫秒时间轴

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;
}

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值