一、概述

前边已经写了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请求

表1 1.3.2版本和2.0.0版本坐标轴比较

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

三、坐标轴

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

1 class QCP_LIB_DECL QCPAxis : publicQCPLayerable2 {3 enum AxisType {//坐标轴类型,在一个坐标轴矩形QCPAxisRect中包含左、上、右和下四条坐标轴

4 atLeft = 0x01 ///< 0x01Axis is vertical and on the left side of the axis rect

5 , atRight = 0x02 ///< 0x02Axis is vertical and on the right side of the axis rect

6 , atTop = 0x04 ///< 0x04Axis is horizontal and on the top side of the axis rect

7 , atBottom = 0x08 ///< 0x08Axis is horizontal and on the bottom side of the axis rect

8 };9 enum LabelSide {//坐标轴刻度上的文本的位置,刻度线里or外

10 lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect11 , lsOutside///< Tick labels will be displayed outside the axis rect12 };

13 enum ScaleType {//坐标轴类型,直线or对数线

14 stLinear ///< Linear scaling15 , stLogarithmic///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance).16 };

17 enum SelectablePart {/坐标轴可以被选中的部分18 spNone = 0 ///< None of the selectable parts19 , spAxis = 0x001///< The axis backbone and tick marks20 , spTickLabels = 0x002///< Tick labels (numbers) of this axis (as a whole, not individually)21 , spAxisLabel = 0x004///< The axis label22 };

23

24 explicit QCPAxis(QCPAxisRect *parent, AxisType type);25 virtual ~QCPAxis();26   //所有的get接口已经被我删除 看到对应的set接口,get接口的含义就不言而喻27 //setters:

28 Q_SLOT void setScaleType(QCPAxis::ScaleType type);//设置坐标轴类型 直线or对数

29 Q_SLOT void setRange(const QCPRange &range);//设置坐标轴范围

30 void setRange(double lower, double upper); 33 void setTicker(QSharedPointer ticker);//设置坐标轴计算刻度类,该参数是一个shared型智能指针,因此可以被多个坐标轴来同时使用

31 void setTicks(bool show);//是否显示坐标轴,如果不显示坐标轴,那么网格线也就没有啦,因为没有了坐标轴刻度

32 void setTickLabels(bool show);//是否显示坐标轴文本

33 void setTickLabelPadding(int padding);//设置坐标走文本距离坐标轴线距离

34 void setTickLabelFont(const QFont &font);//设置文本字体

35 void setTickLabelColor(const QColor &color);//设置文本颜色

36 void setTickLabelRotation(double degrees);//设置文本角度

37 void setTickLabelSide(LabelSide side);//设置文本在刻度线里or外

38 void setNumberFormat(const QString &formatCode);//设置文本格式

39 void setNumberPrecision(int precision);//设置文本精度

40 void setTickLength(int inside, int outside = 0);//设置大刻度高度

41 void setTickLengthIn(int inside);//设置大刻度在里边长度

42 void setTickLengthOut(int outside);//设置大刻度在外边长度

43 void setSubTicks(bool show);//设置是否显示小刻度

44 void setSubTickLength(int inside, int outside = 0);//设置小刻度高度

45 void setSubTickLengthIn(int inside);//设置小刻度在坐标轴线里边长度

46 void setSubTickLengthOut(int outside);//设置小刻度在坐标轴线外边长度

47 void setBasePen(const QPen &pen);//设置基础线画笔 基础线是零线,即可以认为是坐标轴刻度为0的线

48 void setTickPen(const QPen &pen);//设置大刻度画笔

49 void setSubTickPen(const QPen &pen);//设置小刻度画笔

50 void setLabelFont(const QFont &font);//设置坐标轴名称字体画笔

51 void setLabelColor(const QColor &color);//设置坐标轴名称字体颜色

52 void setLabel(const QString &str);//设置坐标轴名称文本

53 void setLabelPadding(int padding);//设置坐标轴名称文本距离坐标轴刻度线距离

54 void setPadding(int padding);//设置坐标轴距离边界距离

55 void setOffset(int offset);//设置偏移量

56 void setSelectedTickLabelFont(const QFont &font);//设置选中刻度文本时字体

57 void setSelectedLabelFont(const QFont &font);//设置选中坐标轴名称时字体

58 void setSelectedTickLabelColor(const QColor &color);//选中刻度文本时颜色

59 void setSelectedLabelColor(const QColor &color);//选中坐标轴名称时颜色

60 void setSelectedBasePen(const QPen &pen);//选中基础线时画笔

61 void setSelectedTickPen(const QPen &pen);//选中大刻度时画笔

62 void setSelectedSubTickPen(const QPen &pen);//选中小刻度时画笔

63 Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts);//设置能选中项的类型

64 Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts);65 void setLowerEnding(const QCPLineEnding &ending);//设置坐标轴小刻度端样式

66 void setUpperEnding(const QCPLineEnding &ending);//坐标轴大刻度端样式 7367 //non-property methods:

68 Qt::Orientation orientation() const { return mOrientation; }//坐标轴朝向

69 int pixelOrientation() const { return rangeReversed() != (orientation() == Qt::Vertical) ? -1 : 1; }70 void moveRange(double diff);//移动坐标轴

71 void scaleRange(double factor);//按比例因子缩放

72 void scaleRange(double factor, double center);//按范围缩放 81 void rescale(bool onlyVisiblePlottables = false);//重新适配坐标轴范围

73 double pixelToCoord(double value) const;//像素到坐标轴坐标系

74 double coordToPixel(double value) const;//坐标轴坐标系到像素 85 QList plottables() const;//所有的图

75 QList graphs() const;//所有的折线

76 QList items() const;//所有的示意项 92

77 protected:78 AxisType mAxisType;//坐标轴类型

79 QCPAxisRect *mAxisRect;//坐标轴所在矩形11680 //non-property members:

81 QCPGrid *mGrid;//网格120 QSharedPointer mTicker;//坐标轴刻度计算类

82 QVector mTickVector;//大刻度

83 QVector mTickVectorLabels;//大刻度文本

84 QVector mSubTickVector;//小刻度

85 boolmCachedMarginValid;86 intmCachedMargin;87

88 //introduced virtual methods:

89 virtual intcalculateMargin();90

91 //reimplemented virtual methods:

92 virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;//获取缺省的反锯齿属性

93 virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;//画坐标轴

94 virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;//选择策略13795 //non-virtual methods:

96 void setupTickVectors();//计算刻度

97 QPen getBasePen() const;//获取基础画笔

98 QPen getTickPen() const;//获取大刻度画笔

99 QPen getSubTickPen() const;//获取小刻度画笔

100 QFont getTickLabelFont() const;//获取刻度文本画笔

101 QFont getLabelFont() const;//获取坐标轴名称文本字体

102 QColor getTickLabelColor() const;//获取大刻度文本颜色

103 QColor getLabelColor() const;..获取坐标轴名称文本颜色104 };

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

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

1 classQCP_LIB_DECL QCPAxisTicker2 {3 Q_GADGET4 public:5 enum TickStepStrategy//刻度生成策略

6 {7 tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount)8 , tssMeetTickCount///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count9 };

10

11 QCPAxisTicker();12 virtual ~QCPAxisTicker();13

14 //setters:

15 void setTickStepStrategy(TickStepStrategy strategy);//设置刻度生成策略

16 void setTickCount(int count);//设置大刻度个数 有可能计算出来的刻度数不完全等于设置的刻度个数,取决于刻度生成策略

17 void setTickOrigin(double origin);//设置坐标轴领刻度18

19 //introduced virtual methods:

20 virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels);21

22 protected:23 //introduced virtual methods:

24 virtual double getTickStep(const QCPRange &range);//根据坐标轴范围计算步长

25 virtual int getSubTickCount(double tickStep);//根据步长计算自刻度个数

26 virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision);//根据指定语言、文本格式和精度获取文本

27 virtual QVector createTickVector(double tickStep, const QCPRange &range);//生成大刻度

28 virtual QVector createSubTickVector(int subTickCount, const QVector &ticks);//生成小刻度

29 virtual QVector createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision);//生成刻度文本30

31 //non-virtual methods:

32 void trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const;//去除无效的刻度值

33 double pickClosest(double target, const QVector &candidates) const;//该函数返回范围内第一个不小于(大于或等于)指定target的值。

34 };

四、网格线

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

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

1 class QCP_LIB_DECL QCPGrid :publicQCPLayerable2 {3 QCPGrid(QCPAxis *parentAxis);4

5 //setters:

6 void setSubGridVisible(boolvisible);//设置是否显示自网格线7 void setAntialiasedSubGrid(boolenabled);//设置子网格线是否反锯齿8 void setAntialiasedZeroLine(boolenabled);//设置零线(就是刻度值为0的线)是否反锯齿9 void setPen(const QPen &pen);//设置画笔10 void setSubGridPen(const QPen &pen);//设置子网格画笔11 void setZeroLinePen(const QPen &pen);//设置零线画笔12

13 protected:14 boolmSubGridVisible;//子网格是否显示标记15 boolmAntialiasedSubGrid, mAntialiasedZeroLine;//子网格和零线是否反锯齿标记16 QPen mPen, mSubGridPen, mZeroLinePen;//这个就不用说了17 QCPAxis *mParentAxis;//对于的坐标轴,一个网格线对应一个坐标轴18 virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const;//获取缺省的反锯齿属性19 virtual void draw(QCPPainter *painter);//绘制网格线,内部调用drawGridLines和drawSubGridLines20

21 //non-virtual methods:

22 void drawGridLines(QCPPainter *painter) const;//绘制网格线23 void drawSubGridLines(QCPPainter *painter) const;//绘制子网格线24 };

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

五、简单的示例

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

图1 y轴固定像素伸缩

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

1 class AxisFixedPixelTicker : publicQCPAxisTicker2 {3 public:4 AxisFixedPixelTicker(QCPAxis *axis);5 ~AxisFixedPixelTicker();6

7 public:8 void SetTickPixelStep(intpixel);//设置固定像素9 int GetTickPixelStep() const;//获取固定像素大小10

11 protected:12 //QCPAxisTicker

13 virtual double getTickStep(const QCPRange & range) override;//重写父类方法,根据固定像素返回步长值14

15 private:16 QScopedPointerd_ptr;17 };

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

1 double AxisFixedPixelTicker::getTickStep(const QCPRange &range)2 {3 if (d_ptr->m_pDependAxis)4 {5 boolvertical;6 if (d_ptr->m_pDependAxis->axisType() ==QCPAxis::atLeft7 || d_ptr->m_pDependAxis->axisType() ==QCPAxis::atRight)8 {9 vertical = true;10 }11 else

12 {13 vertical = false;14 }15

16 int screenLength = vertical ? d_ptr->m_pDependAxis->axisRect()->rect().height() : d_ptr->m_pDependAxis->axisRect()->rect().width();17 return d_ptr->m_iPixel * range.size() /screenLength;18 }19 else

20 {21 return__super::getTickStep(range);22 }23 }

六、相关文章

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

很重要--转载声明

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

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

qcustomplot时间坐标轴画直线_QCustomplot使用分享(六) 坐标轴和网格线相关推荐

  1. qcustomplot时间坐标轴画直线_为什么鸡看到画直线会晕?

    最近网上流传一个非常火的视频,视频中一人按着鸡,一人在其面前画直线,神奇的是当直线画完时,按着鸡的人把手松开,鸡一动不动,好像中了"定身术". 而把鸡稍微挪动下,离开直线,又生龙活 ...

  2. QCustomplot使用分享(六) 坐标轴和网格线

    文章目录 一.概述 二.历史版本对比 三.坐标轴 四.网格线 五.简单的示例 六.相关文章 一.概述 前边已经写了5篇对QCustomPlot的讲解,看过上述的几篇文章后,基本就能做一些简单的使用了, ...

  3. 0.96寸OLED用两点式画直线算法思路分享—代码开源—简单易懂超详细

    这个算法是纯原创,没有任何借鉴的元素 实现原理大概就是通过两个点算出直线方程然后描点 在这个函数中OLED_DrawDot函数是描点函数,如果和自己代码里不匹配可以换成自己代码里的描点函数. 先看整个 ...

  4. qcustomplot圆_QCustomplot使用分享(二) 源码解读

    一.头文件概述 从这篇文章开始,我们将正式的进入到QCustomPlot的实践学习中来,首先我们先来学习下QCustomPlot的类图,如果下载了QCustomPlot源码的同学可以自己去QCusto ...

  5. Canvas---Canvas版画图,坐标轴绘制,网格绘制,橡皮筋式画直线

    使用Canvas实现画图程序. 这个量还是比较大的,请允许我慢慢来. 目前做到了:坐标轴的绘制,网格绘制,橡皮筋式画直线 目前的不足:没有应用多个图层将网格,坐标轴与实际绘画区域分离 接下要做:为橡皮 ...

  6. matlab画平行坐标轴的直线

    想要在普通图形的基础上添加平行于坐标轴的直线 clc clear xmin = 2000 xmax = 2120 ymin = 0 ymax = 16 x=[2020 2040 2060 2080 2 ...

  7. qt QCustomplot 用QCPItemStraightLine画参考线,阈值线,水平线

    想要在两个坐标系下都画上如下参考线(阈值线,或者 水平线), 这个参考线随着坐标轴的拖拽能够一直显示 我们找到了QCPItemStraightLine,该类能够画一条无限延伸的直线,通过下面的代码能够 ...

  8. python画圆简单代码-Python画直线 画圆 画矩形代码

    时间:2018-11-27 概述:画图 Python画图的一些例子代码,学用rectangle画方形.利用for循环控制100-999个数,每个数分解出个位,十位,百位.程序源代码: from tki ...

  9. 画直线_在鸡的面前画直线,鸡为什么会晕呢,西瓜视频带你揭秘

    不知道你们有没有看过这样一个视频,把鸡按在地上,然后在它的面前画一条直线,在直线画完的时候,按着鸡的人把手松开,结果鸡一动不动,好像是被催眠了一样.视频一出很多网友都纷纷开始模仿,并且都成功了,这到底 ...

最新文章

  1. Android startActivityForResult
  2. 人工智能三年行动计划启动,推动人工智能和实体经济深度融合
  3. docker之Dockerfile实践
  4. linux joe复制一行,Linux joe命令
  5. Opengl-基本概念-可编程的渲染管线(僵硬啊)
  6. Fragment重影(重叠)白屏等问题原理解析,以及解决方案
  7. Android实现点击通知栏后,先启动应用再打开目标Activity
  8. 计算机系统结构相关技术,计算机系统结构第1章技术总结.pptx
  9. 大话javascript 2期:执行上下文与执行上下文栈
  10. 学习笔记_vnpy实战培训day01
  11. LLVM和clang
  12. .Net Remoting 入门
  13. 运筹学牛顿法c语言源代码,运筹学与MATlab编程.doc
  14. OEM 10g R5 online documentation
  15. 新买的固态硬盘写保护,无法格式化,怎么破!
  16. 【贪玩巴斯】一文学会检索三要素:检索字段、检索词、检索算法检索(二)——「一文学会检索三要素:检索字段、检索词、检索算法」 2021-09-18
  17. codecademy课程笔记——JavaScript Promise
  18. 社会学转计算机博士,科学网—记我国社会计算学科第一位博士 - 王帅的博文
  19. 跨境电商必知的交叉销售和追加销售:2022终极指南
  20. 蓝桥杯试题 基础练习 数列排序

热门文章

  1. php生成订单 调微信支付,PHP后台微信支付使用方法
  2. 【阿里云云计算工程师ACP认证】云计算工程师知识图谱
  3. [TCP]基于TCP的心跳和加密设计
  4. SQL 两行两列显示一行四列或一行两列
  5. 2008 mysql 本地安全_apache在windows2003或win2008环境中的安全设置
  6. 使用vue解决vs编辑器格式化分号逗号问题
  7. mysql的安装使用(免安装版)
  8. 莫纳什计算机专业强吗,2020年莫纳什大学计算机科学专业好不好
  9. Android 仿QQ动态背景登录
  10. OpenGL 纹理基础与索引