2020-09-12

转载自: https://www.freesion.com/article/253183141/

由于项目需要,实现天气预报的曲线绘制功能,进而学习了QCustomPlot的第三方控件,这里浅尝辄止的分享一下自己对QCPAxisTicker坐标轴类的使用,先上图看QCPAxisTicker的几种用法:

一、QCPAXISTICKER基类

QCPAxisTicker是坐标轴的基类,它的属性和方法如下,其中有刻度轴步长显示策略TickStepStrategy的枚举类型,可参考此篇文章QCustomplot使用分享(六) 坐标轴和网格线

 
  1. class QCPAxisTicker

  2. {

  3.  
  4. public:

  5. /*!

  6. 定义选择坐标轴步长策略

  7. */

  8. enum TickStepStrategy

  9. {

  10. tssReadability //具有更好可读性的(由系统分配)刻度步长匹配优先于自定义分配刻度数目匹配

  11. ,tssMeetTickCount //使用setTickCount()函数设置用户自定义的刻度数目

  12. };

  13. // getters:

  14. TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; }//获得刻度匹配策略

  15. int tickCount() const { return mTickCount; }//返回刻度数

  16. double tickOrigin() const { return mTickOrigin; }//获得起点坐标偏移量

  17. // setters:

  18. void setTickStepStrategy(TickStepStrategy strategy);//设置刻度匹配策略

  19. void setTickCount(int count);//设置刻度数目

  20. void setTickOrigin(double origin);//设置起点坐标偏移量

  21. // introduced virtual methods:虚函数自定义生成坐标刻度

  22. virtua void generate(const QCPRange &range, const QLocale &locale, QChar formatChar,

  23. int precision, QVector<double> &ticks, QVector<double> *subTicks, QVector<QString> *tickLabels);

  24.  
  25. protected:

  26. // property members:

  27. TickStepStrategy mTickStepStrategy;

  28. int mTickCount;

  29. double mTickOrigin;

  30.  
  31. // introduced virtual methods:

  32. virtual double getTickStep(const QCPRange &range);//获得轴范围内刻度间距

  33. virtual int getSubTickCount(double tickStep);//一个大刻度间距中子刻度的数目

  34. virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision);//获得刻度向量

  35. virtual QVector<double> createTickVector(double tickStep, const QCPRange &range);//生成刻度向量

  36. virtual QVector<double> createSubTickVector(int subTickCount, const QVector<double> &ticks);//生成子刻度向量

  37. //生成刻度标签向量

  38. virtual QVector<QString> createLabelVector(const QVector<double> &ticks,

  39. const QLocale &locale, QChar formatChar, int precision);

  40.  
  41. // non-virtual methods:

  42. //trimTicks()从指定范围之外的刻中移除刻度坐标,如果keepOneOutlier==true,则在保留的刻度范围两边保留刻度标记

  43. void trimTicks(const QCPRange &range, QVector<double> &ticks, bool keepOneOutlier) const;

  44. //pickClosest()返回包含在与所提供的目标最接近的候选坐标,此方法假定候选者不是空的,按升序排序

  45. double pickClosest(double target, const QVector<double> &candidates) const;

  46. //getMantissa()返回输入的十进制尾数,例如142.6的输入将返回尾数1.426和100的大小。

  47. double getMantissa(double input, double *magnitude=0) const;

  48. //cleanMantissa()返回一个接近输入的数字,它有一个更简单的人类可读尾数

  49. double cleanMantissa(double input) const;

  50. };

二、 QCPAXISTICKERDATETIME

1.QCPAXISTICKERDATETIME类是日期时间坐标轴

关于日期时间可看我前一篇Qt由入门到放弃-QDate、QTime、QDateTime的相关函数,具体方法如下所示:

 
  1. class QCPAxisTickerDateTime : public QCPAxisTicker

  2. {

  3. public:

  4.  
  5. // getters:

  6. QString dateTimeFormat();//获得日期显示格式

  7. Qt::TimeSpec dateTimeSpec();//获得时区

  8.  
  9. // setters:

  10. void setDateTimeFormat(const QString &format);//设置时间显示格式

  11. void setDateTimeSpec(Qt::TimeSpec spec);//设置时区

  12. void setTickOrigin(double origin);

  13. void setTickOrigin(const QDateTime &origin);

  14.  
  15. // static methods:

  16. static QDateTime keyToDateTime(double key);//时间戳转成日期

  17. static double dateTimeToKey(const QDateTime dateTime);//日期转成时间戳秒

  18. static double dateTimeToKey(const QDate date);//日期转成时间戳秒

  19.  
  20. protected:

  21. // property members:

  22. QString mDateTimeFormat;//格式化时间

  23. Qt::TimeSpec mDateTimeSpec;//时区

  24.  
  25. // non-property members:

  26. enum DateStrategy //设置刻度策略

  27. {

  28. dsNone //刻度不设置间距,默认大于等于一秒

  29. , dsUniformTimeInDay //刻度间距大于等于一天

  30. , dsUniformDayInMonth //刻度间距大于等于一月

  31. } mDateStrategy;

  32.  
  33. // reimplemented virtual methods:

  34. virtual double getTickStep(const QCPRange &range);

  35. virtual int getSubTickCount(double tickStep) ;

  36. virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) ;

  37. virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) ;

  38. };

2.据此实现了一个小例子:

 
  1. void setupTestQCPAxisTickerDateTime()

  2. {

  3. customPlot->setInteraction(QCP::iRangeDrag, true);

  4. customPlot->setInteraction(QCP::iRangeZoom, true);

  5. QDateTime dateTime = QDateTime::currentDateTime();

  6. double now = dateTime.toTime_t();//当前时间转化为秒

  7. //生成时间刻度对象

  8. QSharedPointer<QCPAxisTickerDateTime> dateTimeTicker(new QCPAxisTickerDateTime);

  9. customPlot->xAxis->setTicker(dateTimeTicker);

  10. //dateTimeTicker->setDateTimeSpec(Qt::UTC);//设施世界时间,即不加上时区的时间

  11. dateTimeTicker->setTickCount(12);

  12. dateTimeTicker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);

  13. customPlot->xAxis->setSubTicks(false);

  14. customPlot->xAxis->setRange(now, now+3600*24);//x轴范围,从当前时间起往后推24小时

  15. QVector<double> yData, xData;//生成数据

  16. for (int i = 0; i <= 24; i++)

  17. {

  18. xData.push_back(now + i * 3600.0);

  19. yData.push_back(pow(double(i), 2) + 550.0*sin(double(i)/4.0));

  20. }

  21. dateTimeTicker->setDateTimeFormat("yyyy-M-d h:m");//设置x轴刻度显示格式

  22. customPlot->xAxis->setTickLabelRotation(30);//设置刻度标签顺时针旋转30度

  23. customPlot->yAxis->setRange(-1000,10000);

  24. customPlot->addGraph();

  25. customPlot->graph(0)->setData(xData, yData);//显示数据

  26. }

3.运行结果图:

4.分析

QCPAxisTickerDateTime坐标轴默认是从时间戳起点即1970-1-1 0:0:0开始,以秒为单位进行刻度划分, 以下前两行代码为核心,获取当前秒数,通过第三行代码来设置时间范围。

 
  1. QDateTime dateTime = QDateTime::currentDateTime();

  2. double  now = dateTime.toTime_t();//当前时间转化为秒

  3. customPlot->xAxis->setRange(now, now+3600*24);//x轴范围,从当前时间起往后推24小时

三、QCPAXISTICKERTIME

1.QCPAXISTICKERTIME是时间轴刻度类

 
  1. class QCPAxisTickerTime : public QCPAxisTicker

  2. {

  3.  
  4. public:

  5.  
  6. enum TimeUnit { tuMilliseconds ///< 毫秒(%z 在setTimeFormat中设置)

  7. ,tuSeconds ///< 秒 (%s)

  8. ,tuMinutes ///< 分钟 (%m)

  9. ,tuHours ///< 小时 (%h)

  10. ,tuDays ///< 天 (%d)

  11. };

  12. // getters:

  13. QString timeFormat();//获得时间显示格式

  14. int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); }

  15.  
  16. // setters:

  17. void setTimeFormat(const QString &format);

  18. void setFieldWidth(TimeUnit unit, int width);//设置刻度间距宽度

  19.  
  20. protected:

  21. // property members:

  22. QString mTimeFormat;//时间格式化字符串

  23. QHash<TimeUnit, int> mFieldWidth;//时间宽度格式

  24.  
  25. // non-property members:

  26. //最小的单位,最大的单位(如定义mSmallestUnit(tuSeconds),mBiggestUnit(tuHours))

  27. TimeUnit mSmallestUnit, mBiggestUnit;

  28. QHash<TimeUnit, QString> mFormatPattern;

  29.  
  30. // reimplemented virtual methods:

  31. virtual double getTickStep(const QCPRange &range) ;

  32. virtual int getSubTickCount(double tickStep) ;

  33. virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) ;

  34. //对特定的值value用指定文本text替换时间单位

  35. void replaceUnit(QString &text, TimeUnit unit, int value) const;

  36. };

2.据此实现了一个小例子:

 
  1. void MainWindow::setupTestQCPAxisTickerTime()

  2. {

  3.  
  4. customPlot->setInteraction(QCP::iRangeDrag, true);

  5. customPlot->setInteraction(QCP::iRangeZoom, true);

  6. customPlot->rescaleAxes();

  7.  
  8. QDateTime dateTime = QDateTime::currentDateTime();

  9. QString dataString = dateTime.toString("yyyy:M:dd:hh:mm:ss");

  10. qDebug()<<"*********"<<dataString;

  11. int hours = dateTime.time().hour();//获取当前的小时数

  12.  
  13. QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);

  14. customPlot->xAxis->setTicker(timeTicker);

  15. timeTicker->setTickCount(6);

  16. //设置刻度表示策略

  17. timeTicker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);

  18. customPlot->xAxis->setSubTicks(false);

  19. timeTicker->setTickOrigin(3600*3);//x轴起点坐标加3小时,即从当前hours+3开始

  20. customPlot->xAxis->setRange(hours*3600, hours*3600 +3600*12);

  21. customPlot->yAxis->setRange(-1000,1000);

  22. timeTicker->setTimeFormat("%dday-%hhour");

  23.  
  24. QVector<double> yData, xData;

  25. for (int i = 0; i <= 24; i++){

  26. xData.push_back(hours*3600 + i * 3600);

  27. yData.push_back(pow(double(i), 2) + 550.0*sin(double(i)/4.0));

  28. }

  29. customPlot->addGraph();

  30. customPlot->graph(0)->setData(xData, yData);

  31.  
  32. }

3.运行结果图:

4.分析

时间可以以毫秒、秒、分钟、小时和天显示。取决于通过setTimeFormat函数定义的最大可用单位,超过最大单位的。例如,如果格式字符串为"%M:%s",则为坐标值7815(2小时,10分钟和15秒)被创建,得到的刻度标签将显示"130:15"(130分钟,15秒)。如果格式字符串为"%H:%M:%s",则为"小时"。单位将被使用,标签将是“2:10:15”。

四、QCPAXISTICKERTEXT

1.QCPAXISTICKERTEXT是文本刻度标签

 
  1. /*

  2. 设置文本刻度标签

  3. */

  4. class QCPAxisTickerText : public QCPAxisTicker

  5. {

  6. public:

  7.  
  8. // getters:

  9. QMap<double, QString> &ticks();//获得坐标轴标签

  10. int subTickCount();//获得子刻度数目

  11.  
  12. // setters:

  13. void setTicks(const QMap<double, QString> &ticks);//坐标轴标签添加坐标轴

  14. void setTicks(const QVector<double> &positions, const QVector<QString> labels);//坐标轴标签添加坐标轴

  15. void setSubTickCount(int subTicks);//设置子刻度数目

  16.  
  17. // non-virtual methods:

  18. void clear();

  19. //addTick()坐标轴添加文本标签三种形式

  20. void addTick(double position, QString label);

  21. void addTicks(const QMap<double, QString> &ticks);

  22. void addTicks(const QVector<double> &positions, const QVector<QString> &labels);

  23.  
  24. protected:

  25. // property members:

  26. QMap<double, QString> mTicks;//坐标轴标签

  27. int mSubTickCount;//子刻度数目

  28.  
  29. // reimplemented virtual methods:

  30. virtual double getTickStep(const QCPRange &range) ;

  31. virtual int getSubTickCount(double tickStep) ;

  32. virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) ;

  33. virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) ;

  34.  
  35. };

2.据此实现了一个小例子:

 
  1. void MainWindow::setupTestQCPAxisTickerText()

  2. {

  3. //画柱状图

  4. QCPBars *regen = new QCPBars(customPlot->xAxis, customPlot->yAxis);

  5. regen->setAntialiased(false); // gives more crisp, pixel aligned bar borders

  6. regen->setStackingGap(1);

  7. regen->setName("Regenerative");

  8. regen->setPen(QPen(QColor(0, 168, 140).lighter(130)));

  9. regen->setBrush(QColor(0, 168, 140));

  10. // stack bars on top of each other:

  11. // regen->moveAbove(nuclear);

  12. QVector<double> ticks;

  13. QVector<QString> labels;

  14. ticks << 1 << 2 << 3 << 4 << 5 << 6 << 7;

  15. labels << "USA" << "Japan" << "Germany" << "France" << "UK" << "Italy" << "Canada";

  16. QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);

  17. textTicker->addTicks(ticks, labels);

  18. customPlot->xAxis->setTicker(textTicker);

  19. customPlot->xAxis->setTickLabelRotation(60);

  20. customPlot->xAxis->setSubTicks(false);

  21. customPlot->xAxis->setTickLength(0, 4);

  22. customPlot->xAxis->setRange(0, 8);

  23. customPlot->xAxis->setTickPen(QPen(Qt::white));

  24.  
  25. // prepare y axis:

  26. customPlot->yAxis->setRange(0, 12.1);

  27. customPlot->yAxis->setPadding(5); // a bit more space to the left border

  28. customPlot->yAxis->setLabel("Power Consumption in\nKilowatts per Capita (2007)");

  29. //customPlot->yAxis->setBasePen(QPen(Qt::white));

  30. customPlot->yAxis->setTickPen(QPen(Qt::white));

  31. customPlot->yAxis->setSubTickPen(QPen(Qt::white));

  32. // Add data:

  33. QVector<double> regenData;

  34. regenData << 0.06*10.5 << 0.05*5.5 << 0.04*5.5 << 0.06*5.8 << 0.02*5.2 << 0.07*4.2 << 0.25*11.2;

  35. regen->setData(ticks, regenData);

  36.  
  37. }

3.运行结果图:

五、QCPAXISTICKERPI

1.QCPAXISTICKERPI设置PI刻度标签

 
  1. class QCPAxisTickerPi : public QCPAxisTicker

  2. {

  3.  
  4. public:

  5.  
  6. enum FractionStyle { fsFloatingPoint //分数被显示为规则十进制浮点数,例如“0.25”或“0.125”

  7. ,fsAsciiFractions //分数是用ASCII字符写成的有理数,例如“1/4”或“1/8”

  8. ,fsUnicodeFractions //分数使用子和上标UTF-8数字和分数符号来编写

  9. };

  10.  
  11. QString piSymbol() const { return mPiSymbol; }//返回代替PI的符号标志

  12. double piValue() const { return mPiValue; }//返回PI表示的值

  13. bool periodicity() const { return mPeriodicity; }//是否周期性地出现

  14. FractionStyle fractionStyle() const { return mFractionStyle; }//轴上数据分数显示风格

  15.  
  16. void setPiSymbol(QString symbol);//设置PI符号位的用symbol代替显示

  17. void setPiValue(double pi);//设置PI表示的值,不指定PI表示默认值3.1415926....

  18. //setPeriodicity()设置轴标签是否周期性地出现

  19. //若要禁用周期性,将multiplesOfPi设置为0。例如将轴定义0到2PI的周期则会将multiplesOfPi设置为2

  20. void setPeriodicity(int multiplesOfPi);

  21. //设置轴的分数显示形式

  22. void setFractionStyle(FractionStyle style);

  23.  
  24. protected:

  25. QString mPiSymbol;

  26. double mPiValue;

  27. int mPeriodicity;

  28. FractionStyle mFractionStyle;

  29.  
  30. double mPiTickStep; // size of one tick step in units of mPiValue

  31.  
  32. virtual double getTickStep(const QCPRange &range) ;

  33. virtual int getSubTickCount(double tickStep) ;

  34. virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) ;

  35.  
  36. void simplifyFraction(int &numerator, int &denominator) const;//对给定的分子numerator,分母denominator化成最简真分数

  37. QString fractionToString(int numerator, int denominator) const;//转成字符串

  38. QString unicodeFraction(int numerator, int denominator) const;//转成unicode编码

  39. QString unicodeSuperscript(int number) const;//返回表示数字为上标的Unicode字符串

  40. QString unicodeSubscript(int number) const;//返回表示数字为下标的Unicode字符串

  41. };

2.据此实现了一个小例子:

 
  1. void MainWindow::setupTestQCPAxisTickerPi()

  2. {

  3. QSharedPointer<QCPAxisTickerPi> pITicker(new QCPAxisTickerPi());

  4. customPlot->xAxis->setTicker(pITicker);

  5. //pITicker->setPeriodicity(2);

  6. //pITicker->setPiSymbol("--");

  7. pITicker->setFractionStyle(QCPAxisTickerPi::fsUnicodeFractions);

  8. pITicker->setPiValue(3.1415*2);//设置pi表示的值

  9. customPlot->xAxis->setRange(0, 3.0*M_PI);

  10. customPlot->xAxis->setVisible(true);

  11. QVector<double> x2(250), y2(250);

  12. for (int i=0; i<250; ++i) // data for graphs 2, 3 and 4

  13. {

  14. x2[i] = i/250.0*3*M_PI;

  15. y2[i] = qSin(x2[i]+ M_PI) + M_PI;

  16. }

  17. customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);

  18. customPlot->graph(0)->setData(x2, y2);

  19.  
  20. }

3.运行结果图:

六、QCPAXISTICKERLOG

1.QCPAXISTICKERLOG设置LOG对数刻度标签

 
  1. class QCPAxisTickerLog : public QCPAxisTicker

  2. {

  3. public:

  4. QCPAxisTickerLog();

  5.  
  6. double logBase() const { return mLogBase; }

  7. int subTickCount() const { return mSubTickCount; }

  8.  
  9. void setLogBase(double base);//设置对数的基数值

  10. void setSubTickCount(int subTicks);//设置子刻度数目

  11.  
  12. protected:

  13. double mLogBase;

  14. int mSubTickCount;

  15.  
  16. double mLogBaseLnInv;

  17.  
  18. virtual double getTickStep(const QCPRange &range) ;

  19. virtual int getSubTickCount(double tickStep) ;

  20. virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) ;

  21. };

2.据此实现了一个小例子:

 
  1. void MainWindow::setupTestQCPAxisTickerLog()

  2. {

  3. QSharedPointer<QCPAxisTickerLog> logTicker(new QCPAxisTickerLog);

  4. customPlot->xAxis->setTicker(logTicker);

  5. // don't forget to also set the scale type accordingly, otherwise you'll have

  6. // logarithmically spaced ticks on a linear axis:

  7. customPlot->xAxis->setScaleType(QCPAxis::stLogarithmic);

  8. customPlot->xAxis->setRange(0,250);

  9. logTicker->setLogBase(10);

  10. QVector<double> x2(250), y2(250);

  11. for (int i=0; i<250; ++i) // data for graphs 2, 3 and 4

  12. {

  13. x2[i] = i;

  14. y2[i] = log(i);

  15. }

  16. customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);

  17. customPlot->graph(0)->setData(x2, y2);

  18.  
  19. }

3.运行结果图:

七、QCPAXISTICKERFIXED

1.QCPAXISTICKERFIXED定义轴标尺修改指定的步长控制坐标轴刻度的数目

 
  1.  
  2. class QCPAxisTickerFixed : public QCPAxisTicker

  3. {

  4.  
  5. public:

  6.  
  7. enum ScaleStrategy { ssNone //固定刻度,不允许修改

  8. ,ssMultiples //设置刻度间距为整数倍长度

  9. ,ssPowers //设置刻度间距为指数倍长度

  10. };

  11.  
  12. // getters:

  13. double tickStep() const { return mTickStep; }

  14. ScaleStrategy scaleStrategy() const { return mScaleStrategy; }

  15.  
  16. // setters:

  17. void setTickStep(double step);

  18. void setScaleStrategy(ScaleStrategy strategy);

  19.  
  20. protected:

  21. // property members:

  22. double mTickStep;

  23. ScaleStrategy mScaleStrategy;

  24.  
  25. // reimplemented virtual methods:

  26. virtual double getTickStep(const QCPRange &range) ;

  27. };

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值