QChart数据可视化

news2024/11/28 22:42:25

目录

一、QChart基本介绍

1.1 QChart基本概念与用途

1.2 主要类的介绍

1.2.1 QChartView类

1.2.2 QChart类

1.2.3QAbstractSeries类

1.2.4 QAbstractAxis类

1.2.5 QLegendMarker

二、与图表交互

1. 动态绘制数据

2. 深入数据

3. 缩放和滚动

4. 鼠标悬停

三、主题

四、代码实践

4.1 踩坑

4.2 线性图绘制

4.3 散点图

 4.4 柱状图

4.5 饼状图


一、QChart基本介绍

1.1 QChart基本概念与用途

        QtCharts是一个Qt模块,它提供了许多种常见的图表类型,如折线图、柱状图、饼图、散点图、区域图、极坐标图等等。使用QtCharts可以轻松地把数据可视化,帮助用户更好地理解数据,进行分析和决策。以下是Qt官方的介绍:

       The QChart class manages the graphical representation of the chart's series, legends, and axes.

        QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical representation of different types of series and other chart related objects like legend and axes. To simply show a chart in a layout, the convenience class QChartView can be used instead of QChart. In addition, line, spline, area, and scatter series can be presented as polar charts by using the QPolarChart class.

1.2 主要类的介绍

QChart主要由一下几个大类组成:

1.2.1 QChartView类

        视图对象,实际是一个独立的widget,用以展示图表。

1.2.2 QChart类

        是真正的图表对象,QChart需要添加在QChartView对象下才可在正确展示出来。

1.2.3QAbstractSeries类

        是数据集合,在QChart中添加QAbstractSeries,才可以展示出数据,否则QChart只能展现坐标轴 ,主要数据类及继承关系如下。

1.2.4 QAbstractAxis类

        坐标轴类,用来设置QChart类的坐标轴属性,包括范围、精度等,也用来将QAbstractSeries类与QChart类对应起来。

Qt Charts支持以下坐标轴类型:

  • 值轴 QValueAxis):实际值添加到图表的轴上。它是使用QValueAxis类或ValueAxis QML类型实现的。
  • 类别轴(QCategoryAxis):有命名范围和可调范围宽度
  • 条形类别轴 (QBarCategoryAxis):类似于类别轴,但所有范围的范围宽度都相同。bar类别轴是使用QBarCategoryAxis类或BarCategoryAxis QML类型实现的。
  • 日期-时间轴(QDateTimeAxis):将日期和时间添加到图表轴上。它是使用QDateTimeAxis类或DateTimeAxis QML类型实现的。
  • 对数值轴(QLogValueAxis):向图表的轴添加对数刻度。对数标度是一种基于数量级的非线性标度,因此轴上的每个刻度都是前一个刻度乘以一个值。使用QLogValueAxis类或LogValueAxis QML类型实现对数轴

       可以为一个图表定义多个轴。坐标轴可以放在图表的上下左右。此外,轴可以是不同的类型。但是,不支持混合轴类型,这会导致不同的域,例如在同一方向上指定QValueAxis和QLogValueAxis。

1.2.5 QLegendMarker

        图例是一个显示图表图例的图形对象。图例对象不能被创建或删除,但是它们可以通过QChart类被引用。当序列发生变化时,图例状态由QChart或ChartView更新。
        图例可以位于图表的下方或上方,也可以位于图表的左侧或右侧。默认情况下,图例是附加到图表视图的,但它可以分离到一个可以自由移动的单独图形项。可以隐藏图例中的单个标记,也可以隐藏整个图例。
        图例标记可以通过使用QLegendMarker基类和每个序列类型的子类来修改:

        QAreaLegendMarker、QBarLegendMarker、QBoxPlotLegendMarker、                   QCandlestickLegendMarker和QXYLegendMarker。

二、与图表交互

        用户可以通过以下方式与图表进行交互:动态地向图表添加值、深入聚焦数据、放大和缩小图表、滚动图表、单击图表中的项目或将鼠标悬停在图表上。

1. 动态绘制数据

        可以动态地向图表添加数据,并使图表视图自动滚动以显示新数据

