Version Bump
Remember Save paths add missing files
This commit is contained in:
@ -68,7 +68,7 @@ int main(int argc, char *argv[])
|
|||||||
QCoreApplication::setOrganizationName("UVOS");
|
QCoreApplication::setOrganizationName("UVOS");
|
||||||
QCoreApplication::setOrganizationDomain("uvos.xyz");
|
QCoreApplication::setOrganizationDomain("uvos.xyz");
|
||||||
QCoreApplication::setApplicationName("MAClient");
|
QCoreApplication::setApplicationName("MAClient");
|
||||||
QCoreApplication::setApplicationVersion("0.1");
|
QCoreApplication::setApplicationVersion("0.5");
|
||||||
|
|
||||||
//parse comand line
|
//parse comand line
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
|
34
src/regessioncalculator.cpp
Executable file
34
src/regessioncalculator.cpp
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#include "regessioncalculator.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <math.h>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
RegessionCalculator::RegessionCalculator(const std::vector<double>& xValues, const std::vector<double>& yValues)
|
||||||
|
{
|
||||||
|
if(xValues.size() == yValues.size())
|
||||||
|
{
|
||||||
|
this->xValues = xValues;
|
||||||
|
this->yValues = yValues;
|
||||||
|
|
||||||
|
double sumY = 0;
|
||||||
|
double sumX = 0;
|
||||||
|
double sumXTimesY = 0;
|
||||||
|
double sumSquaredX = 0;
|
||||||
|
double sumSquaredY = 0;
|
||||||
|
for (unsigned i = 0; i < xValues.size(); i++)
|
||||||
|
{
|
||||||
|
sumY += yValues[i];
|
||||||
|
sumX += xValues[i];
|
||||||
|
sumSquaredX += xValues[i]*xValues[i];
|
||||||
|
sumSquaredY += yValues[i]*yValues[i];
|
||||||
|
sumXTimesY += xValues[i]*yValues[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
slope = (sumXTimesY - (sumX*sumY)/xValues.size()) / (sumSquaredX - (sumX*sumX)/xValues.size());
|
||||||
|
offset = sumY/xValues.size() - slope*(sumX/xValues.size());
|
||||||
|
|
||||||
|
double error = (xValues.size()*sumSquaredY-sumY*sumY-slope*slope*(xValues.size()*sumSquaredX-sumX*sumX)) / (xValues.size()*(xValues.size()-2));
|
||||||
|
stdError = sqrt( (error*error*xValues.size() ) / ( xValues.size()*sumSquaredX-sumX*sumX));
|
||||||
|
}
|
||||||
|
else throw std::invalid_argument("xValues and yValues need to be the same size");
|
||||||
|
}
|
19
src/regessioncalculator.h
Executable file
19
src/regessioncalculator.h
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef REGESSIONCALCULATOR_H
|
||||||
|
#define REGESSIONCALCULATOR_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class RegessionCalculator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<double> xValues;
|
||||||
|
std::vector<double> yValues;
|
||||||
|
|
||||||
|
double slope;
|
||||||
|
double offset;
|
||||||
|
double stdError;
|
||||||
|
|
||||||
|
RegessionCalculator(const std::vector<double>& xValues, const std::vector<double>& yValues);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // REGESSIONCALCULATOR_H
|
23
src/ui/aboutdiag.cpp
Executable file
23
src/ui/aboutdiag.cpp
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#include "aboutdiag.h"
|
||||||
|
#include "ui_aboutdiag.h"
|
||||||
|
#include <QPalette>
|
||||||
|
|
||||||
|
AboutDiag::AboutDiag(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::AboutDiag)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
setFixedSize(size());
|
||||||
|
|
||||||
|
QPalette pal = palette();
|
||||||
|
pal.setColor(QPalette::Window, QColor(52,52,60));
|
||||||
|
pal.setColor(QPalette::WindowText, QColor(255,255,255));
|
||||||
|
pal.setColor(QPalette::Text, QColor(255,255,255));
|
||||||
|
setAutoFillBackground(true);
|
||||||
|
setPalette(pal);
|
||||||
|
}
|
||||||
|
|
||||||
|
AboutDiag::~AboutDiag()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
22
src/ui/aboutdiag.h
Executable file
22
src/ui/aboutdiag.h
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef ABOUTTELSYS_H
|
||||||
|
#define ABOUTTELSYS_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AboutDiag;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AboutDiag : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AboutDiag(QWidget *parent = 0);
|
||||||
|
~AboutDiag();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::AboutDiag *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ABOUTTELSYS_H
|
85
src/ui/aboutdiag.ui
Executable file
85
src/ui/aboutdiag.ui
Executable file
@ -0,0 +1,85 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AboutDiag</class>
|
||||||
|
<widget class="QDialog" name="AboutDiag">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>812</width>
|
||||||
|
<height>315</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>80000</width>
|
||||||
|
<height>15200</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>About</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>30</horstretch>
|
||||||
|
<verstretch>50</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>800</width>
|
||||||
|
<height>200</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="../../res/resources.qrc">:/images/splash.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p><span style=" font-weight:600;">UVOS MAClient Version: 0.5</span></p><p>© 2021 Carl Philipp Klemm</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::RichText</enum>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../res/resources.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -48,14 +48,15 @@ void CvImageViewer::saveImage()
|
|||||||
QString fileName;
|
QString fileName;
|
||||||
if(origImage_.type() == CV_8UC3 || origImage_.type() == CV_8SC3 || origImage_.type() == CV_8UC1 || origImage_.type() == CV_8SC1)
|
if(origImage_.type() == CV_8UC3 || origImage_.type() == CV_8SC3 || origImage_.type() == CV_8UC1 || origImage_.type() == CV_8SC1)
|
||||||
{
|
{
|
||||||
fileName = QFileDialog::getSaveFileName(this, "Save Image", "./", "*.mat *.png" );
|
fileName = QFileDialog::getSaveFileName(this, "Save Image", lastSavePath_, "*.mat *.png" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fileName = QFileDialog::getSaveFileName(this, "Save Image", "./", "*.mat" );
|
fileName = QFileDialog::getSaveFileName(this, "Save Image", lastSavePath_, "*.mat" );
|
||||||
}
|
}
|
||||||
if(!fileName.isEmpty())
|
if(!fileName.isEmpty())
|
||||||
{
|
{
|
||||||
|
lastSavePath_= fileName.mid(0, fileName.lastIndexOf('/'));
|
||||||
QStringList tokens = fileName.split('.');
|
QStringList tokens = fileName.split('.');
|
||||||
if(tokens.back() != "mat" && tokens.back() != "png")
|
if(tokens.back() != "mat" && tokens.back() != "png")
|
||||||
fileName.append(".mat");
|
fileName.append(".mat");
|
||||||
|
@ -34,7 +34,7 @@ private:
|
|||||||
QLine yLine_;
|
QLine yLine_;
|
||||||
bool selectionStarted_ = false;
|
bool selectionStarted_ = false;
|
||||||
double clamp_ = std::numeric_limits<double>::max();
|
double clamp_ = std::numeric_limits<double>::max();
|
||||||
static QString lastSavePath_;
|
inline static QString lastSavePath_ = "./";
|
||||||
|
|
||||||
void transfromToSourceCoordinates(int inX, int inY, int& outX, int& outY);
|
void transfromToSourceCoordinates(int inX, int inY, int& outX, int& outY);
|
||||||
void convertImage(cv::Mat image);
|
void convertImage(cv::Mat image);
|
||||||
|
@ -55,9 +55,10 @@ void MainWindow::saveImage()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString fileName = QFileDialog::getSaveFileName(this, "Save Image", "./", "*.mat");
|
QString fileName = QFileDialog::getSaveFileName(this, "Save Image", lastSavedPath_, "*.mat");
|
||||||
if(!fileName.isEmpty())
|
if(!fileName.isEmpty())
|
||||||
{
|
{
|
||||||
|
lastSavedPath_= fileName.mid(0, fileName.lastIndexOf('/'));
|
||||||
QStringList tokens = fileName.split('.');
|
QStringList tokens = fileName.split('.');
|
||||||
if(tokens.back() != "mat")
|
if(tokens.back() != "mat")
|
||||||
fileName.append(".mat");
|
fileName.append(".mat");
|
||||||
@ -69,7 +70,7 @@ void MainWindow::saveImage()
|
|||||||
|
|
||||||
void MainWindow::openImage()
|
void MainWindow::openImage()
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getOpenFileName(this, "Open Image", "./", "*.mat");
|
QString fileName = QFileDialog::getOpenFileName(this, "Open Image", lastSavedPath_, "*.mat");
|
||||||
if(!fileName.isEmpty())
|
if(!fileName.isEmpty())
|
||||||
{
|
{
|
||||||
cv::Mat image;
|
cv::Mat image;
|
||||||
|
@ -16,7 +16,8 @@ class MainWindow : public QMainWindow
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
std::vector<CvImageViewer*> viewers_;
|
std::vector<CvImageViewer*> viewers_;
|
||||||
AboutDiag about_;
|
AboutDiag about_;
|
||||||
|
inline static QString lastSavedPath_ = "./";
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void setImageValue(size_t x, size_t y, double value);
|
void setImageValue(size_t x, size_t y, double value);
|
||||||
|
279
src/ui/plot.cpp
Executable file
279
src/ui/plot.cpp
Executable file
@ -0,0 +1,279 @@
|
|||||||
|
#include "plot.h"
|
||||||
|
|
||||||
|
#include <QKeySequence>
|
||||||
|
#include <QFont>
|
||||||
|
|
||||||
|
#include "statisticsdialog.h"
|
||||||
|
#include "regressiondiag.h"
|
||||||
|
|
||||||
|
Plot::Plot(QWidget* parent):
|
||||||
|
QCustomPlot(parent),
|
||||||
|
actionStatistics("Show statistics", nullptr),
|
||||||
|
actionAdd_Regression("Add regression", nullptr),
|
||||||
|
actionDelete_Regression("Delete regression", nullptr),
|
||||||
|
actionExport_Selection("Export selection", nullptr),
|
||||||
|
actionSetValueString("Set Y Axis Label", nullptr)
|
||||||
|
{
|
||||||
|
xAxis->setLabel("Coordinate");
|
||||||
|
yAxis->setLabel("Counts");
|
||||||
|
xAxis->setRange(0, 10);
|
||||||
|
yAxis->setRange(0, 65535);
|
||||||
|
addMainGraph();
|
||||||
|
setInteraction(QCP::iSelectPlottables, true);
|
||||||
|
setInteraction(QCP::iRangeDrag, true);
|
||||||
|
setInteraction(QCP::iRangeZoom);
|
||||||
|
axisRect()->setRangeDrag(Qt::Horizontal);
|
||||||
|
axisRect()->setRangeZoom(Qt::Horizontal);
|
||||||
|
setSelectionRectMode(QCP::srmNone);
|
||||||
|
|
||||||
|
//setup actions
|
||||||
|
actionStatistics.setShortcut(Qt::Key_S);
|
||||||
|
actionStatistics.setShortcutVisibleInContextMenu(true);
|
||||||
|
addAction(&actionStatistics);
|
||||||
|
|
||||||
|
actionAdd_Regression.setShortcut(Qt::Key_R);
|
||||||
|
actionAdd_Regression.setShortcutVisibleInContextMenu(true);
|
||||||
|
addAction(&actionAdd_Regression);
|
||||||
|
|
||||||
|
actionDelete_Regression.setShortcut(Qt::Key_Delete);
|
||||||
|
actionDelete_Regression.setShortcutVisibleInContextMenu(true);
|
||||||
|
addAction(&actionDelete_Regression);
|
||||||
|
|
||||||
|
actionExport_Selection.setShortcut(Qt::CTRL + Qt::Key_E);
|
||||||
|
actionExport_Selection.setShortcutVisibleInContextMenu(true);
|
||||||
|
addAction(&actionExport_Selection);
|
||||||
|
|
||||||
|
//graph context menu
|
||||||
|
|
||||||
|
connect(&actionStatistics, &QAction::triggered, this, &Plot::showStatistics);
|
||||||
|
connect(&actionAdd_Regression, &QAction::triggered, this, &Plot::addRegression);
|
||||||
|
connect(&actionDelete_Regression, &QAction::triggered, this, &Plot::deleteRegression);
|
||||||
|
connect(&actionExport_Selection, &QAction::triggered, this, &Plot::saveCsvDiag);
|
||||||
|
connect(&actionSetValueString, &QAction::triggered, this, &Plot::askForValueString);
|
||||||
|
|
||||||
|
graphContextMenu.addAction(&actionStatistics);
|
||||||
|
graphContextMenu.addAction(&actionAdd_Regression);
|
||||||
|
graphContextMenu.addAction(&actionDelete_Regression);
|
||||||
|
graphContextMenu.addAction(&actionExport_Selection);
|
||||||
|
graphContextMenu.addAction(&actionSetValueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
Plot::~Plot()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Plot::event(QEvent *event)
|
||||||
|
{
|
||||||
|
if(event->type()==QEvent::Gesture) graphContextMenu.show();
|
||||||
|
return QCustomPlot::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::setLabel(QString label)
|
||||||
|
{
|
||||||
|
yAxis->setLabel(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::addMainGraph()
|
||||||
|
{
|
||||||
|
addGraph();
|
||||||
|
graph(graphCount()-1)->setSelectable(QCP::stDataRange);
|
||||||
|
QPen selectionPen = graph(graphCount()-1)->pen();
|
||||||
|
selectionPen.setColor(QColor(255,0,0));
|
||||||
|
graph(graphCount()-1)->selectionDecorator()->setPen(selectionPen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::clear()
|
||||||
|
{
|
||||||
|
clearGraphs();
|
||||||
|
addMainGraph();
|
||||||
|
xAxis->setRange(0, 10);
|
||||||
|
replot();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::askForValueString()
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
QString label = QInputDialog::getText(this, "Y Axis Label", "New Label:", QLineEdit::Normal, yAxis->label(), &ok);
|
||||||
|
if(ok)
|
||||||
|
{
|
||||||
|
setLabel(label);
|
||||||
|
replot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::setMaxValue(double maxVal)
|
||||||
|
{
|
||||||
|
yAxis->setRange(0, maxVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::saveCsvDiag()
|
||||||
|
{
|
||||||
|
if(graphCount() > 0 && !graph(0)->selection().dataRanges().at(0).isEmpty())
|
||||||
|
{
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this, "Save selection as CSV", "./", "*.csv" );
|
||||||
|
saveCsv(fileName);
|
||||||
|
}
|
||||||
|
else QMessageBox::warning(this, "Warning", "No selection has been made", QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::saveCsv(QString fileName)
|
||||||
|
{
|
||||||
|
if(!fileName.isEmpty())
|
||||||
|
{
|
||||||
|
QCPDataRange range = graph(0)->selection().dataRanges().at(0);
|
||||||
|
QCPGraphDataContainer::const_iterator begin = graph(0)->data()->at(range.begin());
|
||||||
|
QCPGraphDataContainer::const_iterator end = graph(0)->data()->at(range.end());
|
||||||
|
|
||||||
|
std::vector<double> keys;
|
||||||
|
keys.resize(end-begin);
|
||||||
|
|
||||||
|
std::vector<double> values;
|
||||||
|
values.resize(end-begin);
|
||||||
|
|
||||||
|
for (QCPGraphDataContainer::const_iterator item=begin; item != end; ++item)
|
||||||
|
{
|
||||||
|
keys[item-begin]=item->key;
|
||||||
|
values[item-begin]=item->value;
|
||||||
|
}
|
||||||
|
saveToCsv(fileName, keys, values, xAxis->label(), yAxis->label());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Plot::addRegression()
|
||||||
|
{
|
||||||
|
if(graphCount() > 0 && !graph(0)->selection().dataRanges().at(0).isEmpty())
|
||||||
|
{
|
||||||
|
QCPDataRange range = graph(0)->selection().dataRanges().at(0);
|
||||||
|
QCPGraphDataContainer::const_iterator begin = graph(0)->data()->at(range.begin());
|
||||||
|
QCPGraphDataContainer::const_iterator end = graph(0)->data()->at(range.end());
|
||||||
|
|
||||||
|
std::vector<double> values;
|
||||||
|
std::vector<double> keys;
|
||||||
|
|
||||||
|
values.resize(end-begin);
|
||||||
|
keys.resize(end-begin);
|
||||||
|
|
||||||
|
for (QCPGraphDataContainer::const_iterator item=begin; item != end; ++item)
|
||||||
|
{
|
||||||
|
values[item-begin] = item->value;
|
||||||
|
keys[item-begin] = item->key;
|
||||||
|
}
|
||||||
|
|
||||||
|
regressions.push_back(RegessionCalculator(keys, values));
|
||||||
|
|
||||||
|
QPen regressionPen =graph(0)->pen();
|
||||||
|
regressionPen.setColor(QColor(0,255,0));
|
||||||
|
|
||||||
|
QPen selectionPen = graph(0)->pen();
|
||||||
|
selectionPen.setColor(QColor(255,0,0));
|
||||||
|
|
||||||
|
QCPGraphDataContainer::const_iterator center = begin + (end - begin)/2;
|
||||||
|
|
||||||
|
addGraph();
|
||||||
|
graph(graphCount()-1)->setPen(regressionPen);
|
||||||
|
graph(graphCount()-1)->addData(100+center->key, regressions.back().slope*(100+center->key) + regressions.back().offset);
|
||||||
|
graph(graphCount()-1)->addData(-100+center->key, regressions.back().slope*(-100+center->key) + regressions.back().offset);
|
||||||
|
graph(graphCount()-1)->selectionDecorator()->setPen(selectionPen);
|
||||||
|
replot();
|
||||||
|
|
||||||
|
}
|
||||||
|
else QMessageBox::warning(this, "Warning", "No selection has been made", QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::deleteRegression()
|
||||||
|
{
|
||||||
|
if(graphCount() > 0 && selectedGraphs().size() > 1 && selectedGraphs().at(1) != graph(0))
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while(selectedGraphs().at(1) != graph(i) ) i++;
|
||||||
|
regressions.erase(regressions.begin()+i-1);
|
||||||
|
removeGraph(selectedGraphs().at(1));
|
||||||
|
replot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Plot::showStatistics()
|
||||||
|
{
|
||||||
|
if(graphCount() > 0 && !graph(0)->selection().dataRanges().at(0).isEmpty())
|
||||||
|
{
|
||||||
|
QCPDataRange dataRange = graph(0)->selection().dataRanges().at(0);
|
||||||
|
QCPGraphDataContainer::const_iterator begin = graph(0)->data()->at(dataRange.begin());
|
||||||
|
QCPGraphDataContainer::const_iterator end = graph(0)->data()->at(dataRange.end());
|
||||||
|
std::vector<double> dataVct;
|
||||||
|
dataVct.reserve(dataRange.size());
|
||||||
|
for (QCPGraphDataContainer::const_iterator item = begin; item != end; item++)
|
||||||
|
dataVct.push_back(item->value);
|
||||||
|
StatisticsDialog statDiag(dataVct, this);
|
||||||
|
statDiag.show();
|
||||||
|
statDiag.exec();
|
||||||
|
}
|
||||||
|
else if(graphCount() > 0 && selectedGraphs().size() > 1 && selectedGraphs().at(1) != graph(0))
|
||||||
|
{
|
||||||
|
unsigned i = 0;
|
||||||
|
while(selectedGraphs().at(1) != graph(i)) i++;
|
||||||
|
RegressionDiag regDiag(regressions.at(i-1), this);
|
||||||
|
regDiag.show();
|
||||||
|
regDiag.exec();
|
||||||
|
}
|
||||||
|
else QMessageBox::warning(this, "Warning", "No selection has been made", QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::addData(QVector<double> keys, QVector<double> values, bool inOrder, bool ignoreLimit)
|
||||||
|
{
|
||||||
|
if(graphCount() > 0)
|
||||||
|
{
|
||||||
|
graph(0)->addData(keys, values, inOrder);
|
||||||
|
if(!ignoreLimit)while(graph(0)->data()->size() > graphPointLimit) graph(0)->data()->remove(graph(0)->data()->begin()->key);
|
||||||
|
xAxis->setRange( graph(0)->data()->begin()->key, keys.back() );
|
||||||
|
replot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::addData(double key, double value, bool ignoreLimit)
|
||||||
|
{
|
||||||
|
if(graphCount() > 0)
|
||||||
|
{
|
||||||
|
graph(0)->addData(key, value);
|
||||||
|
if(!ignoreLimit)while(graph(0)->data()->size() > graphPointLimit) graph(0)->data()->remove(graph(0)->data()->begin()->key);
|
||||||
|
xAxis->setRange( graph(0)->data()->begin()->key, key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::setLimit(int graphPointLimit)
|
||||||
|
{
|
||||||
|
this->graphPointLimit = graphPointLimit;
|
||||||
|
if(graphCount() > 0) while(graph(0)->data()->size() > graphPointLimit) graph(0)->data()->remove(graph(0)->data()->begin()->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Plot::getLimit()
|
||||||
|
{
|
||||||
|
return graphPointLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if(event->button() == Qt::MiddleButton || (event->button() == Qt::LeftButton && event->modifiers() == Qt::Modifier::SHIFT) )
|
||||||
|
{
|
||||||
|
setCursor(Qt::ClosedHandCursor);
|
||||||
|
setSelectionRectMode(QCP::srmNone);
|
||||||
|
}
|
||||||
|
else if(event->button() == Qt::LeftButton)
|
||||||
|
{
|
||||||
|
setSelectionRectMode(QCP::srmSelect);
|
||||||
|
}
|
||||||
|
else if(event->button() == Qt::RightButton)
|
||||||
|
{
|
||||||
|
graphContextMenu.popup(event->globalPos());
|
||||||
|
setSelectionRectMode(QCP::srmNone);
|
||||||
|
}
|
||||||
|
QCustomPlot::mousePressEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plot::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
setCursor(Qt::ArrowCursor);
|
||||||
|
QCustomPlot::mouseReleaseEvent(event);
|
||||||
|
}
|
64
src/ui/plot.h
Executable file
64
src/ui/plot.h
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef PLOT_H
|
||||||
|
#define PLOT_H
|
||||||
|
|
||||||
|
#include<QVector>
|
||||||
|
#include<QAction>
|
||||||
|
#include<QWidget>
|
||||||
|
|
||||||
|
#include "qcustomplot/qcustomplot.h"
|
||||||
|
#include "regessioncalculator.h"
|
||||||
|
#include "statisticsdialog.h"
|
||||||
|
#include "utilites.h"
|
||||||
|
|
||||||
|
class Plot : public QCustomPlot
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<RegessionCalculator> regressions;
|
||||||
|
|
||||||
|
QMenu graphContextMenu;
|
||||||
|
|
||||||
|
int graphPointLimit = 10000;
|
||||||
|
QAction actionStatistics;
|
||||||
|
QAction actionAdd_Regression;
|
||||||
|
QAction actionDelete_Regression;
|
||||||
|
QAction actionExport_Selection;
|
||||||
|
QAction actionSetValueString;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Plot(QWidget* parent = nullptr);
|
||||||
|
~Plot();
|
||||||
|
|
||||||
|
void setLabel(QString label);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
void setLimit(int graphPointLimit);
|
||||||
|
int getLimit();
|
||||||
|
|
||||||
|
void setMaxValue(double maxVal);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sigSaveCsv();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void addPoints(QVector<double> keys, QVector<double> values);
|
||||||
|
void saveCsv(QString fileName);
|
||||||
|
void saveCsvDiag();
|
||||||
|
void showStatistics();
|
||||||
|
void deleteRegression();
|
||||||
|
void addRegression();
|
||||||
|
void askForValueString();
|
||||||
|
|
||||||
|
void addData(QVector<double> keys, QVector<double> values, bool inOrder = false, bool ignoreLimit = false);
|
||||||
|
void addData(double key, double value, bool ignoreLimit = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void mousePressEvent(QMouseEvent *event);
|
||||||
|
virtual void mouseReleaseEvent(QMouseEvent *event);
|
||||||
|
virtual bool event(QEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addMainGraph();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLOT_H
|
||||||
|
|
24
src/ui/regressiondiag.cpp
Executable file
24
src/ui/regressiondiag.cpp
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#include "regressiondiag.h"
|
||||||
|
#include "ui_regressiondiag.h"
|
||||||
|
|
||||||
|
RegressionDiag::RegressionDiag(const RegessionCalculator& reg, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::RegressionDiag)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->lcdNumber_slope->display(reg.slope);
|
||||||
|
ui->lcdNumber_offset->display(reg.offset);
|
||||||
|
ui->lcdNumber_StdError->display(reg.stdError);
|
||||||
|
ui->lcdNumbe_count->display((int)reg.xValues.size());
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
setWindowState(Qt::WindowMaximized);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
RegressionDiag::~RegressionDiag()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
24
src/ui/regressiondiag.h
Executable file
24
src/ui/regressiondiag.h
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef REGRESSIONDIAG_H
|
||||||
|
#define REGRESSIONDIAG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "regessioncalculator.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RegressionDiag;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegressionDiag : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RegressionDiag(const RegessionCalculator& reg, QWidget *parent = 0);
|
||||||
|
~RegressionDiag();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::RegressionDiag *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // REGRESSIONDIAG_H
|
160
src/ui/regressiondiag.ui
Executable file
160
src/ui/regressiondiag.ui
Executable file
@ -0,0 +1,160 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>RegressionDiag</class>
|
||||||
|
<widget class="QDialog" name="RegressionDiag">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>377</width>
|
||||||
|
<height>208</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Regression</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Slope:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_slope">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="digitCount">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="value" stdset="0">
|
||||||
|
<double>99999999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="intValue" stdset="0">
|
||||||
|
<number>99999999</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_offset">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="digitCount">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="value" stdset="0">
|
||||||
|
<double>99999999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="intValue" stdset="0">
|
||||||
|
<number>99999999</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Slope standard error:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_StdError">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="smallDecimalPoint">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="digitCount">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="value" stdset="0">
|
||||||
|
<double>99999999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="intValue" stdset="0">
|
||||||
|
<number>99999999</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Offset:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Count:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLCDNumber" name="lcdNumbe_count">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="digitCount">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="intValue" stdset="0">
|
||||||
|
<number>99999999</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>RegressionDiag</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>RegressionDiag</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
82
src/ui/statisticsdialog.cpp
Executable file
82
src/ui/statisticsdialog.cpp
Executable file
@ -0,0 +1,82 @@
|
|||||||
|
#include "statisticsdialog.h"
|
||||||
|
#include "ui_statisticsdialog.h"
|
||||||
|
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <limits>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
StatisticsDialog::StatisticsDialog(const std::vector<double>& data, QWidget *parent):
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::StatisticsDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(ui->pushButton_1, &QPushButton::clicked, this, &StatisticsDialog::copyCount);
|
||||||
|
connect(ui->pushButton_4, &QPushButton::clicked, this, &StatisticsDialog::copyMean);
|
||||||
|
connect(ui->pushButton_5, &QPushButton::clicked, this, &StatisticsDialog::copyMinMax);
|
||||||
|
connect(ui->pushButton_Sd, &QPushButton::clicked, this, &StatisticsDialog::copySd);
|
||||||
|
|
||||||
|
ui->lcdNumber_Count->display(static_cast<double>(data.size()));
|
||||||
|
|
||||||
|
double mean = 0;
|
||||||
|
double max = std::numeric_limits<double>::min();
|
||||||
|
double min = std::numeric_limits<double>::max();
|
||||||
|
for(double point : data)
|
||||||
|
{
|
||||||
|
mean += point;
|
||||||
|
if(point < min)
|
||||||
|
min = point;
|
||||||
|
if(point > max)
|
||||||
|
max = point;
|
||||||
|
}
|
||||||
|
mean = mean / data.size();
|
||||||
|
ui->lcdNumber_Mean->display(mean);
|
||||||
|
|
||||||
|
double sd = 0;
|
||||||
|
for(double point : data)
|
||||||
|
{
|
||||||
|
sd += (point - mean)*(point - mean);
|
||||||
|
}
|
||||||
|
sd /= data.size();
|
||||||
|
sd = sqrt(sd);
|
||||||
|
ui->lcdNumber_Sd->display(sd);
|
||||||
|
|
||||||
|
ui->lcdNumber_Max->display(max);
|
||||||
|
ui->lcdNumber_Min->display(min);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatisticsDialog::copyCount()
|
||||||
|
{
|
||||||
|
QString buffer(QString::number(ui->lcdNumber_Count->value(), 'g', 10));
|
||||||
|
QGuiApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||||
|
QGuiApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatisticsDialog::copyMean()
|
||||||
|
{
|
||||||
|
QString buffer(QString::number(ui->lcdNumber_Mean->value(), 'g', 10));
|
||||||
|
QGuiApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||||
|
QGuiApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatisticsDialog::copyMinMax()
|
||||||
|
{
|
||||||
|
QString buffer(QString::number(ui->lcdNumber_Min->value(), 'g', 10));
|
||||||
|
buffer.append(",");
|
||||||
|
buffer.append(QString::number(ui->lcdNumber_Max->value(), 'g', 10));
|
||||||
|
QGuiApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||||
|
QGuiApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatisticsDialog::copySd()
|
||||||
|
{
|
||||||
|
QString buffer(QString::number(ui->lcdNumber_Sd->value(), 'g', 10));
|
||||||
|
QGuiApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||||
|
QGuiApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
StatisticsDialog::~StatisticsDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
29
src/ui/statisticsdialog.h
Executable file
29
src/ui/statisticsdialog.h
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef STATISTICSDIALOG_H
|
||||||
|
#define STATISTICSDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class StatisticsDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class StatisticsDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit StatisticsDialog(const std::vector<double>& data, QWidget *parent = 0);
|
||||||
|
~StatisticsDialog();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void copyCount();
|
||||||
|
void copyMean();
|
||||||
|
void copyMinMax();
|
||||||
|
void copySd();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::StatisticsDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STATISTICSDIALOG_H
|
269
src/ui/statisticsdialog.ui
Executable file
269
src/ui/statisticsdialog.ui
Executable file
@ -0,0 +1,269 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>StatisticsDialog</class>
|
||||||
|
<widget class="QDialog" name="StatisticsDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>491</width>
|
||||||
|
<height>201</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Statistics</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Count:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_Count">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="digitCount">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="segmentStyle">
|
||||||
|
<enum>QLCDNumber::Flat</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_1">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Geometric mean:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_Mean">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="digitCount">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="segmentStyle">
|
||||||
|
<enum>QLCDNumber::Flat</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_4">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Standard deviation:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_Sd">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="digitCount">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="segmentStyle">
|
||||||
|
<enum>QLCDNumber::Flat</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_Sd">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Maximum:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_Max">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="digitCount">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="segmentStyle">
|
||||||
|
<enum>QLCDNumber::Flat</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Minimum:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_Min">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="digitCount">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="segmentStyle">
|
||||||
|
<enum>QLCDNumber::Flat</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>StatisticsDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>StatisticsDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
33
src/utilites.cpp
Executable file
33
src/utilites.cpp
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#include "utilites.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <thread>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
bool saveToCsv(const QString& filename, const std::vector<double> &keys, const std::vector<double> &values, const QString& keyLable, const QString& valueLable )
|
||||||
|
{
|
||||||
|
if(keys.size() != values.size())
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("keys and values need to be the same size");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QFile file(filename);
|
||||||
|
if(file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||||
|
{
|
||||||
|
QTextStream fileStream(&file);
|
||||||
|
fileStream<<"id"<<','<<keyLable<<','<<valueLable<<'\n';
|
||||||
|
for(size_t i = 0; i < keys.size(); i++)
|
||||||
|
{
|
||||||
|
fileStream<<i<<','<<(int64_t)keys[i]<<','<<values[i]<<'\n';
|
||||||
|
}
|
||||||
|
fileStream.flush();
|
||||||
|
file.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
11
src/utilites.h
Executable file
11
src/utilites.h
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef UTILITYS_H
|
||||||
|
#define UTILITYS_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
bool saveToCsv(const QString& filename, const std::vector<double> &keys, const std::vector<double> &values, const QString& keyLable, const QString& valueLable);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // UTILITYS_H
|
Reference in New Issue
Block a user