QCustomplot使用分享(二) 源碼解讀


一、頭文件概述

     從這篇文章開始,我們將正式的進入到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所示

 1 customPlot->legend->setVisible(true);
 2  
 3 // 生成2種隨機的蠟燭圖數據,第一個是蠟燭圖數據,第二個是美國線數據
 4 int n = 500;
 5 QVector<double> time(n), value1(n), value2(n);
 6 QDateTime start = QDateTime(QDate(2014, 6, 11));
 7 start.setTimeSpec(Qt::UTC);
 8 double startTime = start.toTime_t();
 9 double binSize = 3600*24; // 1天的數據
10 time[0] = startTime;
11 value1[0] = 60;
12 value2[0] = 20;
13 qsrand(9);//生成隨機數時給指定的種子,那么生成的隨機數都是相同的,因此每次運行后得到的結果都是不變的
14 for (int i=1; i<n; ++i)
15 {
16   time[i] = startTime + 3600*i;
17   value1[i] = value1[i-1] + (qrand()/(double)RAND_MAX-0.5)*10;
18   value2[i] = value2[i-1] + (qrand()/(double)RAND_MAX-0.5)*3;
19 }
20  
21 // 初始化一個蠟燭圖指針:
22 QCPFinancial *candlesticks = new QCPFinancial(customPlot->xAxis, customPlot->yAxis);
23 candlesticks->setName("Candlestick");
24 candlesticks->setChartStyle(QCPFinancial::csCandlestick);//設置圖類型為蠟燭圖
25 candlesticks->data()->set(QCPFinancial::timeSeriesToOhlc(time, value1, binSize, startTime));//設置數據
26 candlesticks->setWidth(binSize*0.9);//設置每一個數據項的繪制寬度
27 candlesticks->setTwoColored(true);//設置是否顯示兩種顏色
28 candlesticks->setBrushPositive(QColor(245, 245, 245));//設置收>開畫刷
29 candlesticks->setBrushNegative(QColor(40, 40, 40));//設置收<開畫刷
30 candlesticks->setPenPositive(QPen(QColor(0, 0, 0)));//設置收>開畫筆
31 candlesticks->setPenNegative(QPen(QColor(0, 0, 0)));//設置收>開畫筆
32  
33 // 初始化一個美國線圖指針:
34 QCPFinancial *ohlc = new QCPFinancial(customPlot->xAxis, customPlot->yAxis);
35 ohlc->setName("OHLC");
36 ohlc->setChartStyle(QCPFinancial::csOhlc);//設置圖表類型為美國線
37 ohlc->data()->set(QCPFinancial::timeSeriesToOhlc(time, value2, binSize/3.0, startTime)); //為了區分於蠟燭圖顯示,
38 ohlc->setWidth(binSize*0.2);
39 ohlc->setTwoColored(true);
40  
41 // 創建一個坐標軸矩形
42 QCPAxisRect *volumeAxisRect = new QCPAxisRect(customPlot);
43 customPlot->plotLayout()->addElement(1, 0, volumeAxisRect);
44 volumeAxisRect->setMaximumSize(QSize(QWIDGETSIZE_MAX, 100));
45 volumeAxisRect->axis(QCPAxis::atBottom)->setLayer("axes");
46 volumeAxisRect->axis(QCPAxis::atBottom)->grid()->setLayer("grid");
47 // 設置自己構造的坐標軸矩形屬性
48 customPlot->plotLayout()->setRowSpacing(0);
49 volumeAxisRect->setAutoMargins(QCP::msLeft|QCP::msRight|QCP::msBottom);
50 volumeAxisRect->setMargins(QMargins(0, 0, 0, 0));
51 // 生成兩種顏色的柱狀圖
52 customPlot->setAutoAddPlottableToLegend(false);//是否自動生成圖例
53 QCPBars *volumePos = new QCPBars(volumeAxisRect->axis(QCPAxis::atBottom), volumeAxisRect->axis(QCPAxis::atLeft));
54 QCPBars *volumeNeg = new QCPBars(volumeAxisRect->axis(QCPAxis::atBottom), volumeAxisRect->axis(QCPAxis::atLeft));
55 for (int i=0; i<n/5; ++i)
56 {
57   int v = qrand()%20000+qrand()%20000+qrand()%20000-10000*3;
58   (v < 0 ? volumeNeg : volumePos)->addData(startTime+3600*5.0*i, qAbs(v)); //構造隨機數據
59 }
60 volumePos->setWidth(3600*4);
61 volumePos->setPen(Qt::NoPen);
62 volumePos->setBrush(QColor(100, 180, 110));
63 volumeNeg->setWidth(3600*4);
64 volumeNeg->setPen(Qt::NoPen);
65 volumeNeg->setBrush(QColor(180, 90, 90));
66  
67 // 設置自己構造的坐標軸矩形的x軸和QCustomPlot中的坐標軸矩形(默認的會生成一個)x軸同步,兩個坐標軸永遠顯示的坐標范圍是一樣的
68 connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), volumeAxisRect->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
69 connect(volumeAxisRect->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis, SLOT(setRange(QCPRange)));
70 // 構造一個新的坐標軸刻度計算類
71 QSharedPointer<QCPAxisTickerDateTime> dateTimeTicker(new QCPAxisTickerDateTime);
72 dateTimeTicker->setDateTimeSpec(Qt::UTC);
73 dateTimeTicker->setDateTimeFormat("dd. MMMM");
74 volumeAxisRect->axis(QCPAxis::atBottom)->setTicker(dateTimeTicker);//賦予自己構造的坐標軸矩形的x軸一個新的刻度計算類
75 volumeAxisRect->axis(QCPAxis::atBottom)->setTickLabelRotation(15);
76 customPlot->xAxis->setBasePen(Qt::NoPen);
77 customPlot->xAxis->setTickLabels(false);//不顯示坐標軸文本
78 customPlot->xAxis->setTicks(false); //  不顯示坐標軸  (這個接口實現的不友好,后續文章我會具體說到)
79 customPlot->xAxis->setTicker(dateTimeTicker);//賦予默認的坐標軸矩形的x軸一個新的刻度計算類
80 customPlot->rescaleAxes();
81 customPlot->xAxis->scaleRange(1.025, customPlot->xAxis->range().center());
82 customPlot->yAxis->scaleRange(1.1, customPlot->yAxis->range().center());
83  
84 // 設置兩個坐標軸矩形左右對齊
85 QCPMarginGroup *group = new QCPMarginGroup(customPlot);
86 customPlot->axisRect()->setMarginGroup(QCP::msLeft|QCP::msRight, group);
87 volumeAxisRect->setMarginGroup(QCP::msLeft|QCP::msRight, group);

圖3 蠟燭圖運行示意圖

三、示例下載

    關於QCustomPlot的系列講解,我可能會分為7篇文章來分別介紹,分別是QCustomplot使用分享(二) 源碼解讀、QCustomplot使用分享(三) 圖   折線、參數曲線、蠟燭圖、柱狀圖、面積圖、QCustomplot使用分享(四) QCPAbstractItem、QCustomplot使用分享(五) 布局、QCustomplot使用分享(六) 坐標軸  網格線和QCustomplot使用分享(七) 層。等到圖層講完之后我會放出一個最終的demo,供大家下載。。。

四、相關文章

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

 

 

如果您覺得文章不錯,不妨給個 打賞,寫作不易,感謝各位的支持。您的支持是我最大的動力,謝謝!!! 

 

  


很重要--轉載聲明

  1. 本站文章無特別說明,皆為原創,版權所有,轉載時請用鏈接的方式,給出原文出處。同時寫上原作者:朝十晚八 or Twowords
  2. 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時通過修改本文達到有利於轉載者的目的。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM