QT数据可视化框架编程实战之三维柱状图_补天云QT技术培训专家

简介
本文将介绍QT数据可视化框架编程实战之三维柱状图可视化的运行效果以及具体实现代码。
(本文广泛参考了QT数据可视化框架的例程。)

正文

QT数据可视化框架编程实战:三维柱状图可视化运行效果

QT数据可视化框架编程实战之三维柱状图可视化的运行效果如下图所示。数据按照每年12个月,每月数据对应一个三维柱体。共三个坐标轴,水平方向的两个坐标轴分别是年份和月份;垂直方向一个坐标轴是收入。

演示视频如下所示:

QT数据可视化框架编程实战之三维柱状图 补天云QT技术培训专家

读者也可以访问这个链接观看演示视频:
QT数据可视化框架编程实战之三维柱状图 补天云QT技术培训专家

主程序实现C++代码

#include <QtGui/qguiapplication.h>
#include <QtQuick/qquickview.h>
#include <QtQml/qqmlengine.h> int main(int argc, char *argv[])
{
qputenv("QSG_RHI_BACKEND", "opengl");
QGuiApplication app(argc, argv); QQuickView viewer; QString extraImportPath(QStringLiteral("%1/../../../../%2"));
viewer.engine()->addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath(),
QString::fromLatin1("qml"))); viewer.setTitle(QStringLiteral("Monthly income")); viewer.setSource(QUrl("qrc:/qml/qmlbars/main.qml"));
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
viewer.setColor("black");
viewer.show(); return app.exec();
}

主场景 QML代码

main.qml文件:


