博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
QCustomplot使用分享(三) 图
阅读量:5806 次
发布时间:2019-06-18

本文共 5976 字,大约阅读时间需要 19 分钟。

一、可以实现的图

      相对于其他绘制图表的第三方库来说,QCustomPlot算是比较轻量的,不仅仅能实现功能,而且二次开发比较容易。下面我们来具体说下他可以实现那些图

  1. QCPGraph:折线图,LineStyle枚举可以设置折线图绘制的风格,主要区别是两点间连线的方式,常规的方式就是直连,其他还有L型、Z型等,如图1所示,都是折线图,只是设置了不同的折线参数;QCPScatterStyle枚举用于设置节点类型,包括:圆形、三角形等,如图2所示。
  2. QCPBars:柱状图,如图3所示
  3. QCPFinancial:蜡烛图,主要用于展示股票k线图,如图4所示。
  4. 其他图表还包括:色谱图(QCPColorMap)、统计箱(QCPStatisticalBox)、参数曲线(QCPCurve),这几个图我就不单独贴图说明了,想看效果的同学可以去查看。

二、效果预览

    这里我在单独贴出来QCustomPlot可以实现的图表,或者点击,这篇文章里有一个gif图,图中包含所有的图。

图1 折线图

  

图2 折线图

图3 柱状图

   

图4 蜡烛图

三、数据存储

    因为本篇文章是基于QCustomPlot2.0.0beta版本分析,如果有同学发现和自己手头的源码有出入,首先看下源码版本是否一致,如果源码版本一致,但是和我说的有出入,欢迎指正。

    一个关键的模板类QCPDataContainer,提供了一些基础的数据操作方法,例如:设置数据、新增数据、按键移除数据、清空、排序和查找等一些的方法,这个类出现的原因主要在于图和图仅仅是存储的数据类型不同,但是他们对这些数据操作时的接口基本相同,而这个类的功能就是把这些公有的接口提取出来,如果那个图表需要这样的数据存储,只需要用这个类来存储,类的模板参数指明具体的存储数据类型即可。

    因为不同的表只是数据存储格式不一样,而他们对数据的接口操作已经被QCPDataContainer类抽象到一起了,比如:折线图数据存储类QCPGraphData、柱状图数据存储类QCPBarsData等,当他们使用数据存储的时候会像这样QCPDataContainer<QCPGraphData>和QCPDataContainer<QCPBarsData>来声明对象。

    这个时候呢抽象还没有结束,因为所有的绘图类仅仅是提供的接口参数不一样,就像最终存储数据的结构不一样似的,比如折线图可能会像addData(QCPGraphData),柱状图可能会像addData(QCPBarsData),但是这些接口里实现的时候调用的操作完全是一样的,这个时候又出现了一个操作的抽象接口类QCPPlottableInterface1D,这个类的实现类是QCPAbstractPlottable1D,其中包含了一个QCPDataContainer指针,存储着具体的图表类型数据,他的声明可能会像下边这样

1 template 
//该类在被继承的时候初始化该参数,一般设置为图表存储的数据类型 2 class QCP_LIB_DECL QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D 3 { 4 // No Q_OBJECT macro due to template class 5 6 public: 7 QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); 8 virtual ~QCPAbstractPlottable1D(); 9 10 // virtual methods of 1d plottable interface:11 virtual int dataCount() const;12 virtual double dataMainKey(int index) const;13 virtual double dataSortKey(int index) const;14 virtual double dataMainValue(int index) const;15 virtual QCPRange dataValueRange(int index) const;16 virtual QPointF dataPixelPosition(int index) const;17 virtual bool sortKeyIsMainKey() const;18 virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const;19 virtual int findBegin(double sortKey, bool expandedRange = true) const;20 virtual int findEnd(double sortKey, bool expandedRange = true) const;21 22 // virtual methods:23 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details = 0) const;24 virtual QCPPlottableInterface1D *interface1D() { return this; }25 26 protected:27 // property members:28 QSharedPointer
> mDataContainer;//数据存储容器,提供了绝大多数的操作29 30 // helpers for subclasses:31 void getDataSegments(QList
&selectedSegments, QList
&unselectedSegments) const;32 void drawPolyline(QCPPainter *painter, const QVector
&lineData) const;33 34 private:35 Q_DISABLE_COPY(QCPAbstractPlottable1D)36 };

    说到这里可能大家还是迷迷糊糊,那么接下来我们就上一个QCPGraph类的添加数据接口代码展示,大家一看就一目了然了。虽然QCPDataContainer容器类给我们提供了很多接口,但是有些接口的返回值我们是拿不到的,比如说begine和end指针地址,但是QCPPlottableInterface1D类帮助我们拿到了,因为我们所有的图表类都是该类的子类,我们都可以使用其中的方法,具体的可以自行查看QCPPlottableInterface1D接口类的实现类QCPAbstractPlottable1D

1 void QCPGraph::addData(const QVector
&keys, const QVector
&values, bool alreadySorted) 2 { 3 if (keys.size() != values.size()) 4 qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); 5 const int n = qMin(keys.size(), values.size()); 6 QVector
tempData(n); 7 QVector
::iterator it = tempData.begin(); 8 const QVector
::iterator itEnd = tempData.end(); 9 int i = 0;10 while (it != itEnd)11 {12 it->key = keys[i];13 it->value = values[i];14 ++it;15 ++i;16 }17 mDataContainer->add(tempData, alreadySorted); // 这个add接口其实就是QCPDataContainer类提供的,18 }  

    上边的这个数据存储抽象其实在QCustomPlot1.3.2发布版本中是没有的,不过我觉着这一部分做的挺不错的,不仅简化了代码,而且可维护性更强。

四、一个简单的示例

    QCustomPlot的接口封装还是比较易懂的,那我在这里也就不一一举例说明每个图表的使用方法了,下面是折线图的简单用法,对应的效果图是图1

1     ui.widget_12->legend->setVisible(true); 2     ui.widget_12->legend->setFont(QFont("Helvetica", 9)); 3     QPen pen; 4     QStringList lineNames;//设置图例的文本 5     lineNames << "lsNone" << "lsLine" << "lsStepLeft" << "lsStepRight" << "lsStepCenter" << "lsImpulse"; 6     // add graphs with different line styles: 7     for (int i = QCPGraph::lsNone; i <= QCPGraph::lsImpulse; ++i) 8     { 9         ui.widget_12->addGraph();10         pen.setColor(QColor(qSin(i * 1 + 1.2) * 80 + 80, qSin(i*0.3 + 0) * 80 + 80, qSin(i*0.3 + 1.5) * 80 + 80));11         ui.widget_12->graph()->setPen(pen);12         ui.widget_12->graph()->setName(lineNames.at(i - QCPGraph::lsNone));13         ui.widget_12->graph()->setLineStyle((QCPGraph::LineStyle)i);//设置线性14         ui.widget_12->graph()->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 5));//设置每个节点数据绘制风格,默认是空,这里设置为空心圆15         // generate data:16         QVector
x(15), y(15);17 for (int j = 0; j < 15; ++j)18 {19 x[j] = j / 15.0 * 5 * 3.14 + 0.01;20 y[j] = 7 * qSin(x[j]) / x[j] - (i - QCPGraph::lsNone) * 5 + (QCPGraph::lsImpulse) * 5 + 2;21 }22 ui.widget_12->graph()->setData(x, y);23 ui.widget_12->graph()->rescaleAxes(true);//坐标轴自适应24 }25 // zoom out a bit:26 ui.widget_12->yAxis->scaleRange(1.1, ui.widget_12->yAxis->range().center());27 ui.widget_12->xAxis->scaleRange(1.1, ui.widget_12->xAxis->range().center());28 // set blank axis lines:29 ui.widget_12->xAxis->setTicks(false);//x轴不显示刻度30 ui.widget_12->yAxis->setTicks(true);//y轴显示刻度31 ui.widget_12->xAxis->setTickLabels(false);//x轴不显示文本32 ui.widget_12->yAxis->setTickLabels(true);//y轴显示文本33 // make top right axes clones of bottom left axes:34 ui.widget_12->axisRect()->setupFullAxesBox();一个默认的坐标轴矩形配置,包括:顶部坐标轴跟随底部坐标轴同步、右侧坐标轴跟随左侧坐标轴同步,不仅仅是坐标轴范围跟随同步,包括文本精度、文本格式、坐标轴类型、是否自动生成刻度、刻度间距等等。

五、相关文章

   

   

转载地址:http://vgkbx.baihongyu.com/

你可能感兴趣的文章
Spring ’14 Wave Update: Installing Dynamics CRM on Tablets for Windows 8.1
查看>>
MySQL 备份与恢复
查看>>
TEST
查看>>
PAT A1037
查看>>
ReactiveSwift源码解析(三) Signal代码的基本实现
查看>>
(六)Oracle学习笔记—— 约束
查看>>
[Oracle]如何在Oracle中设置Event
查看>>
top.location.href和localtion.href有什么不同
查看>>
02-创建hibernate工程
查看>>
Scrum之 Sprint计划会议
查看>>
svn命令在linux下的使用
查看>>
Gradle之module间依赖版本同步
查看>>
java springcloud版b2b2c社交电商spring cloud分布式微服务(十五)Springboot整合RabbitMQ...
查看>>
SpringCloud使用Prometheus监控(基于Eureka)
查看>>
10g手动创建数据库
查看>>
Spring MVC EL表达式不能显示
查看>>
Windwos Server 2008 R2 DHCP服务
查看>>
SAS和SATA硬盘的区别
查看>>
C# 矩阵作业
查看>>
关于数据库查询时报“query block has incorrect number of result columns”
查看>>