一、頭文件概述
從這篇文章開始,我們將正式的進入到QCustomPlot的實踐學習中來,首先我們先來學習下QCustomPlot的類圖,如果下載了QCustomPlot源碼的同學可以自己去QCustomPlot的目錄下documentation/qcustomplot下尋找一個名字叫做index.html的文件,將其在瀏覽器中打開,也是可以找到這個庫的類圖。如圖1所示,是組成一個QCustomPlot類圖的可能組成形式。
- 一個圖表(QCustomPlot):包含一個或者多個圖層、一個或多個item(用於展示一些固定的元素,例如文本、線段等)、一個或者多個可以繪制的元素、一個布局
- 一個圖層(QCPLayer):包含基本的元素(QCPLayerable)
- 一個QCPAbstractItem:包含一個或者多個位置信息
- 一個坐標軸矩形(QCPAxisRect):包含多個坐標軸、有一個圖例類(多個圖例項)
圖1 圖表組成
在一個QCustomPlot類圖中最重要、用的最多的是QCPLayerable元素,幾乎除了QCPLayer以外的元素都是繼承於該類。
- QCPAbstractPlottable:繪圖元素,包含:折線圖(QCPGraph)、曲線圖(QCPCurve)、柱狀圖(QCPBars)、QCPStatiBox(盒子圖)、QCPColorMap(色譜圖)、QCPFinancial(金融圖)
- QCPAbstractItem:標示項,包含:直線(QCPItemStraightLine)、線段(QCPItemLine)、曲線(QCPItemCurve)、矩形(QCPItemRect)、橢圓(QCPItemEllipse)、文本(QCPItemText)、小圓球(QCPItemTracer)、圖片(QCPItemPixmap)、括弧(QCPItemBracket)
- 布局項(QCPLayoutElement):布局項(QCPAbstractLegendItem)、坐標軸矩形(QCPAxisRect)
- 網格線(QCPGrid):每一個坐標軸對應一個網格線
- 坐標軸(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,供大家下載。。。
四、相關文章
如果您覺得文章不錯,不妨給個
打賞,寫作不易,感謝各位的支持。您的支持是我最大的動力,謝謝!!!


