Qt Graphs 使用 3D 进行数据处理
系列
系列结合了一组逻辑上相连的数据项和可视化属性,可视化属性描述了数据项的渲染方式,如项目网格和颜色。每种图形类型都有自己的系列类型。例如,条形图使用QBar3DSeries 。所有图表都可以同时添加多个系列。每个系列都拥有自己的数据。
本代码片段展示了如何使用QBar3DSeries 将条形图渲染为圆柱体,并使用渐变色而不是统一颜色:
QQuickWidget quickWidget; Q3DBarsWidgetItem graph; graph.setWidget(&quickWidget); QBar3DSeries series; QLinearGradient barGradient(0, 0, 1, 100); barGradient.setColorAt(1.0, Qt::white); barGradient.setColorAt(0.0, Qt::black); series.setBaseGradient(barGradient); series.setColorStyle(QGraphsTheme::ColorStyle::ObjectGradient); series.setMesh(QAbstract3DSeries::Mesh::Cylinder); graph.addSeries(&series);
数据代理
用户希望可视化的数据有多种格式,但所有格式都无法直接支持。因此,Qt Graphs 实现了数据代理,用户可以将已知格式的数据输入其中。每个图表的系列中都有一个基本的代理类型,它以适合该图表的格式获取数据。关于代理与系列的关系,由于数据是存储在系列中的,所以有几点很重要。首先,通过这种实现方式,用户可以通过系列访问数据。如果用户想对这些数据执行添加或删除等操作,他们仍然可以通过代理执行这些操作。不过,要执行这些操作,必须创建一个与该代理相关联的系列。
例如,QBar3DSeries 的基本代理是QBarDataProxy ,用于将数据作为QBarDataItem 对象添加到系列中。每个QBarDataItem 保存一个条形图值。还为QBarDataArray 和QBarDataRow 容器提供了其他类型定义。
本代码片段展示了如何在数据存储在假定的myData
对象中时使用基本代理,并以QBarDataItems 的形式返回数据:
QQuickWidget quickWidget; Q3DBarsWidgetItem graph; graph.setWidget(&quickWidget); QBar3DSeries series; for (int i = 0; i < 10; ++i) { QBarDataRow dataRow; for (int j = 0; j < 5; ++j) dataRow.append(myData->getValue(i, j)); series.dataProxy()->addRow(dataRow); } graph.addSeries(&series);
注意: 系列对象一次只能拥有一个代理。当为系列设置另一个代理时,现有代理将被删除。不过,图表可以包含多个系列。如果需要在两组不同的数据之间来回切换,通常更有效的做法是将每组数据存储在不同的系列中,然后更改系列,而不是每次需要切换时都使用代理重置系列中的数据。
项目模型和数据映射
对于常见的使用情况,Qt Graphs 提供了专门的代理。其中一种情况是在项模型(QAbstractItemModel 子类)中拥有数据,这是 Qt XML 应用程序中存储数据的常见方式。图形的每种类型都为此提供了一个特殊的代理类,例如QItemModelBarDataProxy 用于QBar3DSeries 。这些代理的使用很简单:向它们提供一个指向包含数据的项目模型的指针,并指定如何将数据映射为基本代理可以处理的格式的规则。
映射使用项目模型角色。模型中的每个数据项可以为不同的角色提供不同的值。例如,通过QItemModelBarDataProxy ,可以指定哪个角色用于确定项属于哪一行,哪个角色用于确定列,哪个角色用于指定项的值。当代理从模型中解析数据时,它会使用这些映射来生成条形图的行和列。
通常情况下,项目模型会有一个单一角色,其中包含的信息需要映射到多个值。一个典型的例子是,在生成具有两个时间相关轴(如年和月)的条形图时,需要使用时间戳字段。为了能将单个项目模型角色映射到多个数据字段,项目模型代理应实现模式匹配和替换机制。即使在一对一映射的情况下,也可以使用该机制重新格式化数据。
根据图表类型的不同,代理还可能支持其他功能,例如QItemModelBarDataProxy 可选择将QAbstractItemModel 行和列直接映射为条形图行和列。
有关如何使用代理的详细信息和示例,请参见各个代理类:QItemModelBarDataProxy、QItemModelScatterDataProxy 和QItemModelSurfaceDataProxy 。
其他自定义代理
QHeightMapSurfaceDataProxy 是一个专门的代理,用于从高度图图像生成曲面图。更多信息请参见 文档。QHeightMapSurfaceDataProxy
Bar Graph 选项卡中的图形库示例展示了如何创建自定义代理。该示例定义了基于变体列表的自定义数据集,并扩展了基本代理,以使用相关映射器解析该数据。
处理实时数据
当数据集更新较快时,必须正确处理数据以确保良好的性能。由于内存分配是一项代价高昂的操作,因此在构建数组以提供给代理时,应尽可能使用QList::reserve() 和QList::resize() 来避免不必要的重新分配。
如果您需要
- 更改每帧的整个数据集,大多数情况下最好重新使用现有数组,尤其是在数组维数不 变的情况下。
- 为每一帧添加、插入、移除或更改若干行或项目时,调用一个方法比调用多个方法更有效。例如,使用一个QBarDataProxy::addRows() 调用来添加十条行比使用十个单独的QBarDataProxy::addRow() 调用要有效得多。
Bars3D 在使用代理时,我们优化了对数据窗口内数据的访问,因此即使使用代理不断向序列添加更多数据,速度也不会明显降低。
由于散点图数据未排序的特性,数据窗口范围的任何变化都需要检查所有数据点的可见性,如果数据不断添加到代理中,可能会导致速度越来越慢。要想获得散点图的最佳性能,只需在代理中保留所需的数据。
曲面数据虽然在项目级别上与散点图数据类似,但已分配到行和列中。因此,曲面渲染器可以通过假设行和列中的数据沿各自的轴排序来优化绘制。虽然效率不如条形图,但也差不多了。
© 2025 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.