2. 深入数据

        例如,可以将下钻效果实现为条形图或饼状图。当用户在图表中选择项目时,将显示该项的更详细视图
        例如,可以对条形图或饼图实现下钻效果。当用户在图表中选择一个项目时,将显示该项目的更详细视图。这是通过删除第一个序列并添加另一个序列来实现的。

3. 缩放和滚动

        用户可以使用键盘进行缩放和滚动。它们可以使用方向键滚动图表,也可以使用正负键放大或缩小图表。此外,QRubberBand可以用来选择要放大的区域。

4. 鼠标悬停

        可以将槽连接到终端用户单击图表中的项或将鼠标悬停在图表上时发出的信号。这使您能够向图表中添加元素,如标注。

三、主题

        主题是应用于图表的所有视觉元素的UI样式相关设置的内置集合,例如颜色、画笔、画刷和字体系列,以及轴、标题和图例。

Qt图表具有以下预定义的主题:

  • Light主题,这是默认主题
  • 天蓝色的主题
  • 黑暗的主题
  • 砂褐色主题
  • 自然颜色系统(NCS)蓝色主题
  • 高反差主题
  • 冰蓝色主题
  • Qt的主题

可以通过更改颜色、画笔、画刷和字体来定制主题。可以通过修改Qt Charts的源代码来添加新的主题

注意:更改主题将覆盖之前应用于该系列的所有自定义。

四、代码实践

4.1 踩坑

必须声明命名空间,库必须与编译器选择模式对应。

using namespace QtCharts;

4.2 线性图绘制

//折线图
	connect(ui.pushButton_zhexian, &QPushButton::clicked, this, [=] {
		//QLineSeries *lineSeries1 = new QLineSeries();  //折线
		//QLineSeries *lineSeries2 = new QLineSeries();
		QSplineSeries *lineSeries1 = new QSplineSeries(); //平滑曲线
		QLineSeries *lineSeries2 = new QLineSeries();
		qsrand(QTime::currentTime().second());
		for (int i = 0; i <= 41; ++i)
		{	
			qreal y = qrand() % 100;
			if (i <= 20)
			{
				qreal x = i;
				lineSeries1->append(x, y);
			}
			else
			{
				qreal x = i - 21;
				lineSeries2->append(x, y);
			}
		}

		lineSeries1->setColor(Qt::blue);
		lineSeries1->setPen(QPen(Qt::blue, 2));
		lineSeries1->setName("line1");//图例的名字
		lineSeries2->setColor(Qt::red);
		lineSeries2->setPen(QPen(Qt::red, 2, Qt::PenStyle::DashDotDotLine));
		lineSeries2->setName("line2");
		lineSeries1->setPointLabelsVisible(true);
		lineSeries2->setPointLabelsVisible(true);

		//创建QChart
		QChart *chart = new QChart();
		chart->setTitle("Line Chart");//设置标题
		chart->addSeries(lineSeries1); //将折线系列添加到图标
		chart->addSeries(lineSeries2);

		//修改图例
		QLegend * legned = chart->legend();
		legned->setAlignment(Qt::AlignBottom);
		legned->setBackgroundVisible(false);
		legned->setMarkerShape(QLegend::MarkerShape::MarkerShapeRectangle);

		//创建X轴
		QValueAxis *axisX = new QValueAxis();
		axisX->setLabelFormat("%.0f");//设置标签格式
		axisX->setTitleText("X轴");
		axisX->setRange(0, 20);//设置范围
		axisX->setTickCount(21); //设置tickCount 即标签数量为21 0-21
		axisX->setGridLineVisible(false);//设置主刻度线不可见
		//axisX->hide();//隐藏刻度线 X周 0-10 不可见
	

		//创建Y轴
		QValueAxis *axisY = new QValueAxis();
		axisY->setTitleText("Y轴");
		axisY->setRange(0, 100);//设置范围
		axisY->setTickCount(11); //设置tickCount 即标签数量为11 100进行10等分 11个标签 

		//关联轴到Chart和QSeries
		chart->addAxis(axisX, Qt::AlignBottom);
		chart->addAxis(axisY, Qt::AlignLeft);
		lineSeries1->attachAxis(axisX);
		lineSeries1->attachAxis(axisY);
		lineSeries2->attachAxis(axisX);
		lineSeries2->attachAxis(axisY);

		//创建QChartView 对象显示图表
		QChartView * chartview = new QChartView(chart, ui.tab_3);
		chartview->setRenderHint(QPainter::Antialiasing);//抗锯齿

		//显示窗口、
		QMainWindow *win = new QMainWindow(ui.tab_3);
		win->setCentralWidget(chartview);
		win->resize(800, 600);
		win->setWindowTitle("Test_折线图");
		win->show();
		
	});

 

4.3 散点图

connect(ui.pushButton_sactter, &QPushButton::clicked, this, [=]() {
    QScatterSeries *scatterSeries = new QScatterSeries();

	// 添加散点数据
	qsrand(QTime::currentTime().second());//设置随机数生成器的种子
	for (int i = 0; i <= 20; i++) {
		qreal x = i;
		qreal y = qrand() % 100;
		scatterSeries->append(x, y);
		qDebug() << QPoint(x, y);//测试输出
	}

	// 创建 QChart 对象
	QChart *chart = new QChart();
	chart->setTitle("Scatter Chart"); // 设置标题
	chart->addSeries(scatterSeries); // 将散点系列添加到图表中

									 // 创建 QValueAxis 对象作为 X 轴
	QValueAxis *axisX = new QValueAxis();
	axisX->setLabelFormat("%.0f"); // 设置标签格式
	axisX->setTitleText("X Axis");
	axisX->setRange(0, 20); // 设置范围
	axisX->setTickCount(21); // 设置 tickCount,即标签数量为 21
	chart->addAxis(axisX, Qt::AlignBottom); // 将 X 轴添加到图表中
	scatterSeries->attachAxis(axisX); // 散点系列关联 X 轴

									  // 创建 QValueAxis 对象作为 Y 轴
	QValueAxis *axisY = new QValueAxis();
	axisY->setTitleText("Y Axis");
	axisY->setRange(0, 100); // 设置范围
	axisY->setTickCount(11); // 设置 tickCount,即标签数量为 11
	chart->addAxis(axisY, Qt::AlignLeft); // 将 Y 轴添加到图表中
	scatterSeries->attachAxis(axisY); // 散点系列关联 Y 轴

									  // 创建 QChartView 对象显示图表
	QChartView *chartView = new QChartView(chart);
	chartView->setRenderHint(QPainter::Antialiasing); // 抗锯齿

	QMainWindow *win = new QMainWindow(ui.tab_3);
	win->setCentralWidget(chartView);
	win->resize(800, 600);
	win->setWindowTitle("Test_饼状图");
	win->show();

});

 4.4 柱状图

