探索基于QCustomPlot的强大数据可视化工具

qcustomplot曲线图,数据可视化分析工具源码;加载excel和xml数据展示,数据接口可很方便扩展,数据展示具备多条曲线同时窗口展示,支持多窗口的鼠标同步操作(滚轮缩放,左键平移,右键框选等功能),添加阈值线-计算范围值;支持属性面板设置曲线样式,窗口布局类似于vs可以隐藏/显示dock窗口;代码可以扩展,采用qt5.9环境开发;

在数据驱动的时代,高效的数据可视化对于理解和分析数据至关重要。今天咱就来唠唠一个基于QCustomPlot开发的数据可视化分析工具,它功能那叫一个丰富,源码在手,探索不愁。

一、整体框架与开发环境

这个工具基于Qt5.9环境开发。Qt可是个好东西,跨平台能力一流,让咱开发效率蹭蹭往上涨。为啥选Qt5.9呢?稳定呀,很多功能已经相当成熟,对各种系统的适配也很到位。

二、数据加载

1. Excel数据加载

加载Excel数据,极大地方便了从常见办公数据文件中获取信息。在Qt中,咱可以借助第三方库如QAxObject来实现Excel数据读取。以下是一段简单示例代码:

cpp 复制代码
#include <QAxObject>
void loadExcelData(const QString& filePath) {
    QAxObject excel("Excel.Application");
    excel.setProperty("Visible", false);
    QAxObject* workbooks = excel.querySubObject("Workbooks");
    QAxObject* workbook = workbooks->querySubObject("Open(const QString&)", filePath);
    QAxObject* worksheet = workbook->querySubObject("Sheets(int)", 1);
    QAxObject* usedRange = worksheet->querySubObject("UsedRange");
    QAxObject* rows = usedRange->querySubObject("Rows");
    int rowCount = rows->property("Count").toInt();
    QAxObject* columns = usedRange->querySubObject("Columns");
    int columnCount = columns->property("Count").toInt();

    for (int i = 1; i <= rowCount; ++i) {
        for (int j = 1; j <= columnCount; ++j) {
            QAxObject* cell = worksheet->querySubObject("Cells(int, int)", i, j);
            QVariant cellValue = cell->dynamicCall("Value");
            // 这里可以将cellValue处理后存储到你的数据结构中
            qDebug() << cellValue;
            cell->deleteLater();
        }
    }

    workbook->dynamicCall("Close()");
    workbooks->deleteLater();
    excel.dynamicCall("Quit()");
    excel.deleteLater();
}

代码分析:首先创建了一个Excel应用程序对象,并设置其不可见。然后通过Workbooks对象打开指定的Excel文件,获取第一个工作表。接着确定使用范围的行列数,遍历每个单元格获取其值。最后关闭工作簿、工作簿集合以及Excel应用程序。

2. XML数据加载

XML也是常用的数据存储格式,Qt提供了QXmlStreamReader来方便地解析XML数据。示例代码如下:

cpp 复制代码
#include <QFile>
#include <QXmlStreamReader>
void loadXmlData(const QString& filePath) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Could not open file";
        return;
    }
    QXmlStreamReader xmlReader(&file);
    while (!xmlReader.atEnd() &&!xmlReader.hasError()) {
        QXmlStreamReader::TokenType token = xmlReader.readNext();
        if (token == QXmlStreamReader::StartDocument) {
            continue;
        }
        if (token == QXmlStreamReader::StartElement) {
            if (xmlReader.name() == "data") {
                // 处理data元素下的子元素
                while (!(xmlReader.atEnd() || xmlReader.hasError()) && (token = xmlReader.readNext())!= QXmlStreamReader::EndElement) {
                    if (token == QXmlStreamReader::StartElement) {
                        if (xmlReader.name() == "item") {
                            QString value = xmlReader.attributes().value("value").toString();
                            // 这里可以将value处理后存储到你的数据结构中
                            qDebug() << value;
                        }
                    }
                }
            }
        }
    }
    if (xmlReader.hasError()) {
        qDebug() << "XML parsing error: " << xmlReader.errorString();
    }
    file.close();
}

