From 0cd8e3e85130b7bcc8856bbd3ede263908fc9bc6 Mon Sep 17 00:00:00 2001 From: zynfly Date: Fri, 7 Jan 2022 15:42:08 +0800 Subject: [PATCH] Init Commit --- .gitignore | 2 + CMakeLists.txt | 55 ++++++++++++++ DataTableModel.cpp | 114 +++++++++++++++++++++++++++++ DataTableModel.h | 44 ++++++++++++ Pearson.cpp | 39 ++++++++++ Pearson.h | 33 +++++++++ icon.ico | Bin 0 -> 161862 bytes main.cpp | 12 ++++ mainwindow.cpp | 175 +++++++++++++++++++++++++++++++++++++++++++++ mainwindow.h | 72 +++++++++++++++++++ mainwindow.ui | 149 ++++++++++++++++++++++++++++++++++++++ resource.rc | 1 + 12 files changed, 696 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 DataTableModel.cpp create mode 100644 DataTableModel.h create mode 100644 Pearson.cpp create mode 100644 Pearson.h create mode 100644 icon.ico create mode 100644 main.cpp create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h create mode 100644 mainwindow.ui create mode 100644 resource.rc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e3fcfb5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +cmake-build-*/ +.idea/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..52ef028 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.21) +project(Pearson) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + + +find_package(Qt5 COMPONENTS + Core + Gui + Widgets + REQUIRED) + +if (WIN32) + add_executable(Pearson WIN32 main.cpp mainwindow.cpp mainwindow.h mainwindow.ui Pearson.cpp Pearson.h DataTableModel.cpp DataTableModel.h) + target_sources(Pearson PRIVATE resource.rc) +else () + add_executable(Pearson main.cpp mainwindow.cpp mainwindow.h mainwindow.ui Pearson.cpp Pearson.h DataTableModel.cpp DataTableModel.h) +endif () +target_link_libraries(Pearson + Qt5::Core + Qt5::Gui + Qt5::Widgets + ) + +if (MSVC) + set(DEBUG_SUFFIX) + if (CMAKE_BUILD_TYPE MATCHES "Debug") + set(DEBUG_SUFFIX "d") + endif () + set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}") + if (NOT EXISTS "${QT_INSTALL_PATH}/bin") + set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..") + if (NOT EXISTS "${QT_INSTALL_PATH}/bin") + set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..") + endif () + endif () + if (EXISTS "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll") + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory + "$/plugins/platforms/") + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll" + "$/plugins/platforms/") + endif () + foreach (QT_LIB Core Gui Widgets) + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + "${QT_INSTALL_PATH}/bin/Qt5${QT_LIB}${DEBUG_SUFFIX}.dll" + "$") + endforeach (QT_LIB) +endif () diff --git a/DataTableModel.cpp b/DataTableModel.cpp new file mode 100644 index 0000000..5e752dc --- /dev/null +++ b/DataTableModel.cpp @@ -0,0 +1,114 @@ +// +// Created by fly on 2021/11/25. +// + +#include "DataTableModel.h" +#include +#include + + +DataTableModel::DataTableModel(QObject *parent) : QAbstractTableModel(parent) { + m_headerData << "Name" << "Pearson" << "Pearson.Abs"; +} + +QVariant DataTableModel::headerData(int section, Qt::Orientation orientation, int role) const { + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { + return m_headerData.at(section); + } + return QAbstractItemModel::headerData(section, orientation, role); +} + +int DataTableModel::rowCount(const QModelIndex &parent) const { + return m_tableData.size(); +} + +int DataTableModel::columnCount(const QModelIndex &parent) const { + return m_headerData.size(); +} + +QVariant DataTableModel::data(const QModelIndex &index, int role) const { + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) { + auto const &row = m_tableData.at(index.row()); + switch (index.column()) { + case 0: + return std::get<0>(row); + case 1: + return std::get<1>(row); + case 2: + return std::get<2>(row); + default: + break; + } + } + + return QVariant(); +} + +void DataTableModel::clear() { + beginResetModel(); + m_tableData.clear(); + endResetModel(); +} + +void DataTableModel::InsertRow(QString name, double pearson) { + beginInsertRows(QModelIndex(), m_tableData.size(), m_tableData.size()); + m_tableData.push_back({name, pearson, std::abs(pearson)}); + endInsertRows(); +} + +void DataTableModel::sort(int column, Qt::SortOrder order) { + beginResetModel(); + std::sort(m_tableData.begin(), m_tableData.end(), [&](auto first, auto last) { + if (order == Qt::AscendingOrder) { + switch (column) { + case 0: + return std::get<0>(first) > std::get<0>(last); + break; + case 1: + return std::get<1>(first) > std::get<1>(last); + break; + case 2: + return std::get<2>(first) > std::get<2>(last); + break; + default: + break; + } + } else { + switch (column) { + case 0: + return std::get<0>(first) < std::get<0>(last); + break; + case 1: + return std::get<1>(first) < std::get<1>(last); + break; + case 2: + return std::get<2>(first) < std::get<2>(last); + break; + default: + break; + } + } + return false; + }); + endResetModel(); +// QAbstractItemModel::sort(column, order); +} + +bool DataTableModel::SaveFile(const QString &fileName) { + QFile saveFile(fileName); + if (saveFile.open(QFile::WriteOnly)) { + auto header = QString("%1,%2,%3\r\n").arg(m_headerData.at(0)).arg(m_headerData.at(1)).arg(m_headerData.at(2)); + saveFile.write(header.toLocal8Bit()); + for (auto const &data: m_tableData) { + auto strData = QString("%1,%2,%3\r\n").arg(std::get<0>(data)).arg(std::get<1>(data)).arg(std::get<2>(data)); + saveFile.write(strData.toLocal8Bit()); + } + saveFile.close(); + return true; + } + + return false; +} diff --git a/DataTableModel.h b/DataTableModel.h new file mode 100644 index 0000000..bafe28c --- /dev/null +++ b/DataTableModel.h @@ -0,0 +1,44 @@ +// +// Created by fly on 2021/11/25. +// + +#ifndef PEARSON_DATATABLEMODEL_H +#define PEARSON_DATATABLEMODEL_H + +#include +#include +#include +#include +#include +#include + +class DataTableModel : public QAbstractTableModel { +Q_OBJECT +public: + explicit DataTableModel(QObject *parent = nullptr); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + void sort(int column, Qt::SortOrder order) override; + + void clear(); + + void InsertRow(QString name, double pearson); + + bool SaveFile(QString const &fileName); + +private: + QStringList m_headerData; + std::vector> m_tableData; +}; + + +#endif //PEARSON_DATATABLEMODEL_H diff --git a/Pearson.cpp b/Pearson.cpp new file mode 100644 index 0000000..aee0f98 --- /dev/null +++ b/Pearson.cpp @@ -0,0 +1,39 @@ +// +// Created by fly on 2021/11/25. +// + +#include "Pearson.h" +#include +#include + +Pearson::Pearson(uint64_t index, const std::vector &primary, const std::vector &other, QObject *parent) + : + m_index(index), + m_primary(primary), + m_other(other), + QObject(parent) { + +} + +void Pearson::run() { + auto n = m_primary.size() * 1.0; + double pearson = n * std::inner_product(m_primary.begin(), m_primary.end(), m_other.begin(), 0.0) - + std::accumulate(m_primary.begin(), m_primary.end(), 0.0) * + std::accumulate(m_other.begin(), m_other.end(), 0.0); + + double temp1 = n * std::inner_product(m_primary.begin(), m_primary.end(), m_primary.begin(), 0.0) - + std::pow(std::accumulate(m_primary.begin(), m_primary.end(), 0.0), 2.0); + double temp2 = n * std::inner_product(m_other.begin(), m_other.end(), m_other.begin(), 0.0) - + std::pow(std::accumulate(m_other.begin(), m_other.end(), 0.0), 2.0); + temp1 = std::sqrt(temp1); + temp2 = std::sqrt(temp2); + auto temp = (temp1 * temp2); + if (temp != 0) { + pearson = pearson / temp; + if (!std::isnan(pearson)) { + emit result(m_index, pearson); + } + } + + emit finished(); +} diff --git a/Pearson.h b/Pearson.h new file mode 100644 index 0000000..9ab2e4c --- /dev/null +++ b/Pearson.h @@ -0,0 +1,33 @@ +// +// Created by fly on 2021/11/25. +// + +#ifndef PEARSON_PEARSON_H +#define PEARSON_PEARSON_H + +#include +#include +#include + +class Pearson : public QObject, public QRunnable { +Q_OBJECT +public: + Pearson(uint64_t index, std::vector const &primary, std::vector const &other, + QObject *parent = nullptr); + + void run() override; + +signals: + + void result(uint64_t index, double pearson); + + void finished(); + +private: + std::vector const &m_primary; + std::vector const &m_other; + uint16_t m_index; +}; + + +#endif //PEARSON_PEARSON_H diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..4b63f569d89c8cb4664996d2715bb4e2397113b3 GIT binary patch literal 161862 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 Q%9!(A{tk~*J3bEme`NO`IRF3v literal 0 HcmV?d00001 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..5834df1 --- /dev/null +++ b/main.cpp @@ -0,0 +1,12 @@ +#include +#include "mainwindow.h" + +int main(int argc, char *argv[]) { + QApplication a(argc, argv); + + qRegisterMetaType("uint64_t"); + MainWindow w; + w.show(); + + return QApplication::exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..e8c00f6 --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,175 @@ +// +// Created by fly on 2021/11/25. +// + +// You may need to build the project (run Qt uic code generator) to get "ui_MainWindow.h" resolved + +#include "mainwindow.h" +#include "ui_MainWindow.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "Pearson.h" + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), ui(new Ui::MainWindow) { + ui->setupUi(this); + + m_threadPool.setMaxThreadCount(1); + + InitWidgetEnableState(); + InitThreadCountComboBox(); + InitTableView(); +} + +void MainWindow::InitHeaderComboBox() { + ui->primaryColComboBox->setEnabled(true); + ui->dropColComboBox->setEnabled(true); + + ui->primaryColComboBox->clear(); + ui->dropColComboBox->clear(); + + for (uint64_t i = 0; i < m_dataHeader.size(); ++i) { + ui->primaryColComboBox->addItem(m_dataHeader.at(i), i); + ui->dropColComboBox->addItem(m_dataHeader.at(i)); + } +} + +void MainWindow::InitThreadCountComboBox() { + auto count = QThread::idealThreadCount(); + for (int i = 1; i <= count; ++i) { + ui->threadCountComboBox->addItem(QString("%1").arg(i), i); + } + ui->threadCountComboBox->setCurrentIndex(0); +} + +void MainWindow::InitTableView() { + ui->tableView->setModel(&m_dataTableModel); + ui->tableView->setSelectionMode(QTableView::SingleSelection); + ui->tableView->setSelectionBehavior(QTableView::SelectRows); + ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + ui->tableView->setSortingEnabled(true); +} + +MainWindow::~MainWindow() { + delete ui; +} + +void MainWindow::InitWidgetEnableState() { + ui->primaryColComboBox->setEnabled(false); + ui->dropColComboBox->setEnabled(false); + ui->progressBar->setValue(0); + ui->threadCountComboBox->setEnabled(false); + ui->exportDataButton->setEnabled(false); + ui->startAnalysisButton->setEnabled(false); +} + +void MainWindow::on_exploreButton_clicked() { + m_fileName = QFileDialog::getOpenFileName(this, "请选择要分析的csv文件", "", "CSV File (*.csv)"); + if (m_fileName.size()) { + ui->openFileButton->setEnabled(true); + ui->filePathEdit->setText(m_fileName); + InitWidgetEnableState(); + } +} + +void MainWindow::on_openFileButton_clicked() { + static QRegExp split("\\s?,\\s?"); + static QRegExp remove("[ \\r\\n]"); + QFile file(m_fileName); + if (file.open(QFile::ReadOnly)) { + m_dataHeader.clear(); + m_dataVector.clear(); + QString headerLine = file.readLine(); + headerLine.remove(remove); + auto headers = headerLine.split(split); + for (const auto &header: headers) { + m_dataHeader.emplace_back(header); + m_dataVector.emplace_back(); + } + + while (!file.atEnd()) { + QString dataLine = file.readLine(); + dataLine.remove(remove); + auto strData = dataLine.split(split); + for (int i = 0; i < strData.size(); ++i) { + m_dataVector[i].push_back(strData[i].toDouble()); + } + } + + InitHeaderComboBox(); + } +} + +void MainWindow::on_primaryColComboBox_currentIndexChanged(int index) { + if (0 <= index) { + ui->threadCountComboBox->setEnabled(true); + ui->exportDataButton->setEnabled(true); + ui->startAnalysisButton->setEnabled(true); + m_primaryIndex = ui->primaryColComboBox->currentData().toULongLong(); + } +} + +void MainWindow::on_dropColComboBox_currentIndexChanged(int index) { + if (index == -1) return; + auto colName = ui->dropColComboBox->currentText(); + auto items = ui->dropListWidget->findItems(colName, Qt::MatchFixedString); + if (!items.size()) { + ui->dropListWidget->addItem(colName); + } + ui->dropColComboBox->setCurrentIndex(-1); +} + +void MainWindow::on_dropListWidget_itemDoubleClicked(QListWidgetItem *item) { + ui->dropListWidget->removeItemWidget(item); + ui->dropListWidget->takeItem(ui->dropListWidget->currentRow()); +} + +void MainWindow::on_threadCountComboBox_currentIndexChanged(int index) { + if (0 <= index) { + m_threadPool.setMaxThreadCount(ui->threadCountComboBox->currentData().toInt()); + } +} + +void MainWindow::on_startAnalysisButton_clicked() { + + auto const &primaryData = m_dataVector.at(m_primaryIndex); + ui->progressBar->setMaximum(m_dataHeader.size() - 1 - ui->dropListWidget->count()); + ui->progressBar->setValue(0); + m_dataTableModel.clear(); + for (int i = 0; i < m_dataHeader.size(); ++i) { + if (i == m_primaryIndex || !ui->dropListWidget->findItems(m_dataHeader[i], Qt::MatchFixedString).empty()) { + continue; + } + auto *pearson = new Pearson(i, primaryData, m_dataVector.at(i), this); + connect(pearson, SIGNAL(result(uint64_t, double)), this, SLOT(PearsonResult(uint64_t, double))); + connect(pearson, SIGNAL(finished()), this, SLOT(PearsonFinished())); + //pearson->run(); + m_threadPool.start(pearson); + } +} + +void MainWindow::on_exportDataButton_clicked() { + auto saveFileName = QFileDialog::getSaveFileName(this, "文件保存", "", "CSV File (*.csv)"); + if (m_dataTableModel.SaveFile(saveFileName)) { + QMessageBox::information(this, "保存成功", "文件保存成功", "确定"); + } else { + QMessageBox::warning(this, "保存失败", "文件保存失败", "确定"); + + } +} + +void MainWindow::PearsonResult(uint64_t index, double pearson) { + qDebug() << m_dataHeader[index] << " " << pearson; + m_dataTableModel.InsertRow(m_dataHeader[index], pearson); +} + +void MainWindow::PearsonFinished() { + // delete sender(); + ui->progressBar->setValue(ui->progressBar->value() + 1); +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..8cb6eb4 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,72 @@ +// +// Created by fly on 2021/11/25. +// + +#ifndef PEARSON_MAINWINDOW_H +#define PEARSON_MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include "DataTableModel.h" + + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow { +Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = nullptr); + + ~MainWindow() override; + + void InitWidgetEnableState(); + + void InitHeaderComboBox(); + + void InitThreadCountComboBox(); + + void InitTableView(); + + +protected slots: + + void on_exploreButton_clicked(); + + void on_openFileButton_clicked(); + + void on_primaryColComboBox_currentIndexChanged(int index); + + void on_dropColComboBox_currentIndexChanged(int index); + + void on_threadCountComboBox_currentIndexChanged(int index); + + void on_dropListWidget_itemDoubleClicked(QListWidgetItem *item); + + void on_startAnalysisButton_clicked(); + + void on_exportDataButton_clicked(); + + void PearsonResult(uint64_t index, double pearson); + + void PearsonFinished(); + +private: + Ui::MainWindow *ui; + QThreadPool m_threadPool; + QString m_fileName; + uint64_t m_primaryIndex; + std::vector m_dataHeader; + std::vector> m_dataVector; + DataTableModel m_dataTableModel; +}; + + +#endif //PEARSON_MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..6db0c61 --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,149 @@ + + + MainWindow + + + + 0 + 0 + 642 + 600 + + + + Pearson分析工具 v0.1.0 + + + + + + + ③ 选择丢弃数据列(双击删除) + + + + + + 请选择无需分析列 + + + + + + + + + + + + + ① 选择文件并打开 + + + + QLayout::SetDefaultConstraint + + + + + true + + + 请选择文件... + + + + + + + + 0 + 0 + + + + + 24 + 16777215 + + + + ... + + + + + + + 打开文件 + + + + + + + + + + ② 选择主要数据列 + + + + + + 请选择主要数据列 + + + + + + + + + + ④ 分析操作(先选择工作线程数量再分析) + + + + + + 请选择分析线程数 + + + + + + + 开始分析 + + + + + + + 导出数据 + + + + + + + + + + + + + 0 + + + Qt::AlignCenter + + + + + + + + + diff --git a/resource.rc b/resource.rc new file mode 100644 index 0000000..14d43bd --- /dev/null +++ b/resource.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON "icon.ico" \ No newline at end of file