From 42d84dbfa0e78a79a5e14ae3c8417d623d65df0d Mon Sep 17 00:00:00 2001 From: Daniel Dunn Date: Wed, 2 Apr 2025 19:22:29 -0600 Subject: [PATCH] Fix wire gauge bugs, add extra outputs to generic calc generation --- package-lock.json | 12 +++ package.json | 2 + src/components/input/NumericInputWithUnit.tsx | 78 +++++++++++++++++++ src/datatables/data/wire_gauge.ts | 2 +- .../tools/number/generic-calc/data/types.ts | 6 ++ .../generic-calc/data/wire_voltage_drop.ts | 15 +++- src/pages/tools/number/generic-calc/index.tsx | 32 ++++++++ 7 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 src/components/input/NumericInputWithUnit.tsx diff --git a/package-lock.json b/package-lock.json index 6511848..cfa3e2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@mui/material": "^5.15.20", "@playwright/test": "^1.45.0", "@types/ffmpeg": "^1.0.7", + "@types/js-quantities": "^1.6.6", "@types/lodash": "^4.17.5", "@types/morsee": "^1.0.2", "@types/omggif": "^1.0.5", @@ -26,6 +27,7 @@ "color": "^4.2.3", "formik": "^2.4.6", "jimp": "^0.22.12", + "js-quantities": "^1.8.0", "lint-staged": "^15.4.3", "lodash": "^4.17.21", "mime": "^4.0.6", @@ -3112,6 +3114,11 @@ "hoist-non-react-statics": "^3.3.0" } }, + "node_modules/@types/js-quantities": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@types/js-quantities/-/js-quantities-1.6.6.tgz", + "integrity": "sha512-k2Q8/Avj4Oz50flfTnfVGnUCkt7OYQ3U+lfQVELE/x5mdbwChZ7fM0wpUpVWzbuSL8kIYt9ZsFQ0RFNBv8T3Qw==" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -6970,6 +6977,11 @@ "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", "license": "BSD-3-Clause" }, + "node_modules/js-quantities": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/js-quantities/-/js-quantities-1.8.0.tgz", + "integrity": "sha512-swDw9RJpXACAWR16vAKoSojAsP6NI7cZjjnjKqhOyZSdybRUdmPr071foD3fejUKSU2JMHz99hflWkRWvfLTpQ==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index cd950ab..b8dd4f8 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@mui/material": "^5.15.20", "@playwright/test": "^1.45.0", "@types/ffmpeg": "^1.0.7", + "@types/js-quantities": "^1.6.6", "@types/lodash": "^4.17.5", "@types/morsee": "^1.0.2", "@types/omggif": "^1.0.5", @@ -43,6 +44,7 @@ "color": "^4.2.3", "formik": "^2.4.6", "jimp": "^0.22.12", + "js-quantities": "^1.8.0", "lint-staged": "^15.4.3", "lodash": "^4.17.21", "mime": "^4.0.6", diff --git a/src/components/input/NumericInputWithUnit.tsx b/src/components/input/NumericInputWithUnit.tsx new file mode 100644 index 0000000..bef047b --- /dev/null +++ b/src/components/input/NumericInputWithUnit.tsx @@ -0,0 +1,78 @@ +import React, { useState, useEffect } from 'react'; +import { TextField, Grid } from '@mui/material'; +import Autocomplete from '@mui/material/Autocomplete'; +import Qty from 'js-quantities'; + +export default function NumericInputWithUnit(props: { + value: { value: number; unit: string }; + onChange: (value: { value: number; unit: string }) => void; +}) { + const [inputValue, setInputValue] = useState(props.value.value); + const [unit, setUnit] = useState(props.value.unit); + const [unitOptions, setUnitOptions] = useState([]); + + useEffect(() => { + try { + const kind = Qty(props.value.unit).kind(); + const units = Qty.getUnits(kind); + setUnitOptions(units); + } catch (error) { + console.error('Invalid unit kind', error); + } + }, [props.value.unit]); + + useEffect(() => { + setInputValue(props.value.value); + setUnit(props.value.unit); + }, [props.value]); + + const handleValueChange = (event: React.ChangeEvent) => { + const newValue = parseFloat(event.target.value) || 0; + setInputValue(newValue); + if (props.onChange) { + try { + const qty = Qty(newValue, unit).to('meters'); + props.onChange({ unit: 'meters', value: qty.scalar }); + } catch (error) { + console.error('Conversion error', error); + } + } + }; + + const handleUnitChange = (newUnit: string) => { + if (!newUnit) return; + setUnit(newUnit); + try { + const convertedValue = Qty(inputValue, unit).to(newUnit).scalar; + setInputValue(convertedValue); + } catch (error) { + console.error('Unit conversion error', error); + } + }; + + return ( + + + + + + { + handleUnitChange(unit); + }} + renderInput={(params) => ( + + )} + /> + + + ); +} diff --git a/src/datatables/data/wire_gauge.ts b/src/datatables/data/wire_gauge.ts index 94b2a19..52e4536 100644 --- a/src/datatables/data/wire_gauge.ts +++ b/src/datatables/data/wire_gauge.ts @@ -69,7 +69,7 @@ const data: DataTable = { }; for (const key in data.data) { - data.data[key].area = Math.PI * data.data[key].diameter ** 2; + data.data[key].area = Math.PI * (data.data[key].diameter / 2) ** 2; } export default data; diff --git a/src/pages/tools/number/generic-calc/data/types.ts b/src/pages/tools/number/generic-calc/data/types.ts index 084413b..52d6a57 100644 --- a/src/pages/tools/number/generic-calc/data/types.ts +++ b/src/pages/tools/number/generic-calc/data/types.ts @@ -2,6 +2,12 @@ export interface GenericCalcType { title: string; name: string; formula: string; + + extraOutputs?: { + title: string; + formula: string; + unit: string; + }[]; selections?: { title: string; source: string; diff --git a/src/pages/tools/number/generic-calc/data/wire_voltage_drop.ts b/src/pages/tools/number/generic-calc/data/wire_voltage_drop.ts index f0338a2..59deba8 100644 --- a/src/pages/tools/number/generic-calc/data/wire_voltage_drop.ts +++ b/src/pages/tools/number/generic-calc/data/wire_voltage_drop.ts @@ -2,7 +2,7 @@ import type { GenericCalcType } from './types'; const voltagedropinwire: GenericCalcType = { title: 'Round trip voltage drop in cable', name: 'cable-voltage-drop', - formula: 'x = (((p * L) / (A/10**6) ) *2) * I**2', + formula: 'x = (((p * L) / (A/10**6) ) *2) * I', selections: [ { title: 'Material', @@ -22,6 +22,19 @@ const voltagedropinwire: GenericCalcType = { } } ], + + extraOutputs: [ + { + title: 'Total Resistance', + formula: '((p * L) / (A/10**6))*2', + unit: 'Ω' + }, + { + title: 'Total Power Dissipated', + formula: 'I**2 * (((p * L) / (A/10**6))*2)', + unit: 'W' + } + ], variables: [ { name: 'L', diff --git a/src/pages/tools/number/generic-calc/index.tsx b/src/pages/tools/number/generic-calc/index.tsx index 473c85d..207a237 100644 --- a/src/pages/tools/number/generic-calc/index.tsx +++ b/src/pages/tools/number/generic-calc/index.tsx @@ -49,6 +49,10 @@ export default async function makeTool( [key: string]: string; }>({}); + const [extraOutputs, setExtraOutputs] = useState<{ + [key: string]: string; + }>({}); + const updateVarField = ( name: string, value: number, @@ -273,6 +277,15 @@ export default async function makeTool( ))} + + {calcData.extraOutputs?.map((extraOutput) => ( + + {extraOutput.title} + {extraOutputs[extraOutput.title]} + {extraOutput.unit} + + + ))} ) @@ -311,6 +324,25 @@ export default async function makeTool( } else { setShortResult(''); } + + if (calcData.extraOutputs !== undefined) { + for (let i = 0; i < calcData.extraOutputs.length; i++) { + const extraOutput = calcData.extraOutputs[i]; + + let expr = nerdamer(extraOutput.formula); + + Object.keys(values.vars).forEach((key) => { + if (key === values.outputVariable) return; + expr = expr.sub(key, values.vars[key].value.toString()); + }); + + const result: nerdamer.Expression = expr.evaluate(); + + if (result) { + extraOutputs[extraOutput.title] = result.toDecimal(); + } + } + } }} /> );