Qt 是一個跨平臺C++圖形介面開發庫,利用Qt可以快速開發跨平臺窗體應用程式,在Qt中我們可以透過拖拽的方式將不同元件放到指定的位置,實現圖形化開發極大的方便了開發效率,本章將重點介紹TreeWidget
與QCharts
的常用方法及靈活運用。
在之前的文章中筆者介紹瞭如何使用QCharts
模組來繪製簡單的折線圖並對通用API介面進行了概括,本章我們透過在TreeWidget
元件中提取資料,並依次實現柱狀圖、餅狀圖、堆疊圖、百分比圖、散點圖等。
1.1 建立柱狀圖
柱狀圖(Bar Chart)用於顯示各類別之間的數量關係。它透過在一個座標系中繪製垂直的矩形條(柱)來表示資料。每個柱的高度表示相應類別的數量或數值,柱的寬度一般是固定的,類別之間的間隔可以根據需要調整。
柱狀圖主要用於比較不同類別的數值或數量,幫助觀察資料的分佈趨勢、對比不同類別的資料大小,以及發現資料之間的關係。柱狀圖通常在橫軸上表示不同的類別,縱軸上表示數量或數值。
以下是柱狀圖的一些主要特點:
- 垂直柱狀圖(Vertical Bar Chart):柱狀圖的柱是垂直排列的,縱軸表示數值或數量。
- 水平柱狀圖(Horizontal Bar Chart):柱狀圖的柱是水平排列的,橫軸表示數值或數量。
- 分組柱狀圖(Grouped Bar Chart):將柱按照類別分組,同一組內的柱一般在相同的位置。
- 堆疊柱狀圖(Stacked Bar Chart):將柱疊加在一起,柱的高度表示總和。
- 百分比柱狀圖(Percentage Bar Chart):每個柱的高度表示相對於總和的百分比。
柱狀圖是資料視覺化中常用的工具之一,易於理解且能夠直觀地傳達資訊。在業務、科學研究、金融等領域,柱狀圖被廣泛用於展示資料的分佈和趨勢。在Qt
中柱狀圖的繪製離不開三個類的支援,其分別是QBarSet
、QBarSeries
、QBarCategoryAxis
這三個類提供了用於操作和管理條形圖資料集的方法。
QBarSet
類主要用於建立或表示一個柱狀圖的集合元素。以下是關於QBarSet
的主要方法的說明和概述,以表格形式呈現:
方法 | 描述 |
---|---|
QBarSet(const QString &label = QString()) |
建構函式,建立一個空的 QBarSet 物件,可以透過提供標籤進行初始化。 |
void append(qreal value) |
將一個值新增到資料集的末尾。 |
void append(const QList<qreal> &values) |
將一組值新增到資料集的末尾。 |
void replace(int index, qreal value) |
替換資料集中指定索引位置的值。 |
void replace(const QList<qreal> &values) |
用提供的一組值替換整個資料集。 |
void clear() |
清除資料集中的所有值。 |
int count() const |
返回資料集中值的數量。 |
bool isEmpty() const |
檢查資料集是否為空。 |
QString label() const |
返回資料集的標籤。 |
void setLabel(const QString &label) |
設定資料集的標籤。 |
qreal at(int index) const |
返回資料集中指定索引位置的值。 |
QList<qreal> values() const |
返回包含資料集所有值的列表。 |
QBarSeries
用於表示條形圖資料系列。以下是 QBarSeries
類的一些主要方法和概述:
方法 | 描述 |
---|---|
QBarSeries(QObject *parent = nullptr) |
建構函式,建立一個空的 QBarSeries 物件。 |
void append(QBarSet *set) |
將一個 QBarSet 物件新增到系列的末尾。 |
void append(const QList<QBarSet*> &sets) |
將一組 QBarSet 物件新增到系列的末尾。 |
void replace(int index, QBarSet *set) |
替換系列中指定索引位置的 QBarSet 物件。 |
void replace(const QList<QBarSet*> &sets) |
用提供的一組 QBarSet 物件替換整個系列。 |
void remove(int index) |
移除系列中指定索引位置的 QBarSet 物件。 |
void clear() |
清除系列中的所有 QBarSet 物件。 |
int count() const |
返回系列中 QBarSet 物件的數量。 |
bool isEmpty() const |
檢查系列是否為空。 |
QBarSet* at(int index) const |
返回系列中指定索引位置的 QBarSet 物件。 |
QList<QBarSet*> barSets() const |
返回包含系列所有 QBarSet 物件的列表。 |
QBarCategoryAxis
表示條形圖橫座標,用於管理和顯示條形圖中的分類軸,其中每個條形圖都屬於特定的類別。以下是 QBarCategoryAxis
類的一些主要方法和概述:
方法 | 描述 |
---|---|
QBarCategoryAxis(QObject *parent = nullptr) |
建構函式,建立一個空的 QBarCategoryAxis 物件。 |
void append(const QStringList &categories) |
將一組類別新增到軸的末尾。 |
void append(const QString &category) |
將一個類別新增到軸的末尾。 |
void insert(int index, const QString &category) |
在指定索引位置插入一個類別。 |
void insert(int index, const QStringList &categories) |
在指定索引位置插入一組類別。 |
void remove(const QString &category) |
移除指定的類別。 |
void remove(int index, int count = 1) |
從指定索引位置開始移除指定數量的類別。 |
void clear() |
清除軸中的所有類別。 |
int count() const |
返回軸中類別的數量。 |
QString categoryAt(int index) const |
返回軸中指定索引位置的類別。 |
QStringList categories() const |
返回包含軸所有類別的列表。 |
void setCategories(const QStringList &categories) |
設定軸的類別。 |
void setStartValue(qreal value) |
設定軸的起始值。 |
qreal startValue() const |
返回軸的起始值。 |
void setRange(qreal min, qreal max) |
設定軸的範圍。 |
void append(const QVector<QPointF> &points) |
將一組點新增到軸的末尾,用於自動設定類別。 |
void replace(const QVector<QPointF> &points) |
用提供的一組點替換整個軸,用於自動設定類別。 |
如下程式碼是使用 Qt 的圖表模組建立一個包含柱狀圖和折線圖的圖表,並顯示在 QGraphicsView
控制元件中,在MainWindow::MainWindow
建構函式中我們可以使用如下程式碼實現柱狀圖的建立。
圖表初始化:建立一個 QChart
物件,並設定圖表的標題和動畫效果。然後將圖表設定給 ui->graphicsView
控制元件,同時啟用抗鋸齒渲染。
QChart *chart = new QChart();
chart->setTitle("柱狀圖統計");
chart->setAnimationOptions(QChart::SeriesAnimations);
// 為graphicsView設定chart
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
// 構造柱狀圖
chart =ui->graphicsView->chart();
chart->removeAllSeries(); // 刪除所有序列
chart->removeAxis(chart->axisX()); // 刪除座標軸
chart->removeAxis(chart->axisY()); // 刪除座標軸
建立資料集:構造三個 QBarSet
物件,分別表示數學、語文、英語的資料集。同時建立一個 QLineSeries
物件,表示平均分資料集,並設定線條的顏色和寬度。
QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(1)->text()); // 數學欄位
QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(2)->text()); // 語文欄位
QBarSet *setEnglish= new QBarSet(theModel->horizontalHeaderItem(3)->text()); // 英語欄位
// 建立折線線條
QLineSeries *Line = new QLineSeries();
Line->setName(theModel->horizontalHeaderItem(4)->text()); // 表示平均分
QPen pen;
pen.setColor(Qt::red); // 使用紅色
pen.setWidth(2); // 設定寬度
Line->setPen(pen); // 繪製
新增資料:遍歷前10個資料行,將數學、語文、英語的成績和平均分新增到相應的資料集中。
for(int i=0;i< 10;i++)
{
// 從資料模型獲取資料
setMath->append(theModel->item(i,1)->text().toInt()); // 數學
setChinese->append(theModel->item(i,2)->text().toInt()); // 語文
setEnglish->append(theModel->item(i,3)->text().toInt()); // 英語
Line->append(QPointF(i,theModel->item(i,4)->text().toFloat())); // 平均分
}
建立柱狀圖序列:使用 QBarSeries
建立一個柱狀圖序列,並將三個資料集新增到序列中。同時,將折線圖序列也新增到圖表中。
cppCopy codeQBarSeries *series = new QBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
chart->addSeries(series);
chart->addSeries(Line);
設定座標軸:建立橫座標軸 axisX
和縱座標軸 axisY
,設定它們的範圍、標籤等資訊,然後將它們與相應的序列關聯。
// 建立柱狀圖序列 QBarSeries 並新增三個資料集
QBarSeries *series = new QBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
chart->addSeries(series); // 新增柱狀圖序列
chart->addSeries(Line); // 新增折線圖序列
// 用於橫座標在字串列表 即UID
QStringList categories;
for (int i=0;i<10;i++)
{
categories <<theModel->item(i,0)->text();
}
// 柱狀圖的座標軸
QBarCategoryAxis *axisX = new QBarCategoryAxis();
axisX->append(categories); // 新增橫座標文字列表
chart->setAxisX(axisX, series); // 設定橫座標
chart->setAxisX(axisX, Line); // 設定橫座標
// 設定座標範圍
axisX->setRange(categories.at(0), categories.at(categories.count()-1));
// 數值型座標作為縱軸
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 100);
axisY->setTitleText("分數");
axisY->setTickCount(6);
axisY->setLabelFormat("%.0f");
圖例顯示設定:顯示圖例,並設定圖例在底部對齊。
chart->setAxisY(axisY, series);
chart->setAxisY(axisY, Line);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);
這樣,你就建立了一個包含柱狀圖和折線圖的圖表,並將其顯示在 QGraphicsView
控制元件中,執行後則可以得到如下圖所示的圖例;
1.2 建立餅狀圖
餅狀圖(Pie Chart)用於展示各部分佔整體的比例關係。它透過在一個圓形區域內繪製扇形來表示資料的相對大小。整個圓表示總體,而每個扇形的弧長(或面積)表示相應類別的數量或比例。
餅狀圖的主要特點包括:
- 佔比表示:每個扇形的大小表示相應類別在總體中所佔的比例,從而直觀地展示各類別之間的相對關係。
- 圓形佈局:餅狀圖的資料以圓形的方式呈現,使得使用者能夠輕鬆比較各部分的大小。
- 清晰易懂:餅狀圖通常用於表示資料的相對比例,特別適用於展示類別之間的佔比關係,非常直觀。
- 單一變數:餅狀圖適合展示單一變數的佔比關係,不適用於多個變數或時間序列的比較。
- 限制資料量:由於餅狀圖是基於整個圓的,適合表示少量類別的佔比關係。當類別過多時,可能導致圖形複雜,難以解讀。
餅狀圖常見的應用場景包括市場份額分析、調查結果的佔比展示、資源分配比例等。然而,有時候,為了更好地表達資料,也會使用改進版的餅狀圖,如環形圖(Donut Chart)等。
QPieSeries
是 Qt Charts 模組中用於繪製餅狀圖的資料序列類。它派生自 QAbstractSeries
類,用於管理和展示餅狀圖中的資料。以下是 QPieSeries
類的一些常用方法和屬性,以表格形式概述:
方法 | 描述 |
---|---|
QPieSeries(QObject *parent = nullptr) |
建構函式,建立一個 QPieSeries 物件。 |
~QPieSeries() |
解構函式,釋放 QPieSeries 物件。 |
append(QPieSlice *slice) |
向餅狀圖序列中追加一個餅塊。 |
insert(int index, QPieSlice *slice) |
在指定位置插入一個餅塊。 |
remove(QPieSlice *slice) |
從餅狀圖序列中移除指定的餅塊。 |
clear() |
清除餅狀圖序列中的所有餅塊。 |
slices() |
返回餅狀圖序列中的所有餅塊。 |
count() |
返回餅狀圖序列中的餅塊數量。 |
at(int index) |
返回餅狀圖序列中指定索引位置的餅塊。 |
setVisible(bool visible) |
設定餅狀圖序列的可見性。 |
isVisible() |
返回餅狀圖序列的可見性。 |
setHoleSize(double size) |
設定餅狀圖中間空心的大小,範圍為 [0.0, 1.0],0.0 表示沒有空心,1.0 表示整個餅狀圖都是空心。 |
holeSize() |
返回餅狀圖中間空心的大小。 |
setPieSize(double size) |
設定餅狀圖的大小,範圍為 [0.0, 1.0],預設為 1.0。 |
pieSize() |
返回餅狀圖的大小。 |
setLabelsVisible(bool visible) |
設定餅塊的標籤是否可見。 |
labelsVisible() |
返回餅塊的標籤是否可見。 |
setLabelsPosition(QPieSlice::LabelPosition position) |
設定餅塊標籤的位置。 |
labelsPosition() |
返回餅塊標籤的位置。 |
setLabelsPrecision(int precision) |
設定餅塊標籤顯示的小數位數。 |
labelsPrecision() |
返回餅塊標籤顯示的小數位數。 |
clicked(QPieSlice *slice) |
點選餅塊時發出的訊號,引數為被點選的餅塊。 |
hovered(QPieSlice *slice, bool state) |
滑鼠懸停在餅塊上時發出的訊號,引數為被懸停的餅塊和懸停狀態。 |
pressed(QPieSlice *slice) |
滑鼠按下餅塊時發出的訊號,引數為被按下的餅塊。 |
released(QPieSlice *slice) |
滑鼠釋放餅塊時發出的訊號,引數為被釋放的餅塊。 |
QPieSlice
是 Qt Charts 模組中用於表示餅狀圖中的單個餅塊的類。每個 QPieSlice
物件都代表餅狀圖中的一個資料分塊。
以下是關於 QPieSlice
的一些方法以及說明:
方法 | 描述 |
---|---|
QPieSlice(qreal value, QString label) |
建構函式,建立一個帶有給定值和標籤的 QPieSlice 物件。 |
~QPieSlice() |
解構函式,釋放 QPieSlice 物件。 |
setLabel(QString label) |
設定餅塊的標籤文字。 |
label() |
返回餅塊的標籤文字。 |
setValue(qreal value) |
設定餅塊的值。 |
value() |
返回餅塊的值。 |
setExploded(bool exploded) |
設定餅塊是否為爆炸狀態,即是否與餅圖分離。 |
isExploded() |
返回餅塊是否為爆炸狀態。 |
setPieSeries(QPieSeries *series) |
設定餅塊所屬的 QPieSeries 物件。 |
pieSeries() |
返回餅塊所屬的 QPieSeries 物件。 |
setBrush(const QBrush &brush) |
設定餅塊的畫刷,即填充顏色。 |
brush() |
返回餅塊的畫刷。 |
setLabelBrush(const QBrush &brush) |
設定餅塊標籤的畫刷,即標籤的顏色。 |
labelBrush() |
返回餅塊標籤的畫刷。 |
setPen(const QPen &pen) |
設定餅塊的畫筆,即邊框顏色和樣式。 |
pen() |
返回餅塊的畫筆。 |
setLabelVisible(bool visible) |
設定餅塊標籤是否可見。 |
isLabelVisible() |
返回餅塊標籤是否可見。 |
setExplodeDistanceFactor(qreal factor) |
設定餅塊爆炸時的距離因子,即與餅圖分離的距離。 |
explodeDistanceFactor() |
返回餅塊爆炸時的距離因子。 |
setPercentage(qreal percentage) |
設定餅塊的百分比值。 |
percentage() |
返回餅塊的百分比值。 |
clicked(bool state) |
滑鼠點選餅塊時發出的訊號,引數為滑鼠點選的狀態(按下或釋放)。 |
hovered(bool state) |
滑鼠懸停在餅塊上時發出的訊號,引數為懸停狀態。 |
pressed() |
滑鼠按下餅塊時發出的訊號。 |
released() |
滑鼠釋放餅塊時發出的訊號。 |
QPieSlice
主要用於配置和管理餅狀圖中的單個資料分塊,包括設定餅塊的標籤、值、顏色、樣式等屬性。
餅狀圖的繪製流程與柱狀圖一樣,主要以下幾個步驟:
餅圖初始化: 建立一個QChart
物件,並設定其動畫選項。然後將該圖表物件設定為QGraphicsView
的圖表,並啟用反鋸齒渲染。
// 餅圖初始化
QChart *chart = new QChart();
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
// 繪製餅圖
chart->removeAllSeries();
建立餅圖序列:為圖表建立一個新的餅圖序列(QPieSeries
),並透過迴圈的方式向序列中新增成績。
// 建立餅圖序列
QPieSeries *series = new QPieSeries();
// 餅圖中間空心的大小
series->setHoleSize(0.30);
// 新增分塊資料
for (int i=0;i<=4;i++)
{
// 獲得QTreeWidgetItem的item
QTreeWidgetItem* item=ui->treeWidget->topLevelItem(i);
// 獲取分析物件,數學、英語、語文或平均分,新增一個餅圖分塊資料,標籤,數值
series->append(item->text(0),item->text(1).toFloat());
}
新增分塊資料到餅圖: 從QTreeWidget
中獲取每個分析物件(數學、英語、語文或平均分),並將其新增到餅圖序列中。
// 餅圖分塊
QPieSlice *slice;
// 設定每個分塊的標籤文字
for(int i=0;i<=4;i++)
{
// 獲取分塊
slice =series->slices().at(i);
// 設定分塊的標籤
slice->setLabel(slice->label()+QString::asprintf(": %.0f人, %.1f%%", slice->value(),slice->percentage()*100));
// 訊號與槽函式關聯,滑鼠落在某個分塊上時,此分塊彈出
connect(slice, SIGNAL(hovered(bool)),this, SLOT(on_PieSliceHighlight(bool)));
}
slice->setExploded(true); // 最後一個設定為exploded
series->setLabelsVisible(true); // 隻影響當前的slices,必須新增完slice之後再設定
chart->addSeries(series); // 新增餅圖序列
chart->legend()->setVisible(true); // 圖例
chart->legend()->setAlignment(Qt::AlignRight);
設定餅圖分塊的標籤和槽函式關聯: 對於每個分塊,設定其標籤文字,包括數值和百分比,並關聯滑鼠懸停事件的槽函式。
// 滑鼠移入移出時觸發hovered訊號
void MainWindow::on_PieSliceHighlight(bool show)
{
QPieSlice *slice;
slice=(QPieSlice *)sender();
// 動態設定setExploded效果
// slice->setLabelVisible(show);
slice->setExploded(show);
}
上述程式碼流程實現了在Qt中使用QPieSeries
和QPieSlice
繪製餅狀圖的功能,包括圖表的初始化、資料的設定、分塊標籤的新增、餅圖分塊的突出顯示等。在圖表中,每個分塊代表一種分析物件,標籤包含人數和百分比資訊,執行後輸出如下效果;
1.3 建立堆疊圖
堆疊圖(Stacked Chart)用於展示多個資料系列的累積效果,即將不同系列的資料在同一數值點上進行堆疊顯示。這種圖表形式旨在突出整體的趨勢以及各組成部分的相對貢獻。
堆疊圖有多種形式,其中兩種常見的型別包括:
- 堆疊柱狀圖(Stacked Bar Chart):在同一類別或數值點上,將不同系列的柱狀圖堆疊在一起。每個柱狀圖的高度表示該系列在該點上的數值,而整個柱狀圖的高度表示各個系列在該點上的累積總和。
- 堆疊面積圖(Stacked Area Chart):在同一類別或數值點上,將不同系列的面積圖堆疊在一起。每個面積圖的面積表示該系列在該點上的數值,而整個堆疊面積圖的高度表示各個系列在該點上的累積總和。
堆疊圖的優勢在於能夠直觀地顯示各部分在整體中的相對比例,並清晰地展示隨時間或其他維度的變化。這種圖表型別通常用於比較多個系列的總體趨勢,並強調各個系列之間的相對貢獻。在堆疊圖中,每個系列的數值貢獻會在相同的數值點上疊加顯示,使得讀者能夠更容易比較各系列的相對大小。
堆疊圖的建立需要用到QStackedBarSeries
和QBarCategoryAxis
類,QStackedBarSeries
是 Qt Charts 模組中用於建立堆疊柱狀圖的類。堆疊柱狀圖顯示多個柱狀系列的堆疊效果,每個柱狀系列由一個或多個柱狀條組成,這些柱狀條按照資料堆疊在一起,形成整體的柱狀圖。
以下是 QStackedBarSeries
的一些重要方法和屬性:
方法 | 描述 |
---|---|
QStackedBarSeries(QObject *parent = nullptr) |
建構函式,建立一個 QStackedBarSeries 物件。 |
void append(QBarSet *set) |
將一個 QBarSet 新增到序列中。 |
void append(QList<QBarSet *> sets) |
將一組 QBarSet 新增到序列中。 |
QList<QBarSet *> barSets() const |
返回序列中的所有 QBarSet 。 |
void setLabelsVisible(bool visible) |
設定是否顯示柱狀圖的標籤。 |
bool labelsVisible() const |
返回柱狀圖的標籤可見性。 |
void setLabelsFormat(const QString &format) |
設定標籤的顯示格式。 |
QString labelsFormat() const |
返回標籤的顯示格式。 |
void setLabelsPosition(QAbstractBarSeries::LabelsPosition position) |
設定標籤的位置。 |
QAbstractBarSeries::LabelsPosition labelsPosition() const |
返回標籤的位置。 |
QStackedBarSeries
透過新增不同的 QBarSet
物件來建立堆疊效果。每個 QBarSet
物件代表一個柱狀系列,它包含了一組柱狀條的資料。標籤、顏色和其他樣式屬性可以透過 QBarSet
進行定製。使用這些方法和屬性,可以方便地控制堆疊柱狀圖的外觀和行為,如下程式碼則是堆疊圖建立的實現;
// 初始化疊加柱狀圖繪製視窗
QChart *chart = new QChart();
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
// 繪製疊加柱狀圖
chart->removeAllSeries();
chart->removeAxis(chart->axisX());
chart->removeAxis(chart->axisY());
// 建立三門課程的資料集
QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(1)->text());
QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(2)->text());
QBarSet *setEnglish= new QBarSet(theModel->horizontalHeaderItem(3)->text());
// 新增前十個分數資料到資料集
for(int i=0;i<20;i++)
{
setMath->append(theModel->item(i,1)->text().toInt());
setChinese->append(theModel->item(i,2)->text().toInt());
setEnglish->append(theModel->item(i,3)->text().toInt());
}
// 建立QStackedBarSeries物件並新增資料集
QStackedBarSeries *series = new QStackedBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
series->setLabelsVisible(true);
// 新增序列到圖表
chart->addSeries(series);
QStringList categories;
// 繪製前十個資料
for (int i=0;i<10;i++)
{
categories <<theModel->item(i,0)->text();
}
// 類別座標軸 作為橫軸
QBarCategoryAxis *axisX = new QBarCategoryAxis();
axisX->append(categories);
chart->setAxisX(axisX, series);
axisX->setRange(categories.at(0), categories.at(categories.count()-1));
// 數值座標軸 作為縱軸
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 300);
axisY->setTitleText("總分");
axisY->setTickCount(6);
axisY->setLabelFormat("%.0f");
chart->setAxisY(axisY, series);
// 設定圖表屬性
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);
執行後,透過QBarSet
儲存課程資料集,最後增加橫軸縱軸區間,當資料被載入後,圖表則會輸出如下所示的資料集;
1.4 建立百分比圖
百分比圖(Percentage Chart)用於顯示各部分佔整體的百分比關係的圖表。這種圖表透過以百分比形式展示每個部分在總體中所佔比例,提供了一種直觀的方式來比較不同部分的相對大小。
百分比圖有多種形式,其中一些常見的型別包括:
- 百分比柱狀圖(Percentage Bar Chart):類似於常規柱狀圖,但每個柱的高度表示相對於整體的百分比。
- 百分比堆疊柱狀圖(Percentage Stacked Bar Chart):將柱疊加在一起,每個部分的高度表示相對於總體的百分比。
- 百分比餅狀圖(Percentage Pie Chart):類似於餅狀圖,但每個扇形的角度或面積表示相對於整體的百分比。
- 百分比面積圖(Percentage Area Chart):面積圖的每個區域表示相對於整體的百分比。
- 百分比堆疊面積圖(Percentage Stacked Area Chart):將面積疊加在一起,每個區域的面積表示相對於總體的百分比。
這些圖表形式在不同情境下用於展示資料的佔比關係,特別適用於需要強調相對比例的場景。百分比圖通常能夠幫助觀眾更容易地理解各部分在整體中的貢獻,是一種有力的資料視覺化工具。
使用百分比圖時,注意確保資料的總和為100%。百分比圖在市場份額分析、調查結果的佔比展示、資源分配比例等方面得到廣泛應用。
QPercentBarSeries
是 Qt Charts 模組中用於繪製百分比柱狀圖的類。它派生自 QAbstractBarSeries
類,表示一個二維座標系中的資料系列,其中的資料以百分比柱狀圖的形式呈現。
以下是關於 QPercentBarSeries
的一些方法以及說明:
方法 | 描述 |
---|---|
QPercentBarSeries() |
建構函式,建立一個 QPercentBarSeries 物件。 |
~QPercentBarSeries() |
解構函式,釋放 QPercentBarSeries 物件。 |
setLabelsVisible(bool) |
設定百分比柱狀圖上的資料標籤是否可見。 |
labelsVisible() |
返回百分比柱狀圖上的資料標籤是否可見的狀態。 |
setLabelsPosition(Position) |
設定百分比柱狀圖上的資料標籤位置,Position 是一個列舉型別,表示標籤的位置,如上方、下方、內部等。 |
labelsPosition() |
返回百分比柱狀圖上的資料標籤位置。 |
setLabelsFormat(QString) |
設定百分比柱狀圖上的資料標籤的格式,使用字串指定標籤的顯示格式。 |
labelsFormat() |
返回百分比柱狀圖上的資料標籤的顯示格式。 |
setPercentageVisible(bool) |
設定百分比柱狀圖上的百分比標籤是否可見。 |
percentageVisible() |
返回百分比柱狀圖上的百分比標籤是否可見的狀態。 |
setStackingGap(qreal) |
設定百分比柱狀圖中堆疊的百分比柱之間的間隙。 |
stackingGap() |
返回百分比柱狀圖中堆疊的百分比柱之間的間隙。 |
append(QBarSet*) |
在百分比柱狀圖中追加一個資料集。 |
insert(int, QBarSet*) |
在百分比柱狀圖中插入一個資料集,引數為位置索引和 QBarSet 物件。 |
remove(QBarSet*) |
從百分比柱狀圖中移除指定的資料集。 |
take(int) |
從百分比柱狀圖中移除並返回指定位置的資料集。 |
take(QBarSet*) |
從百分比柱狀圖中移除指定的資料集並返回。 |
count() |
返回百分比柱狀圖中資料集的數量。 |
barSets() |
返回百分比柱狀圖中所有資料集的列表。 |
barWidth() |
返回百分比柱狀圖中百分比柱的寬度。 |
barWidthChanged(qreal) |
當百分比柱狀圖中百分比柱的寬度發生變化時發出的訊號,引數為新的寬度值。 |
QPercentBarSeries
類主要用於在圖表中繪製百分比柱狀圖,其中的資料集可以包含多個柱子,每個柱子表示一個百分比。
// 百分比柱狀圖初始化
QChart *chart = new QChart();
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
// 繪製百分比柱狀圖
chart->removeAllSeries();
chart->removeAxis(chart->axisX());
chart->removeAxis(chart->axisY());
// 建立資料集
QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(1)->text());
QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(2)->text());
QBarSet *setEnglish= new QBarSet(theModel->horizontalHeaderItem(3)->text());
QTreeWidgetItem *item;
QStringList categories;
for (int i=0;i<=4;i++)
{
// 從分數段統計資料表裡獲取資料新增到資料集
item=ui->treeWidget->topLevelItem(i);
// 橫座標的標籤
categories<<item->text(0);
// 新增資料到QBarSet中
setMath->append(item->text(1).toFloat());
setChinese->append(item->text(2).toFloat());
setEnglish->append(item->text(3).toFloat());
}
// 新增序列
QPercentBarSeries *series = new QPercentBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
series->setLabelsVisible(true);
series->setLabelsFormat("@value人");
chart->addSeries(series);
// 新增橫座標
QBarCategoryAxis *axisX = new QBarCategoryAxis();
axisX->append(categories);
chart->setAxisX(axisX, series);
axisX->setRange(categories.at(0), categories.at(categories.count()-1));
// 新增縱座標
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 100);
axisY->setTitleText("百分比");
axisY->setTickCount(6);
axisY->setLabelFormat("%.1f");
chart->setAxisY(axisY, series);
// 設定屬性
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignRight);
執行後則可輸出不同分數段每一門成績的百分比分佈情況,如下圖所示;
1.5 建立散點圖
散點圖(Scatter Plot)是一種二維圖表,用於顯示兩個變數之間的關係。散點圖的每個資料點由兩個數值組成,分別對應於圖表的橫軸和縱軸。透過在圖表中繪製這些點,可以觀察和分析變數之間的關聯性、趨勢、聚集程度等。
散點圖的特點包括:
- 資料點表示:每個資料點在圖表上表示為一個獨立的點,其中橫軸對應一個變數,縱軸對應另一個變數。
- 關係展示:散點圖主要用於展示兩個變數之間的關係,例如相關性、分佈情況、趨勢等。
- 離散資料:適用於離散型資料,每個點表示一個具體的觀測值。
- 聚類發現:透過觀察資料點的分佈,可以發現資料是否呈現出某種聚類模式。
- 異常值檢測:可以用於檢測異常值,即圖表中偏離正常分佈的離群點。
散點圖的應用場景非常廣泛,常見的用途包括:
- 相關性分析:透過觀察散點圖,可以初步瞭解兩個變數之間的相關性,是進行相關性分析的一種視覺化手段。
- 趨勢分析:散點圖可以用於觀察兩個變數之間是否存在趨勢,是進行趨勢分析的有力工具。
- 異常值檢測:透過識別離群點,可以發現資料中的異常值,有助於資料清理和分析的準確性。
- 聚類分析:觀察資料點的分佈,可以發現是否存在某種聚類模式,對於資料的分組有一定幫助。
總體而言,散點圖是一種簡單而強大的工具,可用於初步探索和理解兩個變數之間的關係。
QSplineSeries
是 Qt Charts 模組中用於繪製光滑曲線的類。它表示圖表中的一條曲線,透過一系列的資料點來定義曲線的形狀。
以下是關於 QSplineSeries
的一些方法以及說明:
方法 | 描述 |
---|---|
QSplineSeries(QObject *parent = nullptr) |
建構函式,建立一個 QSplineSeries 物件。 |
~QSplineSeries() |
解構函式,釋放 QSplineSeries 物件。 |
append(QPointF point) |
向曲線中追加一個資料點。 |
append(QList<QPointF> points) |
向曲線中追加一組資料點。 |
replace(int index, QPointF point) |
替換指定索引處的資料點。 |
replace(QList<QPointF> points) |
替換曲線中的所有資料點。 |
remove(int index) |
移除指定索引處的資料點。 |
remove(int index, int count) |
移除從指定索引開始的指定數量的資料點。 |
clear() |
清空曲線中的所有資料點。 |
pointsVector() |
返回曲線的資料點。 |
setUseOpenGL(bool enable) |
設定是否使用 OpenGL 進行繪製。 |
useOpenGL() |
返回是否使用 OpenGL 進行繪製。 |
setPen(const QPen &pen) |
設定曲線的畫筆,即曲線的顏色和樣式。 |
pen() |
返回曲線的畫筆。 |
setBrush(const QBrush &brush) |
設定曲線的畫刷,即填充顏色。 |
brush() |
返回曲線的畫刷。 |
setPointLabelsVisible(bool visible) |
設定是否顯示資料點的標籤。 |
isPointLabelsVisible() |
返回資料點的標籤是否可見。 |
setPointLabelsFormat(const QString &format) |
設定資料點標籤的顯示格式,支援使用佔位符。 |
pointLabelsFormat() |
返回資料點標籤的顯示格式。 |
setPointLabelsColor(const QColor &color) |
設定資料點標籤的顏色。 |
pointLabelsColor() |
返回資料點標籤的顏色。 |
setPointLabelsFont(const QFont &font) |
設定資料點標籤的字型。 |
pointLabelsFont() |
返回資料點標籤的字型。 |
setPointsVisible(bool visible) |
設定是否顯示資料點。 |
arePointsVisible() |
返回資料點是否可見。 |
setPointLabelsClipping(bool clipping) |
設定是否裁剪超出繪圖區域的資料點標籤。 |
isPointLabelsClipping() |
返回資料點標籤是否裁剪超出繪圖區域。 |
clicked(QPointF point) |
滑鼠點選曲線時發出的訊號,引數為滑鼠點選的資料點座標。 |
hovered(QPointF point, bool state) |
滑鼠懸停在曲線上時發出的訊號,引數為懸停狀態以及懸停位置的資料點座標。 |
pressed(QPointF point) |
滑鼠按下曲線時發出的訊號,引數為滑鼠按下的資料點座標。 |
released(QPointF point) |
滑鼠釋放曲線時發出的訊號,引數為滑鼠釋放的資料點座標。 |
doubleClicked(QPointF point) |
滑鼠雙擊曲線時發出的訊號,引數為滑鼠雙擊的資料點座標。 |
QSplineSeries
主要用於繪製光滑曲線,透過新增一系列的資料點,可以在圖表中呈現出相應的曲線形狀。
QScatterSeries
是 Qt Charts 模組中用於繪製散點圖的類。它派生自 QXYSeries
類,用於表示圖表中的一組散點資料,透過一系列的座標點來顯示離散的資料分佈。
以下是關於 QScatterSeries
的一些方法以及說明:
方法 | 說明 |
---|---|
QScatterSeries(QObject *parent = nullptr) |
建構函式,建立一個 QScatterSeries 物件。 |
~QScatterSeries() |
解構函式,釋放 QScatterSeries 物件。 |
append(QPointF point) |
向散點圖中追加一個資料點。 |
append(QList<QPointF> points) |
向散點圖中追加一組資料點。 |
replace(int index, QPointF point) |
替換指定索引處的資料點。 |
replace(QList<QPointF> points) |
替換散點圖中的所有資料點。 |
remove(int index) |
移除指定索引處的資料點。 |
remove(int index, int count) |
移除從指定索引開始的指定數量的資料點。 |
clear() |
清空散點圖中的所有資料點。 |
pointsVector() |
返回散點圖的資料點。 |
setMarkerShape(QScatterSeries::MarkerShape shape) |
設定散點的形狀,可以是圓形、方形等。 |
markerShape() |
返回散點的形狀。 |
setMarkerSize(qreal size) |
設定散點的大小。 |
markerSize() |
返回散點的大小。 |
setPen(const QPen &pen) |
設定散點圖的畫筆,即散點的邊框顏色和樣式。 |
pen() |
返回散點圖的畫筆。 |
setBrush(const QBrush &brush) |
設定散點圖的畫刷,即散點的填充顏色。 |
brush() |
返回散點圖的畫刷。 |
setBorderColor(const QColor &color) |
設定散點的邊框顏色。 |
borderColor() |
返回散點的邊框顏色。 |
setBackgroundColor(const QColor &color) |
設定散點的背景顏色。 |
backgroundColor() |
返回散點的背景顏色。 |
setBorderColor(const QColor &color) |
設定散點的邊框顏色。 |
borderColor() |
返回散點的邊框顏色。 |
setBrush(const QBrush &brush) |
設定散點的畫刷,即填充顏色。 |
brush() |
返回散點的畫刷。 |
setPen(const QPen &pen) |
設定散點的畫筆,即邊框顏色和樣式。 |
pen() |
返回散點的畫筆。 |
setUseOpenGL(bool enable) |
設定是否使用 OpenGL 進行繪製。 |
useOpenGL() |
返回是否使用 OpenGL 進行繪製。 |
setMarkerShape(QScatterSeries::MarkerShape shape) |
設定散點的形狀,可以是圓形、方形等。 |
markerShape() |
返回散點的形狀。 |
setMarkerSize(qreal size) |
設定散點的大小。 |
markerSize() |
返回散點的大小。 |
setMarkerColor(const QColor &color) |
設定散點的顏色。 |
markerColor() |
返回散點的顏色。 |
clicked(QPointF point) |
滑鼠點選散點時發出的訊號,引數為滑鼠點選的資料點座標。 |
hovered(QPointF point, bool state) |
滑鼠懸停在散點上時發出的信 |
繪製散點圖實現程式碼如下所示;
// 散點圖初始化
QChart *chart = new QChart();
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);
// 清空繪圖區
chart->removeAllSeries();
chart->removeAxis(chart->axisX());
chart->removeAxis(chart->axisY());
// 光滑曲線序列
QSplineSeries *seriesLine = new QSplineSeries();
seriesLine->setName("曲線");
QPen pen;
pen.setColor(Qt::blue);
pen.setWidth(2);
seriesLine->setColor(Qt::blue);
seriesLine->setPen(pen);
// 散點序列
QScatterSeries *series0 = new QScatterSeries();
series0->setName("散點");
series0->setMarkerShape(QScatterSeries::MarkerShapeCircle);
series0->setBorderColor(Qt::black);
series0->setBrush(QBrush(Qt::red));
series0->setMarkerSize(12);
// 隨機數種子
qsrand(QTime::currentTime().second());
// 設定曲線隨機數
for (int i=0;i<10;i++)
{
int x=(qrand() % 20); // 0到20之間的隨機數
int y=(qrand() % 20);
series0->append(x,y); // 散點序列
seriesLine->append(x,y); // 光滑曲線序列
}
chart->addSeries(series0);
chart->addSeries(seriesLine);
// 增加Y座標軸(可註釋)
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 20);
axisY->setTitleText("Y座標");
axisY->setTickCount(11);
axisY->setLabelFormat("%.0f");
axisY->setGridLineVisible(true);
chart->setAxisY(axisY, series0);
chart->setAxisY(axisY, seriesLine);
// 增加X座標軸(可註釋)
QValueAxis *axisX = new QValueAxis;
axisX->setRange(0, 20);
axisX->setTitleText("X");
axisX->setTickCount(11);
axisX->setLabelFormat("%.0f");
axisX->setGridLineVisible(true);
chart->setAxisX(axisX, series0);
chart->setAxisX(axisX, seriesLine);
// 建立預設的座標軸(預設預設值)
chart->createDefaultAxes();
chart->axisX()->setTitleText("X 軸");
chart->axisX()->setRange(-2,22);
chart->axisY()->setTitleText("Y 軸");
chart->axisY()->setRange(-2,22);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignRight);
// 繫結槽函式,用於點選圖例顯示與隱藏資料
foreach (QLegendMarker* marker, chart->legend()->markers())
{
QObject::disconnect(marker, SIGNAL(clicked()), this, SLOT(on_chartBarLegendMarkerClicked()));
QObject::connect(marker, SIGNAL(clicked()), this, SLOT(on_chartBarLegendMarkerClicked()));
}
執行上述程式碼則可實現輸出隨機散點圖,其中右側散點與曲線可以進行自定義隱藏與顯示,如下圖所示;