2025-01-15 22:24:43 -05:00
|
|
|
|
var numDies = 0; // master counter for our number of dies
|
2025-01-21 02:42:11 -05:00
|
|
|
|
var outputVisible = 0; // Status of whether the output graph is displayed or not
|
2025-01-15 22:24:43 -05:00
|
|
|
|
|
2025-01-21 10:59:21 -05:00
|
|
|
|
// Arrays to store values for graphs
|
|
|
|
|
var dieCount = [];
|
|
|
|
|
var dataROA = [];
|
|
|
|
|
var dataElong = [];
|
|
|
|
|
var dataDelta = [];
|
|
|
|
|
|
2025-01-21 11:13:04 -05:00
|
|
|
|
///// START OF MATHS FUNCTIONS /////
|
|
|
|
|
|
2025-01-15 22:24:43 -05:00
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 02:42:11 -05:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 11:13:04 -05:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///// END OF MATHS SECTION /////
|
|
|
|
|
|
|
|
|
|
///// START OF DISPLAY SECTION /////
|
|
|
|
|
|
2025-01-15 22:24:43 -05:00
|
|
|
|
function addReduction() {
|
2025-01-21 02:42:11 -05:00
|
|
|
|
numDies ++; // Increment our die count
|
2025-01-15 22:24:43 -05:00
|
|
|
|
|
2025-01-21 02:42:11 -05:00
|
|
|
|
// 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;\"/>";
|
2025-01-15 22:24:43 -05:00
|
|
|
|
|
|
|
|
|
// create the row
|
2025-01-21 02:42:11 -05:00
|
|
|
|
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();
|
|
|
|
|
}
|
2025-01-15 22:24:43 -05:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function removeReduction() { // function to remove the last row
|
|
|
|
|
numDies --;
|
|
|
|
|
document.getElementById("data").deleteRow(-1); // delete the last row in the table
|
2025-01-21 02:42:11 -05:00
|
|
|
|
|
|
|
|
|
if (outputVisible == 1) { // Check if out output is visible and update immediately when adding dies
|
|
|
|
|
doMath();
|
|
|
|
|
}
|
2025-01-15 22:24:43 -05:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 11:13:04 -05:00
|
|
|
|
///// END OF DISPLAY SECTION /////
|
|
|
|
|
|
|
|
|
|
///// START OF ALGORITHMS SECTION /////
|
|
|
|
|
|
2025-01-15 22:24:43 -05:00
|
|
|
|
function doMath() {
|
2025-01-21 02:42:11 -05:00
|
|
|
|
outputVisible = 1; // set visible status to enabled
|
2025-01-15 22:24:43 -05:00
|
|
|
|
outputTable = document.getElementById("output"); // Select our output data table
|
|
|
|
|
outputTable.innerHTML = "";
|
2025-01-21 02:42:11 -05:00
|
|
|
|
|
2025-01-21 10:59:21 -05:00
|
|
|
|
// Make the output graph visible
|
|
|
|
|
outputGraph = document.getElementById("outputChart");
|
|
|
|
|
outputGraph.innerHTML = "<canvas id=\"outputData\"></canvas>";
|
2025-01-21 02:42:11 -05:00
|
|
|
|
|
|
|
|
|
|
2025-01-15 22:24:43 -05:00
|
|
|
|
var row = [];
|
|
|
|
|
row[0] = outputTable.insertRow(0);
|
|
|
|
|
row[0].id = "outputHeader"; // set the header row
|
|
|
|
|
var r1c1 = row[0].insertCell(0); //blank
|
|
|
|
|
var r1c2 = row[0].insertCell(1); // "Start -> Finish"
|
|
|
|
|
var r1c3 = row[0].insertCell(2); // "ROA"
|
|
|
|
|
var r1c4 = row[0].insertCell(3); // "Elong"
|
|
|
|
|
var r1c5 = row[0].insertCell(4); // "Delta"
|
|
|
|
|
|
|
|
|
|
// Create the header of the table
|
2025-01-21 10:59:21 -05:00
|
|
|
|
r1c1.innerHTML = "Draft";
|
2025-01-21 02:42:11 -05:00
|
|
|
|
r1c1.id = "reductionNumHeader";
|
2025-01-15 22:24:43 -05:00
|
|
|
|
r1c2.innerHTML = "Start -> Finish";
|
|
|
|
|
r1c2.id = "startFinish";
|
|
|
|
|
r1c3.innerHTML = "ROA (%)";
|
|
|
|
|
r1c3.id = "roa";
|
|
|
|
|
r1c4.innerHTML = "Elong (%)";
|
|
|
|
|
r1c4.id = "elong";
|
2025-01-21 10:59:21 -05:00
|
|
|
|
r1c5.innerHTML = "Δ Factor";
|
2025-01-15 22:24:43 -05:00
|
|
|
|
r1c5.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
|
2025-01-21 02:42:11 -05:00
|
|
|
|
angle = document.getElementById("angle" + i).value;
|
2025-01-15 22:24:43 -05:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 02:42:11 -05:00
|
|
|
|
row[i] = outputTable.insertRow(i); // Add a new row to the END of the table
|
2025-01-15 22:24:43 -05:00
|
|
|
|
|
|
|
|
|
|
2025-01-21 02:42:11 -05:00
|
|
|
|
// Add all our cells to the table
|
|
|
|
|
// We also give them HTML ID's to format things with CSS nicely
|
2025-01-15 22:24:43 -05:00
|
|
|
|
var cell1 = row[i].insertCell(0);
|
2025-01-21 02:42:11 -05:00
|
|
|
|
cell1.id = "reductionNum";
|
2025-01-15 22:24:43 -05:00
|
|
|
|
var cell2 = row[i].insertCell(1);
|
|
|
|
|
cell2.id = "startFinish";
|
|
|
|
|
var cell3 = row[i].insertCell(2);
|
|
|
|
|
cell3.id = "roa";
|
|
|
|
|
var cell4 = row[i].insertCell(3);
|
|
|
|
|
cell4.id = "elong";
|
2025-01-21 02:42:11 -05:00
|
|
|
|
var cell5 = row[i].insertCell(4);
|
|
|
|
|
cell5.id = "delta";
|
2025-01-15 22:24:43 -05:00
|
|
|
|
|
2025-01-21 02:42:11 -05:00
|
|
|
|
// These next lines calculate and round the data to two decimal places
|
|
|
|
|
dataROA[i - 1] = Math.round(getReduction(inSize, outSize) * 100) / 100;
|
|
|
|
|
dataElong[i - 1] = Math.round(getElongation(inSize, outSize) * 100) / 100;
|
|
|
|
|
dataDelta[i - 1] = Math.round(getDelta(inSize, outSize, angle) * 100) / 100;
|
2025-01-15 22:24:43 -05:00
|
|
|
|
|
2025-01-21 02:42:11 -05:00
|
|
|
|
// Set the values of the cells in our table
|
|
|
|
|
cell1.innerHTML = "#" + i + ": ";
|
|
|
|
|
cell2.innerHTML = inSize + "\" (" + toMillimetres(inSize) + " mm) -> " + outSize + "\" (" + toMillimetres(outSize) + " mm)";
|
|
|
|
|
cell3.innerHTML = dataROA[i - 1];
|
|
|
|
|
cell4.innerHTML = dataElong[i - 1];
|
|
|
|
|
cell5.innerHTML = dataDelta[i - 1];
|
2025-01-21 10:59:21 -05:00
|
|
|
|
|
|
|
|
|
dieCount[i - 1] = i;
|
2025-01-15 22:24:43 -05:00
|
|
|
|
}
|
2025-01-21 10:59:21 -05:00
|
|
|
|
drawGraph();
|
2025-01-15 22:24:43 -05:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 10:59:21 -05:00
|
|
|
|
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
|
|
|
|
|
},{
|
|
|
|
|
data: dataElong,
|
|
|
|
|
label: "Elongation",
|
|
|
|
|
borderColor: "blue",
|
|
|
|
|
fill: false,
|
|
|
|
|
pointStyle: 'rect',
|
|
|
|
|
pointRadius: 5,
|
|
|
|
|
pointHoverRadius: 8,
|
|
|
|
|
yAxisID: 'y',
|
|
|
|
|
tension: 0
|
|
|
|
|
},{
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
scales: {
|
|
|
|
|
y: {
|
|
|
|
|
type: 'linear',
|
|
|
|
|
display: true,
|
|
|
|
|
position: 'left',
|
|
|
|
|
title: {
|
|
|
|
|
display: true,
|
|
|
|
|
text: "% (RoA/Elong)"
|
|
|
|
|
},
|
|
|
|
|
suggestedMin: 0,
|
|
|
|
|
suggestedMax: 30,
|
|
|
|
|
},
|
|
|
|
|
y1: {
|
|
|
|
|
type: 'linear',
|
|
|
|
|
display: true,
|
|
|
|
|
position: 'right',
|
|
|
|
|
title: {
|
|
|
|
|
display: true,
|
|
|
|
|
text: "Δ Factor"
|
|
|
|
|
},
|
|
|
|
|
suggestedMin: 0,
|
|
|
|
|
suggestedMax: 6,
|
|
|
|
|
grid: {
|
|
|
|
|
drawOnChartArea: false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
x: {
|
|
|
|
|
title: {
|
|
|
|
|
display: true,
|
|
|
|
|
text: "Draft #"
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-01-21 02:42:11 -05:00
|
|
|
|
|
2025-01-21 11:13:04 -05:00
|
|
|
|
function clearScreen() {
|
|
|
|
|
// Reset variables back to defaults
|
2025-01-21 12:43:55 -05:00
|
|
|
|
numDies = 0;
|
2025-01-21 11:13:04 -05:00
|
|
|
|
outputVisible = 0;
|
|
|
|
|
|
2025-01-21 12:43:55 -05:00
|
|
|
|
// 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");
|
2025-01-21 11:13:04 -05:00
|
|
|
|
outputTable.innerHTML = "";
|
|
|
|
|
|
|
|
|
|
// Delete the output graph
|
|
|
|
|
outputGraph = document.getElementById("outputChart");
|
2025-01-21 12:43:55 -05:00
|
|
|
|
outputGraph.innerHTML = "";
|
2025-01-15 22:24:43 -05:00
|
|
|
|
|
2025-01-21 12:43:55 -05:00
|
|
|
|
// Add two fresh entries
|
|
|
|
|
addReduction();
|
|
|
|
|
addReduction();
|
2025-01-15 22:24:43 -05:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 11:13:04 -05:00
|
|
|
|
|
2025-01-21 12:43:55 -05:00
|
|
|
|
///// 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 (inputSize < 10.0 && inputSize > 0) { // If we have a 'proper' number i.e. ".130"
|
|
|
|
|
inputSize = Number(inputSize);
|
|
|
|
|
} else { // re-format the number if it's 'wrong' i.e. "130"
|
|
|
|
|
inputSize = inputSize / 1000;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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 = inputSize + "\" (" + toMillimetres(inputSize) + " mm)";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get the final size and format it
|
|
|
|
|
var outputSize = document.getElementById("die" + numDies).value;
|
|
|
|
|
if (outputSize < 10.0 && outputSize > 0) { // If we have a 'proper' number i.e. ".130"
|
|
|
|
|
outputSize = Number(outputSize);
|
|
|
|
|
} else { // re-format the number if it's 'wrong' i.e. "130"
|
|
|
|
|
outputSize = outputSize / 1000;
|
|
|
|
|
}
|
|
|
|
|
console.log(outputSize);
|
|
|
|
|
var outputText = outputSize + "\" (" + toMillimetres(outputSize) + " mm)";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
subtitle.innerHTML = "For " + inputText + " to " + outputText;
|
|
|
|
|
reductionCount.innerHTML = "Across " + numDies + " reductions";
|
|
|
|
|
window.print();
|
|
|
|
|
}
|