代码分析:打开XML文件后,通过QXmlStreamReader逐行读取。遇到开始文档标记就跳过,遇到开始元素标记时,如果是"data"元素,就进一步处理其下的"item"子元素,并获取"value"属性值。最后检查是否有解析错误并关闭文件。

三、数据展示

1. 多曲线同时展示

QCustomPlot是实现多曲线展示的利器。下面看看如何在窗口中同时展示多条曲线:

cpp 复制代码
#include "qcustomplot.h"
void setupMultiCurvePlot(QCustomPlot* customPlot) {
    QVector<double> x(101), y1(101), y2(101);
    for (int i = 0; i < 101; ++i) {
        x[i] = i / 10.0;
        y1[i] = sin(x[i]);
        y2[i] = cos(x[i]);
    }
    customPlot->addGraph();
    customPlot->graph(0)->setData(x, y1);
    customPlot->graph(0)->setPen(QPen(Qt::blue));

    customPlot->addGraph();
    customPlot->graph(1)->setData(x, y2);
    customPlot->graph(1)->setPen(QPen(Qt::red));

    customPlot->xAxis->setLabel("X Axis");
    customPlot->yAxis->setLabel("Y Axis");
    customPlot->replot();
}

代码分析:先创建了三个QVector分别存储x轴数据以及两条曲线的y轴数据。通过addGraph方法添加两条曲线,分别设置数据和画笔颜色。最后设置坐标轴标签并重新绘制图表。

2. 多窗口鼠标同步操作

实现多窗口鼠标同步操作,让用户在不同窗口间能以相同的交互方式查看数据。以滚轮缩放为例,在每个窗口的鼠标滚轮事件处理函数中:

cpp 复制代码
void MainWindow::wheelEvent(QWheelEvent* event) {
    if (event->delta() > 0) {
        ui->customPlot->xAxis->scaleRange(0.9, ui->customPlot->xAxis->range().center());
        ui->customPlot->yAxis->scaleRange(0.9, ui->customPlot->yAxis->range().center());
    } else {
        ui->customPlot->xAxis->scaleRange(1.1, ui->customPlot->xAxis->range().center());
        ui->customPlot->yAxis->scaleRange(1.1, ui->customPlot->yAxis->range().center());
    }
    ui->customPlot->replot();
    // 同步到其他窗口,这里假设还有一个customPlot2
    ui->customPlot2->xAxis->scaleRange(ui->customPlot->xAxis->scaleFactor(), ui->customPlot->xAxis->range().center());
    ui->customPlot2->yAxis->scaleRange(ui->customPlot->yAxis->scaleFactor(), ui->customPlot->yAxis->range().center());
    ui->customPlot2->replot();
}

代码分析:根据滚轮滚动方向,对当前窗口的坐标轴进行缩放,然后重新绘制。接着将缩放比例同步到其他窗口并重新绘制。左键平移和右键框选功能实现思路类似,都是通过获取鼠标事件的坐标信息,计算相应的偏移量或区域,然后应用到各个窗口的图表上。

3. 添加阈值线 - 计算范围值

添加阈值线能直观地显示数据与设定值的关系。以下是添加阈值线的代码:

cpp 复制代码
void addThresholdLine(QCustomPlot* customPlot, double threshold) {
    QCPItemLine* thresholdLine = new QCPItemLine(customPlot);
    thresholdLine->start->setCoords(customPlot->xAxis->range().lower, threshold);
    thresholdLine->end->setCoords(customPlot->xAxis->range().upper, threshold);
    thresholdLine->setPen(QPen(Qt::green, 1, Qt::DashLine));
}

代码分析:创建一个QCPItemLine对象,设置其起点和终点的坐标,使其跨越整个x轴范围且y坐标为设定的阈值。同时设置画笔为绿色虚线,这样就添加好了阈值线。计算范围值可以通过获取图表数据的最值来实现,比如:

cpp 复制代码
double minY = ui->customPlot->graph(0)->data()->at(0).value;
double maxY = ui->customPlot->graph(0)->data()->at(0).value;
for (int i = 1; i < ui->customPlot->graph(0)->data()->size(); ++i) {
    double value = ui->customPlot->graph(0)->data()->at(i).value;
    if (value < minY) {
        minY = value;
    }
    if (value > maxY) {
        maxY = value;
    }
}
double rangeValue = maxY - minY;

代码分析:先初始化最小值和最大值为第一条曲线的第一个数据点的值,然后遍历曲线数据,更新最小值和最大值,最后计算范围值。

四、属性面板与窗口布局

1. 属性面板设置曲线样式

通过属性面板可以灵活地调整曲线样式。比如,在属性面板中选择曲线颜色,然后更新图表曲线颜色的代码:

cpp 复制代码
void MainWindow::on_colorComboBox_currentIndexChanged(int index) {
    QColor color = QColorDialog::customColor(index);
    ui->customPlot->graph(0)->setPen(QPen(color));
    ui->customPlot->replot();
}

代码分析:当颜色选择框的索引改变时,获取对应的颜色,设置到第一条曲线上并重新绘制图表。

2. 类似VS的窗口布局

采用Qt的QDockWidget来实现类似VS的窗口布局,可以方便地隐藏/显示dock窗口。

cpp 复制代码
QDockWidget* dockWidget = new QDockWidget("Data Panel", this);
QWidget* dockWidgetContents = new QWidget();
// 在dockWidgetContents中添加各种控件,比如属性面板的控件
dockWidget->setWidget(dockWidgetContents);
addDockWidget(Qt::RightDockWidgetArea, dockWidget);

代码分析:创建一个QDockWidget对象,并设置其标题。然后创建一个内容部件,将其设置为dock窗口的部件,最后将dock窗口添加到主窗口的右侧停靠区域。

五、代码扩展性

整个工具的代码设计得很有扩展性。比如数据接口部分,若要添加新的数据来源,只需要按照现有数据加载的模式,实现新的数据读取逻辑并集成到数据加载模块中。像前面提到的Excel和XML数据加载,都是相对独立的模块,新的数据加载方式也可以以类似方式加入,不会对其他部分造成太大影响。

qcustomplot曲线图,数据可视化分析工具源码;加载excel和xml数据展示,数据接口可很方便扩展,数据展示具备多条曲线同时窗口展示,支持多窗口的鼠标同步操作(滚轮缩放,左键平移,右键框选等功能),添加阈值线-计算范围值;支持属性面板设置曲线样式,窗口布局类似于vs可以隐藏/显示dock窗口;代码可以扩展,采用qt5.9环境开发;

总之,这个基于QCustomPlot的数据可视化分析工具,从数据加载到展示,再到用户交互和布局设置,功能丰富且代码具备良好的扩展性,在实际的数据处理和分析场景中能发挥大作用。希望大家可以基于它进行更多有趣的开发和探索。

相关推荐
fen_fen17 小时前
Oracle建表语句示例
数据库·oracle
此刻你21 小时前
常用的 SQL 语句
数据库·sql·oracle
海心焱1 天前
从零开始构建 AI 插件生态:深挖 MCP 如何打破 LLM 与本地数据的连接壁垒
jvm·人工智能·oracle
德彪稳坐倒骑驴1 天前
MySQL Oracle面试题
数据库·mysql·oracle
吕司1 天前
MySQL库的操作
数据库·mysql·oracle
dishugj1 天前
【Oracle】 rac的一些问题以及解决方案
数据库·oracle
eWidget1 天前
面向信创环境的Oracle兼容型数据库解决方案
数据库·oracle·kingbase·数据库平替用金仓·金仓数据库
熊文豪1 天前
关系数据库替换用金仓——Oracle兼容性深度解析
数据库·oracle·金仓数据库·电科金仓·kes
eWidget1 天前
面向Oracle生态的国产高兼容数据库解决方案
数据库·oracle·kingbase·数据库平替用金仓·金仓数据库
A懿轩A1 天前
【MySQL 数据库】MySQL 数据库核心概念详解:库、表、字段、主键与关系型模型一文读懂
数据库·mysql·oracle