setup_analyser/analyser.js
Taylor Courage 333372348c Added Reduction of Diameter calculations
Changed formatting of page per industry professional recommendation
2025-01-23 14:34:01 -05:00

577 lines
20 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var numDies = 0; // master counter for our number of dies
var outputVisible = 0; // Status of whether the output is displayed or not
// Arrays to store values for graphs
var dieCount = [];
var dataROA = [];
var dataROD = [];
var dataElong = [];
var dataAngle = [];
var dataDelta = [];
///// START OF MATHS FUNCTIONS /////
// This function gets the reduction of area with two provided sizes, and returns it
function getReduction(startSize, finalSize) {
var startArea = Math.PI * ((startSize / 2) * (startSize / 2));
var finalArea = Math.PI * ((finalSize / 2) * (finalSize / 2));
return ((startArea - finalArea) / startArea) * 100;
}
// This function gets the elongation
function getElongation(startSize, finalSize) {
return (Math.pow(startSize / finalSize, 2) - 1) * 100;
}
function getDelta(startSize, finalSize, angle) {
angle = (angle * 0.5) * (Math.PI / 180); // Convert to semi-angle and radians
return ((startSize + finalSize) / (startSize - finalSize)) * Math.sin(angle);
}
function toMillimetres(size) { //convert to mm
size = Math.round((size * 100) * 25.4) / 100;
return size;
}
function toInches(size) { //convert to inches
size = Math.round((size * 1000) / 25.4) / 1000;
return size;
}
function getRoDiameter(startSize, finishSize){
return (startSize - finishSize) / ((startSize + finishSize) / 2) * 100;
}
///// END OF MATHS SECTION /////
///// START OF DISPLAY SECTION /////
function addReduction() {
numDies ++; // Increment our die count
// Create the data going into the row
var inputLabel = "<label for=\"die" + numDies + "\" style=\"text-align:right;\">#" + (numDies) + ": </label>";
var inputSize = "<input id=\"die" + numDies + "\" type=\"text\" autocomplete=\"off\" value=\"0.000\" size=\"4\" onchange=\"doMath()\" />";
var inputAngle = "<input id=\"angle" + numDies + "\" type=\"text\" autocomplete=\"off\" value=\"16\" size=\"2\" onchange=\"doMath()\" style=\"text-align:center;\"/>";
// create the row
var table = document.getElementById("data"); // get table ID
var row = table.insertRow(-1); // Insert a new row (the -1 means we add to the END of the table)
var cell1 = row.insertCell(0); // Create and add a cell to the table
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
cell1.innerHTML = inputLabel; // Set the values of the cells we've created
cell2.innerHTML = inputSize
cell3.innerHTML = inputAngle;
if (outputVisible == 1) { // Check if out output is visible and update immediately when adding dies
doMath();
}
}
function removeReduction() { // function to remove the last row
numDies --;
document.getElementById("data").deleteRow(-1); // delete the last row in the table
// Remove the last item in each array to remove the tick from the graph
dieCount.splice(-1);
dataROA.splice(-1);
dataElong.splice(-1);
dataDelta.splice(-1);
if (outputVisible == 1) { // Check if out output is visible and update immediately when adding dies
doMath();
}
}
///// END OF DISPLAY SECTION /////
///// START OF ALGORITHMS SECTION /////
function doMath() {
outputVisible = 1; // set visible status to enabled
outputTable = document.getElementById("output"); // Select our output data table
outputTable.innerHTML = "";
// Make the output graph visible
outputGraph = document.getElementById("outputChart");
outputGraph.innerHTML = "<canvas id=\"outputData\"></canvas>";
var row = [];
row[0] = outputTable.insertRow(0);
row[0].id = "outputHeader"; // set the header row
var cell1 = row[0].insertCell(0); //blank
var cell2 = row[0].insertCell(1); // "Start -> Finish"
var cell3 = row[0].insertCell(2); // "ROA"
var cell4 = row[0].insertCell(3); // "ROD"
var cell5 = row[0].insertCell(4); // "Elong"
var cell6 = row[0].insertCell(5); // "Angle"
var cell7 = row[0].insertCell(6); // "Delta"
// Create the header of the table
cell1.innerHTML = "Draft";
cell1.id = "reductionNumHeader";
cell2.innerHTML = "Start -> Finish";
cell2.id = "startFinish";
cell3.innerHTML = "R. Area (%)";
cell3.id = "roa";
cell4.innerHTML = "R. Dia. (%)";
cell4.id = "rod";
cell5.innerHTML = "Elong (%)";
cell5.id = "elong";
cell6.innerHTML = "Angle";
cell6.id = "angle";
cell7.innerHTML = "Δ Factor";
cell7.id = "delta";
for (var i = 1; i < numDies + 1; i++) {
inSize = document.getElementById("die" + (i - 1)).value; // the input size
outSize = document.getElementById("die" + i).value; // output size
angle = document.getElementById("angle" + i).value;
if (i == 1 && document.getElementById("metric").checked == true) {
// If this is the first die in the setup, check if it's a metric/rod start and convert it
inSize = toInches(inSize);
}
// Format our numbers to prevent maximum user stupidity
if (inSize < 10.0 && inSize > 0) { // If we have a 'proper' number i.e. ".130"
inSize = Number(inSize);
} else { // re-format the number if it's 'wrong' i.e. "130"
inSize = inSize / 1000;
}
if (outSize < 10.0 && outSize > 0) { // If we have a 'proper' number i.e. ".130"
outSize = Number(outSize);
} else { // re-format the number if it's 'wrong' i.e. "130"
outSize = outSize / 1000;
}
row[i] = outputTable.insertRow(i); // Add a new row to the END of the table
// Add all our cells to the table
// We also give them HTML ID's to format things with CSS nicely
cell1 = row[i].insertCell(0);
cell1.id = "reductionNum";
cell2 = row[i].insertCell(1);
cell2.id = "startFinish";
cell3 = row[i].insertCell(2);
cell3.id = "roa";
cell4 = row[i].insertCell(3);
cell4.id = "rod";
cell5 = row[i].insertCell(4);
cell5.id = "elong";
cell6 = row[i].insertCell(5);
cell6.id = "angle";
cell7 = row[i].insertCell(6);
cell7.id = "delta";
// These next lines calculate and round the data to two decimal places
dataROA[i - 1] = (Math.round(getReduction(inSize, outSize) * 100) / 100).toFixed(2);
dataROD[i - 1] = (Math.round(getRoDiameter(inSize, outSize) * 100) / 100).toFixed(2);
dataElong[i - 1] = (Math.round(getElongation(inSize, outSize) * 100) / 100).toFixed(2);
dataDelta[i - 1] = (Math.round(getDelta(inSize, outSize, angle) * 100) / 100).toFixed(2);
dataAngle[i - 1] = angle;
// Set the values of the cells in our table
cell1.innerHTML = "#" + i + ":&nbsp;";
cell2.innerHTML = inSize.toFixed(3) + "\" (" + toMillimetres(inSize) + " mm) -> " + outSize.toFixed(3) + "\" (" + toMillimetres(outSize) + " mm)";
cell3.innerHTML = dataROA[i - 1];
cell4.innerHTML = dataROD[i - 1];
cell5.innerHTML = dataElong[i - 1];
cell6.innerHTML = dataAngle[i - 1];
cell7.innerHTML = dataDelta[i - 1];
dieCount[i - 1] = i;
}
getStatistics();
drawGraph();
// Add spacers
document.getElementById("spacer1").style.display = 'block';
document.getElementById("spacer2").style.display = 'block';
document.getElementById("spacer3").style.display = 'block';
}
function drawGraph() {
// Documentation for the following chart-building command can be found at https://chartjs.org
const outputData = new Chart("outputData", {
type: "line",
data: {
labels: dieCount,
datasets: [{
data: dataROA,
label: "Reduction of Area",
borderColor: "green",
fill: false,
pointStyle: 'circle',
pointRadius: 4,
pointHoverRadius: 7,
yAxisID: 'y',
tension: 0,
tooltip: {
callbacks: {
label: function(tooltipItem, d){
return "RoA: " + Number(tooltipItem.formattedValue).toFixed(2) + "%";
},
},
},
},{
data: dataROD,
label: "Reduction of Dia.",
borderColor: "orange",
fill: false,
pointStyle: 'rect',
pointRadius: 5,
pointHoverRadius: 8,
yAxisID: 'y',
tension: 0,
tooltip: {
callbacks: {
label: function(tooltipItem, d){ // Add a % sign to the value
return "RoD: " + Number(tooltipItem.formattedValue).toFixed(2) + "%";
},
},
},
},{
data: dataElong,
label: "Elongation",
borderColor: "blue",
fill: false,
pointStyle: 'rect',
pointRadius: 5,
pointHoverRadius: 8,
yAxisID: 'y',
tension: 0,
tooltip: {
callbacks: {
label: function(tooltipItem, d){ // Add a % sign to the value
return "Elong: " + Number(tooltipItem.formattedValue).toFixed(2) + "%";
},
},
},
},{
data: dataDelta,
label: "Δ Factor",
borderColor: "red",
fill: false,
pointStyle: 'triangle',
pointRadius: 5,
pointHoverRadius: 8,
yAxisID: 'y1',
tension: 0
}],
},
options: {
responsive: true,
interaction: {
mode: 'index',
intersect: false,
},
stacked: false,
plugins: {
title: {
display: true,
text: "Draft Analysis"
},
legend: {
labels: {
usePointStyle: true
}
},
tooltip: {
callbacks: {
title: function(tooltipItem, d){
var i = Number(tooltipItem[0].label); // Grab the label (or die number) and use it for start/finish
// We need our start and finish sizes...
inSize = document.getElementById("die" + (i - 1)).value; // the input size
outSize = document.getElementById("die" + i).value; // output size
if (i == 1 && document.getElementById("metric").checked == true) {
// If this is the first die in the setup, check if it's a metric/rod start and convert it
inSize = toInches(inSize);
}
// Format our numbers to prevent maximum user stupidity
if (inSize < 10.0 && inSize > 0) { // If we have a 'proper' number i.e. ".130"
inSize = Number(inSize);
} else { // re-format the number if it's 'wrong' i.e. "130"
inSize = inSize / 1000;
}
if (outSize < 10.0 && outSize > 0) { // If we have a 'proper' number i.e. ".130"
outSize = Number(outSize);
} else { // re-format the number if it's 'wrong' i.e. "130"
outSize = outSize / 1000;
}
// Finally write the new header
return "Draft #" + tooltipItem[0].label + "\n" + inSize.toFixed(3) + "\" -> " + outSize.toFixed(3) + "\"";
},
},
},
},
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
title: {
display: true,
text: "% (RoA/Elong)"
},
suggestedMin: 0,
suggestedMax: 35,
},
y1: {
type: 'linear',
display: true,
position: 'right',
title: {
display: true,
text: "Δ Factor"
},
suggestedMin: 0,
suggestedMax: 7,
grid: {
drawOnChartArea: false
}
},
x: {
title: {
display: true,
text: "Draft #"
},
}
},
},
});
}
function getStatistics() {
// Get data from page
var div = document.getElementById("statistics");
var startSize = formatCheck(document.getElementById("die0").value);
var finalSize = formatCheck(document.getElementById("die" + numDies).value);
// Check if the start size is metric/rod and convert to inches
if (document.getElementById("metric").checked == true) {
startSize = toInches(startSize);
}
// We'll do a lot of the heavy math-lifting here to make things easier to read below
var avgDelta = 0;
var avgROA = 0;
var avgElong = 0;
var totalROA = Math.round(getReduction(startSize, finalSize) * 100) / 100;
var totalElong = Math.round(getElongation(startSize, finalSize) * 100) / 100;
var totalROD = Math.round(getRoDiameter(startSize, finalSize) * 100) / 100;
// Get average ROA
for (var i = 0; i < numDies; i++) {
avgROA += Number(dataROA[i]);
}
avgROA = (Math.round((avgROA / numDies) * 100) / 100).toFixed(2);
// Get average Elong
for (var i = 0; i < numDies; i++) {
avgElong += Number(dataElong[i]);
}
avgElong = (Math.round((avgElong / numDies) * 100) / 100).toFixed(2);
// Get average delta
for (var i = 0; i < numDies; i++) {
avgDelta += Number(dataDelta[i]);
}
avgDelta = (Math.round((avgDelta / numDies) * 100) / 100).toFixed(2);
// Create the table to display statistics
div.innerHTML = "<h5 align=\"center\" id=\"statsSummaryHeader\">Summary</h5><table id=\"statsTable\"></table>";
var statsTable = document.getElementById("statsTable");
//// ROW 1 ////
var row = statsTable.insertRow(0);
var c1 = row.insertCell(0);
var c2 = row.insertCell(1);
var c3 = row.insertCell(2);
var c4 = row.insertCell(3);
var c5 = row.insertCell(4);
// COL 1
c1.innerHTML = "# Of Reductions: ";
c1.id = "statsCol1";
c2.innerHTML = "<b>" + numDies + "</b>";
c2.id = "statsCol2";
//
c3.innerHTML = "|&nbsp;&nbsp;";
c3.id = "statsCol3";
// COL 2
c4.innerHTML = "Avg. Δ Factor: ";
c4.id = "statsCol4";
c5.innerHTML = "<b>" + avgDelta + "</b>";
c5.id = "statsCol5";
//// ROW 2 ////
row = statsTable.insertRow(1);
c1 = row.insertCell(0);
c2 = row.insertCell(1);
c3 = row.insertCell(2);
c4 = row.insertCell(3);
c5 = row.insertCell(4);
// COL 1
c1.innerHTML = "Total R. Of Diameter: ";
c1.id = "statsCol4";
c2.innerHTML = "<b>" + (Math.round((startSize - finalSize) * 1000) / 1000).toFixed(2) + "\"</b>";
c2.id = "statsCol5";
//
c3.innerHTML = "|&nbsp;&nbsp;";
c3.id = "statsCol3";
// COL 2
c4.innerHTML = "% R. Of Diameter";
c4.id = "statsCol4";
c5.innerHTML = "<b>" + totalROD.toFixed(2) + "%</b>";
c5.id = "statsCol5";
//// ROW 3 ////
row = statsTable.insertRow(2);
c1 = row.insertCell(0);
c2 = row.insertCell(1);
c3 = row.insertCell(2);
c4 = row.insertCell(3);
c5 = row.insertCell(4);
// COL 1
c1.innerHTML = "Total R. Of Area: ";
c1.id = "statsCol1";
c2.innerHTML = "<b>" + totalROA + "%</b>";
c2.id = "statsCol2";
//
c3.innerHTML = "|&nbsp;&nbsp;";
c3.id = "statsCol3";
// COL 2
c4.innerHTML = "Avg. R. of Area: ";
c4.id = "statsCol4";
c5.innerHTML = "<b>" + avgROA + "%</b>";
c5.id = "statsCol5";
//// ROW 4 ////
row = statsTable.insertRow(3);
c1 = row.insertCell(0);
c2 = row.insertCell(1);
c3 = row.insertCell(2);
c4 = row.insertCell(3);
c5 = row.insertCell(4);
// COL 1
c1.innerHTML = "Total Elongation: ";
c1.id = "statsCol1";
c2.innerHTML = "<b>" + totalElong + "%</b>";
c2.id = "statsCol2";
//
c3.innerHTML = "|&nbsp;&nbsp;";
c3.id = "statsCol3";
// COL 2
c4.innerHTML = "Avg. Elongation: ";
c4.id = "statsCol4";
c5.innerHTML = "<b>" + avgElong + "%</b>";
c5.id = "statsCol5";
}
function clearScreen() {
// Reset variables back to defaults
numDies = 0;
outputVisible = 0;
// Clear and reset inputs
var inputStart = document.getElementById("die0");
inputStart.value = "0.0";
var unitsType = document.getElementById("metric");
unitsType.checked = true;
var inputTable = document.getElementById("data");
inputTable.innerHTML = "<tr style=\"font-size: 75%;\"><td><p></p>Draft<p></p></td><td>Exit Dia.</td><td>Angle (2α)</td></tr>";
// Delete the output table
var outputTable = document.getElementById("output");
outputTable.innerHTML = "";
// Delete the output graph
outputGraph = document.getElementById("outputChart");
outputGraph.innerHTML = "";
statistics = document.getElementById("statistics");
statistics.innerHTML = "";
// Delete the spacers
document.getElementById("spacer1").style.display = 'none';
document.getElementById("spacer2").style.display = 'none';
document.getElementById("spacer3").style.display = 'none';
// Add two fresh entries
addReduction();
addReduction();
}
///// END OF ALGORITHMS SECTION /////
///// EXTRA SECTION /////
function printScreen() {
var subtitle = document.getElementById("subtitle");
var reductionCount = document.getElementById("numReductions");
// Get input size, and format it
var inputSize = document.getElementById("die0").value;
// If our start size is metric show that, otherwise swap them to show 'murican first
if (document.getElementById("metric").checked) {
var inputText = inputSize + " mm (" + toInches(inputSize) + "\")";
} else {
var inputText = formatCheck(inputSize) + "\" (" + toMillimetres(formatCheck(inputSize)) + " mm)";
}
// Get the final size and format it
var outputSize = document.getElementById("die" + numDies).value;
outputSize = formatCheck(outputSize).toFixed(3);
var outputText = (outputSize) + "\" (" + toMillimetres(outputSize) + " mm)";
// Create and set the header
subtitle.innerHTML = "For " + inputText + " to " + outputText;
// Change the name of the window to save the file with the same
var pageTitle = document.getElementById("pageTitle");
var title = pageTitle.innerHTML;
pageTitle.innerHTML = "Draft Analysis for " + inputSize + " to " + outputSize;
// Let the browser handle printing
window.print();
// Reset the page title back to normal
pageTitle.innerHTML = title;
}
function formatCheck(value) {
if (value < 10.0 && value > 0) { // If we have a 'proper' number i.e. ".130"
value = Number(value);
} else { // re-format the number if it's 'wrong' i.e. "130"
value = value / 1000;
}
return value;
}