文章目录

  • 一、概述
  • 二、历史版本对比
  • 三、坐标轴
  • 四、网格线
  • 五、简单的示例
  • 六、相关文章

一、概述

前边已经写了5篇对QCustomPlot的讲解,看过上述的几篇文章后,基本就能做一些简单的使用了,但是如果想要做到高度的控制图表,那么坐标轴将是很重要的一部分,因为坐标轴就是图表的一个参考系,没有了参考系那么一切都是天方夜谭。关于QCustomPlot的坐标轴我还是会按照之前的套路,首先对比1.3.2版本和2.0.0beta版本,然后在深入的去分析坐标轴使用。

二、历史版本对比

首先我需要和大家伙说明下,我个人觉着在QCustomPlot的定制过程中,坐标轴定制算是比较困难的,因为坐标轴如果要定制的话,那就是坐标轴的刻度需要自己计算,如果这个时候相关的业务逻辑也影响坐标轴的计算,那么就更难计算了,呵呵。。。或许大家伙可能也不会遇到这些问题,有兴趣的同学也可以自己思考下。

- 1.3.2版本 2.0.0版本
坐标轴 1、QCPAxis:坐标轴类,所有坐标轴功能都在这一个类总实现,包括:刻度计算和绘制文本 2、默认刻度自动计算,负责计算大刻度和小刻度 3、如果需要外部计算刻度则处理ticksRequest请求 1、QCPAxis:坐标轴类,所有坐标轴功能都在这一个类总实现,包括:刻度计算和绘制文本 2、默认刻度自动计算,负责计算大刻度和小刻度3、如果需要外部计算刻度则处理ticksRequest请求

下面我将针对2.0.0版本的坐标轴刻度计算来加以解释,为了方便起见,我只解释QCPAxisTicker这个坐标轴刻度计算基类,因为QCPAxis坐标轴默认使用的就是这个类,其余的坐标轴刻度计算类比如QCPAxisTickerDateTime、QCPAxisTickerTime、QCPAxisTickerFixed、QCPAxisTickerText、QCPAxisTickerPi和QCPAxisTickerLog等都是根据不同业务需求,重新实现了vitural相关方法。

三、坐标轴

1、QCPAxis,如下是QCPAxis的头文件,我从中删除了大量不需要注释的部分,但是很是剩下许多,为了写注释方便所以我没有把代码折叠,有兴趣的同学可以阅读下其中的中文注释,其实这个类仅仅是用来连接计算和绘制坐标轴的一个类,也可以说是暴露给使用者的一个导出类。

