QtCharts之QXYSeries

文章首發自公衆號:: nullobject
我的站點: https://www.nullobject.cn
這篇文章主要介紹QXYSeries類的API及其使用

0x00 前言

QXYSeries做爲QAbstractSeries的派生類之一,主要負責實現以二維點集爲數據源,座標類型爲二維座標系的圖表類型,包括折線圖曲線圖散點圖等。QXYSeries封裝了大量對數據源進行增刪改操做的函數和信號,同時內部實現了控制數據點在座標系上的顯示形態(點標籤的格式、顏色、是否顯示等)的功能。html

0x01 顯示和控制點標籤

Qt圖表中的點標籤指的是數據點在圖表上對應位置的附加信息顯示(好比點的座標或者其餘信息):數據結構

QtCharts點標籤

QXYSeries類中提供了pointLabels*開頭的五個屬性及對應的方法和信號來操做點標籤的顯示風格。app

  • pointLabelsClipping : 獲取和設置是否對點標籤超出繪圖區域邊緣的部分進行裁剪:
bool pointLabelsClipping() const;
void setPointLabelsClipping(bool enabled = true);

效果:
pointsLabelsClipping屬性效果函數

能夠看到,當設置pointLabelsClipping屬性爲true(默認值)時,點標籤超出繪圖區域的部分會被裁剪掉。性能

pointLabelsClipping屬性發生改變時,會觸發 pointLabelsClippingChanged(bool clipping)信號。
  • pointLabelsColor : 獲取和設置點標籤的顯示顏色
QColor pointLabelsColor() const;
void setPointLabelsColor(const QColor &color);

效果:
pointLabelsColor屬性效果字體

上圖分別爲將pointLabelsColor屬性設置爲黑色和綠色的效果。看到這您有可能會有疑問:咦怎麼只改變了座標的顏色,而折線上點的顏色沒有變?注意了,這裏的點標籤是指圖表上對數據點加以說明的信息部分,不包括點自己的顯示。spa

pointLabelsColor屬性發生改變時,會觸發 pointLabelsColorChanged(const QColor &color)信號。
  • pointLabelsFont : 獲取和設置點標籤的顯示字體
QFont pointLabelsFont() const;
void setPointLabelsFont(const QFont &font);

該屬性經過一個QFont設置來實現:code

// 獲取pointLabels默認字體
QFont font = series->pointLabelsFont();
// 加粗
font.setBold(true);
// 斜體
font.setItalic(true);
// 設置字體大小
font.setPointSize(12);
// 設置字體爲Arial類型
font.setFamily(QStringLiteral("Arial"));
// 更新pointLabels字體
series->setPointLabelsFont(font);

效果:
pointLabelsFont設置orm

pointLabelsFont屬性發生改變時,會觸發 pointLabelsFontChanged(const QFont &font)信號。
  • pointLabelsFormat : 獲取和設置點標籤的顯示格式
QString pointLabelsFormat() const;
void setPointLabelsFormat(const QString &format);

QXYSeries類提供了兩個佔位符來設置點標籤顯示真實座標數據:htm

@xPoint X軸座標
@yPoint Y軸座標

例如,咱們須要以:(15,23)這樣的格式來顯示點標籤,能夠這樣設置,便可實現上文中點標籤的顯示格式效果:

// 設置點標籤格式
series->setPointLabelsFormat(QStringLiteral("(@xPoint,@yPoint)"));

pointLabelFormat屬性默認被設置爲沒有括號的座標格式:@xPoint, @yPoint

pointLabelsFormat屬性發生改變時,會觸發 pointLabelsFormatChanged(const QString &format)信號。
  • pointLabelsVisible : 獲取和設置顯示/隱藏點標籤:
bool pointLabelsVisible() const;
void setPointLabelsVisible(bool visible=true);

該屬性默認被設置爲false。

// 隱藏點標籤
series->setPointLabelsVisible(false);

效果:
隱藏點標籤

pointLabelsVisible屬性發生改變時,會觸發 pointLabelsVisibilityChanged(bool visible)信號。
  • pointsVisible : 獲取和設置顯示/隱藏點在圖表上的標註
bool pointsVisible() const;
void setPointsVisible(bool visible=true);
pointsLabelVisible不一樣,pointsLabelVisible設置的是 點標籤的顯示,而 pointsVisible設置的是 點自己在圖表上的位置標註

該屬性默認被設置爲false。對比顯示和隱藏點標註效果:

顯示和隱藏點標註

0x02 對數據源進行增刪改

QXYSeries類中封裝了一系列的重載方法用於操做圖表的數據源進行增刪改。QXYSeries內部用一個模板類型爲QPointF的QVector來持有數據源,其聲明在qxyseries_p.h頭文件內:

QVector<QPointF>聲明

  • 增長數據

能夠調用append的對應重載方法,或者是重載操做符<<添加單個點或者整個點集到數據源的尾部:

void append(qreal x, qreal y);
void append(const QPointF &point);
void append(const QList<QPointF> &points);
QXYSeries& operator<<(const QPointF &point);
QXYSeries& operator<<(const QList<QPointF> &points);

也能夠調用insert方法將數據點插入到數據源的指定位置:

void insert(int index, const QPointF &point);

對應地,無論以何種方式,成功添加數據後都會觸發pointAdded(int index)信號,index爲被添加的數據的下標。須要注意:每添加一個點就會觸發一次pointAdded信號,即批量添加數據時會觸發對應次數的pointAdded。

  • 刪除數據

QXYSeries提供了remove重載方法和removePoints方法來移除目標數據:

// 刪除指定座標的點
void remove(qreal x, qreal y);
void remove(const QPointF &point);
// 刪除指定索引下標的點
void remove(int index);
// 從下標index位置開始,刪除count數量的點
void removePoints(int index, int count);

增長數據相似,成功刪除數據後會觸發對應次數的pointRemoved(int index)信號,index爲被刪除的數據的下標。

  • 修改數據源

修改數據源經過replace系列的重載方法實現:

// 替換具體座標的點
void replace(qreal oldX, qreal oldY, qreal newX, qreal newY);
void replace(const QPointF &oldPoint, const QPointF &newPoint);
// 替換指定索引下標的點
void replace(int index, qreal newX, qreal newY);
void replace(int index, const QPointF &newPoint);
// 替換整個數據源
void replace(QList<QPointF> points);
void replace(QVector<QPointF> points);

當只替換數據源的局部數據點(調用前四種重載方法)時,會觸發pointReplaced(int index)信號,index爲被替換的點的下標;而當替換了整個數據源數據(調用後兩種方法)時,則會觸發pointsReplaced()信號。

須要注意:調用replace後兩種重載替換整個數據源時,傳QList仍是傳QVector在性能上是有所區別的:直接傳入QList結構的數據集遠遠比逐個點替換或者先清除全部點再添加這兩種方式的效率要高。而直接傳入QVector結構的數據集又比前者效率要高。所以:須要批量更新數據點時,應當優先選擇void replace(QVector<QPointF> points);這個重載方法。究其緣由:本小節一開始就介紹了,QXYSeries內部持有數據源的數據結構爲QVector<QPointF>,而參數爲QList<QPointF>的重載方法的內部實現也是將QList轉換爲QVector,再調用參數爲QVector<QPointF> 的重載方法實現對數據的更新,無形中多了一個數據轉換的步驟,拉低性能:

replace重載方法實現

Tips:QList和QVector兩個容器自己的效率上也是有區別的,Qt官方推薦優先使用QVector。詳細能夠參考QVector的官方文檔介紹。
  • 獲取數據源

QXYseries提供了返回類型分別爲QList<QPointF>QVector<QPointF>的方法獲取數據源:

QList<QPointF> points() const;
QVector<QPointF> pointsVector() const;

與更新replace方法批量更新數據源的重載相似,points()方法獲取數據源的方法,內部實現也是獲取原始數據源再將其轉爲QList類型返回;pointsVector()方法則直接返回原始的QVector數據源。

0x03 QXYSeries中的鼠標操做

QXYSeries共提供了個鼠標事件響應信號,分別是:單擊clicked、雙擊doubleClicked、鼠標鍵按下pressed,鼠標鍵鬆開released、光標移到圖表線上或從圖表移開hovered:

series->connect(series,&QLineSeries::clicked,[](const QPointF& point){
  qDebug() << "point clicked:" << point;
});
series->connect(series,&QLineSeries::doubleClicked,[](const QPointF& point){
  qDebug() << "point double clicked:" << point;
});
series->connect(series,&QLineSeries::hovered,[](const QPointF& point,bool state){
  qDebug() << "point hovered:" << point << " state:" << (state?"光標移動到圖表上":"光標從圖表上移開");
});
series->connect(series,&QLineSeries::pressed,[](const QPointF& point){
  qDebug() << "point pressed:" << point;

});
series->connect(series,&QLineSeries::released,[](const QPointF& point){
  qDebug() << "point released:" << point;
});

運行程序,執行光標移動到圖表序列上->左鍵雙擊->光標從圖表序列上方移開,結果以下:

point hovered: QPointF(4.58291,8.71473)  state: moved to series
point pressed: QPointF(4.58291,8.71473)
point released: QPointF(4.58291,8.71473)
point clicked: QPointF(4.58291,8.71473)
point double clicked: QPointF(4.58291,8.71473)
point pressed: QPointF(4.58291,8.71473)
point released: QPointF(4.58291,8.71473)
point clicked: QPointF(4.58291,8.71473)
point hovered: QPointF(4.71022,8.18182)  state: moved from series

0x04 The End.

相關文章
相關標籤/搜索