Qt Data Visualization 数据处理
系列
系列是由一组逻辑上相关的数据项(由数据代理处理)与描述数据项应如何渲染的可视化属性(如项网格和颜色)组合而成的。每种可视化类型都有其对应的系列类型。例如,条形图使用 QBar3DSeries。所有图表均可同时添加多个系列。
以下代码片段演示了如何使用 QBar3DSeries 将条形渲染为圆柱体,并使用渐变色代替纯色:
Q3DBars graph;
QBar3DSeries *series = new QBar3DSeries;
QLinearGradient barGradient(0, 0, 1, 100);
barGradient.setColorAt(1.0, Qt::white);
barGradient.setColorAt(0.0, Qt::black);
series->setBaseGradient(barGradient);
series->setColorStyle(Q3DTheme::ColorStyleObjectGradient);
series->setMesh(QAbstract3DSeries::MeshCylinder);
graph->addSeries(series);数据代理
用户希望可视化的数据格式多种多样,显然无法直接支持所有格式。因此,Qt Data Visualization 实现了数据代理,用户可将数据以已知的格式输入其中。 每种可视化类型都有一个基本代理类型,该类型接受适合该可视化格式的数据。例如,QBar3DSeries 的基本代理是 QBarDataProxy,它存储 QBarDataItem 对象的行。每个 QBarDataItem 存储一个柱形图值。此外,还为QBarDataArray 和QBarDataRow 容器提供了额外的 typedef 定义。
以下代码片段演示了当数据存储在某个假设的myData 对象中时,如何使用基本代理:
Q3DBars graph;
QBarDataProxy *newProxy = new QBarDataProxy;
QBarDataArray *dataArray = new QBarDataArray;
dataArray->reserve(10);
for (int i = 0; i < 10; i++) {
QBarDataRow *dataRow = new QBarDataRow(5);
for (int j = 0; j < 5; j++)
(*dataRow)[j].setValue(myData->getValue(i, j));
dataArray->append(dataRow);
}
newProxy->resetArray(dataArray);
graph->addSeries(new QBar3DSeries(newProxy));注意:Series 对象一次只能拥有一个代理。当为系列设置另一个代理时,现有的代理将被删除。不过,图表可以包含多个系列。 如果您需要在两组不同的数据之间来回切换,通常将每组数据存储在不同的系列中并仅更改系列更为高效,而不是每次切换时都重置一个代理中的数据。
项模型与数据映射
针对常见用例,Qt Data Visualization 提供了专门的代理。其中一种情况是数据存储在项目模型中(QAbstractItemModel 的子类),这是 Qt 应用程序中存储数据的常见方式。 每种可视化类型都为此目的提供了一个专门的代理类,例如 QBar3DSeries 对应的 QItemModelBarDataProxy。这些代理的使用非常简单:只需向它们提供一个指向包含数据的项模型的指针,以及将数据映射为基本代理可处理格式的规则即可。
映射通过项模型的角色实现。模型中的每个数据项可以针对不同的角色具有不同的值。 例如,使用 `QItemModelBarDataProxy` 时,您可以指定哪个角色用于确定项目所属的行,哪个角色用于确定项目所属的列,以及哪个角色指定项目的值。当代理从模型中解析数据时,会利用这些映射关系来生成条形图的行和列。
通常,项模型会包含一个角色,其中包含您希望映射到多个值的信息。一个典型的例子是时间戳字段,当生成具有两个时间相关坐标轴(例如年和月)的条形图时。 为了支持将单个项模型角色映射到多个数据字段,项模型代理提供了模式匹配和替换机制。即使在一对一映射的情况下,您也可以使用该机制对数据进行重新格式化。
根据可视化类型的不同,代理还可能支持其他功能,例如 QItemModelBarDataProxy 可选地将QAbstractItemModel 的行和列直接映射到条形图的行和列中。
有关如何使用这些代理的更多信息和示例,请参阅相应的代理类:QItemModelBarDataProxy、QItemModelScatterDataProxy 和 QItemModelSurfaceDataProxy。
其他自定义代理
QHeightMapSurfaceDataProxy 是一个用于从高度图图像生成曲面图的专用代理。更多信息请参阅 QHeightMapSurfaceDataProxy 文档。
“Graph Gallery”示例在“Bar Graph ”选项卡下展示了如何创建自定义代理。它基于变体列表定义了一个自定义数据集,并扩展了基本代理,以便通过关联的映射器解析该数据。
处理实时数据
当数据集更新迅速时,正确处理数据对于确保良好性能至关重要。由于内存分配是一项开销较大的操作,因此在构建要传递给代理的数组时,应尽可能使用 `QList::reserve()` 和 `QList::resize()`,以避免不必要的重新分配。 如果需要为每个帧更改整个数据集,在大多数情况下最好重用现有的数组——尤其是当数组维度没有变化时。 如果您需要为每个帧添加、插入、删除或更改多行或多个项目,使用一次方法调用总比多次调用(每次仅影响一行或一个项目)更高效。例如,通过一次QBarDataProxy::addRows()调用添加十行,远比十次单独的QBarDataProxy::addRow()调用高效得多。
条形图渲染器经过优化,仅访问数据窗口内的数据,因此即使持续向代理添加更多数据,也不会出现明显的性能下降。
由于散点图数据本身未经过排序,数据窗口范围的任何变化都需要检查所有数据点的可见性,如果数据不断被添加到代理中,这可能会导致性能逐渐变慢。为了获得最佳的散点图性能,请仅将所需的数据保留在代理中。
面图数据虽然在项目级别上与散点图数据类似,但已被分配到行和列中,因此面图渲染器可以假设行和列中的数据已沿各自轴进行排序,从而优化绘制过程。虽然其效率不若条形图那么高,但已非常接近。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.