mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
Created Dipole Antenna calculator.
This commit is contained in:
parent
8cf07c2ffb
commit
9986ce8a1f
5 changed files with 395 additions and 221 deletions
|
|
@ -1,227 +1,10 @@
|
|||
import React from "react";
|
||||
import {BackButton, roundDigits, useTitle} from "./Common";
|
||||
import {BackButton, useTitle} from "./Common";
|
||||
import {Button, Header, Icon} from "./Theme";
|
||||
import {GridColumn, GridRow, Input} from "semantic-ui-react";
|
||||
import Grid from "semantic-ui-react/dist/commonjs/collections/Grid";
|
||||
import {useCalcQuery} from "../hooks/customHooks";
|
||||
import {ColoredInput} from "./Apps";
|
||||
|
||||
function TemperatureCalculator() {
|
||||
const [state, setState] = React.useState({
|
||||
celsius: '',
|
||||
fahrenheit: '',
|
||||
kelvin: '',
|
||||
})
|
||||
|
||||
const handleInputChange = (e, {name, value}) => {
|
||||
if (value === '') {
|
||||
// User has cleared the input;
|
||||
setState({volt: '', ohm: '', amp: ''});
|
||||
return
|
||||
}
|
||||
|
||||
const numValue = parseFloat(value.endsWith('.') ? `${value}0` : value);
|
||||
console.debug(`Calculating ${value} ${name}`);
|
||||
let newCelsius;
|
||||
let newKelvin;
|
||||
let newFahrenheit;
|
||||
if (name === 'fahrenheit') {
|
||||
newFahrenheit = value;
|
||||
newCelsius = roundDigits((numValue - 32) / 1.8);
|
||||
newKelvin = roundDigits(newCelsius + 273.15);
|
||||
} else if (name === 'celsius') {
|
||||
newCelsius = value;
|
||||
newFahrenheit = roundDigits((numValue * 1.8) + 32);
|
||||
newKelvin = roundDigits(numValue + 273.15);
|
||||
} else if (name === 'kelvin') {
|
||||
newKelvin = value;
|
||||
newCelsius = roundDigits(numValue - 273.15);
|
||||
newFahrenheit = roundDigits((newCelsius * 1.8) + 32);
|
||||
}
|
||||
setState({
|
||||
celsius: newCelsius,
|
||||
fahrenheit: newFahrenheit,
|
||||
kelvin: newKelvin
|
||||
});
|
||||
}
|
||||
|
||||
const handleClick = (e) => {
|
||||
e.target.select();
|
||||
}
|
||||
|
||||
const commonInputProps = {
|
||||
fluid: true,
|
||||
labelPosition: 'right',
|
||||
type: 'number',
|
||||
onChange: handleInputChange,
|
||||
onClick: handleClick
|
||||
};
|
||||
|
||||
return <Grid columns={3}>
|
||||
<GridRow>
|
||||
<GridColumn>
|
||||
<Input value={state.celsius} label='°C' name='celsius' {...commonInputProps}/>
|
||||
</GridColumn>
|
||||
<GridColumn>
|
||||
<Input value={state.fahrenheit} label='°F' name='fahrenheit' {...commonInputProps}/>
|
||||
</GridColumn>
|
||||
<GridColumn>
|
||||
<Input value={state.kelvin} label='K' name='kelvin' {...commonInputProps}/>
|
||||
</GridColumn>
|
||||
</GridRow>
|
||||
</Grid>
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
volts: '',
|
||||
amps: '',
|
||||
ohms: '',
|
||||
watts: '',
|
||||
lastUpdated: [],
|
||||
};
|
||||
|
||||
// Ohms Law functions. These take two values, and return the other two electrical values.
|
||||
const voltsAmps = (volts, amps) => {
|
||||
const watts = volts * amps;
|
||||
const ohms = volts / amps;
|
||||
return [roundDigits(watts) || 0, roundDigits(ohms) || 0]
|
||||
};
|
||||
const voltsOhms = (volts, ohms) => {
|
||||
const amps = volts / ohms;
|
||||
const watts = volts * amps;
|
||||
return [roundDigits(amps) || 0, roundDigits(watts) || 0]
|
||||
};
|
||||
const ampsOhms = (amps, ohms) => {
|
||||
const volts = amps * ohms;
|
||||
const watts = volts * amps;
|
||||
return [roundDigits(volts) || 0, roundDigits(watts) || 0]
|
||||
};
|
||||
const voltsWatts = (volts, watts) => {
|
||||
const amps = watts / volts;
|
||||
const ohms = volts / amps;
|
||||
return [roundDigits(amps) || 0, roundDigits(ohms) || 0]
|
||||
};
|
||||
const ampsWatts = (amps, watts) => {
|
||||
const volts = watts / amps;
|
||||
const ohms = volts / amps;
|
||||
return [roundDigits(volts) || 0, roundDigits(ohms) || 0]
|
||||
};
|
||||
const wattsOhms = (watts, ohms) => {
|
||||
const volts = Math.sqrt(watts * ohms);
|
||||
const amps = volts / ohms;
|
||||
return [roundDigits(volts), roundDigits(amps)]
|
||||
};
|
||||
|
||||
function ohmsLawReducer(state, action) {
|
||||
const {type, value} = action;
|
||||
let {volts, amps, ohms, watts, lastUpdated} = state;
|
||||
|
||||
// Only replace last updated when a different input was updated.
|
||||
let newLastUpdated = lastUpdated;
|
||||
if (lastUpdated.length === 0) {
|
||||
newLastUpdated = [type];
|
||||
} else if (lastUpdated.length === 1 && lastUpdated[0] !== type) {
|
||||
newLastUpdated = [...lastUpdated, type];
|
||||
} else if (lastUpdated.length > 1 && lastUpdated[1] !== type) {
|
||||
newLastUpdated = [lastUpdated[1], type];
|
||||
}
|
||||
|
||||
// Copy new value into it's respective state. Do not allow negative numbers.
|
||||
if (type === 'amps') {
|
||||
amps = Math.abs(value);
|
||||
} else if (type === 'volts') {
|
||||
volts = Math.abs(value);
|
||||
} else if (type === 'ohms') {
|
||||
ohms = Math.abs(value);
|
||||
} else if (type === 'watts') {
|
||||
watts = Math.abs(value);
|
||||
}
|
||||
|
||||
// Sort the updated values, so we don't have to define everything twice.
|
||||
const sortedLastUpdated = [...newLastUpdated].sort().join(',');
|
||||
switch (sortedLastUpdated) {
|
||||
case 'amps,ohms':
|
||||
[volts, watts] = ampsOhms(amps, ohms);
|
||||
break;
|
||||
case 'amps,volts':
|
||||
[watts, ohms] = voltsAmps(volts, amps);
|
||||
break;
|
||||
case 'amps,watts':
|
||||
[volts, ohms] = ampsWatts(amps, watts);
|
||||
break;
|
||||
case 'ohms,volts':
|
||||
[amps, watts] = voltsOhms(volts, ohms);
|
||||
break;
|
||||
case 'ohms,watts':
|
||||
[volts, amps] = wattsOhms(watts, ohms);
|
||||
break;
|
||||
case 'volts,watts':
|
||||
[amps, ohms] = voltsWatts(volts, watts);
|
||||
break;
|
||||
}
|
||||
|
||||
return {volts, amps, ohms, watts, lastUpdated: newLastUpdated};
|
||||
}
|
||||
|
||||
function ElectricalCalculator() {
|
||||
// Provides a form which provides 4 inputs (volts, amps, ohms, watts), and calculates the missing values.
|
||||
|
||||
const [state, dispatch] = React.useReducer(ohmsLawReducer, initialState);
|
||||
|
||||
const calculateColor = (name) => {
|
||||
// Recently updated inputs are white, others are grey.
|
||||
return state.lastUpdated.indexOf(name) >= 0 ? null : 'grey';
|
||||
}
|
||||
|
||||
const inputProps = {
|
||||
fluid: true,
|
||||
type: 'number',
|
||||
labelPosition: 'right',
|
||||
onSelect: e => e.target.select(), // Select the contents of the Input when a user selects it.
|
||||
};
|
||||
|
||||
return <div>
|
||||
<Header as='h4'>Ohm's Law</Header>
|
||||
<Grid columns={2}>
|
||||
<GridRow>
|
||||
<GridColumn>
|
||||
<ColoredInput {...inputProps}
|
||||
value={state.volts}
|
||||
onChange={e => dispatch({type: 'volts', value: e.target.value})}
|
||||
label='Volts'
|
||||
color={calculateColor('volts')}
|
||||
/>
|
||||
</GridColumn>
|
||||
<GridColumn>
|
||||
<ColoredInput {...inputProps}
|
||||
value={state.amps}
|
||||
onChange={e => dispatch({type: 'amps', value: e.target.value})}
|
||||
label='Amps'
|
||||
color={calculateColor('amps')}
|
||||
/>
|
||||
</GridColumn>
|
||||
</GridRow>
|
||||
<GridRow>
|
||||
<GridColumn>
|
||||
<ColoredInput {...inputProps}
|
||||
value={state.ohms}
|
||||
onChange={e => dispatch({type: 'ohms', value: e.target.value})}
|
||||
label='Ohms'
|
||||
color={calculateColor('ohms')}
|
||||
/>
|
||||
</GridColumn>
|
||||
<GridColumn>
|
||||
<ColoredInput {...inputProps}
|
||||
value={state.watts}
|
||||
onChange={e => dispatch({type: 'watts', value: e.target.value})}
|
||||
label='Watts'
|
||||
color={calculateColor('watts')}
|
||||
/>
|
||||
</GridColumn>
|
||||
</GridRow>
|
||||
</Grid>
|
||||
</div>
|
||||
}
|
||||
import {TemperatureCalculator} from "./calculators/TemperatureCalculator";
|
||||
import {ElectricalCalculator} from "./calculators/ElectricalCalculators";
|
||||
import {DipoleAntennaCalculator} from "./calculators/HamCalculators";
|
||||
|
||||
export function CalculatorsPage() {
|
||||
const {calc, setCalc} = useCalcQuery();
|
||||
|
|
@ -229,6 +12,7 @@ export function CalculatorsPage() {
|
|||
const calculators = [
|
||||
{key: 'temperature', icon: 'thermometer', button: 'Temperature', contents: <TemperatureCalculator/>},
|
||||
{key: 'electrical', icon: 'lightning', button: 'Electrical', contents: <ElectricalCalculator/>},
|
||||
{key: 'antenna', icon: 'signal', button: 'Antenna', contents: <DipoleAntennaCalculator/>},
|
||||
];
|
||||
|
||||
const activeCalculator = calc ?
|
||||
|
|
|
|||
|
|
@ -43,6 +43,11 @@ const SUGGESTED_APPS = [
|
|||
title: 'Electrical Calculator',
|
||||
description: 'Convert Volts, Ohms, Amps, Watts'
|
||||
},
|
||||
{
|
||||
location: '/more/calculators?calc=antenna',
|
||||
title: 'Antenna Calculator',
|
||||
description: 'Calculate dipole length, wavelength.'
|
||||
},
|
||||
];
|
||||
|
||||
export const useSearch = (defaultLimit = 48, totalPages = 0, emptySearch = false, model) => {
|
||||
|
|
|
|||
157
app/src/components/calculators/ElectricalCalculators.js
Normal file
157
app/src/components/calculators/ElectricalCalculators.js
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
import {roundDigits} from "../Common";
|
||||
import React from "react";
|
||||
import {Header} from "../Theme";
|
||||
import Grid from "semantic-ui-react/dist/commonjs/collections/Grid";
|
||||
import {GridColumn, GridRow} from "semantic-ui-react";
|
||||
import {ColoredInput} from "../Apps";
|
||||
|
||||
const initialState = {
|
||||
volts: '',
|
||||
amps: '',
|
||||
ohms: '',
|
||||
watts: '',
|
||||
lastUpdated: [],
|
||||
};
|
||||
|
||||
// Ohms Law functions. These take two values, and return the other two electrical values.
|
||||
const voltsAmps = (volts, amps) => {
|
||||
const watts = volts * amps;
|
||||
const ohms = volts / amps;
|
||||
return [roundDigits(watts) || 0, roundDigits(ohms) || 0]
|
||||
};
|
||||
const voltsOhms = (volts, ohms) => {
|
||||
const amps = volts / ohms;
|
||||
const watts = volts * amps;
|
||||
return [roundDigits(amps) || 0, roundDigits(watts) || 0]
|
||||
};
|
||||
const ampsOhms = (amps, ohms) => {
|
||||
const volts = amps * ohms;
|
||||
const watts = volts * amps;
|
||||
return [roundDigits(volts) || 0, roundDigits(watts) || 0]
|
||||
};
|
||||
const voltsWatts = (volts, watts) => {
|
||||
const amps = watts / volts;
|
||||
const ohms = volts / amps;
|
||||
return [roundDigits(amps) || 0, roundDigits(ohms) || 0]
|
||||
};
|
||||
const ampsWatts = (amps, watts) => {
|
||||
const volts = watts / amps;
|
||||
const ohms = volts / amps;
|
||||
return [roundDigits(volts) || 0, roundDigits(ohms) || 0]
|
||||
};
|
||||
const wattsOhms = (watts, ohms) => {
|
||||
const volts = Math.sqrt(watts * ohms);
|
||||
const amps = volts / ohms;
|
||||
return [roundDigits(volts), roundDigits(amps)]
|
||||
};
|
||||
|
||||
function ohmsLawReducer(state, action) {
|
||||
const {type, value} = action;
|
||||
let {volts, amps, ohms, watts, lastUpdated} = state;
|
||||
|
||||
// Only replace last updated when a different input was updated.
|
||||
let newLastUpdated = lastUpdated;
|
||||
if (lastUpdated.length === 0) {
|
||||
newLastUpdated = [type];
|
||||
} else if (lastUpdated.length === 1 && lastUpdated[0] !== type) {
|
||||
newLastUpdated = [...lastUpdated, type];
|
||||
} else if (lastUpdated.length > 1 && lastUpdated[1] !== type) {
|
||||
newLastUpdated = [lastUpdated[1], type];
|
||||
}
|
||||
|
||||
// Copy new value into it's respective state. Do not allow negative numbers.
|
||||
if (type === 'amps') {
|
||||
amps = Math.abs(value);
|
||||
} else if (type === 'volts') {
|
||||
volts = Math.abs(value);
|
||||
} else if (type === 'ohms') {
|
||||
ohms = Math.abs(value);
|
||||
} else if (type === 'watts') {
|
||||
watts = Math.abs(value);
|
||||
}
|
||||
|
||||
// Sort the updated values, so we don't have to define everything twice.
|
||||
const sortedLastUpdated = [...newLastUpdated].sort().join(',');
|
||||
switch (sortedLastUpdated) {
|
||||
case 'amps,ohms':
|
||||
[volts, watts] = ampsOhms(amps, ohms);
|
||||
break;
|
||||
case 'amps,volts':
|
||||
[watts, ohms] = voltsAmps(volts, amps);
|
||||
break;
|
||||
case 'amps,watts':
|
||||
[volts, ohms] = ampsWatts(amps, watts);
|
||||
break;
|
||||
case 'ohms,volts':
|
||||
[amps, watts] = voltsOhms(volts, ohms);
|
||||
break;
|
||||
case 'ohms,watts':
|
||||
[volts, amps] = wattsOhms(watts, ohms);
|
||||
break;
|
||||
case 'volts,watts':
|
||||
[amps, ohms] = voltsWatts(volts, watts);
|
||||
break;
|
||||
}
|
||||
|
||||
return {volts, amps, ohms, watts, lastUpdated: newLastUpdated};
|
||||
}
|
||||
|
||||
export function ElectricalCalculator() {
|
||||
// Provides a form which provides 4 inputs (volts, amps, ohms, watts), and calculates the missing values.
|
||||
|
||||
const [state, dispatch] = React.useReducer(ohmsLawReducer, initialState);
|
||||
|
||||
const calculateColor = (name) => {
|
||||
// Recently updated inputs are white, others are grey.
|
||||
return state.lastUpdated.indexOf(name) >= 0 ? null : 'grey';
|
||||
}
|
||||
|
||||
const inputProps = {
|
||||
fluid: true,
|
||||
type: 'number',
|
||||
labelPosition: 'right',
|
||||
onSelect: e => e.target.select(), // Select the contents of the Input when a user selects it.
|
||||
};
|
||||
|
||||
return <div>
|
||||
<Header as='h4'>Ohm's Law</Header>
|
||||
<Grid columns={2}>
|
||||
<GridRow>
|
||||
<GridColumn>
|
||||
<ColoredInput {...inputProps}
|
||||
value={state.volts}
|
||||
onChange={e => dispatch({type: 'volts', value: e.target.value})}
|
||||
label='Volts'
|
||||
color={calculateColor('volts')}
|
||||
/>
|
||||
</GridColumn>
|
||||
<GridColumn>
|
||||
<ColoredInput {...inputProps}
|
||||
value={state.amps}
|
||||
onChange={e => dispatch({type: 'amps', value: e.target.value})}
|
||||
label='Amps'
|
||||
color={calculateColor('amps')}
|
||||
/>
|
||||
</GridColumn>
|
||||
</GridRow>
|
||||
<GridRow>
|
||||
<GridColumn>
|
||||
<ColoredInput {...inputProps}
|
||||
value={state.ohms}
|
||||
onChange={e => dispatch({type: 'ohms', value: e.target.value})}
|
||||
label='Ohms'
|
||||
color={calculateColor('ohms')}
|
||||
/>
|
||||
</GridColumn>
|
||||
<GridColumn>
|
||||
<ColoredInput {...inputProps}
|
||||
value={state.watts}
|
||||
onChange={e => dispatch({type: 'watts', value: e.target.value})}
|
||||
label='Watts'
|
||||
color={calculateColor('watts')}
|
||||
/>
|
||||
</GridColumn>
|
||||
</GridRow>
|
||||
</Grid>
|
||||
</div>
|
||||
}
|
||||
158
app/src/components/calculators/HamCalculators.js
Normal file
158
app/src/components/calculators/HamCalculators.js
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
import React from "react";
|
||||
import {TableBody, TableCell, TableHeader, TableHeaderCell, TableRow} from "semantic-ui-react";
|
||||
import {Header, Table} from "../Theme";
|
||||
import Grid from "semantic-ui-react/dist/commonjs/collections/Grid";
|
||||
import {roundDigits} from "../Common";
|
||||
import {ColoredInput} from "../Apps";
|
||||
|
||||
function convertFeetToFeetAndInches(decimalFeet) {
|
||||
// Extract the integer part for feet
|
||||
const feet = Math.floor(decimalFeet);
|
||||
// Calculate the remainder in feet and convert it to inches (1 foot = 12 inches)
|
||||
const inches = Math.round((decimalFeet - feet) * 12);
|
||||
|
||||
return [feet, inches];
|
||||
}
|
||||
|
||||
const defaultMhzInputValue = '144.2';
|
||||
|
||||
export function DipoleAntennaCalculator() {
|
||||
const [mhz, setMhz] = React.useState(144.2);
|
||||
const [wave, setWave] = React.useState(2.08);
|
||||
const [mhzInputValue, setMhzInputValue] = React.useState(defaultMhzInputValue);
|
||||
const [waveInputValue, setWaveInputValue] = React.useState(0);
|
||||
const [feet, setFeet] = React.useState(0);
|
||||
const [inches, setInches] = React.useState(0);
|
||||
const [meters, setMeters] = React.useState(0);
|
||||
const [cm, setCM] = React.useState(0);
|
||||
const c = 299792458;
|
||||
|
||||
// Reduce the full wavelength by the multiplier.
|
||||
const lengths = [
|
||||
{name: '½ Antenna Length', multiplier: 0.5},
|
||||
{name: '¼ Antenna Length', multiplier: 0.25},
|
||||
{name: '⅝ Antenna Length', multiplier: 0.625},
|
||||
];
|
||||
|
||||
React.useEffect(() => {
|
||||
// Calculate full wavelength.
|
||||
const newFeet = 936 / mhz;
|
||||
setFeet(newFeet);
|
||||
setInches(newFeet * 12);
|
||||
setMeters(newFeet * 0.3048);
|
||||
setCM(newFeet * 0.3048 * 100);
|
||||
setWaveInputValue(roundDigits(c / (mhz * 1e6)));
|
||||
}, [mhz]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (wave && parseFloat(wave) > 0) {
|
||||
setMhzInputValue(roundDigits(c / parseFloat(wave) / 1e6));
|
||||
}
|
||||
}, [wave])
|
||||
|
||||
const mhzStorageKey = 'dipole_mhz';
|
||||
const storageMhzValue = localStorage.getItem(mhzStorageKey);
|
||||
React.useEffect(() => {
|
||||
if (storageMhzValue) {
|
||||
setMhz(parseFloat(storageMhzValue));
|
||||
setMhzInputValue(storageMhzValue);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleMhzChange = (e, {value}) => {
|
||||
setMhzInputValue(value);
|
||||
setMhz(value && parseFloat(value) > 0 ? parseFloat(value) : 0);
|
||||
localStorage.setItem(mhzStorageKey, value);
|
||||
}
|
||||
|
||||
const handleWaveChange = (e, {value}) => {
|
||||
setWaveInputValue(value);
|
||||
setWave(value && parseFloat(value) > 0 ? parseFloat(value) : 0);
|
||||
}
|
||||
|
||||
const [mhzSelected, setMhzSelected] = React.useState(true);
|
||||
const handleClick = (e, name) => {
|
||||
if (name === 'mhz') {
|
||||
setMhzSelected(true);
|
||||
} else {
|
||||
setMhzSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
return <>
|
||||
<Header as='h2'>Dipole Antenna</Header>
|
||||
|
||||
<Grid columns={2}>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<ColoredInput fluid
|
||||
label='MHz'
|
||||
labelPosition='right'
|
||||
value={mhzInputValue}
|
||||
onChange={handleMhzChange}
|
||||
onSelect={e => handleClick(e, 'mhz')}
|
||||
color={mhzSelected ? null : 'grey'}
|
||||
/>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<ColoredInput fluid
|
||||
label='Wavelength'
|
||||
labelPosition='right'
|
||||
value={waveInputValue}
|
||||
onChange={handleWaveChange}
|
||||
onSelect={e => handleClick(e, 'wave')}
|
||||
color={mhzSelected ? 'grey' : null}
|
||||
/>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
</Grid>
|
||||
|
||||
{lengths.map(i => {
|
||||
const [feet_, inches_] = convertFeetToFeetAndInches(feet * i.multiplier);
|
||||
const [half_feet, half_inches] = convertFeetToFeetAndInches(feet * i.multiplier / 2);
|
||||
return <Table key={i.name} size='large' striped unstackable>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHeaderCell>{i.name}</TableHeaderCell>
|
||||
<TableHeaderCell>Leg Length</TableHeaderCell>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
{feet_} ft. {inches_} in.
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{half_feet} ft. {half_inches} in.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
{roundDigits(inches * i.multiplier)} inches
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{roundDigits(inches * i.multiplier / 2)} inches
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
{roundDigits(meters * i.multiplier)} meters
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{roundDigits(meters * i.multiplier / 2)} meters
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
{roundDigits(cm * i.multiplier)} cm.
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{roundDigits(cm * i.multiplier / 2)} cm.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
})}
|
||||
</>
|
||||
}
|
||||
70
app/src/components/calculators/TemperatureCalculator.js
Normal file
70
app/src/components/calculators/TemperatureCalculator.js
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import React from "react";
|
||||
import {roundDigits} from "../Common";
|
||||
import Grid from "semantic-ui-react/dist/commonjs/collections/Grid";
|
||||
import {GridColumn, GridRow, Input} from "semantic-ui-react";
|
||||
|
||||
export function TemperatureCalculator() {
|
||||
const [state, setState] = React.useState({
|
||||
celsius: '',
|
||||
fahrenheit: '',
|
||||
kelvin: '',
|
||||
})
|
||||
|
||||
const handleInputChange = (e, {name, value}) => {
|
||||
if (value === '') {
|
||||
// User has cleared the input;
|
||||
setState({volt: '', ohm: '', amp: ''});
|
||||
return
|
||||
}
|
||||
|
||||
const numValue = parseFloat(value.endsWith('.') ? `${value}0` : value);
|
||||
console.debug(`Calculating ${value} ${name}`);
|
||||
let newCelsius;
|
||||
let newKelvin;
|
||||
let newFahrenheit;
|
||||
if (name === 'fahrenheit') {
|
||||
newFahrenheit = value;
|
||||
newCelsius = roundDigits((numValue - 32) / 1.8);
|
||||
newKelvin = roundDigits(newCelsius + 273.15);
|
||||
} else if (name === 'celsius') {
|
||||
newCelsius = value;
|
||||
newFahrenheit = roundDigits((numValue * 1.8) + 32);
|
||||
newKelvin = roundDigits(numValue + 273.15);
|
||||
} else if (name === 'kelvin') {
|
||||
newKelvin = value;
|
||||
newCelsius = roundDigits(numValue - 273.15);
|
||||
newFahrenheit = roundDigits((newCelsius * 1.8) + 32);
|
||||
}
|
||||
setState({
|
||||
celsius: newCelsius,
|
||||
fahrenheit: newFahrenheit,
|
||||
kelvin: newKelvin
|
||||
});
|
||||
}
|
||||
|
||||
const handleClick = (e) => {
|
||||
e.target.select();
|
||||
}
|
||||
|
||||
const commonInputProps = {
|
||||
fluid: true,
|
||||
labelPosition: 'right',
|
||||
type: 'number',
|
||||
onChange: handleInputChange,
|
||||
onClick: handleClick
|
||||
};
|
||||
|
||||
return <Grid columns={3}>
|
||||
<GridRow>
|
||||
<GridColumn>
|
||||
<Input value={state.celsius} label='°C' name='celsius' {...commonInputProps}/>
|
||||
</GridColumn>
|
||||
<GridColumn>
|
||||
<Input value={state.fahrenheit} label='°F' name='fahrenheit' {...commonInputProps}/>
|
||||
</GridColumn>
|
||||
<GridColumn>
|
||||
<Input value={state.kelvin} label='K' name='kelvin' {...commonInputProps}/>
|
||||
</GridColumn>
|
||||
</GridRow>
|
||||
</Grid>
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue