转载自: https://www.freesion.com/article/253183141/
由于项目需要,实现天气预报的曲线绘制功能,进而学习了QCustomPlot的第三方控件,这里浅尝辄止的分享一下自己对QCPAxisTicker坐标轴类的使用,先上图看QCPAxisTicker的几种用法:
一、QCPAXISTICKER基类
QCPAxisTicker是坐标轴的基类,它的属性和方法如下,其中有刻度轴步长显示策略TickStepStrategy的枚举类型,可参考此篇文章QCustomplot使用分享(六) 坐标轴和网格线:
-
class QCPAxisTicker
-
{
-
public:
-
/*!
-
定义选择坐标轴步长策略
-
*/
-
enum TickStepStrategy
-
{
-
tssReadability //具有更好可读性的(由系统分配)刻度步长匹配优先于自定义分配刻度数目匹配
-
,tssMeetTickCount //使用setTickCount()函数设置用户自定义的刻度数目
-
};
-
// getters:
-
TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; }//获得刻度匹配策略
-
int tickCount() const { return mTickCount; }//返回刻度数
-
double tickOrigin() const { return mTickOrigin; }//获得起点坐标偏移量
-
// setters:
-
void setTickStepStrategy(TickStepStrategy strategy);//设置刻度匹配策略
-
void setTickCount(int count);//设置刻度数目
-
void setTickOrigin(double origin);//设置起点坐标偏移量
-
// introduced virtual methods:虚函数自定义生成坐标刻度
-
virtua void generate(const QCPRange &range, const QLocale &locale, QChar formatChar,
-
int precision, QVector<double> &ticks, QVector<double> *subTicks, QVector<QString> *tickLabels);
-
protected:
-
// property members:
-
TickStepStrategy mTickStepStrategy;
-
int mTickCount;
-
double mTickOrigin;
-
// introduced virtual methods:
-
virtual double getTickStep(const QCPRange &range);//获得轴范围内刻度间距
-
virtual int getSubTickCount(double tickStep);//一个大刻度间距中子刻度的数目
-
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision);//获得刻度向量
-
virtual QVector<double> createTickVector(double tickStep, const QCPRange &range);//生成刻度向量
-
virtual QVector<double> createSubTickVector(int subTickCount, const QVector<double> &ticks);//生成子刻度向量
-
//生成刻度标签向量
-
virtual QVector<QString> createLabelVector(const QVector<double> &ticks,
-
const QLocale &locale, QChar formatChar, int precision);
-
// non-virtual methods:
-
//trimTicks()从指定范围之外的刻中移除刻度坐标,如果keepOneOutlier==true,则在保留的刻度范围两边保留刻度标记
-
void trimTicks(const QCPRange &range, QVector<double> &ticks, bool keepOneOutlier) const;
-
//pickClosest()返回包含在与所提供的目标最接近的候选坐标,此方法假定候选者不是空的,按升序排序
-
double pickClosest(double target, const QVector<double> &candidates) const;
-
//getMantissa()返回输入的十进制尾数,例如142.6的输入将返回尾数1.426和100的大小。
-
double getMantissa(double input, double *magnitude=0) const;
-
//cleanMantissa()返回一个接近输入的数字,它有一个更简单的人类可读尾数
-
double cleanMantissa(double input) const;
-
};
二、 QCPAXISTICKERDATETIME
1.QCPAXISTICKERDATETIME类是日期时间坐标轴
关于日期时间可看我前一篇Qt由入门到放弃-QDate、QTime、QDateTime的相关函数,具体方法如下所示:
-
class QCPAxisTickerDateTime : public QCPAxisTicker
-
{
-
public:
-
// getters:
-
QString dateTimeFormat();//获得日期显示格式
-
Qt::TimeSpec dateTimeSpec();//获得时区
-
// setters:
-
void setDateTimeFormat(const QString &format);//设置时间显示格式
-
void setDateTimeSpec(Qt::TimeSpec spec);//设置时区
-
void setTickOrigin(double origin);
-
void setTickOrigin(const QDateTime &origin);
-
// static methods:
-
static QDateTime keyToDateTime(double key);//时间戳转成日期
-
static double dateTimeToKey(const QDateTime dateTime);//日期转成时间戳秒
-
static double dateTimeToKey(const QDate date);//日期转成时间戳秒
-
protected:
-
// property members:
-
QString mDateTimeFormat;//格式化时间
-
Qt::TimeSpec mDateTimeSpec;//时区
-
// non-property members:
-
enum DateStrategy //设置刻度策略
-
{
-
dsNone //刻度不设置间距,默认大于等于一秒
-
, dsUniformTimeInDay //刻度间距大于等于一天
-
, dsUniformDayInMonth //刻度间距大于等于一月
-
} mDateStrategy;
-
// reimplemented virtual methods:
-
virtual double getTickStep(const QCPRange &range);
-
virtual int getSubTickCount(double tickStep) ;
-
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) ;
-
virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) ;
-
};
2.据此实现了一个小例子:
-
void setupTestQCPAxisTickerDateTime()
-
{
-
customPlot->setInteraction(QCP::iRangeDrag, true);
-
customPlot->setInteraction(QCP::iRangeZoom, true);
-
QDateTime dateTime = QDateTime::currentDateTime();
-
double now = dateTime.toTime_t();//当前时间转化为秒
-
//生成时间刻度对象
-
QSharedPointer<QCPAxisTickerDateTime> dateTimeTicker(new QCPAxisTickerDateTime);
-
customPlot->xAxis->setTicker(dateTimeTicker);
-
//dateTimeTicker->setDateTimeSpec(Qt::UTC);//设施世界时间,即不加上时区的时间
-
dateTimeTicker->setTickCount(12);
-
dateTimeTicker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);
-
customPlot->xAxis->setSubTicks(false);
-
customPlot->xAxis->setRange(now, now+3600*24);//x轴范围,从当前时间起往后推24小时
-
QVector<double> yData, xData;//生成数据
-
for (int i = 0; i <= 24; i++)
-
{
-
xData.push_back(now + i * 3600.0);
-
yData.push_back(pow(double(i), 2) + 550.0*sin(double(i)/4.0));
-
}
-
dateTimeTicker->setDateTimeFormat("yyyy-M-d h:m");//设置x轴刻度显示格式
-
customPlot->xAxis->setTickLabelRotation(30);//设置刻度标签顺时针旋转30度
-
customPlot->yAxis->setRange(-1000,10000);
-
customPlot->addGraph();
-
customPlot->graph(0)->setData(xData, yData);//显示数据
-
}
3.运行结果图:
4.分析
QCPAxisTickerDateTime坐标轴默认是从时间戳起点即1970-1-1 0:0:0开始,以秒为单位进行刻度划分, 以下前两行代码为核心,获取当前秒数,通过第三行代码来设置时间范围。
-
QDateTime dateTime = QDateTime::currentDateTime();
-
double now = dateTime.toTime_t();//当前时间转化为秒
-
customPlot->xAxis->setRange(now, now+3600*24);//x轴范围,从当前时间起往后推24小时
三、QCPAXISTICKERTIME
1.QCPAXISTICKERTIME是时间轴刻度类
-
class QCPAxisTickerTime : public QCPAxisTicker
-
{
-
public:
-
enum TimeUnit { tuMilliseconds ///< 毫秒(%z 在setTimeFormat中设置)
-
,tuSeconds ///< 秒 (%s)
-
,tuMinutes ///< 分钟 (%m)
-
,tuHours ///< 小时 (%h)
-
,tuDays ///< 天 (%d)
-
};
-
// getters:
-
QString timeFormat();//获得时间显示格式
-
int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); }
-
// setters:
-
void setTimeFormat(const QString &format);
-
void setFieldWidth(TimeUnit unit, int width);//设置刻度间距宽度
-
protected:
-
// property members:
-
QString mTimeFormat;//时间格式化字符串
-
QHash<TimeUnit, int> mFieldWidth;//时间宽度格式
-
// non-property members:
-
//最小的单位,最大的单位(如定义mSmallestUnit(tuSeconds),mBiggestUnit(tuHours))
-
TimeUnit mSmallestUnit, mBiggestUnit;
-
QHash<TimeUnit, QString> mFormatPattern;
-
// reimplemented virtual methods:
-
virtual double getTickStep(const QCPRange &range) ;
-
virtual int getSubTickCount(double tickStep) ;
-
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) ;
-
//对特定的值value用指定文本text替换时间单位
-
void replaceUnit(QString &text, TimeUnit unit, int value) const;
-
};
2.据此实现了一个小例子:
-
void MainWindow::setupTestQCPAxisTickerTime()
-
{
-
customPlot->setInteraction(QCP::iRangeDrag, true);
-
customPlot->setInteraction(QCP::iRangeZoom, true);
-
customPlot->rescaleAxes();
-
QDateTime dateTime = QDateTime::currentDateTime();
-
QString dataString = dateTime.toString("yyyy:M:dd:hh:mm:ss");
-
qDebug()<<"*********"<<dataString;
-
int hours = dateTime.time().hour();//获取当前的小时数
-
QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
-
customPlot->xAxis->setTicker(timeTicker);
-
timeTicker->setTickCount(6);
-
//设置刻度表示策略
-
timeTicker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);
-
customPlot->xAxis->setSubTicks(false);
-
timeTicker->setTickOrigin(3600*3);//x轴起点坐标加3小时,即从当前hours+3开始
-
customPlot->xAxis->setRange(hours*3600, hours*3600 +3600*12);
-
customPlot->yAxis->setRange(-1000,1000);
-
timeTicker->setTimeFormat("%dday-%hhour");
-
QVector<double> yData, xData;
-
for (int i = 0; i <= 24; i++){
-
xData.push_back(hours*3600 + i * 3600);
-
yData.push_back(pow(double(i), 2) + 550.0*sin(double(i)/4.0));
-
}
-
customPlot->addGraph();
-
customPlot->graph(0)->setData(xData, yData);
-
}
3.运行结果图:
4.分析
时间可以以毫秒、秒、分钟、小时和天显示。取决于通过setTimeFormat函数定义的最大可用单位,超过最大单位的。例如,如果格式字符串为"%M:%s",则为坐标值7815(2小时,10分钟和15秒)被创建,得到的刻度标签将显示"130:15"(130分钟,15秒)。如果格式字符串为"%H:%M:%s",则为"小时"。单位将被使用,标签将是“2:10:15”。
四、QCPAXISTICKERTEXT
1.QCPAXISTICKERTEXT是文本刻度标签
-
/*
-
设置文本刻度标签
-
*/
-
class QCPAxisTickerText : public QCPAxisTicker
-
{
-
public:
-
// getters:
-
QMap<double, QString> &ticks();//获得坐标轴标签
-
int subTickCount();//获得子刻度数目
-
// setters:
-
void setTicks(const QMap<double, QString> &ticks);//坐标轴标签添加坐标轴
-
void setTicks(const QVector<double> &positions, const QVector<QString> labels);//坐标轴标签添加坐标轴
-
void setSubTickCount(int subTicks);//设置子刻度数目
-
// non-virtual methods:
-
void clear();
-
//addTick()坐标轴添加文本标签三种形式
-
void addTick(double position, QString label);
-
void addTicks(const QMap<double, QString> &ticks);
-
void addTicks(const QVector<double> &positions, const QVector<QString> &labels);
-
protected:
-
// property members:
-
QMap<double, QString> mTicks;//坐标轴标签
-
int mSubTickCount;//子刻度数目
-
// reimplemented virtual methods:
-
virtual double getTickStep(const QCPRange &range) ;
-
virtual int getSubTickCount(double tickStep) ;
-
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) ;
-
virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) ;
-
};
2.据此实现了一个小例子:
-
void MainWindow::setupTestQCPAxisTickerText()
-
{
-
//画柱状图
-
QCPBars *regen = new QCPBars(customPlot->xAxis, customPlot->yAxis);
-
regen->setAntialiased(false); // gives more crisp, pixel aligned bar borders
-
regen->setStackingGap(1);
-
regen->setName("Regenerative");
-
regen->setPen(QPen(QColor(0, 168, 140).lighter(130)));
-
regen->setBrush(QColor(0, 168, 140));
-
// stack bars on top of each other:
-
// regen->moveAbove(nuclear);
-
QVector<double> ticks;
-
QVector<QString> labels;
-
ticks << 1 << 2 << 3 << 4 << 5 << 6 << 7;
-
labels << "USA" << "Japan" << "Germany" << "France" << "UK" << "Italy" << "Canada";
-
QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);
-
textTicker->addTicks(ticks, labels);
-
customPlot->xAxis->setTicker(textTicker);
-
customPlot->xAxis->setTickLabelRotation(60);
-
customPlot->xAxis->setSubTicks(false);
-
customPlot->xAxis->setTickLength(0, 4);
-
customPlot->xAxis->setRange(0, 8);
-
customPlot->xAxis->setTickPen(QPen(Qt::white));
-
// prepare y axis:
-
customPlot->yAxis->setRange(0, 12.1);
-
customPlot->yAxis->setPadding(5); // a bit more space to the left border
-
customPlot->yAxis->setLabel("Power Consumption in\nKilowatts per Capita (2007)");
-
//customPlot->yAxis->setBasePen(QPen(Qt::white));
-
customPlot->yAxis->setTickPen(QPen(Qt::white));
-
customPlot->yAxis->setSubTickPen(QPen(Qt::white));
-
// Add data:
-
QVector<double> regenData;
-
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;
-
regen->setData(ticks, regenData);
-
}
3.运行结果图:
五、QCPAXISTICKERPI
1.QCPAXISTICKERPI设置PI刻度标签
-
class QCPAxisTickerPi : public QCPAxisTicker
-
{
-
public:
-
enum FractionStyle { fsFloatingPoint //分数被显示为规则十进制浮点数,例如“0.25”或“0.125”
-
,fsAsciiFractions //分数是用ASCII字符写成的有理数,例如“1/4”或“1/8”
-
,fsUnicodeFractions //分数使用子和上标UTF-8数字和分数符号来编写
-
};
-
QString piSymbol() const { return mPiSymbol; }//返回代替PI的符号标志
-
double piValue() const { return mPiValue; }//返回PI表示的值
-
bool periodicity() const { return mPeriodicity; }//是否周期性地出现
-
FractionStyle fractionStyle() const { return mFractionStyle; }//轴上数据分数显示风格
-
void setPiSymbol(QString symbol);//设置PI符号位的用symbol代替显示
-
void setPiValue(double pi);//设置PI表示的值,不指定PI表示默认值3.1415926....
-
//setPeriodicity()设置轴标签是否周期性地出现
-
//若要禁用周期性,将multiplesOfPi设置为0。例如将轴定义0到2PI的周期则会将multiplesOfPi设置为2
-
void setPeriodicity(int multiplesOfPi);
-
//设置轴的分数显示形式
-
void setFractionStyle(FractionStyle style);
-
protected:
-
QString mPiSymbol;
-
double mPiValue;
-
int mPeriodicity;
-
FractionStyle mFractionStyle;
-
double mPiTickStep; // size of one tick step in units of mPiValue
-
virtual double getTickStep(const QCPRange &range) ;
-
virtual int getSubTickCount(double tickStep) ;
-
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) ;
-
void simplifyFraction(int &numerator, int &denominator) const;//对给定的分子numerator,分母denominator化成最简真分数
-
QString fractionToString(int numerator, int denominator) const;//转成字符串
-
QString unicodeFraction(int numerator, int denominator) const;//转成unicode编码
-
QString unicodeSuperscript(int number) const;//返回表示数字为上标的Unicode字符串
-
QString unicodeSubscript(int number) const;//返回表示数字为下标的Unicode字符串
-
};
2.据此实现了一个小例子:
-
void MainWindow::setupTestQCPAxisTickerPi()
-
{
-
QSharedPointer<QCPAxisTickerPi> pITicker(new QCPAxisTickerPi());
-
customPlot->xAxis->setTicker(pITicker);
-
//pITicker->setPeriodicity(2);
-
//pITicker->setPiSymbol("--");
-
pITicker->setFractionStyle(QCPAxisTickerPi::fsUnicodeFractions);
-
pITicker->setPiValue(3.1415*2);//设置pi表示的值
-
customPlot->xAxis->setRange(0, 3.0*M_PI);
-
customPlot->xAxis->setVisible(true);
-
QVector<double> x2(250), y2(250);
-
for (int i=0; i<250; ++i) // data for graphs 2, 3 and 4
-
{
-
x2[i] = i/250.0*3*M_PI;
-
y2[i] = qSin(x2[i]+ M_PI) + M_PI;
-
}
-
customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);
-
customPlot->graph(0)->setData(x2, y2);
-
}
3.运行结果图:
六、QCPAXISTICKERLOG
1.QCPAXISTICKERLOG设置LOG对数刻度标签
-
class QCPAxisTickerLog : public QCPAxisTicker
-
{
-
public:
-
QCPAxisTickerLog();
-
double logBase() const { return mLogBase; }
-
int subTickCount() const { return mSubTickCount; }
-
void setLogBase(double base);//设置对数的基数值
-
void setSubTickCount(int subTicks);//设置子刻度数目
-
protected:
-
double mLogBase;
-
int mSubTickCount;
-
double mLogBaseLnInv;
-
virtual double getTickStep(const QCPRange &range) ;
-
virtual int getSubTickCount(double tickStep) ;
-
virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) ;
-
};
2.据此实现了一个小例子:
-
void MainWindow::setupTestQCPAxisTickerLog()
-
{
-
QSharedPointer<QCPAxisTickerLog> logTicker(new QCPAxisTickerLog);
-
customPlot->xAxis->setTicker(logTicker);
-
// don't forget to also set the scale type accordingly, otherwise you'll have
-
// logarithmically spaced ticks on a linear axis:
-
customPlot->xAxis->setScaleType(QCPAxis::stLogarithmic);
-
customPlot->xAxis->setRange(0,250);
-
logTicker->setLogBase(10);
-
QVector<double> x2(250), y2(250);
-
for (int i=0; i<250; ++i) // data for graphs 2, 3 and 4
-
{
-
x2[i] = i;
-
y2[i] = log(i);
-
}
-
customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);
-
customPlot->graph(0)->setData(x2, y2);
-
}
3.运行结果图:
七、QCPAXISTICKERFIXED
1.QCPAXISTICKERFIXED定义轴标尺修改指定的步长控制坐标轴刻度的数目
-
class QCPAxisTickerFixed : public QCPAxisTicker
-
{
-
public:
-
enum ScaleStrategy { ssNone //固定刻度,不允许修改
-
,ssMultiples //设置刻度间距为整数倍长度
-
,ssPowers //设置刻度间距为指数倍长度
-
};
-
// getters:
-
double tickStep() const { return mTickStep; }
-
ScaleStrategy scaleStrategy() const { return mScaleStrategy; }
-
// setters:
-
void setTickStep(double step);
-
void setScaleStrategy(ScaleStrategy strategy);
-
protected:
-
// property members:
-
double mTickStep;
-
ScaleStrategy mScaleStrategy;
-
// reimplemented virtual methods:
-
virtual double getTickStep(const QCPRange &range) ;
-
};