一、头文件概述

从这篇文章开始,我们将正式的进入到QCustomPlot的实践学习中来,首先我们先来学习下QCustomPlot的类图,如果下载了QCustomPlot源码的同学可以自己去QCustomPlot的目录下documentation/qcustomplot下寻找一个名字叫做index.html的文件,将其在浏览器中打开,也是可以找到这个库的类图。如图1所示,是组成一个QCustomPlot类图的可能组成形式。

  1. 一个图表(QCustomPlot):包含一个或者多个图层、一个或多个item(用于展示一些固定的元素,例如文本、线段等)、一个或者多个可以绘制的元素、一个布局
  2. 一个图层(QCPLayer):包含基本的元素(QCPLayerable)
  3. 一个QCPAbstractItem:包含一个或者多个位置信息
  4. 一个坐标轴矩形(QCPAxisRect):包含多个坐标轴、有一个图例类(多个图例项)

图1 图表组成

在一个QCustomPlot类图中最重要、用的最多的是QCPLayerable元素,几乎除了QCPLayer以外的元素都是继承于该类。

  1. QCPAbstractPlottable:绘图元素,包含:折线图(QCPGraph)、曲线图(QCPCurve)、柱状图(QCPBars)、QCPStatiBox(盒子图)、QCPColorMap(色谱图)、QCPFinancial(金融图)
  2. QCPAbstractItem:标示项,包含:直线(QCPItemStraightLine)、线段(QCPItemLine)、曲线(QCPItemCurve)、矩形(QCPItemRect)、椭圆(QCPItemEllipse)、文本(QCPItemText)、小圆球(QCPItemTracer)、图片(QCPItemPixmap)、括弧(QCPItemBracket)
  3. 布局项(QCPLayoutElement):布局项(QCPAbstractLegendItem)、坐标轴矩形(QCPAxisRect)
  4. 网格线(QCPGrid):每一个坐标轴对应一个网格线
  5. 坐标轴(QCPAxis):一个坐标轴矩形包含四个坐标轴,上下左右四个坐标轴。

图2 可以绘制元素类图

二、一个简单的示例

如下代码是一个简单的蜡烛图代码,源码我是从官方网站上扒下来的,只是为了让大家有一个初步的了解,本来是英文的注释我换成了中文,然后添加了我自己个人的一些理解,运行结果如图3所示

 customPlot->legend->setVisible(true);

 // 生成2种随机的蜡烛图数据,第一个是蜡烛图数据,第二个是美国线数据
int n = ;
QVector<double> time(n), value1(n), value2(n);
QDateTime start = QDateTime(QDate(, , ));
start.setTimeSpec(Qt::UTC);
double startTime = start.toTime_t();
double binSize = *; // 1天的数据
time[] = startTime;
value1[] = ;
value2[] = ;
qsrand();//生成随机数时给指定的种子,那么生成的随机数都是相同的,因此每次运行后得到的结果都是不变的
for (int i=; i<n; ++i)
{
time[i] = startTime + *i;
value1[i] = value1[i-] + (qrand()/(double)RAND_MAX-0.5)*;
value2[i] = value2[i-] + (qrand()/(double)RAND_MAX-0.5)*;
} // 初始化一个蜡烛图指针:
QCPFinancial *candlesticks = new QCPFinancial(customPlot->xAxis, customPlot->yAxis);
candlesticks->setName("Candlestick");
candlesticks->setChartStyle(QCPFinancial::csCandlestick);//设置图表类型为蜡烛图
candlesticks->data()->set(QCPFinancial::timeSeriesToOhlc(time, value1, binSize, startTime));//设置数据
candlesticks->setWidth(binSize*0.9);//设置每一个数据项的绘制宽度
candlesticks->setTwoColored(true);//设置是否显示两种颜色
candlesticks->setBrushPositive(QColor(, , ));//设置收>开画刷
candlesticks->setBrushNegative(QColor(, , ));//设置收<开画刷
candlesticks->setPenPositive(QPen(QColor(, , )));//设置收>开画笔
candlesticks->setPenNegative(QPen(QColor(, , )));//设置收>开画笔 // 初始化一个美国线图指针:
QCPFinancial *ohlc = new QCPFinancial(customPlot->xAxis, customPlot->yAxis);
ohlc->setName("OHLC");
ohlc->setChartStyle(QCPFinancial::csOhlc);//设置图表类型为美国线
ohlc->data()->set(QCPFinancial::timeSeriesToOhlc(time, value2, binSize/3.0, startTime)); //为了区分于蜡烛图显示,
ohlc->setWidth(binSize*0.2);
ohlc->setTwoColored(true); // 创建一个坐标轴矩形
QCPAxisRect *volumeAxisRect = new QCPAxisRect(customPlot);
customPlot->plotLayout()->addElement(, , volumeAxisRect);
volumeAxisRect->setMaximumSize(QSize(QWIDGETSIZE_MAX, ));
volumeAxisRect->axis(QCPAxis::atBottom)->setLayer("axes");
volumeAxisRect->axis(QCPAxis::atBottom)->grid()->setLayer("grid");
// 设置自己构造的坐标轴矩形属性
customPlot->plotLayout()->setRowSpacing();
volumeAxisRect->setAutoMargins(QCP::msLeft|QCP::msRight|QCP::msBottom);
volumeAxisRect->setMargins(QMargins(, , , ));
// 生成两种颜色的柱状图
customPlot->setAutoAddPlottableToLegend(false);//是否自动生成图例
QCPBars *volumePos = new QCPBars(volumeAxisRect->axis(QCPAxis::atBottom), volumeAxisRect->axis(QCPAxis::atLeft));
QCPBars *volumeNeg = new QCPBars(volumeAxisRect->axis(QCPAxis::atBottom), volumeAxisRect->axis(QCPAxis::atLeft));
for (int i=; i<n/; ++i)
{
int v = qrand()%+qrand()%+qrand()%-*;
(v < ? volumeNeg : volumePos)->addData(startTime+*5.0*i, qAbs(v)); //构造随机数据
}
volumePos->setWidth(*);
volumePos->setPen(Qt::NoPen);
volumePos->setBrush(QColor(, , ));
volumeNeg->setWidth(*);
volumeNeg->setPen(Qt::NoPen);
volumeNeg->setBrush(QColor(, , )); // 设置自己构造的坐标轴矩形的x轴和QCustomPlot中的坐标轴矩形(默认的会生成一个)x轴同步,两个坐标轴永远显示的坐标范围是一样的
connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), volumeAxisRect->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
connect(volumeAxisRect->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis, SLOT(setRange(QCPRange)));
// 构造一个新的坐标轴刻度计算类
QSharedPointer<QCPAxisTickerDateTime> dateTimeTicker(new QCPAxisTickerDateTime);
dateTimeTicker->setDateTimeSpec(Qt::UTC);
dateTimeTicker->setDateTimeFormat("dd. MMMM");
volumeAxisRect->axis(QCPAxis::atBottom)->setTicker(dateTimeTicker);//赋予自己构造的坐标轴矩形的x轴一个新的刻度计算类
volumeAxisRect->axis(QCPAxis::atBottom)->setTickLabelRotation();
customPlot->xAxis->setBasePen(Qt::NoPen);
customPlot->xAxis->setTickLabels(false);//不显示坐标轴文本
customPlot->xAxis->setTicks(false); //  不显示坐标轴 (这个接口实现的不友好,后续文章我会具体说到)
customPlot->xAxis->setTicker(dateTimeTicker);//赋予默认的坐标轴矩形的x轴一个新的刻度计算类
customPlot->rescaleAxes();
customPlot->xAxis->scaleRange(1.025, customPlot->xAxis->range().center());
customPlot->yAxis->scaleRange(1.1, customPlot->yAxis->range().center()); // 设置两个坐标轴矩形左右对齐
QCPMarginGroup *group = new QCPMarginGroup(customPlot);
customPlot->axisRect()->setMarginGroup(QCP::msLeft|QCP::msRight, group);
volumeAxisRect->setMarginGroup(QCP::msLeft|QCP::msRight, group);

图3 蜡烛图运行示意图

三、示例下载

关于QCustomPlot的系列讲解,我可能会分为7篇文章来分别介绍,分别是QCustomplot使用分享(二) 源码解读、QCustomplot使用分享(三) 图   折线、参数曲线、蜡烛图、柱状图、面积图、QCustomplot使用分享(四) QCPAbstractItem、QCustomplot使用分享(五) 布局、QCustomplot使用分享(六) 坐标轴  网格线和QCustomplot使用分享(七) 层。等到图层讲完之后我会放出一个最终的demo,供大家下载。。。

四、相关文章

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

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

 

很重要--转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。

QCustomplot使用分享(二) 源码解读的更多相关文章

  1. Go 源码解读|如何用好 errors 库的 errors.Is() 与 errors.As() 方法

    前言 快一个月没有更新技术文章了,这段时间投注了较多的时间学习字节的开源项目 Kitex/Hertz ,并维护一些简单的 issue ,有兴趣的同学也可以去了解: https://www.cloudw ...

  2. YYModel 源码解读(二)之NSObject+YYModel.h (1)

    本篇文章主要介绍 _YYModelPropertyMeta 前边的内容 首先先解释一下前边的辅助函数和枚举变量,在写一个功能的时候,这些辅助的东西可能不是一开始就能想出来的,应该是在后续的编码过程中 ...

  3. jQuery.Callbacks 源码解读二

    一.参数标记 /* * once: 确保回调列表仅只fire一次 * unique: 在执行add操作中,确保回调列表中不存在重复的回调 * stopOnFalse: 当执行回调返回值为false,则 ...

  4. Alamofire源码解读系列(十二)之时间轴(Timeline)

    本篇带来Alamofire中关于Timeline的一些思路 前言 Timeline翻译后的意思是时间轴,可以表示一个事件从开始到结束的时间节点.时间轴的概念能够应用在很多地方,比如说微博的主页就是一个 ...

  5. Alamofire源码解读系列(十二)之请求(Request)

    本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...

  6. redux源码解读(二)

    之前,已经写过一篇redux源码解读(一),主要分析了 redux 的核心思想,并用100多行代码实现一个简单的 redux .但是,那个实现还不具备合并 reducer 和添加 middleware ...

  7. Spark学习之路 (十六)SparkCore的源码解读(二)spark-submit提交脚本

    一.概述 上一篇主要是介绍了spark启动的一些脚本,这篇主要分析一下Spark源码中提交任务脚本的处理逻辑,从spark-submit一步步深入进去看看任务提交的整体流程,首先看一下整体的流程概要图 ...

  8. js便签笔记(10) - 分享:json2.js源码解读笔记

    1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...

  9. js便签笔记(10) - 分享:json.js源码解读笔记

    1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...

随机推荐

  1. 基于 Quartz 开发企业级任务调度应用

    原文地址:http://www.ibm.com/developerworks/cn/opensource/os-cn-quartz/index.html Quartz 基本概念及原理 Quartz S ...

  2. Think in java 4th读书笔记__last update20151130

    一周至少两章,去掉最后的并发和图形化用户界面,刚好需要2个半月才能学好.这进度感觉有点慢,所以做下调整吧,改成一个月会不会更好点^^,认认真真的把java的圣经给看一遍. 计划: 第1~6 11.17 ...

  3. [Aaronyang] 写给自己的WPF4.5 笔记20 [3d课 1/4]

    假设你是高中毕业的,ok,数学知识几何知识中,我们学过  x,y,z   3个轴然后就可以画出形状了. 1. 新建空白窗体,grid换成canvas,然后新增一个Viewport3D元素 3d中显示的 ...

  4. JAVA自动化测试数据设计

    数据管理是很重要的,数据管理与方法一样,依然是有层次的,我们在测试的过程中,可能会有多个环境,每个环境的URL啊,登录名啊,数据库连接地址啊等等不一样,我们可以把这些环境每个都配置一个数据文件,里面写 ...

  5. asp 时间倒数后按钮可用

    <asp:Button runat="server" ID="btn" Text="免费获取验证码" onclick="bt ...

  6. ADT公司G729 方案指标

    ADT公司G729 方案指标 G.729 Voice Compression Algorithm and its many annexes G.729 is used in wireless voic ...

  7. 如何改变Activity在当前任务堆栈中的顺序,Intent参数大全

    引用:http://blog.csdn.net/think_soft/article/details/7477072 本示例演示如何通过设置Intent对象的标记,来改变当前任务堆栈中既存的Activ ...

  8. asp.net MVC 自动下载apk

    在Asp.net MVC中直接把.apk文件放入/Upload/App/ 路径下,然后通过IIS发布完之后,再通过http://xxx/Upload/App/xx.apk访问是访问不到的,因此不能下载 ...

  9. 通过 Storyboard 快速搭建一系列连贯性的视图控制器

    此例子只是一个简单的 Demo,这里没有过多介绍如何去实现,网上有很多关于 Storyboard 技术的介绍,请自行搜索. 效果如下: iPhone 5s   iPhone 6   iPhone 6 ...

  10. 使用SQL联合查询来构建临时vo对象的应用

    联合查询: 表1: team球队表 表2:schedule 赛程表 需要数据: 球队名称.主队ID.主队名称.客队ID.客队名称.胜负情况 方法1. Object数组取出列和数值 import jav ...