Qt开发总结(20)——Data Visualization

上篇介绍了Qt Charts二维图表模块,本篇笔记总结Qt三维图表模块——Data Visualization。同样,在Qt5.7之前之后商业版才有,从Qt5.7开始免费开放在了社区版中。与QtCharts类似,也是基于Qt的Graphics View图形视图架构。当然,目前的Data Visualization还无法和一些专业的三维显示类库相提并论,但是对于一些简单的三维数据显示是比较实用的。另外,本人目前为止还未用过这个模块,所以文中不适当的地方请多包涵,也请评论区提宝贵意见。

概述

Data Visualization的三维显示功能主要由三种三维图形来实现,分别是三维柱状图Q3DBars,三维空间散点Q3DScatter,三维曲面Q3DSurface。这三个类的父类都是QAbstract3DGraph,从QWindow继承而来。

Data Visualization与Qt Charts类似都是基于Qt Graphics View的图形视图结构,所以一个三维图形也是由图表、序列、坐标轴等元素构成。响应的序列类有:QBar3DSeries,QScatter3DSeries,QSurface3DSeries类。这三个序列类是与图形类Q3DBars,Q3DScatter,Q3DSurface一一对应的。在一个图中可以有多个同类型的序列,但不能有不同类型的序列。另外,三维图形也有坐标轴类,共有两种坐标轴类:QValue3DAxis和QCategory3DAxis,前者用于数值型坐标轴,后者用于文字型坐标轴。

Data Visualization模块中还有数据代理(Data Proxies),数据代理类就是与序列对应,用于存储序列的数据的类。这也涉及一些具体的功能类:QBarDataProxy,QScatterDataProxy和QSurfaceDataProxy,这也与三种图表一一对应。

在使用时,需要在Qt工程.pro文件中加入:

QT += datavisualization

如果是VS工程,需要在Qt Settings中勾选这一模块。

在调用时源码中添加:

#include <QtDataVisualization>

using namespace QtDataVisualization;

如果你仅仅用到了其中部分头文件,比如只用到了Q3DBars,建议只include相关的几个头文件。

扫描二维码关注公众号,回复: 9657271 查看本文章

三维柱状图

Q3DBars实现创建图表,QBar3DSeries and QBarDataProxy用于设置序列和数据,同时可以控制可视化属性。场景默认具备旋转,缩放,可以选中某一条目等。

#include <QtWidgets/QApplication>
#include <QtDataVisualization>
using namespace QtDataVisualization;

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	//构造一个三维柱状图对象
	Q3DBars bars;
	bars.setFlags(bars.flags() ^ Qt::FramelessWindowHint);	//top level
	//设置坐标轴的显示范围
	bars.rowAxis()->setRange(0, 4);
	bars.columnAxis()->setRange(0, 4);
	//创建5行数据,放入序列,添加到图形
	QBar3DSeries *series = new QBar3DSeries;
	QBarDataRow *data = new QBarDataRow;
	*data << 1.0f << 3.0f << 7.5f << 5.0f << 2.2f;
	series->dataProxy()->addRow(data);
	bars.addSeries(series);
	bars.show();
	return a.exec();
}

 

三维散点图

Q3DScatter实现图形,QScatter3DSeries and QScatterDataProxy实现序列和数据,并控制图表的可视化属性。场景默认具备旋转,缩放,可以选中某一条目等。

#include <QtWidgets/QApplication>
#include <QtDataVisualization>
using namespace QtDataVisualization;

int main(int argc, char **argv)
{
	QGuiApplication app(argc, argv);
	//创建Q3DScatter三维散点图类对象
	Q3DScatter scatter;
	scatter.setFlags(scatter.flags() ^ Qt::FramelessWindowHint);
	//新建序列和数据,在序列中加入3个点,把序列添加到图形
	QScatter3DSeries *series = new QScatter3DSeries;
	QScatterDataArray data;
	data << QVector3D(0.5f, 0.5f, 0.5f) << QVector3D(-0.3f, -0.5f, -0.4f) << QVector3D(0.0f, -0.3f, 0.2f);
	series->dataProxy()->addItems(data);
	scatter.addSeries(series);
	scatter.show();

	return app.exec();
}

 

三维曲面图

Q3DSurface类实现图形,QSurface3DSeries and QSurfaceDataProxy实现序列和数据,并控制可视化属性。同样,具备旋转,缩放和选中数据的基本操作。

#include <QtWidgets/QApplication>
#include <QtDataVisualization>
using namespace QtDataVisualization;

int main(int argc, char **argv)
{
	QGuiApplication app(argc, argv);
	//创建一个三维曲面对象
	Q3DSurface surface;
	surface.setFlags(surface.flags() ^ Qt::FramelessWindowHint);
	//创建数据对象
	QSurfaceDataArray *data = new QSurfaceDataArray;
	QSurfaceDataRow *dataRow1 = new QSurfaceDataRow;
	QSurfaceDataRow *dataRow2 = new QSurfaceDataRow;
	//为数据对象赋值
	*dataRow1 << QVector3D(0.0f, 0.1f, 0.5f) << QVector3D(1.0f, 0.5f, 0.5f);
	*dataRow2 << QVector3D(0.0f, 1.8f, 1.0f) << QVector3D(1.0f, 1.2f, 1.0f);
	*data << dataRow1 << dataRow2;
	//创建序列,加入数据,添加到Q3DSurface
	QSurface3DSeries *series = new QSurface3DSeries;
	series->dataProxy()->resetArray(data);
	surface.addSeries(series);
	surface.show();

	return app.exec();
}

 

数据管理

序列(Series)拥有一系列被data proxy控制的数据,可以控制可视化渲染属性,比如颜色等。每一个三维图都有它自己对应的series类。实际使用时,用户想要显示的数据通常是很多格式的,直接添加到Series中是不支持的。Qt实现了数据代理data proxies,以使得用户可以用自己熟知的类型定义数据,通过data proxies转化传递。,每一种图形也是有对应的basic proxy类型。比如,QBar3DSeries对应QBarDataProxy,QBarDataProxy中保存有QBarDataItem对象,每一个QBarDataItem对象保存一个单独的bar value。

  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));

 

上述例子描述了用基本的数据代理实现自定义数据mydata对象的传递。特别的,Series对象一次只能拥有一个proxy。当有新的proxy被设置到Series后,之前的proxy会被删除。但是图表可以同时拥有多条Series,如果你想在两组数据中转换,建议用两个Series会更加有效。

因为三维绘图也是基于Model/View架构,我们当然可以用model管理数据,这也是Qt的常见方式。每个三维图类型也提供了特殊的proxy类以实现Model数据的传递。比如,QItemModelBarDataProxy则可以实现将Model数据于QBar3DSeries关联起来。这些类使用起来很简单,只需要给出Model Item的指针和如何映射到basic proxy就可以。这种映射规则类似于告诉proxy在model item中的哪个值属于哪一行,属于哪一列,哪个值表示了具体的数值等等。通常,item Models只有一种角色,但是包含了映射所需的多个值。这时候将用到item model proxies的模式匹配和自动替换技术。

  

    const VariantDataItemList &itemList = m_dataSet->itemList();
    int rowIndex = m_mapping->rowIndex();
    int columnIndex = m_mapping->columnIndex();
    int valueIndex = m_mapping->valueIndex();
    const QStringList &rowList = m_mapping->rowCategories();
    const QStringList &columnList = m_mapping->columnCategories();

    // Sort values into rows and columns
    typedef QHash<QString, float> ColumnValueMap;
    QHash <QString, ColumnValueMap> itemValueMap;
    foreach (const VariantDataItem *item, itemList) {
        itemValueMap[item->at(rowIndex).toString()][item->at(columnIndex).toString()]
                = item->at(valueIndex).toReal();
    }

 

例子

最后上一个地形图的三维例子:https://download.csdn.net/download/bjtuwayne/12033065

发布了76 篇原创文章 · 获赞 63 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/bjtuwayne/article/details/103723533