import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtDataVisualization
import Qt.labs.qmlmodels pragma ComponentBehavior: Bound Item {
id: mainview
width: 1280
height: 1024 property int buttonLayoutHeight: 180
property int currentRow
state: "landscape" Data {
id: graphData
} Axes {
id: graphAxes
} property Bar3DSeries selectedSeries
selectedSeries: barSeries function handleSelectionChange(series, position) {
if (position !== series.invalidSelectionPosition)
selectedSeries = series; // Set tableView current row to selected bar
var rowRole = series.dataProxy.rowLabels[position.x];
var colRole;
if (barGraph.columnAxis == graphAxes.total)
colRole = "01";
else
colRole = series.dataProxy.columnLabels[position.y];
var checkTimestamp = rowRole + "-" + colRole; if (currentRow === -1 || checkTimestamp !== graphData.model.get(currentRow).timestamp) {
var totalRows = tableView.rows;
for (var i = 0; i < totalRows; i++) {
var modelTimestamp = graphData.model.get(i).timestamp;
if (modelTimestamp === checkTimestamp) {
currentRow = i;
break;
}
}
}
} Item {
id: dataView
anchors.right: mainview.right
anchors.bottom: mainview.bottom Bars3D {
id: barGraph
anchors.fill: parent
shadowQuality: AbstractGraph3D.ShadowQualitySoftHigh
selectionMode: AbstractGraph3D.SelectionItem
theme: Theme3D {
type: Theme3D.ThemeEbony
labelBorderEnabled: true
font.pointSize: 35
labelBackgroundEnabled: true
colorStyle: Theme3D.ColorStyleRangeGradient
singleHighlightGradient: customGradient ColorGradient {
id: customGradient
ColorGradientStop { position: 1.0; color: "#FFFF00" }
ColorGradientStop { position: 0.0; color: "#808000" }
}
}
barThickness: 0.7
barSpacing: Qt.size(0.5, 0.5)
barSpacingRelative: false
scene.activeCamera.cameraPreset: Camera3D.CameraPresetIsometricLeftHigh
columnAxis: graphAxes.column
rowAxis: graphAxes.row
valueAxis: graphAxes.value Bar3DSeries {
id: barSeries
itemLabelFormat: "Income, @colLabel, @rowLabel: @valueLabel"
baseGradient: barGradient ItemModelBarDataProxy {
id: modelProxy
itemModel: graphData.model
rowRole: "timestamp"
columnRole: "timestamp"
valueRole: "income"
rowRolePattern: /^(\d\d\d\d).*$/
columnRolePattern: /^.*-(\d\d)$/
rowRoleReplace: "\\1"
columnRoleReplace: "\\1"
multiMatchBehavior: ItemModelBarDataProxy.MMBCumulative
}
//! [3] ColorGradient {
id: barGradient
ColorGradientStop { position: 1.0; color: "#00FF00" }
ColorGradientStop { position: 0.0; color: "#006000" }
} onSelectedBarChanged: (position) => mainview.handleSelectionChange(barSeries,
position);
}
}
} ColumnLayout {
id: tableViewLayout anchors.top: parent.top
anchors.left: parent.left HorizontalHeaderView {
id: headerView
readonly property var columnNames: ["Month", "Expenses", "Income"] syncView: tableView
Layout.fillWidth: true
delegate: Text {
required property int index
padding: 3
text: headerView.columnNames[index]
color: barGraph.theme.labelTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
} TableView {
id: tableView
Layout.fillWidth: true
Layout.fillHeight: true reuseItems: false
clip: true model: TableModel {
id: tableModel
TableModelColumn { display: "timestamp" }
TableModelColumn { display: "expenses" }
TableModelColumn { display: "income" } rows: graphData.modelAsJsArray
} delegate: Rectangle {
id: delegateRoot
required property int row
required property int column
required property string display
implicitHeight: 30
implicitWidth: column === 0 ? tableView.width / 2 : tableView.width / 4
color: row === mainview.currentRow ? barGraph.theme.gridLineColor
: barGraph.theme.windowColor
border.color: row === mainview.currentRow ? barGraph.theme.labelTextColor
: barGraph.theme.gridLineColor
border.width: 1
MouseArea {
anchors.fill: parent
onClicked: mainview.currentRow = delegateRoot.row;
} Text {
id: delegateText
anchors.verticalCenter: parent.verticalCenter
width: parent.width
anchors.leftMargin: 4
anchors.left: parent.left
anchors.right: parent.right
text: formattedText
property string formattedText: {
if (delegateRoot.column === 0) {
if (delegateRoot.display !== "") {
var pattern = /(\d\d\d\d)-(\d\d)/;
var matches = pattern.exec(delegateRoot.display);
var colIndex = parseInt(matches[2], 10) - 1;
return matches[1] + " - " + graphAxes.column.labels[colIndex];
}
} else {
return delegateRoot.display;
}
}
color: barGraph.theme.labelTextColor
horizontalAlignment: delegateRoot.column === 0 ? Text.AlignLeft
: Text.AlignHCenter
elide: Text.ElideRight
}
}
}
} //! [2]
onCurrentRowChanged: {
var timestamp = graphData.model.get(mainview.currentRow).timestamp;
var pattern = /(\d\d\d\d)-(\d\d)/;
var matches = pattern.exec(timestamp);
var rowIndex = modelProxy.rowCategoryIndex(matches[1]);
var colIndex;
if (barGraph.columnAxis == graphAxes.total)
colIndex = 0 ;// Just one column when showing yearly totals
else
colIndex = modelProxy.columnCategoryIndex(matches[2]);
if (selectedSeries.visible)
mainview.selectedSeries.selectedBar = Qt.point(rowIndex, colIndex);
else if (barSeries.visible)
barSeries.selectedBar = Qt.point(rowIndex, colIndex);
else
secondarySeries.selectedBar = Qt.point(rowIndex, colIndex);
}
//! [2] states: [
State {
name: "landscape"
PropertyChanges {
target: dataView
width: mainview.width / 4 * 3
height: mainview.height
}
PropertyChanges {
target: tableViewLayout
height: mainview.height - buttonLayoutHeight
anchors.right: dataView.left
anchors.left: mainview.left
anchors.bottom: undefined
}
PropertyChanges {
target: controlLayout
width: mainview.width / 4
height: buttonLayoutHeight
anchors.top: tableViewLayout.bottom
anchors.bottom: mainview.bottom
anchors.left: mainview.left
anchors.right: dataView.left
}
}
]
}