class QCP_LIB_DECL QCPAxis : public QCPLayerable
{enum AxisType {//坐标轴类型,在一个坐标轴矩形QCPAxisRect中包含左、上、右和下四条坐标轴atLeft = 0x01  ///< <tt>0x01</tt> Axis is vertical and on the left side of the axis rect, atRight = 0x02  ///< <tt>0x02</tt> Axis is vertical and on the right side of the axis rect, atTop = 0x04  ///< <tt>0x04</tt> Axis is horizontal and on the top side of the axis rect, atBottom = 0x08  ///< <tt>0x08</tt> Axis is horizontal and on the bottom side of the axis rect};enum LabelSide {//坐标轴刻度上的文本的位置,刻度线里or外lsInside    ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect, lsOutside  ///< Tick labels will be displayed outside the axis rect};enum ScaleType {//坐标轴类型,直线or对数线stLinear       ///< Linear scaling, stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance).};enum SelectablePart {/坐标轴可以被选中的部分spNone = 0      ///< None of the selectable parts, spAxis = 0x001  ///< The axis backbone and tick marks, spTickLabels = 0x002  ///< Tick labels (numbers) of this axis (as a whole, not individually), spAxisLabel = 0x004  ///< The axis label};explicit QCPAxis(QCPAxisRect *parent, AxisType type);virtual ~QCPAxis();//所有的get接口已经被我删除  看到对应的set接口,get接口的含义就不言而喻// setters:Q_SLOT void setScaleType(QCPAxis::ScaleType type);//设置坐标轴类型  直线or对数Q_SLOT void setRange(const QCPRange &range);//设置坐标轴范围void setRange(double lower, double upper); 33     void setTicker(QSharedPointer<QCPAxisTicker> ticker);//设置坐标轴计算刻度类,该参数是一个shared型智能指针,因此可以被多个坐标轴来同时使用void setTicks(bool show);//是否显示坐标轴,如果不显示坐标轴,那么网格线也就没有啦,因为没有了坐标轴刻度void setTickLabels(bool show);//是否显示坐标轴文本void setTickLabelPadding(int padding);//设置坐标走文本距离坐标轴线距离void setTickLabelFont(const QFont &font);//设置文本字体void setTickLabelColor(const QColor &color);//设置文本颜色void setTickLabelRotation(double degrees);//设置文本角度void setTickLabelSide(LabelSide side);//设置文本在刻度线里or外void setNumberFormat(const QString &formatCode);//设置文本格式void setNumberPrecision(int precision);//设置文本精度void setTickLength(int inside, int outside = 0);//设置大刻度高度void setTickLengthIn(int inside);//设置大刻度在里边长度void setTickLengthOut(int outside);//设置大刻度在外边长度void setSubTicks(bool show);//设置是否显示小刻度void setSubTickLength(int inside, int outside = 0);//设置小刻度高度void setSubTickLengthIn(int inside);//设置小刻度在坐标轴线里边长度void setSubTickLengthOut(int outside);//设置小刻度在坐标轴线外边长度void setBasePen(const QPen &pen);//设置基础线画笔  基础线是零线,即可以认为是坐标轴刻度为0的线void setTickPen(const QPen &pen);//设置大刻度画笔void setSubTickPen(const QPen &pen);//设置小刻度画笔void setLabelFont(const QFont &font);//设置坐标轴名称字体画笔void setLabelColor(const QColor &color);//设置坐标轴名称字体颜色void setLabel(const QString &str);//设置坐标轴名称文本void setLabelPadding(int padding);//设置坐标轴名称文本距离坐标轴刻度线距离void setPadding(int padding);//设置坐标轴距离边界距离void setOffset(int offset);//设置偏移量void setSelectedTickLabelFont(const QFont &font);//设置选中刻度文本时字体void setSelectedLabelFont(const QFont &font);//设置选中坐标轴名称时字体void setSelectedTickLabelColor(const QColor &color);//选中刻度文本时颜色void setSelectedLabelColor(const QColor &color);//选中坐标轴名称时颜色void setSelectedBasePen(const QPen &pen);//选中基础线时画笔void setSelectedTickPen(const QPen &pen);//选中大刻度时画笔void setSelectedSubTickPen(const QPen &pen);//选中小刻度时画笔Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts);//设置能选中项的类型Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts);void setLowerEnding(const QCPLineEnding &ending);//设置坐标轴小刻度端样式void setUpperEnding(const QCPLineEnding &ending);//坐标轴大刻度端样式 73 // non-property methods:Qt::Orientation orientation() const { return mOrientation; }//坐标轴朝向int pixelOrientation() const { return rangeReversed() != (orientation() == Qt::Vertical) ? -1 : 1; }void moveRange(double diff);//移动坐标轴void scaleRange(double factor);//按比例因子缩放void scaleRange(double factor, double center);//按范围缩放 81     void rescale(bool onlyVisiblePlottables = false);//重新适配坐标轴范围double pixelToCoord(double value) const;//像素到坐标轴坐标系double coordToPixel(double value) const;//坐标轴坐标系到像素 85     QList<QCPAbstractPlottable*> plottables() const;//所有的图QList<QCPGraph*> graphs() const;//所有的折线QList<QCPAbstractItem*> items() const;//所有的示意项 92
protected:AxisType mAxisType;//坐标轴类型QCPAxisRect *mAxisRect;//坐标轴所在矩形116 // non-property members:QCPGrid *mGrid;//网格120     QSharedPointer<QCPAxisTicker> mTicker;//坐标轴刻度计算类QVector<double> mTickVector;//大刻度QVector<QString> mTickVectorLabels;//大刻度文本QVector<double> mSubTickVector;//小刻度bool mCachedMarginValid;int mCachedMargin;// introduced virtual methods:virtual int calculateMargin();// reimplemented virtual methods:virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;//获取缺省的反锯齿属性virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;//画坐标轴virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;//选择策略137 // non-virtual methods:void setupTickVectors();//计算刻度QPen getBasePen() const;//获取基础画笔QPen getTickPen() const;//获取大刻度画笔QPen getSubTickPen() const;//获取小刻度画笔QFont getTickLabelFont() const;//获取刻度文本画笔QFont getLabelFont() const;//获取坐标轴名称文本字体QColor getTickLabelColor() const;//获取大刻度文本颜色QColor getLabelColor() const;..获取坐标轴名称文本颜色
};

具体的绘制类其实是QCPAxisPainterPrivate类,这是一个私有类,从名字就可以看出,他是一个QCPAxis类的绘制私有类,事实确实如此。刻度计算类是QCPAxisTicker,这是一个刻度计算基类,也是QCPAxis默认使用的刻度计算类,当然了这个类还有一大堆子类,都是专门用于生成指定类型的坐标轴。

2、QCPAxisTicker:刻度计算类,该类完成了大刻度、小刻度和大刻度文本的计算,供QCPAxis来调用绘制,其中generate方法是一个公有的虚方法,既可以被重写,又可以被外部调用,QCPAxis坐标轴就是调用该接口来重新计算刻度。

class QCP_LIB_DECL QCPAxisTicker
{Q_GADGET
public:enum TickStepStrategy//刻度生成策略{tssReadability    ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount), tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count};QCPAxisTicker();virtual ~QCPAxisTicker();// setters:void setTickStepStrategy(TickStepStrategy strategy);//设置刻度生成策略void setTickCount(int count);//设置大刻度个数 有可能计算出来的刻度数不完全等于设置的刻度个数,取决于刻度生成策略void setTickOrigin(double origin);//设置坐标轴领刻度// introduced virtual methods:virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector<double> &ticks, QVector<double> *subTicks, QVector<QString> *tickLabels);protected:// 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:void trimTicks(const QCPRange &range, QVector<double> &ticks, bool keepOneOutlier) const;//去除无效的刻度值double pickClosest(double target, const QVector<double> &candidates) const;//该函数返回范围内第一个不小于(大于或等于)指定target的值。
};

四、网格线

QCPGrid网格线,这个算是和QCPAxis坐标轴类似的实现,和其他模块关系基本都不是很大,直接继承自QCPLayerable,头文件格式如下,同样的,我删除了其中无需注释的一部分代码。

在QCustomPlot的源码设计中,一个QCPAxis坐标轴对于一个QCPGrid,这同我之前理解的图表绘制有些不大一样,呵呵呵。。。但是QCustomPlot就是这么干了,如果想对网格线做一些控制,有时候从QCPAxis就可以做到,因为他们直接的数据在使用上还是比较依赖。

class QCP_LIB_DECL QCPGrid :public QCPLayerable
{QCPGrid(QCPAxis *parentAxis);// setters:void setSubGridVisible(bool visible);//设置是否显示自网格线void setAntialiasedSubGrid(bool enabled);//设置子网格线是否反锯齿void setAntialiasedZeroLine(bool enabled);//设置零线(就是刻度值为0的线)是否反锯齿void setPen(const QPen &pen);//设置画笔void setSubGridPen(const QPen &pen);//设置子网格画笔void setZeroLinePen(const QPen &pen);//设置零线画笔protected:bool mSubGridVisible;//子网格是否显示标记bool mAntialiasedSubGrid, mAntialiasedZeroLine;//子网格和零线是否反锯齿标记QPen mPen, mSubGridPen, mZeroLinePen;//这个就不用说了QCPAxis *mParentAxis;//对于的坐标轴,一个网格线对应一个坐标轴virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const;//获取缺省的反锯齿属性virtual void draw(QCPPainter *painter);//绘制网格线,内部调用drawGridLines和drawSubGridLines// non-virtual methods: void drawGridLines(QCPPainter *painter) const;//绘制网格线void drawSubGridLines(QCPPainter *painter) const;//绘制子网格线
};

一般来说,网格线不需要重写,顶多就是设置一个颜色,控制是否显示,网格线的疏密成都市和坐标轴刻度计算有关系的,因此关于网格线的计算我们就不要考虑了,下面我提供一个我自定义的刻度固定像素计算类示例

五、简单的示例

首先来看下效果,如图1所示,当图表放大时,y轴上的刻度间距是保持固定像素的。

如下是刻度计算类头文件,这个类实现起来还是比较简单的,根据屏幕像素返回步长,每次步长都是按当前像素比例下计算的。

class AxisFixedPixelTicker : public QCPAxisTicker
{
public:AxisFixedPixelTicker(QCPAxis * axis);~AxisFixedPixelTicker();public:void SetTickPixelStep(int pixel);//设置固定像素int GetTickPixelStep() const;//获取固定像素大小protected://QCPAxisTickervirtual double getTickStep(const QCPRange & range) override;//重写父类方法,根据固定像素返回步长值private:QScopedPointer<AxisFixedPixelTickerPrivate> d_ptr;
};

下面是重写的父类接口getTickStep方法实现

double AxisFixedPixelTicker::getTickStep(const QCPRange & range)
{if (d_ptr->m_pDependAxis){bool vertical;if (d_ptr->m_pDependAxis->axisType() == QCPAxis::atLeft|| d_ptr->m_pDependAxis->axisType() == QCPAxis::atRight){vertical = true;}else{vertical = false;}int screenLength = vertical ? d_ptr->m_pDependAxis->axisRect()->rect().height() : d_ptr->m_pDependAxis->axisRect()->rect().width();return d_ptr->m_iPixel * range.size() / screenLength;}else{return __super::getTickStep(range);}
}

六、相关文章

QCustomplot使用分享(一) 能做什么事

QCustomplot使用分享(二)源码解读

QCustomplot使用分享(三) 图

QCustomplot使用分享(四) QCPAbstractItem

QCustomplot使用分享(五) 布局

如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!!

很重要–转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords

  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。


QCustomplot使用分享(六) 坐标轴和网格线相关推荐