connect(ui.pushButton_bar, &QPushButton::clicked, this, [=]() {
	//创建柱状形集对象
	QBarSet* set1 = new QBarSet("语文");
	QBarSet* set2 = new QBarSet("数学");
	QBarSet* set3 = new QBarSet("英语");
	*set1 << 130 << 120 << 110 << 97 << 88;
	set2->append({ 148,128,137,98,88 }); 
	set3->append(123);
	set3->append(86);
	set3->append(98);
	set3->append(68);
	set3->append(99);

	set1->setLabelColor(Qt::red);
	set2->setLabelColor(Qt::green);
	set3->setLabelColor(Qt::blue);

	//QBarSet封装为QStackedBarSeries 
	//QBarSet类型封装成QStackedBarSeries类型,是因为chart->append不能接收QBarSet的类型。
	QStackedBarSeries *bar1 = new QStackedBarSeries();
	bar1->append(set1);
	QStackedBarSeries *bar2 = new QStackedBarSeries();
	bar2->append(set2);
	QStackedBarSeries *bar3 = new QStackedBarSeries();
	bar3->append(set3);

	//QChart
	QChart* chart = new QChart();
	chart->addSeries(bar1);
	chart->addSeries(bar2);
	chart->addSeries(bar3);
	//创建QChartView 对象显示图表
	QChartView * chartview = new QChartView(chart, ui.tab_3);
	//创建X轴
		QBarCategoryAxis *axisX = new QBarCategoryAxis();
		QStringList list = { "小张","王五","晓明" ,"小红" ,"小绿" };
		axisX->append(list);
		axisX->setTitleText("姓名");
		axisX->setGridLineVisible(false);
		
		//创建Y轴
		QValueAxis *axisY = new QValueAxis();
		axisY->setTitleText("成绩");
		axisY->setRange(0, 150);//设置范围
		axisY->setTickCount(6); //设置tickCount 即标签数量为6 150进行5等分 6个标签 
	
		//设定坐标轴与数据对应
		chart->setAxisX(axisX, bar1);
		chart->setAxisX(axisX, bar2);
        chart->setAxisX(axisX, bar3);
	
		chart->setAxisY(axisY, bar1);
		chart->setAxisY(axisY, bar2);
		chart->setAxisY(axisY, bar3);
	
		//显示窗口、
		QMainWindow *win = new QMainWindow(ui.tab_3);
		win->setCentralWidget(chartview);
		win->resize(800, 600);
		win->setWindowTitle("Test_柱状图");
		win->show();
	
	});

4.5 饼状图

        该代码中实践饼状图的基本绘制方法和图形属性的设置,设置opengl加速绘制以及chartview的grap抓取保存图片的方法对比QScreen的截屏效果。

connect(ui.pushButton_bingzhuang, &QPushButton::clicked, this, [=]() {
		QChartView*view = new QChartView(ui.tab_3);
		view->setRenderHint(QPainter::Antialiasing);
		QChart* chart = new QChart();
		chart->setTitle("成绩分布");
		view->setChart(chart);

		//设置饼图
		QPieSeries*pie = new QPieSeries;
		QPieSlice* s1 = pie->append("60分以下",20);
		QPieSlice* s2 = pie->append("60-80分", 30);
		QPieSlice* s3 = pie->append("60-90分", 30);
		QPieSlice* s4 = pie->append("90-100分", 20);
		s4->setExploded(true);//设置此分块突出
		
		pie->setHoleSize(0.4);// 设置饼状图中间洞大小 0.0-1.0之间
		pie->setLabelsPosition(QPieSlice::LabelOutside);//设置slice label的位置
		pie->setLabelsVisible(true);
		pie->setUseOpenGL(true);//使用OpenGl来画 GPU 并行不卡顿 QAbstractSeries方法
		//字体
		QFont font = qApp->font();
		font.setBold(true);
		font.setPointSize(20);
		chart->setTitleFont(font);
		//图例
		chart->legend()->setAlignment(Qt::AlignLeft);

		//设置各个模块颜色
		s1->setColor(Qt::red);
		s2->setColor(Qt::blue);
		s3->setColor(Qt::green);
		s4->setColor(Qt::yellow);

		chart->addSeries(pie);
		//设置主题 默认light
		chart->setTheme(QChart::ChartTheme::ChartThemeBlueCerulean);
		//显示窗口、
		QMainWindow *win = new QMainWindow(ui.tab_3);
		win->setCentralWidget(view);
		win->resize(800, 600);
		win->setWindowTitle("Test_饼状图");
		win->show();

		//保存图片 ChartView 自有方式
		QPixmap p = view->grab();//
		QImage image = p.toImage();
		image.save("chart.png");

		//截屏 通过winID
		QScreen *screen=QGuiApplication::primaryScreen();//保留应用程序的主屏幕(最初显示QWindows的屏幕)
		QPixmap pic = screen->grabWindow(view->winId());
		QImage image2 = pic.toImage();
		image2.save("chartPie.png");

	});

 

五、在实际项目中的应用 

        QCharts在实际的项目中可以很好的可视化数据,以多种形式统计可视化程序每日产生的数据,从而多维度的评估项目的运行状况和运维效果等。

       如在交通的停车场场景中对于不同时间尺度可以使用折线图统计车流量(对于商场等常有活动的车场运维更有意义),通过饼状图统计不同支付方式的占比(对于企事业单位学校等固定卡、储值卡、临时卡、ETC等统计更有意义)、通过统计车厂外围不同设备的异常更好的评估运行的稳定性、通过统计每日相机的识别平均置信度评估相机等架设合理性等等。

        业务的评估对于不同场景下的运营状况有直观的反馈,设备 异常、识别率、不同级别的错误报告、内存使用等等的统计对于无人车厂运行的稳定应也有直观的反馈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249347.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot源码-spring boot启动入口ruan方法主线分析(一)

一、SpringBoot启动的入口 1.当我们启动一个SpringBoot项目的时候&#xff0c;入口程序就是main方法&#xff0c;而在main方法中就执行了一个run方法。 SpringBootApplication public class StartApp {public static void main(String[] args) {// testSpringApplication.ru…

C#变量和函数如何和unity组件绑定

1.Button On_click (1)GameObject通过Add component添加上Script (2)Button选GameObject组件而不是直接选Script,直接选Script出现不了Script中的函数 2.RawImage 上面是错的 3.Text 上面是错的&#xff0c;应该是直接在GameObject里面填上对应的值 总结&#xff1a; …

Flink Sink的使用

经过一系列Transformation转换操作后&#xff0c;最后一定要调用Sink操作&#xff0c;才会形成一个完整的DataFlow拓扑。只有调用了Sink操作&#xff0c;才会产生最终的计算结果&#xff0c;这些数据可以写入到的文件、输出到指定的网络端口、消息中间件、外部的文件系统或者是…

【Spring MVC】如何获取cookie/session以及响应@RestController的理解,Header的设置

前言 &#x1f31f;&#x1f31f;本期讲解关于SpringMVC的编程之参数传递~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废…

使用 exe4j 将 Spring Boot 项目打包为 EXE 可执行文件

使用 exe4j 将 Spring Boot 项目打包为 EXE 可执行文件 文章目录 使用 exe4j 将 Spring Boot 项目打包为 EXE 可执行文件什么是 exe4j准备工作打包 Spring Boot 项目为 EXE 文件1.启动 exe4j2. 选择项目类型3. 配置项目名称和输出目录4. 配置项目类型或可执行文件名称5. java配…

前端JavaScript(一)---基本介绍

Javascript是一种由Netscape(网景)的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言&#xff0c;主要目的是为了解决服务器端语言&#xff0c;比如Perl&#xff0c;遗留的速度问题&#xff0c;为客户提供更流畅的浏览效果。当时服务端需要对…

阿里Qwen系列开源模型介绍

模型种类丰富 Qwen2&#xff1a;包含Qwen2-0.5b、Qwen2-1.5b、Qwen2-7b、Qwen2-57b-a14b以及Qwen2-72b等五种规模的预训练和指令微调模型&#xff0c;其在多语言处理、长文本处理、代码生成、数学和逻辑推理等能力上&#xff0c;在mmlu、gpqa、humaneval等国际测评中得到了验证…

基于Java的小程序电商商城开源设计源码

近年来电商模式的发展越来越成熟&#xff0c;基于 Java 开发的小程序电商商城开源源码&#xff0c;为众多开发者和企业提供了构建个性化电商平台的有力工具。 基于Java的电子商城购物平台小程序的设计在手机上运行&#xff0c;可以实现管理员&#xff1b;首页、个人中心、用户…

开源 AI 智能名片 2 + 1 链动模式 S2B2C 商城小程序源码助力品牌共建:价值、策略与实践

摘要&#xff1a;在当今数字化商业环境下&#xff0c;品牌构建已演变为企业与消费者深度共建的过程。本文聚焦于“开源 AI 智能名片 2 1 链动模式 S2B2C 商城小程序源码”&#xff0c;探讨其如何融入品牌建设&#xff0c;通过剖析品牌价值构成&#xff0c;阐述该技术工具在助力…

力扣797. 所有可能的路径

