Skip to content
Snippets Groups Projects
Commit 938647b7 authored by Eilert Tunheim's avatar Eilert Tunheim
Browse files

commented linechart class

parent c622d621
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,12 @@ import java.util.*;
import static com.application.Main.*;
/**
* This class handle all the GUI functionality and statistics calculations
*
* @author Eilert Tunheim, Karin Pettersen, Mads Arnesen
* @version 1.0.0
*/
public class LineChartFunctionality {
private static LineChart<String, Number> lineChart;
......@@ -39,6 +45,7 @@ public class LineChartFunctionality {
private static boolean printLiveData;
private static boolean printPreviousData;
// Constructor
public LineChartFunctionality() {
xAxis = new CategoryAxis();
yAxis = new NumberAxis();
......@@ -63,7 +70,7 @@ public class LineChartFunctionality {
/**
* Prints the graphs to the line chart
* Prints the selected graphs to the line chart
*
* Note: Something wrong when exceeding 8 series, think the next series choose a random series color
*/
......@@ -107,15 +114,11 @@ public class LineChartFunctionality {
getMenuViewPreviousData().setSelected(true);
// If there are more than 5 series, adds 3 new empty series to keep the color scheme
//int index = getLineChart().getData().size();
for (int i = 0; i < getPreviousData().size(); i++) {
int index = getLineChart().getData().size();
//System.out.println(getPreviousData().size());
if (index % 8 == 0 ){
for (int j = 0; j < 3; j++) {
updateLineChart(new XYChart.Series<>());
//index++;
System.out.println("@@@@@@@");
}
}
updateLineChart(getPreviousData().get(i));
......@@ -127,103 +130,102 @@ public class LineChartFunctionality {
}
/**
* This function calculates the confidence interval
*
* @param multiMap input containing the drying cycle data
* @param CIShadow input to indicate if the confidence interval shadow is stored or not
* @return a map containing the processed data
*/
private static Map<Integer, ArrayList<Double>> statistics(Map<Integer, ArrayList<Double>> multiMap, boolean CIShadow){
//System.out.println("\n\nMultimap: \n");
// Iterates through all the data
for (Map.Entry<Integer, ArrayList<Double>> entry : multiMap.entrySet()) {
//System.out.printf("\nIndex: \t%s\t\t\tkWh: \t%s\n", entry.getKey(), entry.getValue());
//System.out.println("entry: "+entry);
//if(entry.getValue().size()>1){
SummaryStatistics stats = new SummaryStatistics();
SummaryStatistics data = new SummaryStatistics();
for (double val : entry.getValue()) {
stats.addValue(val);
data.addValue(val);
}
//System.out.println("Stats: "+stats);
// Calculate 95% confidence interval
double ci = calcMeanCI(stats, Settings.CONFIDENCE_INTERVAL);
//System.out.println(String.format("Mean: %f", stats.getMean()));
double lower = stats.getMean() - ci;
double upper = stats.getMean() + ci;
//System.out.println(String.format("Confidence Interval "+ Settings.CONFIDENCE_INTERVAL*100+"%%: %f, %f", lower, upper));
// Calculate the confidence interval
double confidenceInterval = calcMeanConfidenceInterval(data);
double lower = data.getMean() - confidenceInterval;
double upper = data.getMean() + confidenceInterval;
// Deletes entries if they are out of bounds with the confidence interval
entry.getValue().removeIf(value -> Double.compare(value, lower) < 0 || Double.compare(value, upper) > 0);
// Checks if the confidence interval shall be returned or not
if(CIShadow){
ArrayList<Double> lowerUpperBounds = new ArrayList<>();
lowerUpperBounds.add(lower);
lowerUpperBounds.add(upper);
multiMap.replace(entry.getKey(), lowerUpperBounds);
}
//}
}
return multiMap;
}
private static double calcMeanCI(SummaryStatistics stats, double level) {
/**
* This function calculates the confidence interval mean value
*
* @param data the data to base the calculation on
* @return returns the confidence interval mean value
*/
private static double calcMeanConfidenceInterval(SummaryStatistics data) {
try {
// Create T Distribution with N-1 degrees of freedom
TDistribution tDist = new TDistribution(stats.getN() - 1);
// Calculate critical value
double critVal = tDist.inverseCumulativeProbability(1.0 - (1 - level) / 2);
// Calculate confidence interval
return critVal * stats.getStandardDeviation() / Math.sqrt(stats.getN());
// Create a T distribution
TDistribution tDistribution = new TDistribution(data.getN() - 1);
// Calculate the critical value
double criticalValue = tDistribution.inverseCumulativeProbability(1.0 - (1 - Settings.CONFIDENCE_INTERVAL) / 2);
// Calculate the confidence interval
return criticalValue * data.getStandardDeviation() / Math.sqrt(data.getN());
} catch (MathIllegalArgumentException e) {
return Double.NaN;
}
}
/**
* This function serves as the main function that controls all the functionality.
* This function takes the data inputted and plots it and calculates the statistics.
*
* @param userInput data regarding the drying cycles
* @throws Exception throws exception if an error occurs
*/
public static void loadSingleSeries(Map<Integer, Map<String, Number>> userInput) throws Exception {
public static LineChart<String, Number> loadSingleSeries(Map<Integer, Map<String, Number>> userInput) throws Exception {
// Clears the linechart if there are previous graphs plotted
clearLineChart();
// Defining a map to store data
Map<Integer, ArrayList<Double>> multiMap = new HashMap<>();
// Iterates through the data
for (Map.Entry<Integer, Map<String, Number>> entryKwh : userInput.entrySet()) {
Map data = entryKwh.getValue();
//System.out.println(data.size());
XYChart.Series<String, Number> newSeries = new XYChart.Series<String, Number>();
int index = 0;
for (Object entryData : data.entrySet()) {
//System.out.println("data: \t"+entryData);
String entryString = entryData.toString();
String[] arr = entryString.split("=");
String date = arr[0];
Double kwhValue = Double.parseDouble(arr[1]);
//System.out.printf("Date: \t%s\t\t\tkWh: \t%s\n",date,kwhValue);
// Checks if the index already got an arraylist, if not one is created
multiMap.computeIfAbsent(index, k -> new ArrayList<Double>());
multiMap.get(index).add(kwhValue);
// Connect the data to a series
newSeries.getData().add(new XYChart.Data<String, Number>(String.valueOf(index), kwhValue));
index++;
}
//allSeries.add(newSeries);
//updateLineChart(newSeries);
//lineChart.setOpacity(1);
}
//System.out.println("Series size: "+allSeries.size());
// Finds the end datapoint at the end of each graph
int numberOfGraphs = 0;
// Defines lists to store data
ArrayList<Double> dataArraylistXAxis = new ArrayList<>();
ArrayList<Double> dataArraylistYAxis = new ArrayList<>();
Map<Integer, ArrayList<Double>> endOfGraphPointsXAxis = new HashMap<>();
Map<Integer, ArrayList<Double>> endOfGraphPointsYAxis = new HashMap<>();
// Iterates through the data
for (int i = 0; i < multiMap.size(); i++) {
ArrayList<Double> list = multiMap.get(i);
for (int j = 0; j < list.size(); j++) {
......@@ -231,11 +233,8 @@ public class LineChartFunctionality {
numberOfGraphs = list.size();
}
if (list.size() < numberOfGraphs) {
dataArraylistXAxis.add((double) i);
dataArraylistYAxis.add(multiMap.get(i).get(j));
//System.out.println(tempList);
numberOfGraphs = list.size();
}
}
......@@ -243,56 +242,33 @@ public class LineChartFunctionality {
dataArraylistXAxis.add((double) multiMap.size());
dataArraylistYAxis.add(multiMap.get(multiMap.size()-1).get(0));
//System.out.println(dataArraylistYAxis);
endOfGraphPointsXAxis.put(0,dataArraylistXAxis);
endOfGraphPointsYAxis.put(0,dataArraylistYAxis);
System.out.println(endOfGraphPointsXAxis);
System.out.println(endOfGraphPointsYAxis);
Map<Integer, ArrayList<Double>> endOfGraphPointsConfidenceXAxis = statistics(endOfGraphPointsXAxis,false);
Map<Integer, ArrayList<Double>> endOfGraphPointsConfidenceYaxis = statistics(endOfGraphPointsYAxis,false);
System.out.println("X-axis:"+ endOfGraphPointsConfidenceXAxis);
System.out.println("X-axis size: "+ endOfGraphPointsConfidenceXAxis.size());
System.out.println("------------");
System.out.println("Y-axis:"+ endOfGraphPointsConfidenceYaxis);
System.out.println("Y-axis size: "+ endOfGraphPointsConfidenceYaxis.size());
System.out.println("------------");
// X-axis
dataPointsXAxis = 0;
for (Map.Entry<Integer, ArrayList<Double>> entry : endOfGraphPointsConfidenceXAxis.entrySet()) {
System.out.println("Arraylist: "+ entry.getValue());
for (int i = 0; i < entry.getValue().size(); i++) {
System.out.println("End of graphs: "+ entry.getValue().get(i));
dataPointsXAxis += entry.getValue().get(i);
}
}
dataPointsXAxis = dataPointsXAxis /endOfGraphPointsConfidenceXAxis.get(0).size();
System.out.println("Datapoints: " + dataPointsXAxis);
// Y-axis
dataPointsYAxis = 0;
for (Map.Entry<Integer, ArrayList<Double>> entry : endOfGraphPointsConfidenceYaxis.entrySet()) {
System.out.println("Arraylist: "+ entry.getValue());
for (int i = 0; i < entry.getValue().size(); i++) {
System.out.println("End of graphs: "+ entry.getValue().get(i));
dataPointsYAxis += entry.getValue().get(i);
}
}
dataPointsYAxis = dataPointsYAxis /endOfGraphPointsConfidenceYaxis.get(0).size();
System.out.println("Datapoints Y-axis: " + dataPointsYAxis);
// Stores the data from the confidence interval in a new map
Map<Integer, ArrayList<Double>> confidenceIntervalData = statistics(multiMap,false);
//getNonLinearRegression(confidenceIntervalData);
// Checks the max size for the arraylists needed for the data array later
int jMaxSize = 0;
for (int i = 0; i < confidenceIntervalData.size(); i++) {
......@@ -301,23 +277,20 @@ public class LineChartFunctionality {
}
}
// Defines an array to be used for the regression
// Defines an array to be used for the linear regression
double[][] data = new double[confidenceIntervalData.size()*jMaxSize][2];
int index = 0;
//System.out.println(confidenceIntervalData);
for (int i = 0; i < confidenceIntervalData.size(); i++) {
ArrayList<Double> list = confidenceIntervalData.get(i);
for (int j = 0; j < list.size(); j++) {
for (Double aDouble : list) {
data[index][0] = i;
data[index][1] = list.get(j);
data[index][1] = aDouble;
index++;
}
}
// Adds the data to the confidence interval shadow
getRegressionSeriesConfidenceInterval().getData().clear();
Map<Integer, ArrayList<Double>> confidenceIntervalShadow = statistics(multiMap,true);
for ( Map.Entry<Integer, ArrayList<Double>> entry : confidenceIntervalShadow.entrySet()) {
......@@ -327,59 +300,14 @@ public class LineChartFunctionality {
}
}
System.out.println(data.length);
//System.out.println(data[12][1]);
// Does the linear regression
SimpleRegression simpleRegression = new SimpleRegression();
simpleRegression.addData(data);
//simpleRegression.regress();
for (double[] datum : data) {
//System.out.println("");
for (double v : datum) {
//System.out.println("Data: "+v);
}
}
//updateLineChart(liveDataSeries);
//XYChart.Series<String, Number> regressionSeries = new XYChart.Series<String, Number>();
// Does the logistic regression
getRegressionSeries().getData().clear();
for (int i = 0; i <= getDataPointsXAxis(); i++) {
// Connect the data to a series
//System.out.println(simpleRegression.predict(i));
//regressionSeries.getData().add(new XYChart.Data<String, Number>(String.valueOf(i), simpleRegression.predict(i)));
/*
regressionSeries.getData().add(new XYChart.Data<String, Number>(
String.valueOf(i),
getNonLinearRegression(
confidenceIntervalData,
getDataPointsYAxis(),
//simpleRegression.getIntercept(),
simpleRegression.getSlope(),
//simpleRegression.getIntercept()
getDataPointsYAxis(),
i,
getDataPointsXAxis()
)));
*/
/*
regressionSeries.getData().add(new XYChart.Data<String, Number>(
String.valueOf(i),
getCubicNonLinearRegression(confidenceIntervalData,i)
));
*/
getRegressionSeries().getData().add(new XYChart.Data<String, Number>(
String.valueOf(i),
getNonLinearRegression(
......@@ -389,21 +317,14 @@ public class LineChartFunctionality {
i,
getDataPointsXAxis()
)));
}
//updateLineChart(getRegressionSeries());
//lineChart.setOpacity(1);
// Adds the previous data to series
getPreviousData().clear();
for (Map.Entry<Integer, Map<String, Number>> entryKwh : userInput.entrySet()) {
//System.out.println(data.size());
XYChart.Series<String, Number> newSeries = new XYChart.Series<String, Number>();
index = 0;
for (Object entryData : entryKwh.getValue().entrySet()) {
//System.out.println("data: \t"+entryData);
String entryString = entryData.toString();
Double kwhValue = Double.parseDouble(entryString.split("=")[1]);
......@@ -412,36 +333,17 @@ public class LineChartFunctionality {
index++;
}
addPreviousData(newSeries);
//allSeries.add(newSeries);
//updateLineChart(newSeries);
//lineChart.setOpacity(1);
}
System.out.println("Get R: " + simpleRegression.getR());
System.out.println("Get getRSquare: " + simpleRegression.getRSquare());
System.out.println("Get getRegressionSumSquares: " + simpleRegression.getRegressionSumSquares());
System.out.println("Get N: " + simpleRegression.getN());
// and then you can predict the time at a given temperature value
System.out.println("Predicted Time: " + simpleRegression.predict(35));
// You can also get the slope and intercept from your data
System.out.println("Alpha! = " + simpleRegression.getSlope());
System.out.println("intercept = " + simpleRegression.getIntercept());
//simpleRegression.add
getTimeLeft(0);
printGraphs();
return getLineChart();
}
/**
* This function loads the live data and plots the data in the graph
*
* @param userInput the input parameter for the live data
* @throws Exception throws an exception if an error occur
*/
public static void loadLiveData(Map<String, Number> userInput) throws Exception {
// Clears any data already there
......@@ -466,6 +368,13 @@ public class LineChartFunctionality {
}
}
/**
* Finds the difference between two dates
*
* @param start_date input parameter for the first date
* @param end_date input parameter for the second date
* @return returns the differnce in minutes
*/
private static long findDifference(String start_date, String end_date) {
// Defining a simple date format
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
......@@ -487,11 +396,19 @@ public class LineChartFunctionality {
return 0;
}
/**
* This function calculates the remaining time of the current drying cycle
*
* @param liveData input parameter for the data to base the calculations on
*/
public static void getTimeLeft(int liveData){
// Defines variables
int minutes = 0;
int hours = 0;
if(liveData == 0) {
// There are 10 minutes between each datapoint
minutes = getDataPointsXAxis()*10;
} else {
......@@ -512,135 +429,22 @@ public class LineChartFunctionality {
}
public static double getNonLinearRegression(Map<Integer, ArrayList<Double>> confidenceIntervalData, double y0, double alpha, double j, double n) {
//return Math.exp(intercept+slope*i)/(1+Math.exp(intercept+slope*i));
double beta = 0.0;
//double n = confidenceIntervalData.size();
for (Map.Entry<Integer, ArrayList<Double>> entry : confidenceIntervalData.entrySet()) {
for (int i = 0; i < entry.getValue().size(); i++) {
if(beta < entry.getValue().get(i)){
beta = entry.getValue().get(i);
}
}
}
beta = getDataPointsYAxis()+y0;
//System.out.println("Beta: " +beta);
//System.out.println("y0: "+y0);
//System.out.println("maxYValue: " + maxYValue);
//System.out.println("j*n: "+j/n);
//double p_t = (((beta * y0))/(y0 +((beta- y0)*Math.exp(-alpha*j/n/(ADJUST_REGRESSION)))))-y0; //Beste til nå
double p_t = (((beta * y0))/(y0 +((beta- y0)*Math.exp(-alpha*j/n/((alpha/10))))))-y0; //Beste til nå
//double p_t = (((beta * y0))/(y0 +((beta- y0)*Math.exp(-alpha*(j-n)))))-y0; //Beste til nå
/*
System.out.println("---------------------------");
System.out.println("y0: " + y0);
System.out.println("Alpha: " + alpha);
System.out.println("Beta: " + beta);
//System.out.println(p_t);
*/
return p_t;
}
/**
* Third degree cubic non-linear regression
* This function handles the logistic regression
*
* n =
*
* sumT1 =
* sumT2 =
* sumT3 =
* sumT4 =
*
* sumY =
* sumYxT1=
* sumYxT2 =
* @param confidenceIntervalData Data to process
* @return
* @param confidenceIntervalData the input parameter for the data to base the regression on
* @param y0 the input parameter for the intercept from the linear regression
* @param alpha the input parameter for the slope value from the linear regression
* @param j the input parameter for current x-axis datapoint to predict the value for
* @param n the input parameter for the total number of points along the x-axis
* @return the predicted value at a given point
*/
public static double getCubicNonLinearRegression(Map<Integer, ArrayList<Double>> confidenceIntervalData, int index){
double n = confidenceIntervalData.size();
//double n = getDataPointsYAxis();
//System.out.println(n);
double sumT1 = 0;
double sumT2 = 0;
double sumT3 = 0;
double sumT4 = 0;
double sumY = 0;
double sumYxT1 = 0;
double sumYxT2 = 0;
for (Map.Entry<Integer, ArrayList<Double>> entry : confidenceIntervalData.entrySet()) {
sumT1 += entry.getKey();
sumT2 += Math.pow(entry.getKey(),2);
sumT3 += Math.pow(entry.getKey(),3);
sumT4 += Math.pow(entry.getKey(),4);
for (int j = 0; j < entry.getValue().size(); j++) {
sumY += entry.getValue().get(j);
sumYxT1 += entry.getValue().get(j) * entry.getKey();
sumYxT2 += entry.getValue().get(j) * Math.pow(entry.getKey(), 2);
}
}
/*
for (Map.Entry<Integer, ArrayList<Double>> entry : confidenceIntervalData.entrySet()) {
for (int j = 0; j < entry.getValue().size(); j++) {
sumT1 += Math.pow(entry.getValue().get(j), 1);
sumT2 += Math.pow(entry.getValue().get(j), 2);
sumT3 += Math.pow(entry.getValue().get(j), 3);
sumT4 += Math.pow(entry.getValue().get(j), 4);
sumY += entry.getKey();
sumYxT1 += entry.getKey() * entry.getValue().get(j);
sumYxT2 += entry.getKey() * Math.pow(entry.getValue().get(j), 2);
}
}
*/
DoubleMatrix firstMatrix = new DoubleMatrix(new double[][]{{n,sumT1,sumT2},{sumT1,sumT2,sumT3},{sumT2,sumT3,sumT4}});
DoubleMatrix secondMatrix = new DoubleMatrix( new double[]{sumY, sumYxT1, sumYxT2});
DoubleMatrix solvedMatrix = Solve.solve(firstMatrix,secondMatrix);
//System.out.println(solvedMatrix);
//return ((solvedMatrix.get(0)) + (solvedMatrix.get(1) * index) + (solvedMatrix.get(2) * Math.pow(index, 2)));
//return ((solvedMatrix.get(1) * index) + (solvedMatrix.get(2) * Math.pow(index, 2)))*(-1);
return ((solvedMatrix.get(1) * index) + (solvedMatrix.get(2) * Math.pow(index, 2)));
public static double getNonLinearRegression(Map<Integer, ArrayList<Double>> confidenceIntervalData, double y0, double alpha, double j, double n) {
double beta = getDataPointsYAxis()+y0;
return (((beta * y0))/(y0 +((beta- y0)*Math.exp(-alpha*j/n/((alpha/10))))))-y0;
}
public static int getDataPointsXAxis() {
return dataPointsXAxis;
}
......@@ -661,10 +465,8 @@ public class LineChartFunctionality {
return liveDataSeries;
}
public static void setRegressionSeries(XYChart.Series<String, Number> regressionSeries) {
LineChartFunctionality.regressionSeries = regressionSeries;
}
// Getters and setters
public static XYChart.Series<String, Number> getRegressionSeries() {
return regressionSeries;
}
......@@ -713,10 +515,6 @@ public class LineChartFunctionality {
return regressionSeriesConfidenceInterval;
}
public static void setRegressionSeriesConfidenceInterval(XYChart.Series<String, Number> regressionSeriesConfidenceInterval) {
LineChartFunctionality.regressionSeriesConfidenceInterval = regressionSeriesConfidenceInterval;
}
public static LineChart<String, Number> getLineChart() {
return lineChart;
}
......@@ -729,6 +527,5 @@ public class LineChartFunctionality {
public static void clearLineChart() {
getLineChart().getData().clear();
//lineChart.getData().
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment