diff --git a/graph.js b/graph.js new file mode 100644 index 0000000..1b56796 --- /dev/null +++ b/graph.js @@ -0,0 +1,197 @@ + + +//Create delay function +const delay = ms => new Promise(res => setTimeout(res, ms)); + +//Tennis court coordinates +//Y: [-5.02m, 5.02m] X: [-11.88m, 11.88m] no Z height +var x = [-11.88, 11.88, 11.88, -11.88] +var y = [-5.02, -5.02, 5.02, 5.02] +//Shift the court slightly up so its not interfering with the grid +var z = [0.01, 0.01, 0.01, 0.01] + +//Face is made up of 2 triangles, both need to be set to the same colour +var facecolor = [ 'rgb(30, 175, 0)', 'rgb(30, 175, 0)', ] + +var court = { name:"Court", x, y, z, facecolor, type: 'mesh3d', } + +var x_val =new Array(); +var y_val =new Array(); +var z_val =new Array(); + +var trajectory = { + name: "Trajectory", + type: 'scatter3d', + mode: 'lines+markers', + x: x_val, + y: y_val, + z: z_val, + line: { + width: 4, + color: '#ff0000', + }, + marker: { + color: '#0000ff', + size: 2, + symbol: 'circle', + }, +}; + +var layout = { + title: 'Tennis Ball Trajectory Plot', + autosize: true, + margin: { autoexpand: true, }, + scene:{ + xaxis:{ range:[-18,18], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, + yaxis:{ range:[-10,10], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, + zaxis:{ range:[ 0, 2], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, + } +}; + +//COEFF = document.getElementById("cor_plot"); + +var pointCount = 1600; +var coeff_restitution = 0; +var velocity_vector_pre = 1; +var velocity_vector_post = 1; + + +var bounce_sample = new Array(); +var center_bounce = 0; +var sample = new Array(); + + +// variables for failed PolynomialRegression attempt +//const vector_length = 1; // Determines how many points back to use to calculate average z-velocity +//const degree = 3; +//var sample_division = new Array(); + + +// Failed implementation for PolynomialRegression library +// Implementation using regression to create a function that models all points of bounce +// Third order polynomial has 3 zeros and is the minimum number necessary +//const regression = new PolynomialRegression(sample, z_val, degree) + +// for(let point = 0; point < pointCount * 10; point++) +// { +// //sample_division[point] = regression.predict(point / 10) +// if(sample_division[point] > 0.005 && sample_division[point] < 0.015) +// // gathers all sub-points within the regression that fall at a "bounce height" +// // but this could result in more than one point being recorded. needs to have one centered +// // point. gather into array and then take the middle value? +// { +// bounce_sample.push(point); +// } +// } + +// center_bounce = Math.floor((bounce_sample.length - 1) / 2); // find center of sample + //make sure that this can be indexed within the regression. Is this 10x the actual array size? +// velocity_vector_pre = regression.predict(bounce_sample[center_bounce - 1]); +// velocity_vector_post = regression.predict(bounce_sample[center_bounce + 1]); +// coeff_restitution = Math.abs(velocity_vector_post) / Math.abs(velocity_vector_pre); + + +var cor_trace1 = { + name: "2D Tennis Ball Bounce", + type: 'scatter', + mode: 'lines+markers', + x:sample, + y:z_val, +}; + +var data = [cor_trace1,]; +var cor_layout = { + title: '2D Tennis Ball Bounce Graph', + autosize: true, + margin: { autoexpand: true, }, + scene:{ + xaxis:{ range:[0,1800], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, + yaxis:{ range:[-10,10], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, + } +}; + + +//Init plot +Plotly.newPlot("secondplot", [trajectory,court] , layout, {responsive: true} ); +Plotly.newPlot('cor_plot', data, cor_layout, {responsive: true} ); + +//Update plot with info from GET call +function poll(filename) { + var jqueryRequest = $.get("http://129.21.94.11:8000/serve/" + filename) + .done(function(data) { + Papa.parse(data, { + dynamicTyping: true, + delimiter: " ", + //Only include if the input contains a header row; i.e. the first row is labels. + //header: true, + worker: true, + complete: function(results){ + results.data.forEach((element) => { + x_val.push(element[2]); + y_val.push(element[0]); + //Compensate for court offset + z_val.push(element[1]+0.01); + }); + + console.log(x_val.length) + pointCount = x_val.length; + for (let point = 0; point < pointCount; point++) + { + sample.push(point); // Create a series for just sample count + } + console.log(sample) + Plotly.update("secondplot", [trajectory,court], layout, {responsive: true}); + Plotly.update('cor_plot', data, cor_layout, {responsive: true}); + + console.log(pointCount) + }, + }); + }).fail(function(errorData){ + console.error("Backend Request failed! Is the backend running?"); + }); +} + +//Get the button from the HTML file +var button = document.getElementById("sendPost"); + +//Get the input field from the HTML file +var input_field = document.getElementById("csvSelector"); + +//If the user presses "enter" on the input field, call to press the button, as this is expected behaviour +input_field.addEventListener("keypress",function(event){ + if (event.key === "Enter"){ + event.preventDefault(); + button.click(); + } +}); + +//On button click... +button.addEventListener("click",function(e){ + //Get the file name from the text input + var file_name = input_field.value; + //Send the text input to the web server + $.post("http://129.21.94.11:8000/serve", { file_name }) + //Once the POST response comes back + .done(function(){ + //Wait 2s for image processing to run + delay(2000); + //Clear current values to graph the new file + x_val.length = 0; + y_val.length = 0; + z_val.length = 0; + sample.length = 0; + //Run a GET call, with the given file name + poll(file_name); + //FitCurve(sample, z_val); + }); +},false); + + +//Failed test implementation for polyfit library + +//function FitCurve(x, y) +//{ +// var poly = Polyfit(x, y); +// solver = poly.getPolynomial(degree); +// console.log(solver(1.17)); +//} diff --git a/public/javascripts/graph.js b/public/javascripts/graph.js index d7a18aa..1b56796 100644 --- a/public/javascripts/graph.js +++ b/public/javascripts/graph.js @@ -1,3 +1,5 @@ + + //Create delay function const delay = ms => new Promise(res => setTimeout(res, ms)); @@ -13,7 +15,7 @@ var facecolor = [ 'rgb(30, 175, 0)', 'rgb(30, 175, 0)', ] var court = { name:"Court", x, y, z, facecolor, type: 'mesh3d', } -var x_val =new Array(); +var x_val =new Array(); var y_val =new Array(); var z_val =new Array(); @@ -46,12 +48,76 @@ var layout = { } }; +//COEFF = document.getElementById("cor_plot"); + +var pointCount = 1600; +var coeff_restitution = 0; +var velocity_vector_pre = 1; +var velocity_vector_post = 1; + + +var bounce_sample = new Array(); +var center_bounce = 0; +var sample = new Array(); + + +// variables for failed PolynomialRegression attempt +//const vector_length = 1; // Determines how many points back to use to calculate average z-velocity +//const degree = 3; +//var sample_division = new Array(); + + +// Failed implementation for PolynomialRegression library +// Implementation using regression to create a function that models all points of bounce +// Third order polynomial has 3 zeros and is the minimum number necessary +//const regression = new PolynomialRegression(sample, z_val, degree) + +// for(let point = 0; point < pointCount * 10; point++) +// { +// //sample_division[point] = regression.predict(point / 10) +// if(sample_division[point] > 0.005 && sample_division[point] < 0.015) +// // gathers all sub-points within the regression that fall at a "bounce height" +// // but this could result in more than one point being recorded. needs to have one centered +// // point. gather into array and then take the middle value? +// { +// bounce_sample.push(point); +// } +// } + +// center_bounce = Math.floor((bounce_sample.length - 1) / 2); // find center of sample + //make sure that this can be indexed within the regression. Is this 10x the actual array size? +// velocity_vector_pre = regression.predict(bounce_sample[center_bounce - 1]); +// velocity_vector_post = regression.predict(bounce_sample[center_bounce + 1]); +// coeff_restitution = Math.abs(velocity_vector_post) / Math.abs(velocity_vector_pre); + + +var cor_trace1 = { + name: "2D Tennis Ball Bounce", + type: 'scatter', + mode: 'lines+markers', + x:sample, + y:z_val, +}; + +var data = [cor_trace1,]; +var cor_layout = { + title: '2D Tennis Ball Bounce Graph', + autosize: true, + margin: { autoexpand: true, }, + scene:{ + xaxis:{ range:[0,1800], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, + yaxis:{ range:[-10,10], gridcolor: "#a0a0a0", zerolinecolor: "#a0a0a0", }, + } +}; + + //Init plot Plotly.newPlot("secondplot", [trajectory,court] , layout, {responsive: true} ); +Plotly.newPlot('cor_plot', data, cor_layout, {responsive: true} ); //Update plot with info from GET call function poll(filename) { - var jqueryRequest = $.get("http://192.168.0.90:8000/serve/" + filename) + var jqueryRequest = $.get("http://129.21.94.11:8000/serve/" + filename) .done(function(data) { Papa.parse(data, { dynamicTyping: true, @@ -66,7 +132,18 @@ function poll(filename) { //Compensate for court offset z_val.push(element[1]+0.01); }); + + console.log(x_val.length) + pointCount = x_val.length; + for (let point = 0; point < pointCount; point++) + { + sample.push(point); // Create a series for just sample count + } + console.log(sample) Plotly.update("secondplot", [trajectory,court], layout, {responsive: true}); + Plotly.update('cor_plot', data, cor_layout, {responsive: true}); + + console.log(pointCount) }, }); }).fail(function(errorData){ @@ -93,7 +170,7 @@ button.addEventListener("click",function(e){ //Get the file name from the text input var file_name = input_field.value; //Send the text input to the web server - $.post("http://192.168.0.90:8000/serve", { file_name }) + $.post("http://129.21.94.11:8000/serve", { file_name }) //Once the POST response comes back .done(function(){ //Wait 2s for image processing to run @@ -102,7 +179,19 @@ button.addEventListener("click",function(e){ x_val.length = 0; y_val.length = 0; z_val.length = 0; + sample.length = 0; //Run a GET call, with the given file name poll(file_name); + //FitCurve(sample, z_val); }); },false); + + +//Failed test implementation for polyfit library + +//function FitCurve(x, y) +//{ +// var poly = Polyfit(x, y); +// solver = poly.getPolynomial(degree); +// console.log(solver(1.17)); +//}