一、Data Visualization模块概述
Data Visualization的三维显示功能主要有三种三维图形来实现,三各类的父类都是QAbstract3DGraph,从QWindow继承而来。这三类分别是:
- 三维柱状图Q3DBar
- 三维空间散点Q3DScatter
- 三维曲面Q3DSurface
1、相关类的继承关系
(1)图形类
QWindow
QAbstract3DGraph
Q3DBar
Q3DScatter
Q3DSurface
(2)数据序列类
QAbstract3DSeries
QBar3DSeries
QScatter3DSeries
QSurface3DSeries
(3)轴类
QAbstract3DAxis
QCategory3DAxis
QValue3DAxis
(4)数据代理类
数据代理类与序列对应,用于存储序列的数据的类。
QAbstractDataProxy
QBarDataProxy
QItemModelBarDataProxy
QScatterDataProxy
QItemModelScatterDataProxy
QSurfaceDataProxy
QHeightMapSurfaceDataProxy
QItemModelSurfaceDataProxy
2、使用方法
(1)工程添加
QT += datavisualization
(2)代码中添加头文件与命名空间
using namespace QtDataVisualization;
二、三维柱状图
1、实现程序
(1)创建项目,基于QMainWindow
(2)添加组件
(3)初始化
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QSplitter *splitter = new QSplitter(Qt::Horizontal);
splitter->addWidget(ui->groupBox);
initGraph3D();
splitter->addWidget(createWindowContainer(graph3D));
setCentralWidget(splitter);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::initGraph3D()
{
graph3D = new Q3DBars;
// 创建坐标系统
QStringList rowLabs, colLabs;
rowLabs << "row1" << "row2" << "row3";
colLabs << "col1" << "col2" << "col3" << "col4" << "col5";
QValue3DAxis *axisV = new QValue3DAxis;
axisV->setTitle("Value");
axisV->setTitleVisible(true);
QCategory3DAxis * axisCol = new QCategory3DAxis;
axisCol->setTitle("Column");
axisCol->setTitleVisible(true);
axisCol->setLabels(colLabs);
QCategory3DAxis * axisRow = new QCategory3DAxis;
axisRow->setTitle("Row");
axisRow->setTitleVisible(true);
axisRow->setLabels(rowLabs);
graph3D->setValueAxis(axisV);
graph3D->setColumnAxis(axisCol);
graph3D->setRowAxis(axisRow);
// 创建数据序列
QBar3DSeries *series = new QBar3DSeries;
series->setMesh(QAbstract3DSeries::MeshCylinder); // 形状
series->setItemLabelFormat("(@rowLabel,@colLabel):%.1f");
// 添加数据
QBarDataArray *dataArray = new QBarDataArray;
dataArray->reserve(rowLabs.count()); // 三行数据
qsrand(QTime::currentTime().second());
for (int i = 0; i < rowLabs.count(); ++i)
{
QBarDataRow *dataRow = new QBarDataRow;
for (int j = 0; j < 5; ++j)
{
(*dataRow) << (qrand() % 10);
}
dataArray->append(dataRow);
}
series->dataProxy()->resetArray(dataArray);
graph3D->addSeries(series);
}
(4)实现功能
void MainWindow::on_cboxCarmera_currentIndexChanged(int index)
{
graph3D->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPreset(index));
}
void MainWindow::on_hSliderLevel_valueChanged(int value)
{
Q_UNUSED(value);
int xRot = ui->hSliderLevel->value();
int yRot = ui->hSliderVertical->value();
int zoom = ui->hSliderScale->value();
graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}
void MainWindow::on_hSliderVertical_valueChanged(int value)
{
Q_UNUSED(value);
int xRot = ui->hSliderLevel->value();
int yRot = ui->hSliderVertical->value();
int zoom = ui->hSliderScale->value();
graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}
void MainWindow::on_hSliderScale_valueChanged(int value)
{
Q_UNUSED(value);
int xRot = ui->hSliderLevel->value();
int yRot = ui->hSliderVertical->value();
int zoom = ui->hSliderScale->value();
graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}
void MainWindow::on_cboxTheme_currentIndexChanged(int index)
{
graph3D->activeTheme()->setType(Q3DTheme::Theme(index));
}
void MainWindow::on_cboxStyle_currentIndexChanged(int index)
{
QBar3DSeries *series = graph3D->seriesList().at(0);
series->setMesh(QAbstract3DSeries::Mesh(index));
}
void MainWindow::on_cboxMode_currentIndexChanged(int index)
{
graph3D->setSelectionMode(QAbstract3DGraph::SelectionFlags(index));
}
void MainWindow::on_spinBoxFontSize_valueChanged(int arg1)
{
QFont font = graph3D->activeTheme()->font();
font.setPointSize(arg1);
graph3D->activeTheme()->setFont(font);
}
void MainWindow::on_btnItemColor_clicked()
{
QBar3DSeries *series = graph3D->seriesList().at(0);
QColor color = series->baseColor();
color = QColorDialog::getColor(color);
if(color.isValid())
{
series->setBaseColor(color);
}
}
void MainWindow::on_checkBoxBack_clicked(bool checked)
{
graph3D->activeTheme()->setBackgroundEnabled(checked);
}
void MainWindow::on_checkBoxBackNetwork_clicked(bool checked)
{
graph3D->activeTheme()->setGridEnabled(checked);
}
void MainWindow::on_checkBoxSmooth_clicked(bool checked)
{
QBar3DSeries *series = graph3D->seriesList().at(0);
series->setMeshSmooth(checked);
}
void MainWindow::on_checkBoxReflection_clicked(bool checked)
{
graph3D->setReflection(checked);
}
void MainWindow::on_checkBoxValueAxis_clicked(bool checked)
{
graph3D->valueAxis()->setReversed(checked);
}
void MainWindow::on_checkBoxItemLabel_clicked(bool checked)
{
QBar3DSeries *series = graph3D->seriesList().at(0);
series->setItemLabelVisible(checked);
}
void MainWindow::on_checkBoxAxisBack_clicked(bool checked)
{
graph3D->valueAxis()->setTitleVisible(checked);
graph3D->rowAxis()->setTitleVisible(checked);
graph3D->columnAxis()->setTitleVisible(checked);
}
void MainWindow::on_checkBoxAxisLabelBack_clicked(bool checked)
{
graph3D->activeTheme()->setLabelBackgroundEnabled(checked);
}
三、三维散点图
1、实现程序
(1)创建项目,基于QMainWindow
(2)实现功能
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QSplitter *splitter = new QSplitter(Qt::Horizontal);
splitter->addWidget(ui->groupBox);
initGraph3D();
splitter->addWidget(createWindowContainer(graph3D));
setCentralWidget(splitter);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::initGraph3D()
{
graph3D = new Q3DScatter;
// 创建坐标系统
graph3D->axisX()->setTitle("X轴");
graph3D->axisX()->setTitleVisible(true);
graph3D->axisY()->setTitle("Y轴");
graph3D->axisY()->setTitleVisible(true);
graph3D->axisZ()->setTitle("Z轴");
graph3D->axisZ()->setTitleVisible(true);
// 创建数据序列
QScatterDataProxy *porxy = new QScatterDataProxy;
QScatter3DSeries *series = new QScatter3DSeries(porxy);
// series->setMesh(QAbstract3DSeries::MeshCylinder); // 形状
series->setItemLabelFormat("(@rowLabel,@colLabel):%.1f");
series->setItemSize(0.2);
graph3D->addSeries(series);
// 添加数据
int N = 41;
QScatterDataArray *dataArray = new QScatterDataArray;
dataArray->resize(N * N);
QScatterDataItem *item = &dataArray->first();
// 摩西跟草帽算法
float x, y, z;
x = -10;
for (int i = 0; i < N; ++i)
{
y = -10;
for (int j = 1; j <= N; ++j)
{
z = qSqrt(x * x + y * y);
if(z != 0)
{
z = 10 * qSin(z) / z;
}
else
{
z = 10;
}
// 图形库的坐标系
item->setPosition(QVector3D(x, z, y));
item++;
y += 0.5;
}
x += 0.5;
}
series->dataProxy()->resetArray(dataArray);
}
void MainWindow::on_cboxCarmera_currentIndexChanged(int index)
{
graph3D->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPreset(index));
}
void MainWindow::on_hSliderLevel_valueChanged(int value)
{
Q_UNUSED(value);
int xRot = ui->hSliderLevel->value();
int yRot = ui->hSliderVertical->value();
int zoom = ui->hSliderScale->value();
graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}
void MainWindow::on_hSliderVertical_valueChanged(int value)
{
Q_UNUSED(value);
int xRot = ui->hSliderLevel->value();
int yRot = ui->hSliderVertical->value();
int zoom = ui->hSliderScale->value();
graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}
void MainWindow::on_hSliderScale_valueChanged(int value)
{
Q_UNUSED(value);
int xRot = ui->hSliderLevel->value();
int yRot = ui->hSliderVertical->value();
int zoom = ui->hSliderScale->value();
graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}
void MainWindow::on_cboxTheme_currentIndexChanged(int index)
{
graph3D->activeTheme()->setType(Q3DTheme::Theme(index));
}
void MainWindow::on_cboxStyle_currentIndexChanged(int index)
{
QScatter3DSeries *series = graph3D->seriesList().at(0);
series->setMesh(QAbstract3DSeries::Mesh(index));
}
void MainWindow::on_cboxMode_currentIndexChanged(int index)
{
graph3D->setSelectionMode(QAbstract3DGraph::SelectionFlags(index));
}
void MainWindow::on_spinBoxFontSize_valueChanged(int arg1)
{
QFont font = graph3D->activeTheme()->font();
font.setPointSize(arg1);
graph3D->activeTheme()->setFont(font);
}
void MainWindow::on_btnItemColor_clicked()
{
QScatter3DSeries *series = graph3D->seriesList().at(0);
QColor color = series->baseColor();
color = QColorDialog::getColor(color);
if(color.isValid())
{
series->setBaseColor(color);
}
}
void MainWindow::on_checkBoxBack_clicked(bool checked)
{
graph3D->activeTheme()->setBackgroundEnabled(checked);
}
void MainWindow::on_checkBoxBackNetwork_clicked(bool checked)
{
graph3D->activeTheme()->setGridEnabled(checked);
}
void MainWindow::on_checkBoxSmooth_clicked(bool checked)
{
QScatter3DSeries *series = graph3D->seriesList().at(0);
series->setMeshSmooth(checked);
}
void MainWindow::on_checkBoxReflection_clicked(bool checked)
{
graph3D->setReflection(checked);
}
void MainWindow::on_checkBoxValueAxis_clicked(bool checked)
{
graph3D->axisY()->setReversed(checked);
}
void MainWindow::on_checkBoxItemLabel_clicked(bool checked)
{
QScatter3DSeries *series = graph3D->seriesList().at(0);
series->setItemLabelVisible(checked);
}
void MainWindow::on_checkBoxAxisBack_clicked(bool checked)
{
graph3D->axisY()->setTitleVisible(checked);
graph3D->axisX()->setTitleVisible(checked);
graph3D->axisZ()->setTitleVisible(checked);
}
void MainWindow::on_checkBoxAxisLabelBack_clicked(bool checked)
{
graph3D->activeTheme()->setLabelBackgroundEnabled(checked);
}
四、三维曲面图
1、实现程序
(1)创建项目,基于QMainWindow
(2)添加组件
(3)初始化
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QSplitter *splitter = new QSplitter;
splitter->addWidget(ui->groupBox);
init3DGraph();
splitter->addWidget(createWindowContainer(graph3D));
setCentralWidget(splitter);
// 设置按钮的渐变色
QLinearGradient lgColor1(0, 0, 100, 0);
lgColor1.setColorAt(1.0, Qt::black);
lgColor1.setColorAt(0.67, Qt::blue);
lgColor1.setColorAt(0.33, Qt::red);
lgColor1.setColorAt(0, Qt::yellow);
QPixmap mp(160, 20);
QPainter painter(&mp);
painter.setBrush(lgColor1);
painter.drawRect(0, 0, 160, 20);
ui->btnColors1->setIcon(QIcon(mp));
ui->btnColors1->setIconSize(QSize(160, 20));
lgColor1.setColorAt(1.0, Qt::darkBlue);
lgColor1.setColorAt(0.5, Qt::yellow);
lgColor1.setColorAt(0.2, Qt::red);
lgColor1.setColorAt(0, Qt::darkRed);
painter.setBrush(lgColor1);
painter.drawRect(0, 0, 160, 20);
ui->btnColors2->setIcon(QIcon(mp));
ui->btnColors2->setIconSize(QSize(160, 20));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::init3DGraph()
{
graph3D = new Q3DSurface;
graph3D->axisX()->setTitle("X轴");
graph3D->axisX()->setTitleVisible(true);
graph3D->axisX()->setRange(-11, 11);
graph3D->axisY()->setTitle("Y轴");
graph3D->axisY()->setTitleVisible(true);
graph3D->axisZ()->setTitle("Z轴");
graph3D->axisZ()->setTitleVisible(true);
graph3D->axisZ()->setRange(-11, 11);
QSurfaceDataProxy *proxy = new QSurfaceDataProxy;
series = new QSurface3DSeries(proxy);
series->setDrawMode(QSurface3DSeries::DrawSurface);
series->setMeshSmooth(true); // 光滑曲面
graph3D->addSeries(series);
QSurfaceDataArray *dataArray = new QSurfaceDataArray;
// 摩西跟草帽算法
int N = 41;
dataArray->reserve(N);
float x, y, z;
x = -10;
for (int i = 0; i < N; ++i)
{
QSurfaceDataRow *newRow = new QSurfaceDataRow(N);
y = -10;
int index = 0;
for (int j = 1; j <= N; ++j)
{
z = qSqrt(x * x + y * y);
if(z != 0)
{
z = 10 * qSin(z) / z;
}
else
{
z = 10;
}
// 图形库的坐标系
(*newRow)[index++].setPosition(QVector3D(x, z, y));
y += 0.5;
}
x += 0.5;
*dataArray << newRow;
}
series->dataProxy()->resetArray(dataArray);
}
(4)设置颜色
void MainWindow::on_btnOneColor_clicked()
{
QColor color = series->baseColor();
color = QColorDialog::getColor(color);
if(color.isValid())
{
series->setBaseColor(color);
series->setColorStyle(Q3DTheme::ColorStyleUniform);
}
}
void MainWindow::on_btnColors1_clicked()
{
QLinearGradient lgColor1(0, 0, 100, 0);
lgColor1.setColorAt(1.0, Qt::black);
lgColor1.setColorAt(0.67, Qt::blue);
lgColor1.setColorAt(0.33, Qt::red);
lgColor1.setColorAt(0, Qt::yellow);
series->setBaseGradient(lgColor1);
series->setColorStyle(Q3DTheme::ColorStyleRangeGradient); //设置渐变色
}
void MainWindow::on_btnColors2_clicked()
{
QLinearGradient lgColor1(0, 0, 100, 0);
lgColor1.setColorAt(1.0, Qt::darkBlue);
lgColor1.setColorAt(0.5, Qt::yellow);
lgColor1.setColorAt(0.2, Qt::red);
lgColor1.setColorAt(0, Qt::darkRed);
series->setBaseGradient(lgColor1);
series->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
}
五、三维地形图
1、实现程序
(1)拷贝上一个项目
(2)添加图片资源文件
(3)实现功能
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QSplitter *splitter = new QSplitter;
splitter->addWidget(ui->groupBox);
init3DGraph();
splitter->addWidget(createWindowContainer(graph3D));
setCentralWidget(splitter);
// 设置按钮的渐变色
QLinearGradient lgColor1(0, 0, 100, 0);
lgColor1.setColorAt(1.0, Qt::black);
lgColor1.setColorAt(0.67, Qt::blue);
lgColor1.setColorAt(0.33, Qt::red);
lgColor1.setColorAt(0, Qt::yellow);
QPixmap mp(160, 20);
QPainter painter(&mp);
painter.setBrush(lgColor1);
painter.drawRect(0, 0, 160, 20);
ui->btnColors1->setIcon(QIcon(mp));
ui->btnColors1->setIconSize(QSize(160, 20));
lgColor1.setColorAt(1.0, Qt::darkBlue);
lgColor1.setColorAt(0.5, Qt::yellow);
lgColor1.setColorAt(0.2, Qt::red);
lgColor1.setColorAt(0, Qt::darkRed);
painter.setBrush(lgColor1);
painter.drawRect(0, 0, 160, 20);
ui->btnColors2->setIcon(QIcon(mp));
ui->btnColors2->setIconSize(QSize(160, 20));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::init3DGraph()
{
graph3D = new Q3DSurface;
graph3D->axisX()->setTitle("东--西");
graph3D->axisX()->setTitleVisible(true);
graph3D->axisX()->setLabelFormat("%.2f米");
graph3D->axisZ()->setTitle("南--北");
graph3D->axisZ()->setTitleVisible(true);
graph3D->axisY()->setTitle("海拔");
graph3D->axisY()->setTitleVisible(true);
QImage mapImage(":/images/images/map.png");
QHeightMapSurfaceDataProxy *proxy = new QHeightMapSurfaceDataProxy(mapImage);
proxy->setValueRanges(-5000, 5000, -5000, 5000);
series = new QSurface3DSeries(proxy);
series->setDrawMode(QSurface3DSeries::DrawSurface);
graph3D->addSeries(series);
}
void MainWindow::on_cboxSurfaceStyle_currentIndexChanged(int index)
{
series->setDrawMode(QSurface3DSeries::DrawFlags(index + 1));
}
void MainWindow::on_btnOneColor_clicked()
{
QColor color = series->baseColor();
color = QColorDialog::getColor(color);
if(color.isValid())
{
series->setBaseColor(color);
series->setColorStyle(Q3DTheme::ColorStyleUniform);
}
}
void MainWindow::on_btnColors1_clicked()
{
QLinearGradient lgColor1(0, 0, 100, 0);
lgColor1.setColorAt(1.0, Qt::black);
lgColor1.setColorAt(0.67, Qt::blue);
lgColor1.setColorAt(0.33, Qt::red);
lgColor1.setColorAt(0, Qt::yellow);
series->setBaseGradient(lgColor1);
series->setColorStyle(Q3DTheme::ColorStyleRangeGradient); //设置渐变色
}
void MainWindow::on_btnColors2_clicked()
{
QLinearGradient lgColor1(0, 0, 100, 0);
lgColor1.setColorAt(1.0, Qt::darkBlue);
lgColor1.setColorAt(0.5, Qt::yellow);
lgColor1.setColorAt(0.2, Qt::red);
lgColor1.setColorAt(0, Qt::darkRed);
series->setBaseGradient(lgColor1);
series->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
}
void MainWindow::on_cboxMode_currentIndexChanged(int index)
{
switch (index)
{
case 0:
graph3D->setSelectionMode(QAbstract3DGraph::SelectionNone);
break;
case 1:
graph3D->setSelectionMode(QAbstract3DGraph::SelectionItem);
break;
case 2:
graph3D->setSelectionMode(QAbstract3DGraph::SelectionRow |
QAbstract3DGraph::SelectionSlice);
break;
case 3:
graph3D->setSelectionMode(QAbstract3DGraph::SelectionColumn |
QAbstract3DGraph::SelectionSlice);
break;
default:
break;
}
}