Tom Troppmann 4 years ago
parent
commit
4c526e5567

+ 2 - 0
.gitignore

@@ -16,6 +16,8 @@
 *.ko
 *.obj
 *.elf
+*.metalog
+
 
 # Linker output
 *.ilk

BIN
Distribution.PNG


+ 164 - 47
metavis/CustomLineGraph.cpp

@@ -5,32 +5,25 @@
 #include <random>
 #include <algorithm>
 
-CustomLineGraph::CustomLineGraph(QWidget* parent):QWidget(parent), linePen(Qt::blue), rectPen(Qt::red), axisPen(Qt::black)
+#define X_AXIS_GAP_AMOUNT 5
+#define Y_AXIS_GAP_AMOUNT 10
+#define X_AXIS_NUMBER_LINE_LENGTH 5
+#define Y_AXIS_NUMBER_LINE_LENGTH 5
+
+
+
+CustomLineGraph::CustomLineGraph(QWidget* parent, QString title, int lineWidth, double circleRadius):QWidget(parent), title(title), lineWidth(lineWidth), circleRadius(circleRadius), linePen(Qt::blue), rectPen(Qt::red), axisPen(Qt::black)
 {
-	linePen.setWidth(3);
+	linePen.setWidth(lineWidth);
 	linePen.setJoinStyle(Qt::PenJoinStyle::RoundJoin);
-	LineGraphSeries lgs;
+	
 	//Populate data with DummyData
 	//Draw Points
 	std::random_device rd;  //Will be used to obtain a seed for the random number engine
 	std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
-	std::uniform_int_distribution<> dis(-3, 3);
-	for (int randomSeries = 0; randomSeries < 2; randomSeries++) {
-		for (int i = 0; i < 21; i++) {
-			QPoint point(i * 50 + 500,i * 1 + dis(gen) - 10000);
-			lgs.data.push_back(point);
-		}
-
-		auto pairX = std::minmax_element(std::begin(lgs.data), std::end(lgs.data), [](const QPoint& a,const QPoint& b) -> bool {return a.x() < b.x(); });
-		lgs.minX = pairX.first->x();
-		lgs.maxX = pairX.second->x();
-		auto pairY = std::minmax_element(std::begin(lgs.data), std::end(lgs.data), [](const QPoint& a, const QPoint& b) -> bool {return a.y() < b.y(); });
-		lgs.minY = pairY.first->y();
-		lgs.maxY = pairY.second->y();
-		lgs.rangeX = std::abs(lgs.maxX - lgs.minX);
-		lgs.rangeY = std::abs(lgs.maxY - lgs.minY);
-		seriesVec.push_back(lgs);
-	}
+	std::uniform_real_distribution<double> doubleDistr(0.0, 1.0);
+	hueoffset = doubleDistr(gen);
+	
 }
 
 CustomLineGraph::~CustomLineGraph()
@@ -40,45 +33,56 @@ void CustomLineGraph::paintEvent(QPaintEvent* event)
 {
 	QPainter painter(this);
 	painter.setRenderHint(QPainter::RenderHint::HighQualityAntialiasing);
-	
+	if (seriesVec.empty()) {
+		painter.setPen(axisPen);
+		painter.setFont(QFont("Arial", 12, QFont::Bold));
+		painter.drawText(rect(), Qt::AlignCenter, "No Data connected");
+		return;
+	}
 	//Calculate LineRect
 	QRect lineRect(rect());
 	lineRect.setBottom(lineRect.bottom() - 20);
 	lineRect.setLeft(lineRect.left() + 40);
 	lineRect.setTop(lineRect.top() + 20);
 	lineRect.setRight(lineRect.right() - 10);
-	lineRect.setWidth(lineRect.width() - (lineRect.width() % 10) + 1);
-	lineRect.setHeight(lineRect.height() - (lineRect.height() % 10) + 1);
+	lineRect.setWidth(lineRect.width() - (lineRect.width() % X_AXIS_GAP_AMOUNT) + 1);
+	lineRect.setHeight(lineRect.height() - (lineRect.height() % Y_AXIS_GAP_AMOUNT) + 1);
 
 
 	//draw Title
 	painter.setPen(axisPen);
 	painter.setFont(QFont("Arial", 12));
-	QRect titleRect(QPoint(lineRect.left(), rect().top()), QPoint(lineRect.right(), lineRect.top()));
-	painter.drawText(titleRect, Qt::AlignCenter, "title");
-
+	QRect titleRect(QPoint(rect().left(), rect().top()), QPoint(lineRect.right(), lineRect.top()));
+	painter.drawText(titleRect, Qt::AlignCenter, title);
 
+	painter.setFont(QFont("Arial", 8));
 	//draw X-Axis
 	QRect xAxisRect(QPoint(lineRect.left(), lineRect.bottom()), QPoint(lineRect.right(), rect().bottom()));
 	QPainterPath xAxisPath;
 	xAxisPath.moveTo(xAxisRect.left(), xAxisRect.top());
 	xAxisPath.lineTo(xAxisRect.right(), xAxisRect.top());
-	int xGap = xAxisRect.width() / 10;
+	int xGap = xAxisRect.width() / X_AXIS_GAP_AMOUNT;
+	QRect textRect(0, 0, 40, 9);
+
 	for (int i = 0; i < 11; i++) {
-		xAxisPath.moveTo(xAxisRect.left() + i * xGap, xAxisRect.top() + 5);
+		xAxisPath.moveTo(xAxisRect.left() + i * xGap, xAxisRect.top() + X_AXIS_NUMBER_LINE_LENGTH);
 		xAxisPath.lineTo(xAxisRect.left() + i * xGap, xAxisRect.top());
+		textRect.moveCenter(QPoint(xAxisRect.left() + i * xGap, xAxisRect.top() + 10));
+		painter.drawText(textRect, Qt::AlignCenter, xAxisNumbers[i]);
 	}
 	painter.drawPath(xAxisPath);
 
 	//draw Y-Axis
 	QRect yAxisRect(QPoint(rect().left(), lineRect.top()), QPoint(lineRect.left(), lineRect.bottom()));
 	QPainterPath yAxisPath;
-	yAxisPath.moveTo(yAxisRect.right(), yAxisRect.bottom() + 5);
+	yAxisPath.moveTo(yAxisRect.right(), yAxisRect.bottom());
 	yAxisPath.lineTo(yAxisRect.right(), yAxisRect.top());
-	int yGap = yAxisRect.height() / 10;
+	int yGap = yAxisRect.height() / Y_AXIS_GAP_AMOUNT;
 	for (int i = 0; i < 11; i++) {
-		yAxisPath.moveTo(yAxisRect.right() - 5, yAxisRect.top() + i * yGap);
-		yAxisPath.lineTo(yAxisRect.right(), yAxisRect.top() + i * yGap);
+		yAxisPath.moveTo(yAxisRect.right() - Y_AXIS_NUMBER_LINE_LENGTH, yAxisRect.bottom() - i * yGap);
+		yAxisPath.lineTo(yAxisRect.right(), yAxisRect.bottom() - i * yGap);
+		textRect.moveCenter(QPoint(yAxisRect.right() - Y_AXIS_NUMBER_LINE_LENGTH - 20, yAxisRect.bottom() - i * yGap));
+		painter.drawText(textRect, Qt::AlignCenter, yAxisNumbers[i]);
 	}
 	painter.drawPath(yAxisPath);
 
@@ -88,28 +92,141 @@ void CustomLineGraph::paintEvent(QPaintEvent* event)
 	
 
 	painter.setPen(linePen);
-	for (LineGraphSeries series : seriesVec) {
-
-		double stregth_factorX = lineRect.width() / series.rangeX;
-		double stregth_factorY = lineRect.height() / series.rangeY;
+	double stregth_factorX = lineRect.width() / rangeGraphX;
+	double stregth_factorY = lineRect.height() / rangeGraphY;
+	for (LineGraphSeries lgs : seriesVec) {
+		linePen.setColor(lgs.color);
+		painter.setPen(linePen);
 		QPointF translation(lineRect.left(), lineRect.top());
-		QPainterPath painterPath;
-		painterPath.moveTo(transformPoint(series.data[0], series, stregth_factorX, stregth_factorY));
-		for(int i = 1; i < seriesVec[0].data.size(); i++) {
-			painterPath.lineTo(transformPoint(series.data[i], series, stregth_factorX, stregth_factorY));
+		if (!lgs.type == LineGraphSeries::Dot) {
+			QPainterPath painterPath;
+			painterPath.moveTo(transformPoint(lgs.data[0], stregth_factorX, stregth_factorY));
+			for(int i = 1; i < lgs.data.size(); i++) {
+				painterPath.lineTo(transformPoint(lgs.data[i], stregth_factorX, stregth_factorY));
+			}
+			painterPath.translate(translation);
+			painter.drawPath(painterPath);
 		}
-		painterPath.translate(translation);
-		painter.drawPath(painterPath);
-		int radius;
-		for (int i = 0; i < seriesVec[0].data.size(); i++) {
-			painter.drawEllipse(transformPoint(series.data[i], series, stregth_factorX, stregth_factorY) + translation, 3, 3);
+		/* only draw when circle can be seen*/
+		if (!(lineWidth > 4 * circleRadius || circleRadius == 0)) {
+			painter.setBrush(lgs.color);
+			for (int i = 0; i < lgs.data.size(); i++) {
+				painter.drawEllipse(transformPoint(lgs.data[i], stregth_factorX, stregth_factorY) + translation, circleRadius, circleRadius);
+			}
+			painter.setBrush(Qt::BrushStyle::NoBrush);
 		}
 	}
 	
 }
 
-QPoint CustomLineGraph::transformPoint(QPoint& point, LineGraphSeries& lgs, double stregth_factorX, double stregth_factorY)
+QPointF CustomLineGraph::transformPoint(QPointF& point, double stregth_factorX, double stregth_factorY)
+{
+	return QPointF((point.x() - minGraphX)* stregth_factorX , (maxGraphY - point.y()) * stregth_factorY);
+}
+
+void CustomLineGraph::calculateMinMaxGraphXY()
+{
+	minGraphX = std::min_element(std::begin(seriesVec), std::end(seriesVec), [](const LineGraphSeries& a, const LineGraphSeries& b) -> bool {return a.minX < b.minX; })->minX;
+	maxGraphX = std::max_element(std::begin(seriesVec), std::end(seriesVec), [](const LineGraphSeries& a, const LineGraphSeries& b) -> bool {return a.maxX < b.maxX; })->maxX;
+	minGraphY = std::min_element(std::begin(seriesVec), std::end(seriesVec), [](const LineGraphSeries& a, const LineGraphSeries& b) -> bool {return a.minY < b.minY; })->minY;
+	maxGraphY = std::max_element(std::begin(seriesVec), std::end(seriesVec), [](const LineGraphSeries& a, const LineGraphSeries& b) -> bool {return a.maxY < b.maxY; })->maxY;
+	rangeGraphX = std::abs(maxGraphX - minGraphX);
+	rangeGraphY = std::abs(maxGraphY - minGraphY);
+	if (std::abs(rangeGraphX) < 0.01) {
+		minGraphX -= 1.0;
+		maxGraphX += 1.0;
+		rangeGraphX = 2;
+	}
+	if (std::abs(rangeGraphY) < 0.01) {
+		minGraphY -= 1.0;
+		maxGraphY += 1.0;
+		rangeGraphY = 2;
+	}
+}
+
+void CustomLineGraph::popullateLineGraphSeries(std::vector<QPointF>& line, LineGraphSeries& lgs)
+{
+	lgs.data = line;
+	auto pairX = std::minmax_element(std::begin(lgs.data), std::end(lgs.data), [](const QPointF& a, const QPointF& b) -> bool {return a.x() < b.x(); });
+	lgs.minX = pairX.first->x();
+	lgs.maxX = pairX.second->x();
+	auto pairY = std::minmax_element(std::begin(lgs.data), std::end(lgs.data), [](const QPointF& a, const QPointF& b) -> bool {return a.y() < b.y(); });
+	lgs.minY = pairY.first->y();
+	lgs.maxY = pairY.second->y();
+}
+
+void CustomLineGraph::addSeries(std::vector<QPointF>& line, QColor color, LineGraphSeries::SeriesType type)
+{
+	if (line.empty()) {
+		return;
+	}
+	LineGraphSeries lgs;
+	lgs.type = type;
+	popullateLineGraphSeries(line, lgs);
+	lgs.color = color;
+	seriesVec.push_back(lgs);
+	calculateMinMaxGraphXY();
+	generateAxisNumberStrings();
+}
+
+QColor CustomLineGraph::generateNextColorForGraph()
+{
+	/* http://devmag.org.za/2012/07/29/how-to-choose-colours-procedurally-algorithms/
+		use golden ratio 0.618033988749895f
+	*/
+	hueoffset = std::fmod(hueoffset + 0.618033988749895f, 1.0);
+	return QColor::fromHsvF(hueoffset, 0.83, 1.0);
+}
+
+void CustomLineGraph::generateAxisNumberStrings()
+{
+	for (int i = 0; i < 11; i++) {
+		xAxisNumbers[i] = QString::number(minGraphX + i * (rangeGraphX / (double)X_AXIS_GAP_AMOUNT), 'f', 1);
+		yAxisNumbers[i] = QString::number(minGraphY + i * (rangeGraphY / (double)Y_AXIS_GAP_AMOUNT), 'f', 1);
+	}
+}
+
+void CustomLineGraph::generateAndAddRandomLine()
 {
-	return QPoint((point.x() - lgs.minX)* stregth_factorX , (lgs.maxY - point.y()) * stregth_factorY);
+	std::random_device rd;  //Will be used to obtain a seed for the random number engine
+	std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
+
+
+	std::uniform_real_distribution<double> realDistr(-30, 30);
+	std::uniform_int_distribution<int> intScaleDistr(1, 3);
+
+	for (int randomSeries = 0; randomSeries < 1; randomSeries++) {
+		std::vector<QPointF> randomPointVec(101);
+		int scale = intScaleDistr(gen);
+		for (int i = 0; i < randomPointVec.size(); i++) {
+			randomPointVec[i] = QPointF(i + 500, i * scale + realDistr(gen));
+		}
+		addLine(randomPointVec);
+	}
 }
 
+void CustomLineGraph::addLine(std::vector<QPointF>& line)
+{
+	addLine(line, generateNextColorForGraph());
+}
+
+void CustomLineGraph::addLine(std::vector<QPointF>& line, QColor color)
+{
+	addSeries(line, color, LineGraphSeries::Line);
+}
+
+void CustomLineGraph::addDots(std::vector<QPointF>& dots)
+{
+	addSeries(dots, generateNextColorForGraph(), LineGraphSeries::Dot);
+}
+
+void CustomLineGraph::addDots(std::vector<QPointF>& dots, QColor color)
+{
+	addSeries(dots, color, LineGraphSeries::Dot);
+}
+
+
+
+
+
+

+ 26 - 6
metavis/CustomLineGraph.h

@@ -6,11 +6,13 @@
 #include <vector>
 
 struct LineGraphSeries {
-	std::vector<QPoint> data;
+	std::vector<QPointF> data;
 	double minX, maxX;
 	double minY, maxY;
-	double rangeX, rangeY;
 	QColor color;
+	QString name;
+	enum SeriesType{ Line, Dot};
+	SeriesType type;
 };
 
 //bool compTest(QPoint a, QPoint b) {
@@ -22,14 +24,32 @@ class CustomLineGraph :public QWidget
 	Q_OBJECT
 
 public:
-	CustomLineGraph(QWidget* parent);
+	CustomLineGraph(QWidget* parent, QString title,  int lineWidth = 2, double circleRadius = .5);
 	~CustomLineGraph();
 	void CustomLineGraph::paintEvent(QPaintEvent* event);
-	
+	int lineWidth;
+	double circleRadius;
+	QString title;
 private:
+	//Data
 	std::vector<LineGraphSeries> seriesVec;
+	double minGraphX = 0, maxGraphX = 0, minGraphY = 0, maxGraphY = 0, rangeGraphX = 0, rangeGraphY = 0;
+	//Visualization
+	QString xAxisNumbers[11];
+	QString yAxisNumbers[11];
+	double hueoffset;
 	QPen linePen, rectPen, axisPen;
-	QPoint transformPoint(QPoint& point, LineGraphSeries& lgs, double stregth_factorX, double stregth_factorY);
-
+	QPointF transformPoint(QPointF& point, double stregth_factorX, double stregth_factorY);
+	void generateAxisNumberStrings();
+	void calculateMinMaxGraphXY();
+	void CustomLineGraph::popullateLineGraphSeries(std::vector<QPointF>& line, LineGraphSeries& lgs);
+	void addSeries(std::vector<QPointF>& line, QColor color, LineGraphSeries::SeriesType type);
+	QColor generateNextColorForGraph();
+public:
+	void generateAndAddRandomLine();
+	void addLine(std::vector<QPointF>& line);
+	void addLine(std::vector<QPointF>& line, QColor color);
+	void addDots(std::vector<QPointF>& dots);
+	void addDots(std::vector<QPointF>& dots, QColor color);
 };
 

+ 161 - 0
metavis/RunData.cpp

@@ -0,0 +1,161 @@
+#include "RunData.h"
+#include <QDebug>
+#include <QString>
+#include <regex>
+
+
+
+RunData::RunData()
+{
+}
+
+RunData::RunData(std::string filePath): fileStream(filePath)
+{
+    if (!fileStream.is_open())
+    {
+        //Cant open file
+        badFileFlag = true;
+        return;
+    }
+    /* Start extracting */
+    while (fileStream.peek() != EOF) {
+        std::string buffer;
+        getLine(buffer);
+        //qDebug() << "Line[" << actualLine << "]:" << QString::fromStdString(buffer);
+        SolutionPointData sol;
+
+        std::regex regexIter("i:([\\+\\-]?\\d+)");
+        std::regex regexObjectiveFunction("of:([\\+\\-]?\\d+\\.\\d+(?:E[\\+\\-]\\d+)?)");
+        std::smatch match;
+        if (!std::regex_search(buffer, match, regexIter)) {
+            qDebug() << "Bad formatatted Line[" << actualLine << "].";
+            qDebug() << "Failed to matched:";
+            qDebug() << QString::fromStdString(buffer);
+            return;
+        }
+        sol.iteration = std::stoi(match[1]);
+        if (!std::regex_search(buffer, match, regexObjectiveFunction)) {
+            qDebug() << "Bad formatatted Line[" << actualLine << "].";
+            qDebug() << "Failed to matched:";
+            qDebug() << QString::fromStdString(buffer);
+            return;
+        }
+        sol.objectiveFunction = std::stod(match[1]);
+        std::regex regexParticleNumber("pN:([\\+\\-]?\\d+)");
+        if (!std::regex_search(buffer, match, regexParticleNumber)) {
+            qDebug() << "Bad formatatted Line[" << actualLine << "].";
+            qDebug() << "Failed to matched:";
+            qDebug() << QString::fromStdString(buffer);
+            return;
+        }
+        sol.particleNumber = std::stoi(match[1]);
+        solutionVec.push_back(sol);
+    }
+    fileStream.close();
+    calculateBestAndAverageIter();
+    calculateParticleSolution();
+    calculateDotsForDistribution();
+}
+
+void RunData::getLine(std::string& bufferString)
+{
+    //std::getline(fileStream, bufferString);
+    std::getline(fileStream, bufferString);
+    actualLine++;
+}
+
+void RunData::calculateBestAndAverageIter()
+{
+    if (solutionVec.empty()) {
+        return;
+    }
+    double minObjectiveFunctionInIter = solutionVec[0].objectiveFunction;
+    double maxObjectiveFunctionInIter = solutionVec[0].objectiveFunction;
+    double bestObjectiveFunctionFound = solutionVec[0].objectiveFunction;
+    int actualIter = solutionVec[0].iteration;
+    double actualIterObjectiveFunctionAggregate = solutionVec[0].objectiveFunction;
+    int foundSolutionInIteration = 1; 
+    for(int i = 1; i < solutionVec.size(); i++) {
+        SolutionPointData nextData = solutionVec[i];
+        if (nextData.iteration != actualIter) {
+            //save last
+            bestSolutionPerIteration.push_back(QPointF((double)actualIter, bestObjectiveFunctionFound));
+            averageSolutionPerItertion.push_back(QPointF((double)actualIter, actualIterObjectiveFunctionAggregate / (double)foundSolutionInIteration));
+            minSolutionPerItertion.push_back(QPointF((double)actualIter, minObjectiveFunctionInIter));
+            maxSolutionPerItertion.push_back(QPointF((double)actualIter, maxObjectiveFunctionInIter));
+            //init new iteration
+            actualIter = nextData.iteration;
+            foundSolutionInIteration = 1;
+            actualIterObjectiveFunctionAggregate = nextData.objectiveFunction;
+            minObjectiveFunctionInIter = nextData.objectiveFunction;
+            maxObjectiveFunctionInIter = nextData.objectiveFunction;
+        }
+        else {
+            //increae aggregate
+            foundSolutionInIteration++;
+            actualIterObjectiveFunctionAggregate += nextData.objectiveFunction;
+        }
+        //update best min and max if better
+        if (nextData.objectiveFunction < bestObjectiveFunctionFound) {
+            bestObjectiveFunctionFound = nextData.objectiveFunction;
+        }
+        if (nextData.objectiveFunction < minObjectiveFunctionInIter) {
+            minObjectiveFunctionInIter = nextData.objectiveFunction;
+        }
+        if (nextData.objectiveFunction > maxObjectiveFunctionInIter) {
+            maxObjectiveFunctionInIter = nextData.objectiveFunction;
+        }
+    }
+    //save last iteration
+    bestSolutionPerIteration.push_back(QPointF((double)actualIter, bestObjectiveFunctionFound));
+    averageSolutionPerItertion.push_back(QPointF((double)actualIter, actualIterObjectiveFunctionAggregate / (double)foundSolutionInIteration));
+    minSolutionPerItertion.push_back(QPointF((double)actualIter, minObjectiveFunctionInIter));
+    maxSolutionPerItertion.push_back(QPointF((double)actualIter, maxObjectiveFunctionInIter));
+
+
+}
+
+void RunData::calculateParticleSolution()
+{
+    for (SolutionPointData sol : solutionVec) {
+        QPointF point(sol.iteration, sol.objectiveFunction);
+        auto iter = particleMap.find(sol.particleNumber);
+        if (iter == particleMap.end()) {
+            //create new Entry
+            std::vector<QPointF> vec;
+            vec.push_back(point);
+            particleMap.insert({ sol.particleNumber, vec});
+        }
+        else {
+            //append to vector in Entry
+            iter->second.push_back(point);
+        }
+    }
+    /*for (auto iter = std::begin(particleMap); iter != std::end(particleMap); iter++) {
+        qDebug() << "List with pN[" << iter->first << "]:";
+        for (QPointF point : iter->second) {
+                qDebug() << point;
+        }
+    }*/
+}
+
+void RunData::calculateDotsForDistribution()
+{
+
+    for (SolutionPointData sol : solutionVec) {
+        QPointF point((double)sol.iteration, sol.objectiveFunction);
+        dotsForDistribution.push_back(point);
+    }
+
+    ////check code:
+    //int count = 0;
+    //int actualIter = (int)dotsForDistribution[0].x();
+    //for (int i = 0; i < dotsForDistribution.size(); i++) {
+    //    if (actualIter != (int)dotsForDistribution[i].x()) {
+    //        actualIter = (int)dotsForDistribution[i].x();
+    //        qDebug() << "[" << actualIter << "]Min:" << minSolutionPerItertion[count].y() << " Max: " << maxSolutionPerItertion[count].y();
+    //        count++;
+    //    }
+    //    qDebug() << dotsForDistribution[i];
+    //}
+}

+ 41 - 0
metavis/RunData.h

@@ -0,0 +1,41 @@
+#pragma once
+#include <string>
+#include <vector>
+#include <fstream>
+#include <QPoint>
+#include <map>
+
+struct SolutionPointData {
+public:
+	int iteration;
+	double objectiveFunction;
+	int particleNumber;
+};
+class RunData
+{
+public:
+	std::string name;
+	std::string information;
+	std::vector<SolutionPointData> solutionVec;
+	RunData();
+	RunData(std::string filePath);
+	
+
+	std::vector<QPointF> bestSolutionPerIteration;
+	std::vector<QPointF> averageSolutionPerItertion;
+	std::vector<QPointF> minSolutionPerItertion;
+	std::vector<QPointF> maxSolutionPerItertion;
+	std::vector<QPointF> dotsForDistribution;
+	std::map<int, std::vector<QPointF>> particleMap;
+private:
+	bool badFileFlag = false;
+	std::fstream fileStream;
+	int actualLine = 0;
+	void getLine(std::string& bufferString);
+
+	void calculateBestAndAverageIter();
+	void calculateParticleSolution();
+	void calculateDotsForDistribution();
+
+};
+

+ 3 - 4
metavis/dataTest.cpp

@@ -4,17 +4,16 @@
 dataTest::dataTest()
 {
 	for (int i = 0; i < 1000; i++) {
-		entrys->push_back(solution(2000, i));
+		entrys.push_back(solution(2000, i));
 	}
-	entrys->at(0).bits[34] = true;
-	solution sol = entrys->at(0);
+	entrys.at(0).bits[34] = true;
+	solution sol = entrys.at(0);
 	
 	qDebug() << sol.toQString();
 }
 
 dataTest::~dataTest()
 {
-	free(entrys);
 }
 
 QString dataTest::solution::toQString()

+ 1 - 1
metavis/dataTest.h

@@ -15,7 +15,7 @@ private:
 		QString toQString();
 	};
 public:
-	std::vector<solution>* entrys =  new std::vector<solution>();
+	std::vector<solution> entrys = std::vector<solution>();
 	/* Contructor of this test class*/
 	dataTest();
 	~dataTest();

+ 0 - 2
metavis/main.cpp

@@ -1,12 +1,10 @@
 #include "metavis.h"
 #include <QtWidgets/QApplication>
-#include "dataTest.h"
 #include <QtGui>
 
 /* entrance of the program */
 int main(int argc, char *argv[])
 {
-	dataTest test;
 	QApplication a(argc, argv);
 	metavis w;
 	w.show();

+ 42 - 12
metavis/metavis.cpp

@@ -8,11 +8,14 @@
 #include <QStyleFactory>
 #include <QtWebChannel/QtWebChannel>
 #include <QtWebEngineWidgets/QWebEngineView>
+#include <QFileDialog>
+#include <QDir>
+#include <map>
 #include "LineGraph.h"
-#include "CustomLineGraph.h"
 
-metavis::metavis(QWidget *parent)
-	: QMainWindow(parent)
+
+metavis::metavis(QWidget* parent)
+	: QMainWindow(parent), bestGraph(createCustomWidget("Best vs Avg")), particleGraph(createCustomWidget("Particle")), minMaxGraph(createCustomWidget("MinMaxGraph"))
 {
 	ui.setupUi(this);
 	/* create settings object*/
@@ -22,10 +25,14 @@ metavis::metavis(QWidget *parent)
 	setStyleSheet(styleSheet() + "QTabWidget::pane {border-top: 2px solid #C2C7CB;}");
 	
 	
-	createCustomWidget();
+	/*CustomLineGraph* random = createCustomWidget(QString("Random"));
+	random->generateAndAddRandomLine();
+	random->generateAndAddRandomLine();
+	random->generateAndAddRandomLine();*/
 	/*createCustomWidget();
 	createCustomWidget();
 	createCustomWidget();*/
+
 	readMainWindowSettings();
 }
 
@@ -80,23 +87,24 @@ void metavis::createWebEngineWidget()
 	addDockWidget(Qt::LeftDockWidgetArea, dock);
 }
 
-void metavis::createCustomWidget()
+CustomLineGraph* metavis::createCustomWidget(QString titleString)
 {
-	QDockWidget* dock = new QDockWidget("Customers", this);
-	dock->setObjectName("TestWidget");
+	QDockWidget* dock = new QDockWidget(titleString, this);
+	dock->setObjectName(titleString);
 	dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
-	CustomLineGraph* widget = new CustomLineGraph(dock);
-	widget->setMinimumSize(200, 200);
-	widget->show();
-	widget->repaint();
+	CustomLineGraph* bestGraph = new CustomLineGraph(dock, titleString);
+	bestGraph->setMinimumSize(200, 200);
+	bestGraph->show();
+	bestGraph->repaint();
 	dock->setBaseSize(300, 300);
 	dock->repaint();
 	QPalette pal;
 	pal.setColor(QPalette::Background, Qt::lightGray);
 	//dock->setPalette(pal);
 	//widget->setPalette(pal);
-	dock->setWidget(widget);
+	dock->setWidget(bestGraph);
 	addDockWidget(Qt::LeftDockWidgetArea, dock);
+	return bestGraph;
 }
 
 void metavis::writeActualMainWindowSettings()
@@ -124,3 +132,25 @@ void metavis::readMainWindowSettings()
 	}
 	settings->endGroup();
 }
+
+void metavis::openFile()
+{
+	qDebug() << "openFile";
+	QString fileName = QFileDialog::getOpenFileName(this, tr("Open LogFile"), QStandardPaths::displayName(QStandardPaths::DesktopLocation), tr("Metavis Logfile (*.metalog)"));
+	if (fileName == ("")) {
+		qDebug() << "No file selected";
+		return;
+	}
+	qDebug() << "file:" << fileName;
+	runVec.push_back(RunData(fileName.toStdString()));
+	bestGraph->addLine(runVec[0].bestSolutionPerIteration, QColor(255, 0, 0));
+	bestGraph->addLine(runVec[0].averageSolutionPerItertion, QColor(0, 0, 255));
+
+	minMaxGraph->addLine(runVec[0].minSolutionPerItertion, QColor(255, 0, 0));
+	minMaxGraph->addLine(runVec[0].maxSolutionPerItertion, QColor(0, 0, 255));
+	minMaxGraph->addDots(runVec[0].dotsForDistribution, QColor(255, 165, 0, 100));
+	for (auto iter = runVec[0].particleMap.begin(); iter != runVec[0].particleMap.end(); iter++) {
+		particleGraph->addLine(iter->second);
+	}
+
+}

+ 14 - 3
metavis/metavis.h

@@ -2,7 +2,10 @@
 
 #include <QtWidgets/QMainWindow>
 #include "ui_metavis.h"
-#include <qsettings.h>
+#include <QSettings>
+#include <vector>
+#include "RunData.h"
+#include "CustomLineGraph.h"
 
 /**
  * Main class of the GUI.
@@ -14,16 +17,20 @@ class metavis : public QMainWindow
 public:
 	metavis(QWidget *parent = Q_NULLPTR);
 	~metavis();
-
+	CustomLineGraph* bestGraph;
+	CustomLineGraph* particleGraph;
+	CustomLineGraph* minMaxGraph;
 private:
 	Ui::metavisClass ui;
 	QSettings* settings;
+	std::vector<RunData> runVec;
+
 
 private:
 	/* Widget functions */
 	void createChartWidget();
 	void createWebEngineWidget();
-	void createCustomWidget();
+	CustomLineGraph* createCustomWidget(QString titleString);
 
 
 	/* Setting functions*/
@@ -36,4 +43,8 @@ public slots:
 	 * Opens the settingWindows Dialog.
 	 */
 	void openSetting();
+	/**
+	 * Open a logFile.	
+	 */
+	void openFile();
 };

+ 17 - 0
metavis/metavis.ui

@@ -88,8 +88,25 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>actionOpen</sender>
+   <signal>triggered()</signal>
+   <receiver>metavisClass</receiver>
+   <slot>openFile()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>371</x>
+     <y>279</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
  <slots>
   <slot>openSetting()</slot>
+  <slot>openFile()</slot>
  </slots>
 </ui>

+ 2 - 0
metavis/metavis.vcxproj

@@ -99,6 +99,7 @@
     <ClCompile Include="LineGraph.cpp" />
     <ClCompile Include="main.cpp" />
     <ClCompile Include="metavis.cpp" />
+    <ClCompile Include="RunData.cpp" />
     <ClCompile Include="SettingDialog.cpp" />
   </ItemGroup>
   <ItemGroup>
@@ -118,6 +119,7 @@
     <QtMoc Include="SettingDialog.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="RunData.h" />
     <QtMoc Include="CustomLineGraph.h" />
     <ClInclude Include="dataTest.h" />
     <QtMoc Include="LineGraph.h" />

+ 6 - 0
metavis/metavis.vcxproj.filters

@@ -43,6 +43,9 @@
     <ClCompile Include="CustomLineGraph.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="RunData.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <QtMoc Include="metavis.h">
@@ -78,6 +81,9 @@
     <ClInclude Include="dataTest.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="RunData.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="web.html">