From 1b89b4c18b74a8e22086813030cf06dc0a0a0a83 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Fri, 30 Dec 2016 08:39:52 -0800 Subject: [PATCH] Remove dead code --- qgroundcontrol.pro | 3 - src/ui/MainWindow.cc | 1 - src/ui/MainWindow.h | 1 - src/ui/QGCDataPlot2D.cc | 734 ---------------------------------------- src/ui/QGCDataPlot2D.h | 77 ----- src/ui/QGCDataPlot2D.ui | 309 ----------------- 6 files changed, 1125 deletions(-) delete mode 100644 src/ui/QGCDataPlot2D.cc delete mode 100644 src/ui/QGCDataPlot2D.h delete mode 100644 src/ui/QGCDataPlot2D.ui diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index dd0d319fe..4fa119de4 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -314,7 +314,6 @@ FORMS += \ FORMS += \ src/ui/Linechart.ui \ src/ui/MultiVehicleDockWidget.ui \ - src/ui/QGCDataPlot2D.ui \ src/ui/QGCHilConfiguration.ui \ src/ui/QGCHilFlightGearConfiguration.ui \ src/ui/QGCHilJSBSimConfiguration.ui \ @@ -545,7 +544,6 @@ HEADERS += \ src/ui/MAVLinkDecoder.h \ src/ui/MainWindow.h \ src/ui/MultiVehicleDockWidget.h \ - src/ui/QGCDataPlot2D.h \ src/ui/QGCHilConfiguration.h \ src/ui/QGCHilFlightGearConfiguration.h \ src/ui/QGCHilJSBSimConfiguration.h \ @@ -694,7 +692,6 @@ SOURCES += \ src/ui/MAVLinkDecoder.cc \ src/ui/MainWindow.cc \ src/ui/MultiVehicleDockWidget.cc \ - src/ui/QGCDataPlot2D.cc \ src/ui/QGCHilConfiguration.cc \ src/ui/QGCHilFlightGearConfiguration.cc \ src/ui/QGCHilJSBSimConfiguration.cc \ diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index cd40b1927..d2bce2a37 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -43,7 +43,6 @@ #include "QGCImageProvider.h" #ifndef __mobile__ -#include "QGCDataPlot2D.h" #include "Linecharts.h" #include "QGCUASFileViewMulti.h" #include "UASQuickView.h" diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index a8851c7e2..dc1706a42 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -47,7 +47,6 @@ class QGCStatusBar; class Linecharts; -class QGCDataPlot2D; /** * @brief Main Application Window diff --git a/src/ui/QGCDataPlot2D.cc b/src/ui/QGCDataPlot2D.cc deleted file mode 100644 index 472b91e1f..000000000 --- a/src/ui/QGCDataPlot2D.cc +++ /dev/null @@ -1,734 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2016 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -/** - * @file - * @brief Implementation of QGCDataPlot2D - * @author Lorenz Meier - * - */ - -#include -#ifndef __mobile__ -#include -#include -#endif -#include -#include -#include -#include -#include - -#include - -#include "QGCDataPlot2D.h" -#include "ui_QGCDataPlot2D.h" -#include "MG.h" -#include "QGCFileDialog.h" -#include "QGCMessageBox.h" - -QGCDataPlot2D::QGCDataPlot2D(QWidget *parent) : - QWidget(parent), - plot(new IncrementalPlot(parent)), - logFile(NULL), - ui(new Ui::QGCDataPlot2D) -{ - ui->setupUi(this); - - // Add plot to ui - QHBoxLayout* layout = new QHBoxLayout(ui->plotFrame); - layout->addWidget(plot); - ui->plotFrame->setLayout(layout); - ui->gridCheckBox->setChecked(plot->gridEnabled()); - - // Connect user actions - connect(ui->selectFileButton, &QPushButton::clicked, this, &QGCDataPlot2D::selectFile); - connect(ui->saveCsvButton, &QPushButton::clicked, this, &QGCDataPlot2D::saveCsvLog); - connect(ui->reloadButton, &QPushButton::clicked, this, &QGCDataPlot2D::reloadFile); - connect(ui->savePlotButton, &QPushButton::clicked, this, &QGCDataPlot2D::savePlot); - connect(ui->printButton, &QPushButton::clicked, this, &QGCDataPlot2D::print); - connect(ui->legendCheckBox, &QCheckBox::clicked, plot, &IncrementalPlot::showLegend); - connect(ui->symmetricCheckBox,&QCheckBox::clicked, plot, &IncrementalPlot::setSymmetric); - connect(ui->gridCheckBox, &QCheckBox::clicked, plot, &IncrementalPlot::showGrid); - - connect(ui->style, static_cast(&QComboBox::currentIndexChanged), - plot, &IncrementalPlot::setStyleText); - - //TODO: calculateRegression returns bool, slots are expected to return void, this makes - // converting to new style way too hard. - connect(ui->regressionButton, SIGNAL(clicked()), this, SLOT(calculateRegression())); - - // Allow style changes to propagate through this widget - connect(qgcApp(), &QGCApplication::styleChanged, plot, &IncrementalPlot::styleChanged); -} - -void QGCDataPlot2D::reloadFile() -{ - if (QFileInfo(fileName).isReadable()) { - if (ui->inputFileType->currentText().contains("pxIMU") || ui->inputFileType->currentText().contains("RAW")) { - loadRawLog(fileName, ui->xAxis->currentText(), ui->yAxis->text()); - } else if (ui->inputFileType->currentText().contains("CSV")) { - loadCsvLog(fileName, ui->xAxis->currentText(), ui->yAxis->text()); - } - } -} - -void QGCDataPlot2D::loadFile() -{ - qDebug() << "DATA PLOT: Loading file:" << fileName; - if (QFileInfo(fileName).isReadable()) { - if (ui->inputFileType->currentText().contains("pxIMU") || ui->inputFileType->currentText().contains("RAW")) { - loadRawLog(fileName); - } else if (ui->inputFileType->currentText().contains("CSV")) { - loadCsvLog(fileName); - } - } -} - -void QGCDataPlot2D::loadFile(QString file) -{ - // TODO This "filename" is a private/protected member variable. It should be named in such way - // it indicates so. This same name is used in several places within this file in local scopes. - fileName = file; - QFileInfo fi(fileName); - if (fi.isReadable()) { - if (fi.suffix() == QString("raw") || fi.suffix() == QString("imu")) { - loadRawLog(fileName); - } else if (fi.suffix() == QString("txt") || fi.suffix() == QString("csv")) { - loadCsvLog(fileName); - } - // TODO Else, tell the user it doesn't know what to do with the file... - } -} - -/** - * This function brings up a file name dialog and asks the user to enter a file to save to - */ -QString QGCDataPlot2D::getSavePlotFilename() -{ - QString fileName = QGCFileDialog::getSaveFileName( - this, "Save Plot File", QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), - "PDF Documents (*.pdf);;SVG Images (*.svg)", - "pdf"); - return fileName; -} - -/** - * This function aks the user for a filename and exports to either PDF or SVG, depending on the filename - */ -void QGCDataPlot2D::savePlot() -{ - QString fileName = getSavePlotFilename(); - if (fileName.isEmpty()) - return; - - while(!(fileName.endsWith(".svg") || fileName.endsWith(".pdf"))) { - QMessageBox::StandardButton button = QGCMessageBox::warning( - tr("Unsuitable file extension for Plot document type."), - tr("Please choose .pdf or .svg as file extension. Click OK to change the file extension, cancel to not save the file."), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok); - // Abort if cancelled - if (button == QMessageBox::Cancel) { - return; - } - - fileName = getSavePlotFilename(); - if (fileName.isEmpty()) - return; //Abort if cancelled - } - - if (fileName.endsWith(".pdf")) { - exportPDF(fileName); - } else if (fileName.endsWith(".svg")) { - exportSVG(fileName); - } -} - - -void QGCDataPlot2D::print() -{ -#ifndef __mobile__ - QPrinter printer(QPrinter::HighResolution); - // printer.setOutputFormat(QPrinter::PdfFormat); - // //QPrinter printer(QPrinter::HighResolution); - // printer.setOutputFileName(fileName); - - QString docName = plot->title().text(); - if ( !docName.isEmpty() ) { - docName.replace (QRegExp (QString::fromLatin1 ("\n")), tr (" -- ")); - printer.setDocName (docName); - } - - printer.setCreator("QGroundControl"); - printer.setOrientation(QPrinter::Landscape); - - QPrintDialog dialog(&printer); - if ( dialog.exec() ) { - plot->setStyleSheet("QWidget { background-color: #FFFFFF; color: #000000; background-clip: border; font-size: 10pt;}"); - plot->setCanvasBackground(Qt::white); - // FIXME: QwtPlotPrintFilter no longer exists in Qwt 6.1 - //QwtPlotPrintFilter filter; - //filter.color(Qt::white, QwtPlotPrintFilter::CanvasBackground); - //filter.color(Qt::black, QwtPlotPrintFilter::AxisScale); - //filter.color(Qt::black, QwtPlotPrintFilter::AxisTitle); - //filter.color(Qt::black, QwtPlotPrintFilter::MajorGrid); - //filter.color(Qt::black, QwtPlotPrintFilter::MinorGrid); - //if ( printer.colorMode() == QPrinter::GrayScale ) { - // int options = QwtPlotPrintFilter::PrintAll; - // options &= ~QwtPlotPrintFilter::PrintBackground; - // options |= QwtPlotPrintFilter::PrintFrameWithScales; - // filter.setOptions(options); - //} - //plot->print(printer); - plot->setStyleSheet("QWidget { background-color: #050508; color: #DDDDDF; background-clip: border; font-size: 11pt;}"); - //plot->setCanvasBackground(QColor(5, 5, 8)); - } -#endif -} - -void QGCDataPlot2D::exportPDF(QString fileName) -{ -#ifdef __mobile__ - Q_UNUSED(fileName) -#else - QPrinter printer; - printer.setOutputFormat(QPrinter::PdfFormat); - printer.setOutputFileName(fileName); - //printer.setFullPage(true); - printer.setPageMargins(10.0, 10.0, 10.0, 10.0, QPrinter::Millimeter); - printer.setPageSize(QPrinter::A4); - - QString docName = plot->title().text(); - if ( !docName.isEmpty() ) { - docName.replace (QRegExp (QString::fromLatin1 ("\n")), tr (" -- ")); - printer.setDocName (docName); - } - - printer.setCreator("QGroundControl"); - printer.setOrientation(QPrinter::Landscape); - - plot->setStyleSheet("QWidget { background-color: #FFFFFF; color: #000000; background-clip: border; font-size: 10pt;}"); - // plot->setCanvasBackground(Qt::white); - // FIXME: QwtPlotPrintFilter no longer exists in Qwt 6.1 - // QwtPlotPrintFilter filter; - // filter.color(Qt::white, QwtPlotPrintFilter::CanvasBackground); - // filter.color(Qt::black, QwtPlotPrintFilter::AxisScale); - // filter.color(Qt::black, QwtPlotPrintFilter::AxisTitle); - // filter.color(Qt::black, QwtPlotPrintFilter::MajorGrid); - // filter.color(Qt::black, QwtPlotPrintFilter::MinorGrid); - // if ( printer.colorMode() == QPrinter::GrayScale ) - // { - // int options = QwtPlotPrintFilter::PrintAll; - // options &= ~QwtPlotPrintFilter::PrintBackground; - // options |= QwtPlotPrintFilter::PrintFrameWithScales; - // filter.setOptions(options); - // } - //plot->print(printer); - plot->setStyleSheet("QWidget { background-color: #050508; color: #DDDDDF; background-clip: border; font-size: 11pt;}"); - //plot->setCanvasBackground(QColor(5, 5, 8)); -#endif -} - -void QGCDataPlot2D::exportSVG(QString fileName) -{ -#ifdef __mobile__ - Q_UNUSED(fileName) -#else - if ( !fileName.isEmpty() ) { - plot->setStyleSheet("QWidget { background-color: #FFFFFF; color: #000000; background-clip: border; font-size: 10pt;}"); - //plot->setCanvasBackground(Qt::white); - QSvgGenerator generator; - generator.setFileName(fileName); - generator.setSize(QSize(800, 600)); - - // FIXME: QwtPlotPrintFilter no longer exists in Qwt 6.1 - //QwtPlotPrintFilter filter; - //filter.color(Qt::white, QwtPlotPrintFilter::CanvasBackground); - //filter.color(Qt::black, QwtPlotPrintFilter::AxisScale); - //filter.color(Qt::black, QwtPlotPrintFilter::AxisTitle); - //filter.color(Qt::black, QwtPlotPrintFilter::MajorGrid); - //filter.color(Qt::black, QwtPlotPrintFilter::MinorGrid); - - //plot->print(generator); - plot->setStyleSheet("QWidget { background-color: #050508; color: #DDDDDF; background-clip: border; font-size: 11pt;}"); - } -#endif -} - -/** - * Selects a filename and attempts immediately to load it. - */ -void QGCDataPlot2D::selectFile() -{ - // Open a file dialog prompting the user for the file to load. - // Note the special case for the Pixhawk. - if (ui->inputFileType->currentText().contains("pxIMU") || ui->inputFileType->currentText().contains("RAW")) { - fileName = QGCFileDialog::getOpenFileName(this, tr("Load Log File"), QString(), "Log Files (*.imu *.raw)"); - } - else - { - fileName = QGCFileDialog::getOpenFileName(this, tr("Load Log File"), QString(), "Log Files (*.csv);;All Files (*)"); - } - - // Check if the user hit cancel, which results in an empty string. - // If this is the case, we just stop. - if (fileName.isEmpty()) - { - return; - } - - // Now attempt to open the file - QFileInfo fileInfo(fileName); - if (!fileInfo.isReadable()) - { - // TODO This needs some TLC. File used by another program sounds like a Windows only issue. - QGCMessageBox::critical( - tr("Could not open file"), - tr("The file is owned by user %1. Is the file currently used by another program?").arg(fileInfo.owner())); - ui->filenameLabel->setText(tr("Could not open %1").arg(fileInfo.fileName())); - } - else - { - ui->filenameLabel->setText(tr("Opened %1").arg(fileInfo.completeBaseName()+"."+fileInfo.completeSuffix())); - // Open and import the file - loadFile(); - } - -} - -void QGCDataPlot2D::loadRawLog(QString file, QString xAxisName, QString yAxisFilter) -{ - Q_UNUSED(xAxisName); - Q_UNUSED(yAxisFilter); - - if (logFile != NULL) { - logFile->close(); - delete logFile; - } - // Postprocess log file - logFile = new QTemporaryFile("qt_qgc_temp_log.XXXXXX.csv"); - compressor = new LogCompressor(file, logFile->fileName()); - connect(compressor, &LogCompressor::finishedFile, this, static_cast(&QGCDataPlot2D::loadFile)); - compressor->startCompression(); -} - -/** - * This function loads a CSV file into the plot. It tries to assign the dimension names - * based on the first data row and tries to guess the separator char. - * - * @param file Name of the file to open - * @param xAxisName Optional paramater. If given, the x axis dimension will be selected to match this string - * @param yAxisFilter Optional parameter. If given, only data dimension names present in the filter string will be - * plotted - * - * @code - * - * QString file = "/home/user/datalog.txt"; // With header: xyz - * QString xAxis = "x"; - * QString yAxis = "z"; - * - * // Plotted result will be x vs z with y ignored. - * @endcode - */ -void QGCDataPlot2D::loadCsvLog(QString file, QString xAxisName, QString yAxisFilter) -{ - if (logFile != NULL) { - logFile->close(); - delete logFile; - curveNames.clear(); - } - logFile = new QFile(file); - - // Load CSV data - if (!logFile->open(QIODevice::ReadOnly | QIODevice::Text)) - return; - - // Set plot title - if (ui->plotTitle->text() != "") plot->setTitle(ui->plotTitle->text()); - if (ui->plotXAxisLabel->text() != "") plot->setAxisTitle(QwtPlot::xBottom, ui->plotXAxisLabel->text()); - if (ui->plotYAxisLabel->text() != "") plot->setAxisTitle(QwtPlot::yLeft, ui->plotYAxisLabel->text()); - - // Extract header - - // Read in values - // Find all keys - QTextStream in(logFile); - - // First line is header - QString header = in.readLine(); - - bool charRead = false; - QString separator = ""; - QList sepCandidates; - sepCandidates << '\t'; - sepCandidates << ','; - sepCandidates << ';'; - sepCandidates << ' '; - sepCandidates << '~'; - sepCandidates << '|'; - - // Iterate until separator is found - // or full header is parsed - for (int i = 0; i < header.length(); i++) { - if (sepCandidates.contains(header.at(i))) { - // Separator found - if (charRead) { - separator += header[i]; - } - } else { - // Char found - charRead = true; - // If the separator is not empty, this char - // has been read after a separator, so detection - // is now complete - if (separator != "") break; - } - } - - QString out = separator; - out.replace("\t", ""); - ui->filenameLabel->setText(file.split("/").last().split("\\").last()+" Separator: \""+out+"\""); - //qDebug() << "READING CSV:" << header; - - // Clear plot - plot->removeData(); - - QMap* > xValues; - QMap* > yValues; - - curveNames.append(header.split(separator, QString::SkipEmptyParts)); - - // Eliminate any non-string curve names - for (int i = 0; i < curveNames.count(); ++i) - { - if (curveNames.at(i).length() == 0 || - curveNames.at(i) == " " || - curveNames.at(i) == "\n" || - curveNames.at(i) == "\t" || - curveNames.at(i) == "\r") - { - // Remove bogus curve name - curveNames.removeAt(i); - } - } - - QString curveName; - - // Clear UI elements - ui->xAxis->clear(); - ui->yAxis->clear(); - ui->xRegressionComboBox->clear(); - ui->yRegressionComboBox->clear(); - ui->regressionOutput->clear(); - - int curveNameIndex = 0; - - QString xAxisFilter; - if (xAxisName == "") { - xAxisFilter = curveNames.first(); - } else { - xAxisFilter = xAxisName; - } - - // Fill y-axis renaming lookup table - // Allow the user to rename data dimensions in the plot - QMap renaming; - - QStringList yCurves = yAxisFilter.split("|", QString::SkipEmptyParts); - - // Figure out the correct renaming - for (int i = 0; i < yCurves.count(); ++i) - { - if (yCurves.at(i).contains(":")) - { - QStringList parts = yCurves.at(i).split(":", QString::SkipEmptyParts); - if (parts.count() > 1) - { - // Insert renaming map - renaming.insert(parts.first(), parts.last()); - // Replace curve value with first part only - yCurves.replace(i, parts.first()); - } - } -// else -// { -// // Insert same value, not renaming anything -// renaming.insert(yCurves.at(i), yCurves.at(i)); -// } - } - - - foreach(curveName, curveNames) { - // Add to plot x axis selection - ui->xAxis->addItem(curveName); - // Add to regression selection - ui->xRegressionComboBox->addItem(curveName); - ui->yRegressionComboBox->addItem(curveName); - if (curveName != xAxisFilter) { - if ((yAxisFilter == "") || yCurves.contains(curveName)) { - yValues.insert(curveName, new QVector()); - xValues.insert(curveName, new QVector()); - // Add separator starting with second item - if (curveNameIndex > 0 && curveNameIndex < curveNames.count()) { - ui->yAxis->setText(ui->yAxis->text()+"|"); - } - // If this curve was renamed, re-add the renaming to the text field - QString renamingText = ""; - if (renaming.contains(curveName)) renamingText = QString(":%1").arg(renaming.value(curveName)); - ui->yAxis->setText(ui->yAxis->text()+curveName+renamingText); - // Insert same value, not renaming anything - if (!renaming.contains(curveName)) renaming.insert(curveName, curveName); - curveNameIndex++; - } - } - } - - // Select current axis in UI - ui->xAxis->setCurrentIndex(curveNames.indexOf(xAxisFilter)); - - // Read data - - double x = 0; - double y = 0; - - while (!in.atEnd()) - { - QString line = in.readLine(); - - // Keep empty parts here - we still have to act on them - QStringList values = line.split(separator, QString::KeepEmptyParts); - - bool headerfound = false; - - // First get header - ORDER MATTERS HERE! - foreach(curveName, curveNames) - { - if (curveName == xAxisFilter) - { - // X AXIS HANDLING - - // Take this value as x if it is selected - QString text = values.at(curveNames.indexOf(curveName)); - text = text.trimmed(); - if (text.length() > 0 && text != " " && text != "\n" && text != "\r" && text != "\t") - { - bool okx = true; - x = text.toDouble(&okx); - if (okx && !qIsNaN(x) && !qIsInf(x)) - { - headerfound = true; - } - } - } - } - - if (headerfound) - { - // Search again from start for values - ORDER MATTERS HERE! - foreach(curveName, curveNames) - { - // Y AXIS HANDLING - // Only plot non-x curver and those selected in the yAxisFilter (or all if the filter is not set) - if(curveName != xAxisFilter && (yAxisFilter == "" || yCurves.contains(curveName))) - { - bool oky; - int curveNameIndex = curveNames.indexOf(curveName); - if (values.count() > curveNameIndex) - { - QString text(values.at(curveNameIndex)); - text = text.trimmed(); - y = text.toDouble(&oky); - // Only INF is really an issue for the plot - // NaN is fine - if (oky && !qIsNaN(y) && !qIsInf(y) && text.length() > 0 && text != " " && text != "\n" && text != "\r" && text != "\t") - { - // Only append definitely valid values - xValues.value(curveName)->append(x); - yValues.value(curveName)->append(y); - } - } - } - } - } - } - - // Add data array of each curve to the plot at once (fast) - // Iterates through all x-y curve combinations - for (int i = 0; i < yValues.count(); i++) { - if (renaming.contains(yValues.keys().at(i))) - { - plot->appendData(renaming.value(yValues.keys().at(i)), xValues.values().at(i)->data(), yValues.values().at(i)->data(), xValues.values().at(i)->count()); - } - else - { - plot->appendData(yValues.keys().at(i), xValues.values().at(i)->data(), yValues.values().at(i)->data(), xValues.values().at(i)->count()); - } - } - plot->updateScale(); - plot->setStyleText(ui->style->currentText()); -} - -bool QGCDataPlot2D::calculateRegression() -{ - // TODO: Add support for quadratic / cubic curve fitting - return calculateRegression(ui->xRegressionComboBox->currentText(), ui->yRegressionComboBox->currentText(), "linear"); -} - -/** - * @param xName Name of the x dimension - * @param yName Name of the y dimension - * @param method Regression method, either "linear", "quadratic" or "cubic". Only linear is supported at this point - */ -bool QGCDataPlot2D::calculateRegression(QString xName, QString yName, QString method) -{ - bool result = false; - QString function; - if (xName != yName) { - if (QFileInfo(fileName).isReadable()) { - loadCsvLog(fileName, xName, yName); - ui->xRegressionComboBox->setCurrentIndex(curveNames.indexOf(xName)); - ui->yRegressionComboBox->setCurrentIndex(curveNames.indexOf(yName)); - } - - // Create a couple of arrays for us to use to temporarily store some of the data from the plot. - // These arrays are allocated on the heap as they are far too big to go in the stack and will - // cause an overflow. - // TODO: Look into if this would be better done by having a getter return const double pointers instead - // of using memcpy(). - const int size = 100000; - double *x = new double[size]; - double *y = new double[size]; - int copied = plot->data(yName, x, y, size); - - if (method == "linear") { - double a; // Y-axis crossing - double b; // Slope - double r; // Regression coefficient - if (linearRegression(x, y, copied, &a, &b, &r)) { - function = tr("%1 = %2 * %3 + %4 | R-coefficient: %5").arg(yName, QString::number(b), xName, QString::number(a), QString::number(r)); - - // Plot curve - // y-axis crossing (x = 0) - // Set plotting to lines only - plot->appendData(tr("regression %1-%2").arg(xName, yName), 0.0, a); - plot->setStyleText("lines"); - // x-value of the current rightmost x position in the plot - plot->appendData(tr("regression %1-%2").arg(xName, yName), plot->invTransform(QwtPlot::xBottom, plot->width() - plot->width()*0.08f), (a + b*plot->invTransform(QwtPlot::xBottom, plot->width() - plot->width() * 0.08f))); - - result = true; - } else { - function = tr("Linear regression failed. (Limit: %1 data points. Try with less)").arg(size); - } - } else { - function = tr("Regression method %1 not found").arg(method); - } - - delete[] x; - delete[] y; - } else { - // xName == yName - function = tr("Please select different X and Y dimensions, not %1 = %2").arg(xName, yName); - } - ui->regressionOutput->setText(function); - return result; -} - -/** - * Linear regression (least squares) for n data points. - * Computes: - * - * y = a * x + b - * - * @param x values on x axis - * @param y corresponding values on y axis - * @param n Number of values - * @param a returned slope of line - * @param b y-axis intersection - * @param r regression coefficient. The larger the coefficient is, the better is - * the match of the regression. - * @return 1 on success, 0 on failure (e.g. because of infinite slope) - */ -bool QGCDataPlot2D::linearRegression(double *x, double *y, int n, double *a, double *b, double *r) -{ - int i; - double sumx=0,sumy=0,sumx2=0,sumy2=0,sumxy=0; - double sxx,syy,sxy; - - *a = 0; - *b = 0; - *r = 0; - if (n < 2) - return true; - - /* Conpute some things we need */ - for (i=0; icopy(fileName); - - qDebug() << "Saved CSV log (" << fileName << "). Success: " << success; - - //qDebug() << "READE TO SAVE CSV LOG TO " << fileName; -} - -QGCDataPlot2D::~QGCDataPlot2D() -{ - delete ui; -} - -void QGCDataPlot2D::changeEvent(QEvent *e) -{ - QWidget::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - ui->retranslateUi(this); - break; - default: - break; - } -} diff --git a/src/ui/QGCDataPlot2D.h b/src/ui/QGCDataPlot2D.h deleted file mode 100644 index 2ff6cacab..000000000 --- a/src/ui/QGCDataPlot2D.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef QGCDATAPLOT2D_H -#define QGCDATAPLOT2D_H - -#include -#include -#include "IncrementalPlot.h" -#include "LogCompressor.h" - -namespace Ui -{ -class QGCDataPlot2D; -} - -class QGCDataPlot2D : public QWidget -{ - Q_OBJECT -public: - QGCDataPlot2D(QWidget *parent = 0); - ~QGCDataPlot2D(); - - /** @brief Calculate and display regression function*/ - bool calculateRegression(QString xName, QString yName, QString method="linear"); - - /** @brief Linear regression over data points */ - bool linearRegression(double *x, double *y, int n, double *a, double *b, double *r); - -public slots: - /** @brief Load previously selected file */ - void loadFile(); - /** @brief Load file with this name */ - void loadFile(QString file); - /** @brief Reload a file, with filtering enabled */ - void reloadFile(); - void selectFile(); - void loadCsvLog(QString file, QString xAxisName="", QString yAxisFilter=""); - void loadRawLog(QString file, QString xAxisName="", QString yAxisFilter=""); - void saveCsvLog(); - /** @brief Save plot to PDF or SVG */ - void savePlot(); - /** @brief Export PDF file */ - void exportPDF(QString fileName); - /** @brief Export SVG file */ - void exportSVG(QString file); - /** @brief Print or save PDF file (MacOS/Linux) */ - void print(); - /** @brief Calculate and display regression function*/ - bool calculateRegression(); - -signals: - void visibilityChanged(bool visible); - -protected: - void showEvent(QShowEvent* event) - { - QWidget::showEvent(event); - emit visibilityChanged(true); - } - - void hideEvent(QHideEvent* event) - { - QWidget::hideEvent(event); - emit visibilityChanged(false); - } - - void changeEvent(QEvent *e); - QString getSavePlotFilename(); - IncrementalPlot* plot; - LogCompressor* compressor; - QFile* logFile; - QString fileName; - QStringList curveNames; - -private: - Ui::QGCDataPlot2D *ui; -}; - -#endif // QGCDATAPLOT2D_H diff --git a/src/ui/QGCDataPlot2D.ui b/src/ui/QGCDataPlot2D.ui deleted file mode 100644 index dba180727..000000000 --- a/src/ui/QGCDataPlot2D.ui +++ /dev/null @@ -1,309 +0,0 @@ - - - QGCDataPlot2D - - - - 0 - 0 - 1463 - 311 - - - - Form - - - - - - X - - - - - - - - - - Y - - - - - - - - - - Set line style - - - - Only lines - - - - - Only crosses - - - - - Only circles - - - - - Only rectangles - - - - - Lines and crosses - - - - - Lines and circles - - - - - Lines and rects - - - - - Dotted lines and crosses - - - - - Dotted lines and circles - - - - - Dotted lines and rects - - - - - Dashed lines and crosses - - - - - Dashed lines and circles - - - - - Dashed lines and rects - - - - - - - - Replot - - - - - - - Qt::Vertical - - - - - - - Save Image - - - - - - - Print - - - - - - - Title - - - - - - - - - - X label - - - - - - - - - - Y label - - - - - - - - - - Symmetric - - - - - - - Legend - - - - - - - Grid - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - File - - - - - - - - CSV - - - - - pxIMU - - - - - RAW - - - - - - - - Please select input file.. - - - - - - - Select file - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - - - - Regression - - - - - - - - - - - - - Calculate - - - - - - - true - - - - - - - Save Data - - - - - - - Qt::Horizontal - - - - 5 - 20 - - - - - - - - - -- 2.22.0