算法思想 深度优先搜索&#xff08;DFS&#xff09;&#xff1a; 使用递归从节点 0 开始&#xff0c;探索所有从当前节点到终点 n−1 的路径。每次访问一个节点时&#xff0c;将该节点加入当前路径 path。 回溯法&#xff1a; 在递归返回时&#xff0c;通过 path.pop_back()…

AMD(Xilinx) FPGA配置Flash大小选择

目录 1 FPGA配置Flash大小的决定因素2 为什么选择的Flash容量大小为最小保证能够完成整个FPGA的配置呢&#xff1f; 1 FPGA配置Flash大小的决定因素 在进行FPGA硬件设计时&#xff0c;选择合适的配置Flash是我们进行硬件设计必须考虑的&#xff0c;那么配置Flash大小的选择由什…

Git简单介绍

一、 Git介绍与安装 1.1 Git简介 Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 1.2集中式(SVN&#xff09; VS 分布式(git) 集中式版本控制系统&#xff0c;版本库是集中存放在中央服务器的&#xff0c;工作时要先从中央…

FreeSWITCH 简单图形化界面34 - 网络环境安全的情况下,进行任意SIP注册

FreeSWITCH 简单图形化界面34 -网络环境安全的情况下&#xff0c;进行任意SIP注册 测试环境1、前言2、参数3、实践一下 测试环境 http://myfs.f3322.net:8020/ 用户名&#xff1a;admin&#xff0c;密码&#xff1a;admin FreeSWITCH界面安装参考&#xff1a;https://blog.cs…

力扣 二叉树的层序遍历-102

二叉树的层序遍历-102 class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> res; // 二维数组用来存储每层节点if (root nullptr)return res;queue<TreeNode*> q; // 队列用来进行层序遍历q.push(r…

鸿蒙学习使用本地真机运行应用/元服务 (开发篇)

文章目录 1、前提条件2、使用USB连接方式3、使用无线调试连接方式4、运行 1、前提条件 在Phone和Tablet中运行HarmonyOS应用/元服务的操作方法一致&#xff0c;可以采用USB连接方式或者无线调试的连接方式。两种连接方式是互斥的&#xff0c;只能使用一种&#xff0c;无法同时…

数据库导论

data 数据是数据库中存储的基本数据&#xff0c;描述事物的符号称为数据。 DB 数据库是长期存储在计算机内&#xff0c;有组织&#xff0c;可共享的大量数据的集合。数据库中的数据按照一定的数据模型组织&#xff0c;描述和存储&#xff0c;具有较小的冗余度&#xff0c;较…

数据结构 ——— 归并排序算法的实现

目录 归并排序的思想 归并排序算法的实现 归并排序的思想 将已经有序的子序列合并&#xff0c;得到完全有序的序列&#xff0c;即先使每个子序列有序后&#xff0c;再使子序列段间有序 若将两个有序表合并成一个有序表&#xff0c;称为二路归并 归并排序步骤示意图&#x…

【数据结构】【线性表】一文讲完队列(附C语言源码)

队列 队列的基本概念基本术语基本操作 队列的顺序实现顺序队列结构体的创建顺序队列的初始化顺序队列入队顺序队列出队顺序队列存在的问题分析循环队列代码汇总 队列的链式实现链式队列的创建链式队列初始化-不带头结点链式队列入队-不带头节点链式队列出队-不带头结点带头结点…

chrome允许http网站打开摄像头和麦克风

第一步 chrome://flags/#unsafely-treat-insecure-origin-as-secure 第二步 填入网址&#xff0c;点击启用 第三步 重启 Chrome&#xff1a;设置完成后&#xff0c;点击页面底部的 “Relaunch” 按钮&#xff0c;重新启动 Chrome 浏览器&#xff0c;使更改生效。

Spring Boot教程之十: 使用 Spring Boot 实现从数据库动态下拉列表

使用 Spring Boot 实现从数据库动态下拉列表 动态下拉列表&#xff08;或依赖下拉列表&#xff09;的概念令人兴奋&#xff0c;但编写起来却颇具挑战性。动态下拉列表意味着一个下拉列表中的值依赖于前一个下拉列表中选择的值。一个简单的例子是三个下拉框&#xff0c;分别显示…