坐标轴QML代码

axes.qml文件:


import QtQuick
import QtDataVisualization Item {
property alias column: columnAxis
property alias row: rowAxis
property alias value: valueAxis
property alias total: totalAxis // Custom labels for columns, since the data contains abbreviated month names.
//! [0]
CategoryAxis3D {
id: columnAxis
labels: ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
labelAutoRotation: 30
} CategoryAxis3D {
id: totalAxis
labels: ["Yearly total"]
labelAutoRotation: 30
}
CategoryAxis3D {
id: rowAxis
labelAutoRotation: 30
} ValueAxis3D {
id: valueAxis
min: 0
max: 35
labelFormat: "%.2f M\u20AC"
title: "Monthly income"
labelAutoRotation: 90
}
}

数据模型定义 QML代码

data.qml文件:

import QtQuick
import QtQml.Models Item {
property alias model: dataModel property var modelAsJsArray: {
var arr = [];
for (var i = 0; i < dataModel.count; i++) {
var row = dataModel.get(i);
arr.push({
timestamp: row.timestamp,
expenses: row.expenses,
income: row.income
});
}
return arr;
} ListModel {
id: dataModel
ListElement{ timestamp: "2016-01"; expenses: "-4"; income: "5" }
ListElement{ timestamp: "2016-02"; expenses: "-5"; income: "6" }
ListElement{ timestamp: "2016-03"; expenses: "-7"; income: "4" }
ListElement{ timestamp: "2016-04"; expenses: "-3"; income: "2" }
ListElement{ timestamp: "2016-05"; expenses: "-4"; income: "1" }
ListElement{ timestamp: "2016-06"; expenses: "-2"; income: "2" }
ListElement{ timestamp: "2016-07"; expenses: "-1"; income: "3" }
ListElement{ timestamp: "2016-08"; expenses: "-5"; income: "1" }
ListElement{ timestamp: "2016-09"; expenses: "-2"; income: "3" }
ListElement{ timestamp: "2016-10"; expenses: "-5"; income: "2" }
ListElement{ timestamp: "2016-11"; expenses: "-8"; income: "5" }
ListElement{ timestamp: "2016-12"; expenses: "-3"; income: "3" } ListElement{ timestamp: "2017-01"; expenses: "-3"; income: "1" }
ListElement{ timestamp: "2017-02"; expenses: "-4"; income: "2" }
ListElement{ timestamp: "2017-03"; expenses: "-12"; income: "4" }
ListElement{ timestamp: "2017-04"; expenses: "-13"; income: "6" }
ListElement{ timestamp: "2017-05"; expenses: "-14"; income: "11" }
ListElement{ timestamp: "2017-06"; expenses: "-7"; income: "7" }
ListElement{ timestamp: "2017-07"; expenses: "-6"; income: "4" }
ListElement{ timestamp: "2017-08"; expenses: "-4"; income: "15" }
ListElement{ timestamp: "2017-09"; expenses: "-2"; income: "18" }
ListElement{ timestamp: "2017-10"; expenses: "-29"; income: "25" }
ListElement{ timestamp: "2017-11"; expenses: "-23"; income: "29" }
ListElement{ timestamp: "2017-12"; expenses: "-5"; income: "9" } ListElement{ timestamp: "2018-01"; expenses: "-3"; income: "8" }
ListElement{ timestamp: "2018-02"; expenses: "-8"; income: "14" }
ListElement{ timestamp: "2018-03"; expenses: "-10"; income: "20" }
ListElement{ timestamp: "2018-04"; expenses: "-12"; income: "24" }
ListElement{ timestamp: "2018-05"; expenses: "-10"; income: "19" }
ListElement{ timestamp: "2018-06"; expenses: "-5"; income: "8" }
ListElement{ timestamp: "2018-07"; expenses: "-1"; income: "4" }
ListElement{ timestamp: "2018-08"; expenses: "-7"; income: "12" }
ListElement{ timestamp: "2018-09"; expenses: "-4"; income: "16" }
ListElement{ timestamp: "2018-10"; expenses: "-22"; income: "33" }
ListElement{ timestamp: "2018-11"; expenses: "-16"; income: "25" }
ListElement{ timestamp: "2018-12"; expenses: "-2"; income: "7" } ListElement{ timestamp: "2019-01"; expenses: "-4"; income: "5" }
ListElement{ timestamp: "2019-02"; expenses: "-4"; income: "7" }
ListElement{ timestamp: "2019-03"; expenses: "-11"; income: "14" }
ListElement{ timestamp: "2019-04"; expenses: "-16"; income: "22" }
ListElement{ timestamp: "2019-05"; expenses: "-3"; income: "5" }
ListElement{ timestamp: "2019-06"; expenses: "-4"; income: "8" }
ListElement{ timestamp: "2019-07"; expenses: "-7"; income: "9" }
ListElement{ timestamp: "2019-08"; expenses: "-9"; income: "13" }
ListElement{ timestamp: "2019-09"; expenses: "-1"; income: "6" }
ListElement{ timestamp: "2019-10"; expenses: "-14"; income: "25" }
ListElement{ timestamp: "2019-11"; expenses: "-19"; income: "29" }
ListElement{ timestamp: "2019-12"; expenses: "-5"; income: "7" } ListElement{ timestamp: "2020-01"; expenses: "-14"; income: "22" }
ListElement{ timestamp: "2020-02"; expenses: "-5"; income: "7" }
ListElement{ timestamp: "2020-03"; expenses: "-1"; income: "9" }
ListElement{ timestamp: "2020-04"; expenses: "-1"; income: "12" }
ListElement{ timestamp: "2020-05"; expenses: "-5"; income: "9" }
ListElement{ timestamp: "2020-06"; expenses: "-5"; income: "8" }
ListElement{ timestamp: "2020-07"; expenses: "-3"; income: "7" }
ListElement{ timestamp: "2020-08"; expenses: "-1"; income: "5" }
ListElement{ timestamp: "2020-09"; expenses: "-2"; income: "4" }
ListElement{ timestamp: "2020-10"; expenses: "-10"; income: "13" }
ListElement{ timestamp: "2020-11"; expenses: "-12"; income: "17" }
ListElement{ timestamp: "2020-12"; expenses: "-6"; income: "9" } ListElement{ timestamp: "2021-01"; expenses: "-2"; income: "6" }
ListElement{ timestamp: "2021-02"; expenses: "-4"; income: "8" }
ListElement{ timestamp: "2021-03"; expenses: "-7"; income: "12" }
ListElement{ timestamp: "2021-04"; expenses: "-9"; income: "15" }
ListElement{ timestamp: "2021-05"; expenses: "-7"; income: "19" }
ListElement{ timestamp: "2021-06"; expenses: "-9"; income: "18" }
ListElement{ timestamp: "2021-07"; expenses: "-13"; income: "17" }
ListElement{ timestamp: "2021-08"; expenses: "-5"; income: "9" }
ListElement{ timestamp: "2021-09"; expenses: "-3"; income: "8" }
ListElement{ timestamp: "2021-10"; expenses: "-13"; income: "15" }
ListElement{ timestamp: "2021-11"; expenses: "-8"; income: "17" }
ListElement{ timestamp: "2021-12"; expenses: "-7"; income: "10" } ListElement{ timestamp: "2022-01"; expenses: "-12"; income: "16" }
ListElement{ timestamp: "2022-02"; expenses: "-24"; income: "28" }
ListElement{ timestamp: "2022-03"; expenses: "-27"; income: "22" }
ListElement{ timestamp: "2022-04"; expenses: "-29"; income: "25" }
ListElement{ timestamp: "2022-05"; expenses: "-27"; income: "29" }
ListElement{ timestamp: "2022-06"; expenses: "-19"; income: "18" }
ListElement{ timestamp: "2022-07"; expenses: "-13"; income: "17" }
ListElement{ timestamp: "2022-08"; expenses: "-15"; income: "19" }
ListElement{ timestamp: "2022-09"; expenses: "-3"; income: "8" }
ListElement{ timestamp: "2022-10"; expenses: "-3"; income: "6" }
ListElement{ timestamp: "2022-11"; expenses: "-4"; income: "8" }
ListElement{ timestamp: "2022-12"; expenses: "-5"; income: "9" }
}
}

总结

本文介绍了QT数据可视化框架编程实战之三维柱状图可视化的运行效果以及具体实现代码。

如果读者对如何快速全面了解QT框架感兴趣,可以看一下这篇文章:

bird:快速全面了解QT软件界面开发技术

如果读者对如何学习QT框架有兴趣,可以看一下这篇文章:

bird:如何学习C/C++/QT软件开发技术

如果您认为这篇文章对您有所帮助,请您一定立即点赞+喜欢+收藏,本文作者将能从您的点赞+喜欢+收藏中获取到创作新的好文章的动力。如果您认为作者写的文章还有一些参考价值,您也可以关注这篇文章的作者。

QT数据可视化框架编程实战之三维柱状图_补天云QT技术培训专家的更多相关文章

  1. D3js初探及数据可视化案例设计实战

    摘要:本文以本人目前所做项目为基础,从设计的角度探讨数据可视化的设计的方法.过程和结果,起抛砖引玉之效.在技术方案上,我们采用通用web架构和d3js作为主要技术手段:考虑到项目需求,这里所做的可视化 ...

  2. 大数据学习day20-----spark03-----RDD编程实战案例(1 计算订单分类成交金额,2 将订单信息关联分类信息,并将这些数据存入Hbase中,3 使用Spark读取日志文件,根据Ip地址,查询地址对应的位置信息

    1 RDD编程实战案例一 数据样例 字段说明: 其中cid中1代表手机,2代表家具,3代表服装 1.1 计算订单分类成交金额 需求:在给定的订单数据,根据订单的分类ID进行聚合,然后管理订单分类名称, ...

  3. Qt数据可视化(散点图、折线图、柱状图、盒须图、饼状图、雷达图)开发实例

    ​  目录 散点图 折线图 柱状图 水平柱状图 水平堆叠图 水平百分比柱状图 盒须图 饼状图 雷达图 Qt散点图.折线图.柱状图.盒须图.饼状图.雷达图开发实例. 在开发过程中我们会使用多各种各样的图 ...

  4. Qt编写数据可视化大屏界面电子看板系统

    一.前言 目前大屏大数据可视化UI这块非常火,趁热也用Qt来实现一个,Qt这个一站式超大型GUI超市,没有什么他做不了的,大屏电子看板当然也不在话下,有了QSS和QPainter这两个无敌的工具组合, ...

  5. 前端数据可视化echarts.js使用指南

    一.开篇 首先这里要感谢一下我的公司,因为公司需求上面的新颖(奇葩)的需求,让我有幸可以学习到一些好玩有趣的前端技术,前端技术中好玩而且比较实用的我想应该要数前端的数据可视化这一方面,目前市面上的数据 ...

  6. 使用bokeh-scala进行数据可视化

    目录 前言 bokeh简介及胡扯 bokeh-scala基本代码 我的封装 总结 一.前言        最近在使用spark集群以及geotrellis框架(相关文章见http://www.cnbl ...

  7. 前端数据可视化echarts.js

    一.echarts.js的优势与总体情况 echarts.js作为国内的IT三巨头之一的百度的推出一款相对较为成功的开源项目,总体上来说有这样的一些优点 1.容易使用 echarts.js的官方文档比 ...

  8. Python数据可视化编程实战pdf

    Python数据可视化编程实战(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1vAvKwCry4P4QeofW-RqZ_A 提取码:9pcd 复制这段内容后打开百度 ...

  9. python数据可视化编程实战PDF高清电子书

    点击获取提取码:3l5m 内容简介 <Python数据可视化编程实战>是一本使用Python实现数据可视化编程的实战指南,介绍了如何使用Python最流行的库,通过60余种方法创建美观的数 ...

  10. Python数据可视化编程实战——导入数据

    1.从csv文件导入数据 原理:with语句打开文件并绑定到对象f.不必担心在操作完资源后去关闭数据文件,with的上下文管理器会帮助处理.然后,csv.reader()方法返回reader对象,通过 ...

随机推荐

  1. oeasy教您玩转 linux 010213 中文 fcitx

     我们来回顾一下 上一部分我们都讲了什么? 管道 ls | cowsay 管道的符号是| 管道的作用是连接 原来应该输出到屏幕的内容 通过管道流到了另一个命令做为参数 这次是否可以让cow说出一些中文 ...

  2. oeasy教您玩转vim - 28 - 水平移动

    ​ 水平移动 回忆上节课内容 根据扩展名我们可以设置某些特定类型文件的配置 相关文件类型的设置放在相应的文件夹里 文件类型缩进文件夹 /usr/share/vim/vim81/indent/ 文件类型 ...

  3. Visual Studio 必备插件集合:AI 助力开发

     一.前言 2024年AI浪潮席卷全球,编程界迎来全新的挑战与机遇.智能编程.自动化测试.代码审查,这一切都得益于AI技术的迅猛发展,它正在重塑开发者的日常,让编写代码变得更加高效.智能. 精选出最受 ...

  4. Linux 基于flock命令实现多进程并发读写文件控制

    基于flock命令实现多进程并发读写文件控制 需求描述 实际项目中,需要在Linux下通过shell脚本并发读写同一个文件,但是希望同一时刻,只有一个进程可以在读.写目标文件. 解决方案 使用floc ...

  5. 全网最好看的单细胞umap图绘制教程

    全网最好看的单细胞umap图绘制教程 作者按 大家或许都曾被Nature, Science上的单细胞umap图吸引过,不免心生崇拜.在这里,我们将介绍一种简单方便的顶刊级umap图可视化 全文字数|预 ...

  6. 洛谷[NOIP2015 普及组] 金币

    [NOIP2015 普及组] 金币 题目背景 NOIP2015 普及组 T1 题目描述 国王将金币作为工资,发放给忠诚的骑士.第一天,骑士收到一枚金币:之后两天(第二天和第三天),每天收到两枚金币:之 ...

  7. python Selenium 不要混合隐式和显式等待

    警告:不要混合隐式和显式等待.这样做可能会导致不可预测的等待时间.例如,设置10秒的隐式等待和15秒的显式等待可能会导致20秒后发生超时 Warning: Do not mix implicit an ...

  8. windows10使用scp命令

    windows10使用scp命令 windows自带scp命令 windows上传文件到linux//使用方法:scp 源文件路径 账户@地址:目的路径scp   C:\Users\zbh\Deskt ...

  9. Jmeter JDBC连接配置

    JDBC连接配置(JDBC Connection Configuration),用于创建数据库连接,后续可对数据库进行增删查等操作.和组件[JDBC请求(JDBC Request)]搭配使用 组件路径 ...

  10. 【Java】【常用类】String

    String表示字符串,Java所有的字符串字面值都是String类的实例实现 String是一个final修饰的类,代表不可变的字符序列 字符串是常量,用双引号表示,值在创建之后不能更改 Strin ...