Version Bump
Remember Save paths add missing files
This commit is contained in:
		
							parent
							
								
									42da1746b5
								
							
						
					
					
						commit
						3c788f57c2
					
				
					 20 changed files with 1168 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -68,7 +68,7 @@ int main(int argc, char *argv[])
 | 
			
		|||
		QCoreApplication::setOrganizationName("UVOS");
 | 
			
		||||
		QCoreApplication::setOrganizationDomain("uvos.xyz");
 | 
			
		||||
		QCoreApplication::setApplicationName("MAClient");
 | 
			
		||||
		QCoreApplication::setApplicationVersion("0.1");
 | 
			
		||||
		QCoreApplication::setApplicationVersion("0.5");
 | 
			
		||||
 | 
			
		||||
		 //parse comand line
 | 
			
		||||
		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;
 | 
			
		||||
	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
 | 
			
		||||
	{
 | 
			
		||||
		fileName = QFileDialog::getSaveFileName(this, "Save Image", "./", "*.mat" );
 | 
			
		||||
		fileName = QFileDialog::getSaveFileName(this, "Save Image", lastSavePath_, "*.mat" );
 | 
			
		||||
	}
 | 
			
		||||
	if(!fileName.isEmpty())
 | 
			
		||||
	{
 | 
			
		||||
		lastSavePath_= fileName.mid(0, fileName.lastIndexOf('/'));
 | 
			
		||||
		QStringList tokens = fileName.split('.');
 | 
			
		||||
		if(tokens.back() != "mat" && tokens.back() != "png")
 | 
			
		||||
			fileName.append(".mat");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ private:
 | 
			
		|||
	QLine yLine_;
 | 
			
		||||
	bool selectionStarted_ = false;
 | 
			
		||||
	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 convertImage(cv::Mat image);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,9 +55,10 @@ void MainWindow::saveImage()
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	QString fileName = QFileDialog::getSaveFileName(this, "Save Image", "./", "*.mat");
 | 
			
		||||
	QString fileName = QFileDialog::getSaveFileName(this, "Save Image", lastSavedPath_, "*.mat");
 | 
			
		||||
	if(!fileName.isEmpty())
 | 
			
		||||
	{
 | 
			
		||||
		lastSavedPath_= fileName.mid(0, fileName.lastIndexOf('/'));
 | 
			
		||||
		QStringList tokens = fileName.split('.');
 | 
			
		||||
		if(tokens.back() != "mat")
 | 
			
		||||
			fileName.append(".mat");
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +70,7 @@ void MainWindow::saveImage()
 | 
			
		|||
 | 
			
		||||
void MainWindow::openImage()
 | 
			
		||||
{
 | 
			
		||||
	QString fileName = QFileDialog::getOpenFileName(this, "Open Image", "./", "*.mat");
 | 
			
		||||
	QString fileName = QFileDialog::getOpenFileName(this, "Open Image", lastSavedPath_, "*.mat");
 | 
			
		||||
	if(!fileName.isEmpty())
 | 
			
		||||
	{
 | 
			
		||||
		cv::Mat image;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,7 @@ class MainWindow : public QMainWindow
 | 
			
		|||
private:
 | 
			
		||||
	std::vector<CvImageViewer*> viewers_;
 | 
			
		||||
	AboutDiag about_;
 | 
			
		||||
	inline static QString lastSavedPath_ = "./";
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
	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
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue