adjusted gui, adjusted line and point model classes

This commit is contained in:
Armin Wolf 2020-04-05 19:28:38 +02:00
parent 59b4567d9e
commit 2c97aa1fe8
35 changed files with 138085 additions and 203908 deletions

6
.gitattributes vendored Normal file
View File

@ -0,0 +1,6 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf

View File

@ -8,6 +8,7 @@ plugins {
repositories { repositories {
mavenLocal() mavenLocal()
mavenCentral()
maven { maven {
url = uri('http://repo.maven.apache.org/maven2') url = uri('http://repo.maven.apache.org/maven2')
} }
@ -21,6 +22,7 @@ dependencies {
implementation 'com.opencsv:opencsv:5.1' implementation 'com.opencsv:opencsv:5.1'
implementation 'com.google.guava:guava:28.2-jre' implementation 'com.google.guava:guava:28.2-jre'
implementation 'org.powermock:powermock-core:2.0.6' implementation 'org.powermock:powermock-core:2.0.6'
compile group: 'org.apache.commons', name: 'commons-math3', version: '3.6.1'
} }
group = 'de.wwu.awolf' group = 'de.wwu.awolf'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,4 @@
/* /*
* This file was generated by the Gradle 'init' task. * This file was generated by the Gradle 'init' task.
*/ */
rootProject.name = 'masterarbeit' rootProject.name = 'masterarbeit'

View File

@ -51,9 +51,13 @@ public class App extends Application {
//register at presenter //register at presenter
new GuiRegisterService(fxmlLoader.getController()).start(); new GuiRegisterService(fxmlLoader.getController()).start();
primaryStage.setTitle(TITLE); primaryStage.setTitle(TITLE);
Scene scene = new Scene(pane, 1000, 800); Scene scene = new Scene(pane, 1200, 900);
scene.getStylesheets().add(ViewController.class.getResource("/style/console.css").toExternalForm()); scene.getStylesheets().add(ViewController.class.getResource("/style/style.css").toExternalForm());
primaryStage.setScene(scene); primaryStage.setScene(scene);
primaryStage.setOnCloseRequest(e -> {
Platform.exit();
System.exit(0);
});
primaryStage.show(); primaryStage.show();
} catch (IOException e) { } catch (IOException e) {
Logging.logError("Error reading FXML file. ", e); Logging.logError("Error reading FXML file. ", e);

View File

@ -1,5 +1,9 @@
package de.wwwu.awolf.model; package de.wwwu.awolf.model;
import org.apache.commons.math3.util.Precision;
import java.util.Objects;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *
@ -7,7 +11,9 @@ package de.wwwu.awolf.model;
* @Email: a_wolf28@uni-muenster.de * @Email: a_wolf28@uni-muenster.de
* @Date: 12.06.2017. * @Date: 12.06.2017.
*/ */
public class Line implements Comparable<Line>{ public class Line implements Comparable<Line> {
private final double epsilon = 0.00001;
private final Double MAX = 9999d; private final Double MAX = 9999d;
private final Double MIN = -9999d; private final Double MIN = -9999d;
@ -76,20 +82,20 @@ public class Line implements Comparable<Line>{
} }
private Double calculateX1(Double min) { public Double calculateX1(Double min) {
return min; return min;
} }
private Double calculateY1(Double min) { public Double calculateY1(Double min) {
return (min * m) + b; return (min * (m * -1)) + b;
} }
private Double calculateX2(Double max) { public Double calculateX2(Double max) {
return max; return max;
} }
private Double calculateY2(Double max) { public Double calculateY2(Double max) {
return (max * m) + b; return (max * (m * -1)) + b;
} }
/** /**
@ -189,7 +195,7 @@ public class Line implements Comparable<Line>{
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof Line) { if (obj instanceof Line) {
Line other = (Line) obj; Line other = (Line) obj;
return other.getM().equals(this.getM()) && other.getB().equals(this.getB()); return Precision.equals(other.getM(), this.getM(), epsilon) && Precision.equals(other.getB(), this.getB(), epsilon);
} else { } else {
return super.equals(obj); return super.equals(obj);
} }
@ -197,7 +203,7 @@ public class Line implements Comparable<Line>{
@Override @Override
public int hashCode() { public int hashCode() {
return super.hashCode() + this.getM().hashCode() + this.getB().hashCode(); return Objects.hash(Precision.round(m, 5), Precision.round(b, 5));
} }
@Override @Override
@ -272,16 +278,10 @@ public class Line implements Comparable<Line>{
@Override @Override
public int compareTo(Line line) { public int compareTo(Line line) {
if (this.getM().equals(line.getM())) { if (Precision.compareTo(this.getM(), line.getM(), epsilon) == 0) {
if (this.getB() <= line.getB()) { return this.getB().compareTo(line.getB());
return -1;
} else {
return 1;
}
} else if (this.getM() < line.getM()) {
return -1;
} else { } else {
return 1; return this.getM().compareTo(line.getM());
} }
} }
} }

View File

@ -17,6 +17,8 @@ public class LineModel {
private Double xMaximum; private Double xMaximum;
private Double yMinimum; private Double yMinimum;
private Double yMaximum; private Double yMaximum;
private Double MIN;
private Double MAX;
private int size; private int size;
/** /**
@ -31,6 +33,8 @@ public class LineModel {
yMinimum = Double.MAX_VALUE; yMinimum = Double.MAX_VALUE;
yMaximum = Double.MIN_VALUE; yMaximum = Double.MIN_VALUE;
MIN = 0d;
MAX = 0d;
} }
@ -41,8 +45,17 @@ public class LineModel {
*/ */
public void addLine(Line line) { public void addLine(Line line) {
this.lines.add(line); this.lines.add(line);
MIN = line.getM() <= MIN ? line.getM() : MIN;
MAX = line.getM() >= MAX ? line.getM() : MAX;
} }
public Double getMIN() {
return MIN;
}
public Double getMAX() {
return MAX;
}
/** /**
* @return Liste der Geraden * @return Liste der Geraden
@ -55,7 +68,7 @@ public class LineModel {
* @param lines Liste der Geraden * @param lines Liste der Geraden
*/ */
public void setLines(Set<Line> lines) { public void setLines(Set<Line> lines) {
this.lines = lines; lines.forEach(this::addLine);
this.size = lines.size(); this.size = lines.size();
} }

View File

@ -1,5 +1,9 @@
package de.wwwu.awolf.model; package de.wwwu.awolf.model;
import org.apache.commons.math3.util.Precision;
import java.util.Objects;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *
@ -9,6 +13,8 @@ package de.wwwu.awolf.model;
*/ */
public class Point implements Comparable<Point> { public class Point implements Comparable<Point> {
private final double epsilon = 0.00001;
private Double x; private Double x;
private Double y; private Double y;
private String id; private String id;
@ -67,16 +73,10 @@ public class Point implements Comparable<Point> {
@Override @Override
public int compareTo(Point o) { public int compareTo(Point o) {
if (this.getX().equals(o.getX())) { if (Precision.compareTo(this.getX(), o.getX(), epsilon) == 0) {
if (this.getY() <= o.getY()) { return this.getY().compareTo(o.getY());
return -1;
} else {
return 1;
}
} else if (this.getX() < o.getX()) {
return -1;
} else { } else {
return 1; return this.getX().compareTo(o.getX());
} }
} }
@ -90,7 +90,7 @@ public class Point implements Comparable<Point> {
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof Point) { if (obj instanceof Point) {
Point other = (Point) obj; Point other = (Point) obj;
return other.getX().equals(this.getX()) && other.getY().equals(this.getY()); return Precision.equals(other.getX(), this.getX(), epsilon) && Precision.equals(other.getY(), this.getY(), epsilon);
} else { } else {
return super.equals(obj); return super.equals(obj);
} }
@ -98,7 +98,7 @@ public class Point implements Comparable<Point> {
@Override @Override
public int hashCode() { public int hashCode() {
return super.hashCode() + this.getX().hashCode() + this.getY().hashCode(); return Objects.hash(Precision.round(x, 5), Precision.round(y, 5));
} }
/** /**

View File

@ -1,12 +1,22 @@
package de.wwwu.awolf.model.communication; package de.wwwu.awolf.model.communication;
import de.wwwu.awolf.model.Line; import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
public class AlgorithmData implements Data { public class AlgorithmData implements Data {
private SubscriberType type; private SubscriberType type;
private Algorithm.Type algorithmType;
private Line lineData; private Line lineData;
public Algorithm.Type getAlgorithmType() {
return algorithmType;
}
public void setAlgorithmType(Algorithm.Type algorithmType) {
this.algorithmType = algorithmType;
}
@Override @Override
public SubscriberType getType() { public SubscriberType getType() {
return type; return type;

View File

@ -7,9 +7,7 @@ public enum SubscriberType {
EVAL_T, EVAL_T,
LINES_RES, LINES_RES,
LINES_RES_MULT, LINES_RES_MULT,
LMS, ALGORITHM,
RM,
TS,
PICTURE, PICTURE,
GENERATOR GENERATOR
} }

View File

@ -10,6 +10,7 @@ import de.wwwu.awolf.presenter.evaluation.EvaluatationHandler;
import de.wwwu.awolf.presenter.util.Logging; import de.wwwu.awolf.presenter.util.Logging;
import de.wwwu.awolf.view.ViewController; import de.wwwu.awolf.view.ViewController;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@ -57,32 +58,20 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
@Override @Override
public void onNext(Data data) { public void onNext(Data data) {
Logging.logDebug("Presenter received message. Type: " + data.getType());
switch (data.getType()) { switch (data.getType()) {
case EVALUATION_TABLE_DATA: case EVALUATION_TABLE_DATA:
evaluatedDatas(data); evaluatedDatas(data);
break; break;
case LMS: case ALGORITHM:
visualizeLmsAlgorithm(data); visualizeAlgorithm(data);
break;
case RM:
visualizeRmAlgorithm(data);
break;
case TS:
visualizeTsAlgorithm(data);
break;
case GENERATOR:
Logging.logInfo("Generierung war Erfolgreich");
break; break;
default: default:
break; break;
} }
} }
protected abstract void visualizeTsAlgorithm(Data data); protected abstract void visualizeAlgorithm(Data data);
protected abstract void visualizeRmAlgorithm(Data data);
protected abstract void visualizeLmsAlgorithm(Data data);
protected abstract void evaluatedDatas(Data data); protected abstract void evaluatedDatas(Data data);
@ -107,18 +96,29 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
this.algorithmHandler.runAlgorithmByType(type, lines); this.algorithmHandler.runAlgorithmByType(type, lines);
} }
/**
* Execute an algorithm specified by a type
*
* @param type algorithm type
* @param lines set of lines
*/
public void executeAlgorithmByType(Algorithm.Type type, Set<Line> lines, BooleanProperty guiFlag) {
this.algorithmHandler.runAlgorithmByType(type, lines, guiFlag);
}
/** /**
* Execute an algorithm specified by a type * Execute an algorithm specified by a type
* (use the Lines from the LineModel) * (use the Lines from the LineModel)
* *
* @param type algorithm type * @param type algorithm type
*/ */
public void executeAlgorithmByType(Algorithm.Type type) { public Line executeAlgorithmByType(Algorithm.Type type, BooleanProperty guiFlag) {
if (getModel().getSize() == 0) { if (getModel().getSize() == 0) {
Logging.logDebug("No lines in the Model. Nothing to calculate."); Logging.logDebug("No lines in the Model. Nothing to calculate.");
throw new IllegalArgumentException();
} else { } else {
Logging.logDebug("AlgorithmHandler will start " + type.getName() + ", with " + getModel().getSize()); Logging.logDebug("AlgorithmHandler will start " + type.getName() + ", with " + getModel().getSize());
this.algorithmHandler.runAlgorithmByType(type, getModel().getLines()); return this.algorithmHandler.runAlgorithmByType(type, getModel().getLines(), guiFlag);
} }
} }
@ -141,7 +141,6 @@ public abstract class AbstractPresenter implements Flow.Subscriber<Data> {
*/ */
public void registerView(ViewController view) { public void registerView(ViewController view) {
this.view = view; this.view = view;
Logging.enableGuiLogging();
Logging.logDebug("View has been set."); Logging.logDebug("View has been set.");

View File

@ -7,6 +7,7 @@ import de.wwwu.awolf.model.communication.EvaluationData;
import de.wwwu.awolf.presenter.data.DataHandler; import de.wwwu.awolf.presenter.data.DataHandler;
import de.wwwu.awolf.presenter.evaluation.EvaluatationHandler; import de.wwwu.awolf.presenter.evaluation.EvaluatationHandler;
import de.wwwu.awolf.presenter.util.Logging; import de.wwwu.awolf.presenter.util.Logging;
import javafx.application.Platform;
import javax.swing.*; import javax.swing.*;
import java.io.File; import java.io.File;
@ -37,27 +38,13 @@ public class Presenter extends AbstractPresenter {
} }
@Override @Override
protected void visualizeTsAlgorithm(Data data) { protected void visualizeAlgorithm(Data data) {
AlgorithmData algorithmData = (AlgorithmData) data; AlgorithmData algorithmData = (AlgorithmData) data;
SwingUtilities.invokeLater(() -> getView().visualizeTS(algorithmData.getLineData()));
Logging.logInfo("Theil-Sen Estimator");
Logging.logInfo(algorithmData.getLineData().toString());
}
@Override Platform.runLater(() -> {
protected void visualizeRmAlgorithm(Data data) { getView().getAlgorithmTabControllers().get(algorithmData.getAlgorithmType()).updatePlot(getModel(), algorithmData.getLineData());
AlgorithmData algorithmData = (AlgorithmData) data; });
SwingUtilities.invokeLater(() -> getView().visualizeRM(algorithmData.getLineData())); Logging.logInfo("Type: " + algorithmData.getType() + ". Result: " + algorithmData.getLineData().toString());
Logging.logInfo("Repeated Median Estimator");
Logging.logInfo(algorithmData.getLineData().toString());
}
@Override
protected void visualizeLmsAlgorithm(Data data) {
AlgorithmData algorithmData = (AlgorithmData) data;
SwingUtilities.invokeLater(() -> getView().visualizeLMS(algorithmData.getLineData()));
Logging.logInfo("Least Median of Squares");
Logging.logInfo(algorithmData.getLineData().toString());
} }
@Override @Override
@ -100,6 +87,9 @@ public class Presenter extends AbstractPresenter {
getModel().setLines(data); getModel().setLines(data);
//Berechnung der Schnittpunkte und vis. der Ergebnisse (anz. Geraden, anz. Schnittpunkte) //Berechnung der Schnittpunkte und vis. der Ergebnisse (anz. Geraden, anz. Schnittpunkte)
Logging.logInfo("Import was successful! "); Logging.logInfo("Import was successful! ");
Platform.runLater(() -> {
getView().getAlgorithmTabControllers().values().forEach(e -> e.updatePlot(getModel(), null));
});
return data; return data;
} }
@ -113,6 +103,9 @@ public class Presenter extends AbstractPresenter {
Set<Line> data = getDataHandler().getData(type, n); Set<Line> data = getDataHandler().getData(type, n);
getModel().setLines(data); getModel().setLines(data);
Logging.logInfo("Generate was successful!"); Logging.logInfo("Generate was successful!");
Platform.runLater(() -> {
getView().getAlgorithmTabControllers().values().forEach(e -> e.updatePlot(getModel(), null));
});
return data; return data;
} }

View File

@ -3,6 +3,7 @@ package de.wwwu.awolf.presenter.algorithms;
import de.wwwu.awolf.model.Line; import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.Presenter; import de.wwwu.awolf.presenter.Presenter;
import de.wwwu.awolf.presenter.util.Logging; import de.wwwu.awolf.presenter.util.Logging;
import javafx.beans.property.BooleanProperty;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.EnumMap; import java.util.EnumMap;
@ -38,7 +39,11 @@ public class AlgorithmHandler {
} }
@Nullable @Nullable
public Line runAlgorithmByType(final Algorithm.Type type, final Set<Line> setOfLines) { public Line runAlgorithmByType(final Algorithm.Type type, final Set<Line> setOfLines, final BooleanProperty guiFlag) {
if (guiFlag != null)
guiFlag.setValue(true);
//get the instance //get the instance
Algorithm algorithm = algorithmMapping.get(type); Algorithm algorithm = algorithmMapping.get(type);
algorithm.setPresenter(Presenter.getInstance()); algorithm.setPresenter(Presenter.getInstance());
@ -51,16 +56,25 @@ public class AlgorithmHandler {
completionService.submit(algorithm); completionService.submit(algorithm);
try { try {
return completionService.take().get(); return completionService.take().get();
} catch (InterruptedException e) { } catch (InterruptedException e) {
Logging.logError("Interrupt Exception while waiting for result of Algorithm: " + algorithm.getType(), e); Logging.logError("Interrupt Exception while waiting for result of Algorithm: " + algorithm.getType(), e);
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} catch (ExecutionException e) { } catch (ExecutionException e) {
Logging.logError("Execution Exception while computing the result of Algorithm: " + algorithm.getType(), e); Logging.logError("Execution Exception while computing the result of Algorithm: " + algorithm.getType(), e);
} finally {
if (guiFlag != null)
guiFlag.setValue(false);
} }
return null; return null;
} }
@Nullable
public Line runAlgorithmByType(final Algorithm.Type type, final Set<Line> setOfLines) {
return runAlgorithmByType(type, setOfLines, null);
}
private void lookUp() { private void lookUp() {
Logging.logDebug("Lookup for Algorithm Classes."); Logging.logDebug("Lookup for Algorithm Classes.");
ServiceLoader<Algorithm> load = ServiceLoader.load(Algorithm.class); ServiceLoader<Algorithm> load = ServiceLoader.load(Algorithm.class);

View File

@ -362,14 +362,15 @@ public class LeastMedianOfSquaresEstimator implements Algorithm {
private Line pepareResult() { private Line pepareResult() {
if (this.subscriber != null) { if (this.subscriber != null) {
double m = (getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5; double m = ((getSigmaMin().getX2() + getSigmaMin().getX1()) * 0.5);
double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5; double b = (getSigmaMin().getY2() + getSigmaMin().getY1()) * -0.5;
slope = m; slope = m;
yInterception = b; yInterception = b;
AlgorithmData data = new AlgorithmData(); AlgorithmData data = new AlgorithmData();
data.setType(SubscriberType.LMS); data.setAlgorithmType(getType());
data.setType(SubscriberType.ALGORITHM);
data.setLineData(new Line(m, b)); data.setLineData(new Line(m, b));
this.subscriber.onNext(data); this.subscriber.onNext(data);
} else { } else {

View File

@ -237,7 +237,8 @@ public class RepeatedMedianEstimator implements Algorithm {
if (this.subscriber != null) { if (this.subscriber != null) {
AlgorithmData data = new AlgorithmData(); AlgorithmData data = new AlgorithmData();
data.setType(SubscriberType.RM); data.setAlgorithmType(getType());
data.setType(SubscriberType.ALGORITHM);
data.setLineData(new Line(getSlope(), getyInterception())); data.setLineData(new Line(getSlope(), getyInterception()));
this.subscriber.onNext(data); this.subscriber.onNext(data);
} }

View File

@ -206,7 +206,8 @@ public class TheilSenEstimator implements Algorithm {
if (this.subscriber != null) { if (this.subscriber != null) {
AlgorithmData data = new AlgorithmData(); AlgorithmData data = new AlgorithmData();
data.setType(SubscriberType.TS); data.setAlgorithmType(getType());
data.setType(SubscriberType.ALGORITHM);
data.setLineData(new Line(m, b)); data.setLineData(new Line(m, b));
this.subscriber.onNext(data); this.subscriber.onNext(data);
} }

View File

@ -1,7 +1,9 @@
package de.wwwu.awolf.presenter.algorithms.naiv; package de.wwwu.awolf.presenter.algorithms.naiv;
import de.wwwu.awolf.model.Line; import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.model.communication.AlgorithmData;
import de.wwwu.awolf.model.communication.Data; import de.wwwu.awolf.model.communication.Data;
import de.wwwu.awolf.model.communication.SubscriberType;
import de.wwwu.awolf.presenter.AbstractPresenter; import de.wwwu.awolf.presenter.AbstractPresenter;
import de.wwwu.awolf.presenter.algorithms.Algorithm; import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.util.FastElementSelector; import de.wwwu.awolf.presenter.util.FastElementSelector;
@ -66,6 +68,12 @@ public class NaivLeastMedianOfSquaresEstimator implements Algorithm {
Logging.logInfo("=== E N D - naiv L M S ==="); Logging.logInfo("=== E N D - naiv L M S ===");
Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception()); Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception());
AlgorithmData data = new AlgorithmData();
data.setAlgorithmType(getType());
data.setType(SubscriberType.ALGORITHM);
data.setLineData(new Line(getSlope(), getYInterception()));
this.subscriber.onNext(data);
return new Line(getSlope(), getYInterception()); return new Line(getSlope(), getYInterception());
} }

View File

@ -2,7 +2,9 @@ package de.wwwu.awolf.presenter.algorithms.naiv;
import de.wwwu.awolf.model.Line; import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.model.Point; import de.wwwu.awolf.model.Point;
import de.wwwu.awolf.model.communication.AlgorithmData;
import de.wwwu.awolf.model.communication.Data; import de.wwwu.awolf.model.communication.Data;
import de.wwwu.awolf.model.communication.SubscriberType;
import de.wwwu.awolf.presenter.AbstractPresenter; import de.wwwu.awolf.presenter.AbstractPresenter;
import de.wwwu.awolf.presenter.algorithms.Algorithm; import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.util.FastElementSelector; import de.wwwu.awolf.presenter.util.FastElementSelector;
@ -85,7 +87,11 @@ public class NaivRepeatedMedianEstimator implements Algorithm {
end = System.currentTimeMillis(); end = System.currentTimeMillis();
Logging.logInfo("=== E N D - naiv R M ==="); Logging.logInfo("=== E N D - naiv R M ===");
Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception()); Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception());
AlgorithmData data = new AlgorithmData();
data.setAlgorithmType(getType());
data.setType(SubscriberType.ALGORITHM);
data.setLineData(new Line(getSlope(), getYInterception()));
this.subscriber.onNext(data);
return new Line(getSlope(), getYInterception()); return new Line(getSlope(), getYInterception());
} }

View File

@ -1,7 +1,9 @@
package de.wwwu.awolf.presenter.algorithms.naiv; package de.wwwu.awolf.presenter.algorithms.naiv;
import de.wwwu.awolf.model.Line; import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.model.communication.AlgorithmData;
import de.wwwu.awolf.model.communication.Data; import de.wwwu.awolf.model.communication.Data;
import de.wwwu.awolf.model.communication.SubscriberType;
import de.wwwu.awolf.presenter.AbstractPresenter; import de.wwwu.awolf.presenter.AbstractPresenter;
import de.wwwu.awolf.presenter.algorithms.Algorithm; import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.util.FastElementSelector; import de.wwwu.awolf.presenter.util.FastElementSelector;
@ -66,7 +68,11 @@ public class NaivTheilSenEstimator implements Algorithm {
end = System.currentTimeMillis(); end = System.currentTimeMillis();
Logging.logInfo("=== E N D - naiv T S ==="); Logging.logInfo("=== E N D - naiv T S ===");
Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception()); Logging.logInfo("Slope: " + getSlope() + ", y-Interception: " + getYInterception());
AlgorithmData data = new AlgorithmData();
data.setAlgorithmType(getType());
data.setType(SubscriberType.ALGORITHM);
data.setLineData(new Line(getSlope(), getYInterception()));
this.subscriber.onNext(data);
return new Line(getSlope(), getYInterception()); return new Line(getSlope(), getYInterception());
} }

View File

@ -78,5 +78,11 @@ public class DataHandler {
CIRCLE CIRCLE
} }
public enum ActionType {
IMPORT,
EXPORT,
GENERATE
}
} }

View File

@ -8,6 +8,7 @@ import java.util.*;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask; import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask; import java.util.concurrent.RecursiveTask;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -45,15 +46,21 @@ public class IntersectionComputer {
* @param higher obere Schranke * @param higher obere Schranke
* @return Liste der Schnittpunkte * @return Liste der Schnittpunkte
*/ */
public Collection<Point> compute(final List<Line> lines, final double lower, final double higher) { public Set<Point> compute(final Collection<Line> lines, final double lower, final double higher) {
final Set<Line> fullInput = new HashSet<>(lines);
final Set<Line> copyInput = new HashSet<>(lines);
if (lower == higher) { if (lower == higher) {
return Collections.emptyList(); return Collections.emptySet();
} else { } else {
Logging.logDebug("Open ForkJoinPool: lines: " + lines.size() + " I(" + lower + ", " + higher + "]"); Logging.logDebug("Open ForkJoinPool: lines: " + lines.size() + " I(" + lower + ", " + higher + "]");
ForkJoinPool pool = ForkJoinPool.commonPool(); ForkJoinPool pool = ForkJoinPool.commonPool();
RecursiveComputationTask recursiveComputationTask = new RecursiveComputationTask(lines, lines, lower, higher); RecursiveComputationTask recursiveComputationTask = new RecursiveComputationTask(fullInput, copyInput, lower, higher);
pool.execute(recursiveComputationTask); pool.execute(recursiveComputationTask);
return recursiveComputationTask.join(); Set<Point> join = recursiveComputationTask.join();
return join;
} }
} }
@ -64,7 +71,7 @@ public class IntersectionComputer {
* @param sampledLine eine spezielle Gerade * @param sampledLine eine spezielle Gerade
* @return Liste mit x Koordinaten der Schnittpunkte * @return Liste mit x Koordinaten der Schnittpunkte
*/ */
public List<Double> calculateIntersectionAbscissas(List<Line> set, Line sampledLine, double lower, double upper) { public List<Double> calculateIntersectionAbscissas(Collection<Line> set, Line sampledLine, double lower, double upper) {
List<Line> lines = new LinkedList<>(set); List<Line> lines = new LinkedList<>(set);
Set<Double> intersections = new HashSet<>(); Set<Double> intersections = new HashSet<>();
@ -79,16 +86,16 @@ public class IntersectionComputer {
return new ArrayList<>(intersections); return new ArrayList<>(intersections);
} }
private class RecursiveComputationTask extends RecursiveTask<Collection<Point>> { private class RecursiveComputationTask extends RecursiveTask<Set<Point>> {
private static final int THRESHOLD = 20; private static final int THRESHOLD = 200;
private final List<Line> lines; private final Set<Line> lines;
private final List<Line> fullList; private final Set<Line> fullList;
private final double lower; private final double lower;
private final double upper; private final double upper;
public RecursiveComputationTask(final List<Line> fullList, final List<Line> lines, final double lower, final double upper) { public RecursiveComputationTask(final Set<Line> fullList, final Set<Line> lines, final double lower, final double upper) {
this.lines = lines; this.lines = lines;
this.fullList = fullList; this.fullList = fullList;
this.lower = lower; this.lower = lower;
@ -96,12 +103,11 @@ public class IntersectionComputer {
} }
@Override @Override
protected Collection<Point> compute() { protected Set<Point> compute() {
if (this.lines.isEmpty()) { if (this.lines.isEmpty()) {
return Collections.emptyList(); return Collections.emptySet();
} else if (this.lines.size() > THRESHOLD) { } else if (this.lines.size() > THRESHOLD) {
Logging.logDebug("Bigger than threshold, split into subtask."); return ForkJoinTask.invokeAll(createSubTask()).stream().map(ForkJoinTask::join).flatMap(Collection::stream).collect(Collectors.toSet());
return ForkJoinTask.invokeAll(createSubTask()).stream().map(ForkJoinTask::join).flatMap(Collection::stream).collect(Collectors.toList());
} else { } else {
return work(this.fullList, this.lines, this.lower, this.upper); return work(this.fullList, this.lines, this.lower, this.upper);
} }
@ -109,12 +115,27 @@ public class IntersectionComputer {
private Collection<RecursiveComputationTask> createSubTask() { private Collection<RecursiveComputationTask> createSubTask() {
List<RecursiveComputationTask> dividedTasks = new ArrayList<>(); List<RecursiveComputationTask> dividedTasks = new ArrayList<>();
dividedTasks.add(new RecursiveComputationTask(this.fullList, this.lines.subList(0, this.lines.size() / 2), this.lower, this.upper));
dividedTasks.add(new RecursiveComputationTask(this.fullList, this.lines.subList(this.lines.size() / 2, this.lines.size()), this.lower, this.upper)); long midpoint = Math.round(this.lines.size() * 0.5);
Set<Line> firstSubSet = new HashSet<>();
Set<Line> secondSubSet = new HashSet<>();
AtomicInteger count = new AtomicInteger();
this.lines.forEach(next -> {
int index = count.getAndIncrement();
if (index < midpoint) {
firstSubSet.add(next);
} else {
secondSubSet.add(next);
}
});
dividedTasks.add(new RecursiveComputationTask(this.fullList, firstSubSet, this.lower, this.upper));
dividedTasks.add(new RecursiveComputationTask(this.fullList, secondSubSet, this.lower, this.upper));
return dividedTasks; return dividedTasks;
} }
private Collection<Point> work(List<Line> fullList, List<Line> lines, double lower, double higher) { private Set<Point> work(Set<Line> fullList, Set<Line> lines, double lower, double higher) {
Set<Point> points = new HashSet<>(); Set<Point> points = new HashSet<>();
List<List<Line>> lists = Lists.cartesianProduct(new ArrayList<>(fullList), new ArrayList<>(lines)); List<List<Line>> lists = Lists.cartesianProduct(new ArrayList<>(fullList), new ArrayList<>(lines));
lists.forEach(entry -> { lists.forEach(entry -> {

View File

@ -10,9 +10,7 @@ public class Logging {
} }
public static void enableGuiLogging() {
logger.addAppender(new GuiAppender());
}
private static Logger getLogger() { private static Logger getLogger() {
return logger; return logger;

View File

@ -2,23 +2,21 @@ package de.wwwu.awolf.view;
import de.wwwu.awolf.model.Line; import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.Presenter;
import de.wwwu.awolf.presenter.algorithms.Algorithm; import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.data.DataHandler; import de.wwwu.awolf.presenter.data.DataHandler;
import de.wwwu.awolf.presenter.util.Logging; import de.wwwu.awolf.presenter.util.Logging;
import de.wwwu.awolf.view.controller.AlgorithmTabController; import de.wwwu.awolf.view.controller.AlgorithmTabController;
import de.wwwu.awolf.view.services.DataService; import de.wwwu.awolf.view.services.DataService;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.stage.FileChooser;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.*;
import java.util.HashMap;
import java.util.Map;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
@ -34,10 +32,15 @@ public class ViewController {
public TabPane tabPane; public TabPane tabPane;
public MenuBar menuBar; public MenuBar menuBar;
public TextArea logArea; private Map<Algorithm.Type, AlgorithmTabController> algorithmTabControllers;
public Map<Algorithm.Type, AlgorithmTabController> getAlgorithmTabControllers() {
return algorithmTabControllers;
}
public ViewController() { public ViewController() {
super(); super();
this.algorithmTabControllers = new EnumMap<>(Algorithm.Type.class);
} }
public void initGui() { public void initGui() {
@ -54,7 +57,6 @@ public class ViewController {
props.put("dsfsdfsdf", "dsadasd"); props.put("dsfsdfsdf", "dsadasd");
try { try {
for (Algorithm.Type value : Algorithm.Type.values()) { for (Algorithm.Type value : Algorithm.Type.values()) {
FXMLLoader loader = new FXMLLoader(); FXMLLoader loader = new FXMLLoader();
@ -63,7 +65,9 @@ public class ViewController {
AlgorithmTabController controller = loader.getController(); AlgorithmTabController controller = loader.getController();
controller.setAlgorithmType(value); controller.setAlgorithmType(value);
controller.setProperties(props); controller.setProperties(props);
controller.setModel(Presenter.getInstance().getModel());
controller.init(); controller.init();
this.algorithmTabControllers.put(value, controller);
Tab tab = new Tab(value.getName(), parent); Tab tab = new Tab(value.getName(), parent);
tab.setId(value.name()); tab.setId(value.name());
tabPane.getTabs().add(tab); tabPane.getTabs().add(tab);
@ -74,7 +78,6 @@ public class ViewController {
} }
} }
private void initMenuBar() { private void initMenuBar() {
@ -84,18 +87,39 @@ public class ViewController {
Menu helpMenu = new Menu("Help"); Menu helpMenu = new Menu("Help");
// Create MenuItems // Create MenuItems
//export the data
MenuItem exportItem = new MenuItem("Export"); MenuItem exportItem = new MenuItem("Export");
exportItem.setOnAction(actionEvent -> {
FileChooser fileChooser = new FileChooser();
File file = fileChooser.showOpenDialog(null);
if (file != null && file.canWrite() && file.canRead()) {
new DataService(DataHandler.ActionType.EXPORT, file).start();
}
});
//start an import of data
MenuItem importItem = new MenuItem("Import"); MenuItem importItem = new MenuItem("Import");
importItem.setOnAction(actionEvent -> {
FileChooser fileChooser = new FileChooser();
File file = fileChooser.showOpenDialog(null);
if (file != null && file.canWrite() && file.canRead()) {
new DataService(DataHandler.ActionType.IMPORT, file).start();
}
});
//exit menu item should stop the application
MenuItem exitItem = new MenuItem("Exit"); MenuItem exitItem = new MenuItem("Exit");
exitItem.setOnAction(actionEvent -> {
Platform.exit();
System.exit(0);
});
// about the application
MenuItem aboutItem = new MenuItem("About"); MenuItem aboutItem = new MenuItem("About");
MenuItem generationItem = new MenuItem("Generate"); MenuItem generationItem = new MenuItem("Generate");
generationItem.setOnAction(new EventHandler<ActionEvent>() { generationItem.setOnAction(actionEvent -> {
@Override new DataService(DataHandler.ActionType.GENERATE, DataHandler.DataType.LINE, 1000).start();
public void handle(ActionEvent actionEvent) {
//TODO
new DataService(DataHandler.DataType.LINE, 100).start();
}
}); });
MenuItem evaluationItem = new MenuItem("Evaluate"); MenuItem evaluationItem = new MenuItem("Evaluate");
@ -156,11 +180,6 @@ public class ViewController {
*/ */
public void appendEvalResult(Map<Algorithm.Type, Map<String, String>> tableEntries) { public void appendEvalResult(Map<Algorithm.Type, Map<String, String>> tableEntries) {
// SwingUtilities.invokeLater(() -> {
// evaluationPanel.addRow(tableEntries);
// evaluationPanel.repaint();
// evaluationPanel.revalidate();
// });
} }
/** /**
@ -172,154 +191,16 @@ public class ViewController {
appendEvalResult(res); appendEvalResult(res);
} }
/*******************************************************************************************************************
* init GUI
******************************************************************************************************************/
/**
* Komponenten werden in Container gesetzt
*/
private void addComponents() {
// toolBar.add(importButton);
// toolBar.add(exportButton);
// toolBar.add(generateButton);
// toolBar.setFloatable(false);
//
// setJMenuBar(menu.getMenuBar());
// add(toolBar);
//
// setupSplitPane();
// setupTabbedPane();
// ((JPanel) progressDialog.getContentPane()).setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
//
// this.add(toolBar, BorderLayout.NORTH);
// this.add(splitpane, BorderLayout.CENTER);
}
/**
* Initialisierung der Komponenten
*/
private void initializeComponents(Collection<Node> list) {
// //panels
// toolBar = new JToolBar();
// lmsPanel = new LMSPanel();
// rmPanel = new RMPanel();
// tsPanel = new TSPanel();
// menu = new MenuBar();
//
// //Dialogs
// progressDialog = new JDialog();
// progressDialog.setLocationRelativeTo(null);
// progressContent = progressDialog.getContentPane();
// progressBar = new JProgressBar();
//
// //Panes
// tabbedPane = new JTabbedPane();
// output = new InfoPanel();
// splitpane = new JSplitPane();
//
// //Buttons
// importButton = new JButton();
// generateButton = new JButton();
// exportButton = new JButton();
}
/**
* Icons werden passend gesetzt
*/
private void setIcons() {
// try {
// ClassLoader classLoader = getClass().getClassLoader();
// Image imgImport = ImageIO.read(classLoader.getResource("import.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
// Image imgStart = ImageIO.read(classLoader.getResource("start.png")).getScaledInstance(32, 32, Image.SCALE_SMOOTH);
// Image imgGenerate = ImageIO.read(classLoader.getResource("generate.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
// Image imgExport = ImageIO.read(classLoader.getResource("export.png")).getScaledInstance(16, 16, Image.SCALE_SMOOTH);
// Image imgFrame = ImageIO.read(classLoader.getResource("frame.png")).getScaledInstance(32, 23, Image.SCALE_SMOOTH);
//
// importButton.setIcon(new ImageIcon(imgImport));
// exportButton.setIcon(new ImageIcon(imgExport));
// generateButton.setIcon(new ImageIcon(imgGenerate));
// lmsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
// rmPanel.getStartButton().setIcon(new ImageIcon(imgStart));
// tsPanel.getStartButton().setIcon(new ImageIcon(imgStart));
// this.setIconImage(imgFrame);
// } catch (IOException e) {
// Logging.logError(e.getMessage(), e);
// }
}
/**
* Funktionalitäten werden hinzugefügt
*/
public void setActionListeners() {
// //action listener für MenuItems
// menu.addActionListeners();
//
// //action listener für diese Klasse
// lmsPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), lmsPanel));
// rmPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), rmPanel));
// tsPanel.getStartButton().addActionListener(new StartAlgorithmListener(((Presenter) getPresenter()), tsPanel));
// importButton.addActionListener(new ImportDataListener((Presenter) this.getPresenter()));
// exportButton.addActionListener(new ExportDataListener((Presenter) this.getPresenter()));
// generateButton.addActionListener(new GenerateDataListener((Presenter) this.getPresenter()));
}
/** /**
* Funktionalitäten werden aktiviert. * Funktionalitäten werden aktiviert.
*/ */
public void enableFunctionality() { public void enableFunctionality() {
// this.getLmsPanel().getStartButton().setEnabled(true);
// this.getRmPanel().getStartButton().setEnabled(true);
// this.getTsPanel().getStartButton().setEnabled(true);
// this.getExportButton().setEnabled(true);
} }
/** /**
* Funktionalitäten werden deaktiviert. * Funktionalitäten werden deaktiviert.
*/ */
public void disableFunctionality() { public void disableFunctionality() {
// this.getLmsPanel().getStartButton().setEnabled(false);
// this.getRmPanel().getStartButton().setEnabled(false);
// this.getTsPanel().getStartButton().setEnabled(false);
// this.getExportButton().setEnabled(false);
} }
/*******************************************************************************************************************
* log Methode
******************************************************************************************************************/
/**
* @param s Text der ausgegeben wird
*/
public void logInfo(String s) {
Platform.runLater(() -> {
logArea.appendText(s + "\n");
});
}
/**
* @param s Fehlertext der ausgegeben wird
*/
public void logError(String s) {
Platform.runLater(() -> {
logArea.appendText(s + "\n");
});
}
/**
* @param s Text der in grüner Farbe ausgegeben wird
*/
public void logWarning(String s) {
Platform.runLater(() -> {
logArea.appendText(s + "\n");
});
}
/*******************************************************************************************************************
* Getter und Setter Methoden
******************************************************************************************************************/
} }

View File

@ -1,45 +1,59 @@
package de.wwwu.awolf.view.controller; package de.wwwu.awolf.view.controller;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.model.LineModel;
import de.wwwu.awolf.presenter.algorithms.Algorithm; import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.view.services.ButtonClickService; import de.wwwu.awolf.view.services.ButtonClickService;
import javafx.beans.property.BooleanProperty;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.canvas.Canvas; import javafx.scene.chart.LineChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import java.util.Map; import java.util.Map;
public class AlgorithmTabController { public class AlgorithmTabController {
private final XYChart.Series<Double, Double> dataSerie;
private final XYChart.Series<Double, Double> lineSerie;
private Algorithm.Type algorithmType; private Algorithm.Type algorithmType;
private Map<String, String> properties; private Map<String, String> properties;
private LineModel model;
@FXML @FXML
public Canvas canvas; public LineChart<Double, Double> chart;
@FXML @FXML
public VBox vBox; public VBox vBox;
@FXML @FXML
public Button startButton; public Button startButton;
public AlgorithmTabController() { public AlgorithmTabController() {
dataSerie = new XYChart.Series<>();
dataSerie.setName("Datapoints");
lineSerie = new XYChart.Series<>();
lineSerie.setName("Estimated Line");
} }
public LineModel getModel() {
return model;
}
public void setModel(LineModel model) {
this.model = model;
}
public void init() { public void init() {
// add GUI elements to maintain the parameters // add GUI elements to maintain the parameters
properties.forEach((key, value) -> { properties.forEach((key, value) -> {
//Pane component for the layout //Pane component for the layout
BorderPane borderPane = new BorderPane(); BorderPane borderPane = new BorderPane();
borderPane.setPadding(new Insets(10,0,10,0)); borderPane.setPadding(new Insets(10, 0, 10, 0));
//text field for the input //text field for the input
TextField textField = new TextField(value); TextField textField = new TextField(value);
@ -47,9 +61,8 @@ public class AlgorithmTabController {
//label //label
Label label = new Label(key); Label label = new Label(key);
label.setAlignment(Pos.BASELINE_LEFT); label.setAlignment(Pos.BASELINE_LEFT);
label.setFont(new Font("Arial", 17));
label.setLabelFor(textField); label.setLabelFor(textField);
label.setPadding(new Insets(2,10,0,0)); label.setPadding(new Insets(2, 10, 0, 0));
//add components //add components
borderPane.setLeft(label); borderPane.setLeft(label);
@ -57,9 +70,32 @@ public class AlgorithmTabController {
vBox.getChildren().add(borderPane); vBox.getChildren().add(borderPane);
}); });
BooleanProperty booleanProperty = startButton.disableProperty();
startButton.setOnAction(event -> { startButton.setOnAction(event -> {
new ButtonClickService(algorithmType).start(); ButtonClickService buttonClickService = new ButtonClickService(algorithmType, booleanProperty);
}); buttonClickService.start();
}
);
updatePlot(this.model, null);
chart.getData().add(dataSerie);
chart.getData().add(lineSerie);
}
public void updatePlot(final LineModel model, final Line pLine) {
dataSerie.getData().clear();
model.getLines().forEach(line -> dataSerie.getData().add(new XYChart.Data<>(line.getM(), line.getB())));
if (pLine != null) {
lineSerie.getData().clear();
Double x1 = pLine.calculateX1(model.getMIN());
Double y1 = pLine.calculateY1(model.getMIN());
Double x2 = pLine.calculateX2(model.getMAX());
Double y2 = pLine.calculateY2(model.getMAX());
lineSerie.getData().add(new XYChart.Data<>(x1, y1));
lineSerie.getData().add(new XYChart.Data<>(x2, y2));
}
} }
public Algorithm.Type getAlgorithmType() { public Algorithm.Type getAlgorithmType() {
@ -77,4 +113,6 @@ public class AlgorithmTabController {
public void setProperties(Map<String, String> properties) { public void setProperties(Map<String, String> properties) {
this.properties = properties; this.properties = properties;
} }
} }

View File

@ -1,26 +1,37 @@
package de.wwwu.awolf.view.services; package de.wwwu.awolf.view.services;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.Presenter; import de.wwwu.awolf.presenter.Presenter;
import de.wwwu.awolf.presenter.algorithms.Algorithm; import de.wwwu.awolf.presenter.algorithms.Algorithm;
import javafx.beans.property.BooleanProperty;
import javafx.concurrent.Service; import javafx.concurrent.Service;
import javafx.concurrent.Task; import javafx.concurrent.Task;
public class ButtonClickService extends Service<String> { public class ButtonClickService extends Service<Boolean> {
private final BooleanProperty startButtonDisabled;
private Algorithm.Type type; private Algorithm.Type type;
public ButtonClickService(Algorithm.Type type) { public ButtonClickService(Algorithm.Type algorithmType, BooleanProperty startButtonDisabled) {
this.type = type; this.startButtonDisabled = startButtonDisabled;
this.type = algorithmType;
} }
@Override @Override
protected Task<String> createTask() { protected Task<Boolean> createTask() {
return new Task<String>() { return new Task<Boolean>() {
@Override @Override
protected String call() throws Exception { protected Boolean call() throws Exception {
Presenter.getInstance().executeAlgorithmByType(type); try {
return "done"; Line line = Presenter.getInstance().executeAlgorithmByType(type, startButtonDisabled);
if (line != null) {
return true;
}
} catch (IllegalArgumentException e) {
return true;
}
return false;
} }
}; };
} }

View File

@ -5,23 +5,46 @@ import de.wwwu.awolf.presenter.data.DataHandler;
import javafx.concurrent.Service; import javafx.concurrent.Service;
import javafx.concurrent.Task; import javafx.concurrent.Task;
public class DataService extends Service<String> { import java.io.File;
public class DataService extends Service<Boolean> {
private File file;
private DataHandler.DataType type; private DataHandler.DataType type;
private DataHandler.ActionType actionType;
private int n; private int n;
public DataService(DataHandler.DataType type, int n) { public DataService(final DataHandler.ActionType actionType, final DataHandler.DataType type, final int n) {
this.type = type; this.type = type;
this.actionType = actionType;
this.n = n; this.n = n;
} }
public DataService(final DataHandler.ActionType actionType, final File file) {
this.actionType = actionType;
this.file = file;
this.type = null;
this.n = -1;
}
@Override @Override
protected Task<String> createTask() { protected Task<Boolean> createTask() {
return new Task<>() { return new Task<>() {
@Override @Override
protected String call() throws Exception { protected Boolean call() throws Exception {
Presenter.getInstance().generateDataset(n, type); switch (actionType) {
return "done"; case EXPORT:
Presenter.getInstance().exportDataset(file);
break;
case IMPORT:
Presenter.getInstance().importDataset(file);
break;
case GENERATE:
Presenter.getInstance().generateDataset(n, type);
break;
}
return true;
} }
}; };
} }

View File

@ -5,7 +5,7 @@ import de.wwwu.awolf.view.ViewController;
import javafx.concurrent.Service; import javafx.concurrent.Service;
import javafx.concurrent.Task; import javafx.concurrent.Task;
public class GuiRegisterService extends Service<String> { public class GuiRegisterService extends Service<Boolean> {
private final ViewController view; private final ViewController view;
@ -15,12 +15,12 @@ public class GuiRegisterService extends Service<String> {
} }
@Override @Override
protected Task<String> createTask() { protected Task<Boolean> createTask() {
return new Task<>() { return new Task<>() {
@Override @Override
protected String call() throws Exception { protected Boolean call() throws Exception {
Presenter.getInstance().registerView(view); Presenter.getInstance().registerView(view);
return "Done"; return true;
} }
}; };
} }

View File

@ -2,11 +2,11 @@
<?import javafx.geometry.*?> <?import javafx.geometry.*?>
<?import javafx.scene.*?> <?import javafx.scene.*?>
<?import javafx.scene.canvas.*?> <?import javafx.scene.chart.*?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<BorderPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.wwwu.awolf.view.controller.AlgorithmTabController"> <BorderPane prefHeight="400.0" prefWidth="600.0" styleClass="algoPane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.wwwu.awolf.view.controller.AlgorithmTabController">
<left> <left>
<VBox fx:id="vBox" alignment="TOP_CENTER" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER"> <VBox fx:id="vBox" alignment="TOP_CENTER" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children> <children>
@ -22,16 +22,6 @@
</padding> </padding>
</VBox> </VBox>
</left> </left>
<center>
<Canvas fx:id="canvas" height="334.0" width="391.0" BorderPane.alignment="CENTER" />
</center>
<bottom>
<FlowPane alignment="CENTER" minWidth="-Infinity">
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</BorderPane.margin>
</FlowPane>
</bottom>
<top> <top>
<FlowPane hgap="5.0" prefHeight="25.0" prefWidth="200.0" BorderPane.alignment="CENTER"> <FlowPane hgap="5.0" prefHeight="25.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children> <children>
@ -46,4 +36,20 @@
</BorderPane.margin> </BorderPane.margin>
</FlowPane> </FlowPane>
</top> </top>
<center>
<LineChart fx:id="chart" prefHeight="398.0" prefWidth="390.0" title="Plot" BorderPane.alignment="CENTER">
<xAxis>
<NumberAxis label="X" side="BOTTOM">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding></NumberAxis>
</xAxis>
<yAxis>
<NumberAxis label="Y" side="LEFT">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding></NumberAxis>
</yAxis>
</LineChart>
</center>
</BorderPane> </BorderPane>

View File

@ -12,12 +12,6 @@
<center> <center>
<TabPane fx:id="tabPane" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" BorderPane.alignment="CENTER"> <TabPane fx:id="tabPane" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" BorderPane.alignment="CENTER">
<tabs> <tabs>
<Tab text="Logging">
<BorderPane xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1">
<center>
<TextArea fx:id="logArea" editable="false" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</center></BorderPane>
</Tab>
</tabs> </tabs>
</TabPane> </TabPane>
</center> </center>

View File

@ -1,5 +1,18 @@
package de.wwwu.awolf.presenter.algorithms.advanced; package de.wwwu.awolf.presenter.algorithms.advanced;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.presenter.algorithms.Algorithm;
import de.wwwu.awolf.presenter.algorithms.AlgorithmHandler;
import org.junit.Before;
import org.junit.Test;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *
@ -9,68 +22,44 @@ package de.wwwu.awolf.presenter.algorithms.advanced;
*/ */
public class LeastMedianOfSquaresEstimatorTest { public class LeastMedianOfSquaresEstimatorTest {
// private LeastMedianOfSquaresEstimator lms; private LeastMedianOfSquaresEstimator lms;
// private Set<Line> lines;
// @Before private Line line;
// public void setUp(){
// Double[] x = {18d, 24d, 30d, 34d, 38d}; @Before
// Double[] y = {18d, 26d, 30d, 40d, 70d}; public void setUp(){
// Double[] x = {18d, 24d, 30d, 34d, 38d};
// Double[] y = {18d, 26d, 30d, 40d, 70d};
// LinkedList<Line> lines = new LinkedList<>();
//
// for (int i = 0; i < 5; i++) { lines = new HashSet<>();
// lines.add(new Line(x[i], y[i]));
// } for (int i = 0; i < 5; i++) {
// lines.add(new Line(x[i], y[i]));
// lms = new LeastMedianOfSquaresEstimator(lines); }
// } line = AlgorithmHandler.getInstance().runAlgorithmByType(Algorithm.Type.LMS, lines);
// }
//
// @Test
// public void geEjValues() throws Exception { @Test
// public void geEjValues() throws Exception {
// Double[] expected = {36d, 50d, 60d, 74d, 108d};
// List<Double> actual = lms.getEjValues(1d); Double[] expected = {36d, 50d, 60d, 74d, 108d};
// assertArrayEquals(expected, actual.toArray()); List<Double> actual = lms.getEjValues(1d);
// } assertArrayEquals(expected, actual.toArray());
// }
// @Test
// public void calcKMinusBracelet() throws Exception {
// @Test
// Point point = new Point(1d, 1d); public void upperBound() throws Exception {
// Double[] expected = {24d, 36d, 60d};
// Double[] actual = lms.calcKMinusBracelet(point, 3); Line expected = new Line(5, 5, 146, 210);
//
// assertArrayEquals(expected, actual); assertEquals(expected.getX1(), line.getX1(), 0.01);
// assertEquals(expected.getX2(), line.getX2(), 0.01);
// } assertEquals(expected.getY1(), line.getY1(), 0.01);
// assertEquals(expected.getY2(), line.getY2(), 0.01);
// @Test }
// public void upperBound() throws Exception {
// lms.setkMinus(3);
// lms.setHeightsigmaMin(500);
// lms.setSigmaMin(new Line(0, 0, 0, 0));
// lms.setN(5);
// Line expected = new Line(5, 5, 146, 210);
// lms.upperBound(5d);
//
// assertEquals(expected.getX1(), lms.getSigmaMin().getX1(), 0.01);
// assertEquals(expected.getX2(), lms.getSigmaMin().getX2(), 0.01);
// assertEquals(expected.getY1(), lms.getSigmaMin().getY1(), 0.01);
// assertEquals(expected.getY2(), lms.getSigmaMin().getY2(), 0.01);
// }
//
// @Test
// public void lowerBound() throws Exception {
// //kann nur über sout geprüft werden test passt aber
// Double[] expectedAlpha = {0d, 0d, 0d, 2d, 4d};
// Double[] expectedBeta = {2d, 4d, 4d, 2d, 1d};
// lms.setHeightsigmaMin(500);
//
// Interval interval = new Interval(-2, 0);
// lms.lowerBound(interval);
// assertTrue(interval.getActivity());
// }
} }

View File

@ -1,5 +1,11 @@
package de.wwwu.awolf.presenter.algorithms.advanced; package de.wwwu.awolf.presenter.algorithms.advanced;
import de.wwwu.awolf.model.Line;
import org.junit.Before;
import java.util.LinkedList;
import java.util.List;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *
@ -8,47 +14,20 @@ package de.wwwu.awolf.presenter.algorithms.advanced;
* @Date: 23.10.2017. * @Date: 23.10.2017.
*/ */
public class TheilSenEstimatorTest { public class TheilSenEstimatorTest {
//
// TheilSenEstimator estimator;
// @Before
// @Before public void setUp(){
// public void setUp(){ Double[] x = {18d, 24d, 30d, 34d, 38d};
// Double[] x = {18d, 24d, 30d, 34d, 38d}; Double[] y = {18d, 26d, 30d, 40d, 70d};
// Double[] y = {18d, 26d, 30d, 40d, 70d};
//
// List<Line> lines = new LinkedList<>();
// List<Line> lines = new LinkedList<>();
// for (int i = 0; i < 5; i++) {
// for (int i = 0; i < 5; i++) { lines.add(new Line(x[i], y[i]));
// lines.add(new Line(x[i], y[i])); }
// } }
//
// estimator = new TheilSenEstimator(lines);
// }
//
//
// @Test
// public void getIntervalSize() throws Exception {
// // assertEquals(estimator.getIntervalSize(-2d, 0d), 5, 0.001);
// }
//
// @Test
// public void getOpenIntervalSize() throws Exception {
// // assertEquals(estimator.getIntervalSize(-1.4d, 0.6666d), 4, 0.001);
// }
//
// @Test
// public void getOpenIntervalElements() throws Exception {
// List<Point> intersectionInInterval = estimator.getOpenIntervalElements(-1.4d, -0.67d);
// double[] expected = {-1.375, -1.333, -1.0};
// double[] actual = new double[3];
// for (int i=0;i<intersectionInInterval.size();i++) {
// actual[i] = intersectionInInterval.get(i).getX();
// }
//
// Arrays.sort(expected);
// Arrays.sort(actual);
// assertArrayEquals(expected, actual, 0.001);
// }
} }

View File

@ -5,6 +5,10 @@ import de.wwwu.awolf.model.LineModel;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
/** /**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
* *
@ -29,8 +33,8 @@ public class IntersectionCounterTest {
@Test @Test
public void run() throws Exception { public void run() throws Exception {
// IntersectionComputer instance = IntersectionComputer.getInstance(); IntersectionComputer instance = IntersectionComputer.getInstance();
// assertEquals(3, IntersectionComputer.getInstance().compute(lineModel.getLines(), -9999,9999).size()); assertEquals(3, IntersectionComputer.getInstance().compute(new ArrayList<>(lineModel.getLines()), -9999,9999).size());
} }
} }

Binary file not shown.

Binary file not shown.