  1. qcustomplot时间坐标轴画直线_QCustomplot使用分享(六) 坐标轴和网格线

    一.概述 前边已经写了5篇对QCustomPlot的讲解,看过上述的几篇文章后,基本就能做一些简单的使用了,但是如果想要做到高度的控制图表,那么坐标轴将是很重要的一部分,因为坐标轴就是图表的一个参考系 ...

  2. QCustomplot使用分享(四) QCPAbstractItem

    文章目录 一.分层绘制 二.QCustomPlot的层 三.QCPLayer 四.自定义层 五.相关文章 六.总结 七.示例下载 一.分层绘制 一直说要讲2.0.0版本,但总是想把1.3.2版本拿出来 ...

  3. python使用matplotlib可视化:设置坐标轴的范围、设置主次坐标轴刻度、坐标轴刻度显示样式、坐标轴刻度数颜色、小数点位数、坐标轴刻度网格线、线条类型、数据点形状标签、文本字体、颜色、大小等

    python使用matplotlib可视化:设置坐标轴的范围.设置主次坐标轴刻度.坐标轴刻度显示样式.坐标轴刻度数颜色.小数点位数.坐标轴刻度网格线.线条类型.数据点形状标签.文本字体.颜色.大小等 ...

  4. APP:分享六款非常实用的冷门APP软件,值得一试!

    今天小编给大家分享分享六款非常实用的冷门APP软件,值得一试! 1.泼辣修图 泼辣修图是一款非常专业的手机修图软件. 它的软件定位的目标用户就是摄影师,所以拿它来修出的照片,一下就高大上了许多. 软件 ...

  5. tinypng 批量处理插件_分享六款逆天的Excel插件,高效处理数据必备!低调使用...

    Excel是个很强大的数据处理软件,但也正因为它的强大,很多操作就比较复杂,想要熟练掌握并上手也不是件简单的事情.那么在办公中我们怎样才能快速提高我们的数据处理能力呢?别急,今天小编就来跟大家分享六个 ...

  6. 1000道Python题库系列分享六(40道)

    上一期题目链接:1000道Python题库系列分享五(40道) 上一期题目答案: 本期题目: ----------相关阅读---------- 教学课件 1900页Python系列PPT分享一:基础知 ...

  7. 电脑技巧:分享六个有趣好玩的网站,值得收藏

    目录 1.Weavesilk 2.一键抠图 3.狗屁不通文章生成器 4.小霸王在线小游戏 5.世界名画在线拼图 6.寻找不动的emoji 今天小编给大家分享六个有趣好玩的网站,值得收藏! 1.Weav ...

  8. 电脑技巧:分享六个非常实用的资源网站

    今天小编给大家分享六个非常实用的资源网站,大家一起来看看吧! 1.高清壁纸:Wallhaven 一个免费的高清壁纸下载网站,里面的壁纸资源丰富,更新速度也快,各种类型的壁纸都能找到,尤其是动漫壁纸. ...

  9. 电脑技巧:分享六个背景音乐素材下载网站,值得收藏

    目录 1.musopen 2.耳聆网 3.freeSFX 4.FreePD 5.Mixkit 6.淘声网 总结 今天给大家分享六个背景音乐素材下载网站,个个资源丰富,而且免费无版权,不管是个人使用还是 ...

最新文章

  1. Aix /etc/hosts.equiv 文件的用途及用法
  2. 直播 | AMP:针对模型参数施加对抗扰动的高效神经网络正则化算法
  3. mysql修改表结构(拆分)
  4. Java基础——Java NIO详解(二)
  5. linux-vim设置环境
  6. android面试(4)---文件存储
  7. Android应用程序开发以及背后的设计思想深度剖析(2)
  8. IDEA离线安装maven helper插件
  9. MAC - 必备软件安装与使用
  10. 运维基础实用知识点--软件篇
  11. OpenWrt自定义luci页面来修改配置文件
  12. 服务器在线测速系统源码
  13. C++:动态规划DP;
  14. 【逗老师的无线电】宝峰神机刷OpenGD77摇身变为DMR大热点
  15. 【解决方法】如何压缩网页字体文件
  16. python编程大赛队名_同行——团队展示
  17. 单片机AC220V过零检测电路仿真及改进仿真
  18. 威斯康星大学硕士计算机科学,威斯康星大学麦迪逊分校计算机科学
  19. input框监听输入法输入中文
  20. 云服务器的实用功能——弹性伸缩

热门文章

  1. android r.java_Android的R.java文件
  2. html网页结构:行内和块元素、简单案例
  3. 助你健康的25条习惯(转)
  4. CY3.5/CY5/CY5.5/CY7/CY7.5荧光标记壳多糖/壳质/角素Chitin
  5. 苹果开发者中心客服支持电话
  6. 【幻灯片制作软件】Focusky教程 | 上传幻灯片演示文稿到网站
  7. 达人评测 i31115g4和r55500u选哪个好
  8. Z490主板开机提示the system has posted in safe mode
  9. c#中PropertyGrid 控件简介
  10. 服务器装linux加载raid驱动,DELL R420服务器安装CentOS7 系统加载驱动H310 mini RAID卡...